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>
|
||||
* Improve focusFirstChild() and focusLastChild()
|
||||
|
||||
|
|
1
doc/TODO
1
doc/TODO
|
@ -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
|
||||
|
||||
|
|
217
src/flabel.cpp
217
src/flabel.cpp
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue