Class FLabel: Add multiple lines support

This commit is contained in:
Markus Gans 2015-07-18 21:31:26 +02:00
parent 35a50fdbd7
commit 4ec8a3dda4
6 changed files with 168 additions and 94 deletions

View File

@ -1,3 +1,6 @@
2015-06-18 Markus Gans <guru.mail@muenster.de>
* Add multiple lines support for FLabel
2015-06-12 Markus Gans <guru.mail@muenster.de> 2015-06-12 Markus Gans <guru.mail@muenster.de>
* Improve focusFirstChild() and focusLastChild() * Improve focusFirstChild() and focusLastChild()

View File

@ -20,7 +20,6 @@ Missing Features
└──► tmp └──► tmp
--------------------------------------- ---------------------------------------
- Multiple lines support for FLabel
- Add a window switcher on the right side of the status bar - Add a window switcher on the right side of the status bar
- Add a scrolling area with on-demand scroll bars for FButtonGroup - Add a scrolling area with on-demand scroll bars for FButtonGroup

View File

@ -37,8 +37,8 @@ void FLabel::init()
{ {
flags = 0; flags = 0;
emphasis = 0; emphasis = 0;
xoffset = 0;
alignment = fc::alignLeft; alignment = fc::alignLeft;
multiline = false;
this->text = ""; this->text = "";
accel_widget = 0; accel_widget = 0;
@ -70,6 +70,27 @@ uChar FLabel::getHotkey()
return 0; return 0;
} }
//----------------------------------------------------------------------
int FLabel::getHotkeyPos(wchar_t*& src, wchar_t*& dest, uInt length)
{
// find hotkey position in string
// + generate a new string without the '&'-sign
int hotkeypos = -1;
wchar_t* txt = src;
for (uInt i=0; i < length; i++)
{
if ( (i < length) && (txt[i] == L'&') && (hotkeypos == -1) )
{
hotkeypos = int(i);
i++;
src++;
}
*dest++ = *src++;
}
return hotkeypos;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLabel::setHotkeyAccelerator() void FLabel::setHotkeyAccelerator()
{ {
@ -91,56 +112,40 @@ void FLabel::setHotkeyAccelerator()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLabel::draw() int FLabel::getXOffset(int length)
{ {
register wchar_t* src; switch ( alignment )
register wchar_t* dest; {
wchar_t* LabelText; case fc::alignLeft:
FString txt; return 0;
uInt length;
int hotkeypos, to_char;
bool isActive, isNoUnderline;
if ( text.isNull() || text.isEmpty() ) case fc::alignCenter:
return; if ( length < width )
return int((width - length) / 2);
if ( Encoding == fc::VT100 )
unsetVT100altChar();
setUpdateVTerm(false);
if ( hasEmphasis() )
setColor (emphasis_color, backgroundColor);
else else
setColor (foregroundColor, backgroundColor); return 0;
length = text.getLength(); case fc::alignRight:
hotkeypos = -1; if ( length < width )
LabelText = new wchar_t[length+1]; return width - length;
txt = this->text; else
src = const_cast<wchar_t*>(txt.wc_str()); return 0;
dest = const_cast<wchar_t*>(LabelText); }
return 0;
}
//----------------------------------------------------------------------
void FLabel::printLine ( wchar_t*& line,
uInt length,
int hotkeypos,
int xoffset)
{
int to_char;
bool isActive, isNoUnderline;
isActive = ((flags & ACTIVE) != 0); isActive = ((flags & ACTIVE) != 0);
isNoUnderline = ((flags & NO_UNDERLINE) != 0); isNoUnderline = ((flags & NO_UNDERLINE) != 0);
// find hotkey position in string
// + generate a new string without the '&'-sign
for (uInt i=0; i < length; i++)
{
if ( (i < length) && (txt[i] == '&') && (hotkeypos == -1) )
{
hotkeypos = int(i);
i++;
src++;
}
*dest++ = *src++;
}
if ( hotkeypos != -1 )
length--;
gotoxy (xpos+xmin-1, ypos+ymin-1);
for (int x=0; x < xoffset; x++) for (int x=0; x < xoffset; x++)
print (' '); print (' ');
@ -154,12 +159,14 @@ void FLabel::draw()
for (int z=0; z < to_char; z++) for (int z=0; z < to_char; z++)
{ {
if ( ! iswprint(wint_t(line[z])) )
line[z] = L' ';
if ( (z == hotkeypos) && isActive ) if ( (z == hotkeypos) && isActive )
{ {
setColor (wc.label_hotkey_fg, wc.label_hotkey_bg); setColor (wc.label_hotkey_fg, wc.label_hotkey_bg);
if ( ! isNoUnderline ) if ( ! isNoUnderline )
setUnderline(); setUnderline();
print ( LabelText[z] ); print ( line[z] );
if ( ! isNoUnderline ) if ( ! isNoUnderline )
unsetUnderline(); unsetUnderline();
if ( hasEmphasis() ) if ( hasEmphasis() )
@ -168,22 +175,105 @@ void FLabel::draw()
setColor (foregroundColor, backgroundColor); setColor (foregroundColor, backgroundColor);
} }
else else
print ( LabelText[z] ); print ( line[z] );
} }
for (int x=to_char+2; x < width; x++)
print (' ');
if ( length > uInt(width) ) if ( length > uInt(width) )
{ {
setColor (ellipsis_color, backgroundColor); setColor (ellipsis_color, backgroundColor);
print (".."); print ("..");
setColor (foregroundColor, backgroundColor);
} }
else
{
for (int x=xoffset+to_char; x < width; x++)
print (' ');
}
if ( hasReverseMode() ) if ( hasReverseMode() )
setReverse(false); setReverse(false);
}
setUpdateVTerm(true); //----------------------------------------------------------------------
void FLabel::draw()
{
wchar_t* src;
wchar_t* dest;
wchar_t* LabelText;
uInt length;
int hotkeypos, xoffset;
if ( text.isNull() || text.isEmpty() )
return;
if ( Encoding == fc::VT100 )
unsetVT100altChar();
setUpdateVTerm(false);
if ( hasEmphasis() )
setColor (emphasis_color, backgroundColor);
else
setColor (foregroundColor, backgroundColor);
hotkeypos = -1;
if ( multiline && height > 1 )
{
uInt y = 0;
uInt text_lines = uInt(multiline_text.size());
bool hotkey_printed = false;
while ( y < text_lines && y < uInt(height) )
{
length = multiline_text[y].getLength();
LabelText = new wchar_t[length+1];
if ( ! hotkey_printed )
{
src = const_cast<wchar_t*>(multiline_text[y].wc_str());
dest = const_cast<wchar_t*>(LabelText);
hotkeypos = getHotkeyPos(src, dest, length);
}
else
LabelText = const_cast<wchar_t*>(multiline_text[y].wc_str());
gotoxy (xpos+xmin-1, ypos+ymin-1+int(y));
if ( hotkeypos != -1 )
{
xoffset = getXOffset (int(length-1));
printLine (LabelText, length-1, hotkeypos, xoffset);
hotkey_printed = true;
hotkeypos = -1;
}
else
{
xoffset = getXOffset (int(length));
printLine (LabelText, length, -1, xoffset);
}
y++;
delete[] LabelText; delete[] LabelText;
}
}
else
{
length = text.getLength();
LabelText = new wchar_t[length+1];
src = const_cast<wchar_t*>(text.wc_str());
dest = const_cast<wchar_t*>(LabelText);
hotkeypos = getHotkeyPos (src, dest, length);
if ( hotkeypos != -1 )
length--;
gotoxy (xpos+xmin-1, ypos+ymin-1);
xoffset = getXOffset (int(length));
printLine (LabelText, length, hotkeypos, xoffset);
delete[] LabelText;
}
setUpdateVTerm(true);
} }
@ -284,35 +374,12 @@ void FLabel::setAccelWidget (FWidget* widget)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLabel::setAlignment (uInt align) void FLabel::setAlignment (uInt align)
{ {
int text_length;
if ( align != fc::alignLeft if ( align != fc::alignLeft
&& align != fc::alignCenter && align != fc::alignCenter
&& align != fc::alignRight ) && align != fc::alignRight )
alignment = fc::alignLeft; alignment = fc::alignLeft;
else else
alignment = align; alignment = align;
text_length = int(text.getLength());
if ( getHotkey() )
text_length--;
if ( text_length > width )
text_length = width;
switch ( alignment )
{ // convert type to msg string
case fc::alignLeft:
xoffset = 0;
break;
case fc::alignCenter:
xoffset = int((width - text_length) / 2);
break;
case fc::alignRight:
xoffset = width - text_length;
break;
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -361,6 +428,12 @@ void FLabel::setNumber (long num)
void FLabel::setText (const FString& txt) void FLabel::setText (const FString& txt)
{ {
this->text = txt; this->text = txt;
this->multiline_text = text.split("\r\n");
if ( int(multiline_text.size()) > 1 )
multiline = true;
else
multiline = false;
if ( isEnabled() ) if ( isEnabled() )
{ {
delAccelerator (this); delAccelerator (this);

View File

@ -20,9 +20,10 @@
class FLabel : public FWidget class FLabel : public FWidget
{ {
private: private:
std::vector<FString> multiline_text;
bool multiline;
FString text; FString text;
int emphasis; int emphasis;
int xoffset;
uInt alignment; uInt alignment;
uChar emphasis_color; uChar emphasis_color;
uChar ellipsis_color; uChar ellipsis_color;
@ -35,7 +36,10 @@ class FLabel : public FWidget
void init(); void init();
uChar getHotkey(); uChar getHotkey();
int getHotkeyPos (wchar_t*&, wchar_t*&, uInt);
void setHotkeyAccelerator(); void setHotkeyAccelerator();
int getXOffset(int);
void printLine (wchar_t*&, uInt, int, int xoffset=0);
void draw(); void draw();
public: public:

View File

@ -33,24 +33,19 @@ int main (int argc, char* argv[])
// Create text labels // Create text labels
FLabel label_1(&dgl), FLabel label_1(&dgl),
label_2(&dgl), label_2(&dgl);
label_3(&dgl),
label_4(&dgl),
label_5(&dgl);
label_1.setText (wchar_t(fc::BlackUpPointingTriangle)); label_1.setText ( wchar_t(fc::BlackUpPointingTriangle)
label_2.setText (wchar_t(fc::BoxDrawingsUpAndRight) + std::wstring(L"\n")
+ wchar_t(fc::BoxDrawingsUpAndRight)
+ FString(2, wchar_t(fc::BoxDrawingsHorizontal)) + FString(2, wchar_t(fc::BoxDrawingsHorizontal))
+ FString(" Double click the title bar button,") ); + " Double click the title bar button," );
label_3.setText ("press Q on the keyboard,"); label_2.setText ( "press Q on the keyboard,\n"
label_4.setText ("or push the button below to exit"); "or push the button below to exit\n"
label_5.setText ("the program."); "the program." );
label_1.setGeometry (1, 1, 1, 1); label_1.setGeometry (1, 1, 38, 2);
label_2.setGeometry (1, 2, 38, 1); label_2.setGeometry (5, 3, 34, 3);
label_3.setGeometry (5, 3, 24, 1);
label_4.setGeometry (5, 4, 32, 1);
label_5.setGeometry (5, 5, 12, 1);
// Create the quit button // Create the quit button
FButton btn("&Quit", &dgl); FButton btn("&Quit", &dgl);

View File

@ -286,12 +286,12 @@ MyDialog::MyDialog (FWidget* parent) : FDialog(parent)
tagged_count->setGeometry(28, 4, 5, 1); tagged_count->setGeometry(28, 4, 5, 1);
tagged_count->setNumber(0); tagged_count->setNumber(0);
FLabel* sum = new FLabel(L"Sum:\n123\n456", this); FLabel* sum = new FLabel(L"Sum:", this);
sum->setGeometry(20, 5, 7, 1); sum->setGeometry(20, 5, 7, 3);
sum->setAlignment(fc::alignRight); sum->setAlignment(fc::alignRight);
FLabel* sum_count = new FLabel(this); FLabel* sum_count = new FLabel(this);
sum_count->setGeometry(28, 5, 5, 1); sum_count->setGeometry(28, 5, 5, 3);
sum_count->setNumber(myList->count()); sum_count->setNumber(myList->count());
FStatusBar* statusbar = new FStatusBar(this); FStatusBar* statusbar = new FStatusBar(this);