Class FLabel: Add multiple lines support
This commit is contained in:
parent
35a50fdbd7
commit
4ec8a3dda4
|
@ -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()
|
||||||
|
|
||||||
|
|
1
doc/TODO
1
doc/TODO
|
@ -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
|
||||||
|
|
||||||
|
|
221
src/flabel.cpp
221
src/flabel.cpp
|
@ -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;
|
case fc::alignCenter:
|
||||||
|
if ( length < width )
|
||||||
|
return int((width - length) / 2);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
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;
|
bool isActive, isNoUnderline;
|
||||||
|
|
||||||
if ( text.isNull() || text.isEmpty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( Encoding == fc::VT100 )
|
|
||||||
unsetVT100altChar();
|
|
||||||
|
|
||||||
setUpdateVTerm(false);
|
|
||||||
if ( hasEmphasis() )
|
|
||||||
setColor (emphasis_color, backgroundColor);
|
|
||||||
else
|
|
||||||
setColor (foregroundColor, backgroundColor);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
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);
|
setUpdateVTerm(true);
|
||||||
delete[] LabelText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue