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>
* Improve focusFirstChild() and focusLastChild()

View File

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

View File

@ -37,8 +37,8 @@ void FLabel::init()
{
flags = 0;
emphasis = 0;
xoffset = 0;
alignment = fc::alignLeft;
multiline = false;
this->text = "";
accel_widget = 0;
@ -70,6 +70,27 @@ uChar FLabel::getHotkey()
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()
{
@ -91,56 +112,40 @@ void FLabel::setHotkeyAccelerator()
}
//----------------------------------------------------------------------
void FLabel::draw()
int FLabel::getXOffset(int length)
{
register wchar_t* src;
register wchar_t* dest;
wchar_t* LabelText;
FString txt;
uInt length;
int hotkeypos, to_char;
bool isActive, isNoUnderline;
switch ( alignment )
{
case fc::alignLeft:
return 0;
if ( text.isNull() || text.isEmpty() )
return;
if ( Encoding == fc::VT100 )
unsetVT100altChar();
setUpdateVTerm(false);
if ( hasEmphasis() )
setColor (emphasis_color, backgroundColor);
case fc::alignCenter:
if ( length < width )
return int((width - length) / 2);
else
setColor (foregroundColor, backgroundColor);
return 0;
length = text.getLength();
hotkeypos = -1;
LabelText = new wchar_t[length+1];
txt = this->text;
src = const_cast<wchar_t*>(txt.wc_str());
dest = const_cast<wchar_t*>(LabelText);
case fc::alignRight:
if ( length < width )
return width - length;
else
return 0;
}
return 0;
}
//----------------------------------------------------------------------
void FLabel::printLine ( wchar_t*& line,
uInt length,
int hotkeypos,
int xoffset)
{
int to_char;
bool isActive, isNoUnderline;
isActive = ((flags & ACTIVE) != 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++)
print (' ');
@ -154,12 +159,14 @@ void FLabel::draw()
for (int z=0; z < to_char; z++)
{
if ( ! iswprint(wint_t(line[z])) )
line[z] = L' ';
if ( (z == hotkeypos) && isActive )
{
setColor (wc.label_hotkey_fg, wc.label_hotkey_bg);
if ( ! isNoUnderline )
setUnderline();
print ( LabelText[z] );
print ( line[z] );
if ( ! isNoUnderline )
unsetUnderline();
if ( hasEmphasis() )
@ -168,23 +175,106 @@ void FLabel::draw()
setColor (foregroundColor, backgroundColor);
}
else
print ( LabelText[z] );
print ( line[z] );
}
for (int x=to_char+2; x < width; x++)
print (' ');
if ( length > uInt(width) )
{
setColor (ellipsis_color, backgroundColor);
print ("..");
setColor (foregroundColor, backgroundColor);
}
else
{
for (int x=xoffset+to_char; x < width; x++)
print (' ');
}
if ( hasReverseMode() )
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;
}
}
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);
}
// public methods of FLabel
@ -284,35 +374,12 @@ void FLabel::setAccelWidget (FWidget* widget)
//----------------------------------------------------------------------
void FLabel::setAlignment (uInt align)
{
int text_length;
if ( align != fc::alignLeft
&& align != fc::alignCenter
&& align != fc::alignRight )
alignment = fc::alignLeft;
else
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)
{
this->text = txt;
this->multiline_text = text.split("\r\n");
if ( int(multiline_text.size()) > 1 )
multiline = true;
else
multiline = false;
if ( isEnabled() )
{
delAccelerator (this);

View File

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

View File

@ -33,24 +33,19 @@ int main (int argc, char* argv[])
// Create text labels
FLabel label_1(&dgl),
label_2(&dgl),
label_3(&dgl),
label_4(&dgl),
label_5(&dgl);
label_2(&dgl);
label_1.setText (wchar_t(fc::BlackUpPointingTriangle));
label_2.setText (wchar_t(fc::BoxDrawingsUpAndRight)
label_1.setText ( wchar_t(fc::BlackUpPointingTriangle)
+ std::wstring(L"\n")
+ wchar_t(fc::BoxDrawingsUpAndRight)
+ FString(2, wchar_t(fc::BoxDrawingsHorizontal))
+ FString(" Double click the title bar button,") );
label_3.setText ("press Q on the keyboard,");
label_4.setText ("or push the button below to exit");
label_5.setText ("the program.");
+ " Double click the title bar button," );
label_2.setText ( "press Q on the keyboard,\n"
"or push the button below to exit\n"
"the program." );
label_1.setGeometry (1, 1, 1, 1);
label_2.setGeometry (1, 2, 38, 1);
label_3.setGeometry (5, 3, 24, 1);
label_4.setGeometry (5, 4, 32, 1);
label_5.setGeometry (5, 5, 12, 1);
label_1.setGeometry (1, 1, 38, 2);
label_2.setGeometry (5, 3, 34, 3);
// Create the quit button
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->setNumber(0);
FLabel* sum = new FLabel(L"Sum:\n123\n456", this);
sum->setGeometry(20, 5, 7, 1);
FLabel* sum = new FLabel(L"Sum:", this);
sum->setGeometry(20, 5, 7, 3);
sum->setAlignment(fc::alignRight);
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());
FStatusBar* statusbar = new FStatusBar(this);