From 0240d782ca12963a143f8eb45c0b1239103f64b9 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Fri, 28 Jul 2017 22:18:42 +0200 Subject: [PATCH] Possibility for a FListView column to set the alignment --- ChangeLog | 4 ++ src/flabel.cpp | 33 ++++++----- src/flabel.h | 2 +- src/flistbox.cpp | 2 +- src/flistview.cpp | 139 +++++++++++++++++++++++++++++++++++----------- src/flistview.h | 97 +++++++++++++++++--------------- src/fstring.cpp | 9 +++ test/listview.cpp | 11 +++- 8 files changed, 198 insertions(+), 99 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7132e17..883aeb8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-07-28 Markus Gans + * Possibility for a FListView column to set + the alignment (left, center or right) + 2017-07-23 Markus Gans * Check an object with isInstanceOf(...) whether it is an instance of a specified class diff --git a/src/flabel.cpp b/src/flabel.cpp index 3a4c4737..e98b2bbe 100644 --- a/src/flabel.cpp +++ b/src/flabel.cpp @@ -340,7 +340,7 @@ void FLabel::setHotkeyAccelerator() } //---------------------------------------------------------------------- -int FLabel::getXOffset(int length) +int FLabel::getAlignOffset (int length) { switch ( alignment ) { @@ -358,25 +358,24 @@ int FLabel::getXOffset(int length) return getWidth() - length; else return 0; - - default: - return 0; } + + return 0; } //---------------------------------------------------------------------- void FLabel::printLine ( wchar_t*& line , uInt length , int hotkeypos - , int xoffset ) + , int align_offset ) { int to_char; bool isActive, isNoUnderline; isActive = ((flags & fc::active) != 0); isNoUnderline = ((flags & fc::no_underline) != 0); - for (int x=0; x < xoffset; x++) - print (' '); + if ( align_offset > 0 ) + print (FString(align_offset, ' ')); // leading spaces if ( length <= uInt(getWidth()) ) to_char = int(length); @@ -423,10 +422,10 @@ void FLabel::printLine ( wchar_t*& line print (".."); setColor(); } - else + else if ( align_offset + to_char < getWidth() ) { - for (int x=xoffset+to_char; x < getWidth(); x++) - print (' '); + int len = getWidth() - align_offset - to_char; + print (FString(len, ' ')); // tailing spaces } if ( hasReverseMode() ) @@ -440,7 +439,7 @@ void FLabel::draw() wchar_t* dest; wchar_t* LabelText; uInt length; - int hotkeypos, xoffset; + int hotkeypos, align_offset; if ( text.isNull() || text.isEmpty() ) return; @@ -482,15 +481,15 @@ void FLabel::draw() if ( hotkeypos != -1 ) { - xoffset = getXOffset (int(length-1)); - printLine (LabelText, length-1, hotkeypos, xoffset); + align_offset = getAlignOffset (int(length-1)); + printLine (LabelText, length-1, hotkeypos, align_offset); hotkey_printed = true; hotkeypos = -1; } else { - xoffset = getXOffset (int(length)); - printLine (LabelText, length, -1, xoffset); + align_offset = getAlignOffset (int(length)); + printLine (LabelText, length, -1, align_offset); } y++; @@ -509,8 +508,8 @@ void FLabel::draw() length--; setPrintPos (1,1); - xoffset = getXOffset (int(length)); - printLine (LabelText, length, hotkeypos, xoffset); + align_offset = getAlignOffset (int(length)); + printLine (LabelText, length, hotkeypos, align_offset); delete[] LabelText; } diff --git a/src/flabel.h b/src/flabel.h index 192a729b..3b90e87d 100644 --- a/src/flabel.h +++ b/src/flabel.h @@ -99,7 +99,7 @@ class FLabel : public FWidget uChar getHotkey(); int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); void setHotkeyAccelerator(); - int getXOffset (int); + int getAlignOffset (int); void printLine (wchar_t*&, uInt, int, int = 0); void draw(); diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 93914393..de75c574 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -1351,7 +1351,7 @@ void FListBox::drawList() isFocus = ((flags & fc::focus) != 0); start = 0; - end = uInt(getHeight()-2); + end = uInt(getHeight() - 2); inc_len = inc_search.getLength(); if ( end > getCount() ) diff --git a/src/flistview.cpp b/src/flistview.cpp index 12357946..629c94bf 100644 --- a/src/flistview.cpp +++ b/src/flistview.cpp @@ -19,7 +19,6 @@ FListViewItem::FListViewItem (const FListViewItem& item) : FObject(item.getParent()) , column_line(item.column_line) , data_pointer(item.data_pointer) - , alignment(fc::alignLeft) { FObject* parent = getParent(); @@ -27,14 +26,28 @@ FListViewItem::FListViewItem (const FListViewItem& item) static_cast(parent)->insert (this); } +//---------------------------------------------------------------------- +FListViewItem::FListViewItem (FListViewItem* item) + : FObject(item->getParent()) + , column_line(item->column_line) + , data_pointer(item->data_pointer) +{ + // Add the FListViewItem to the parent + FObject* parent = getParent(); + + if ( parent && parent->isInstanceOf("FListView") ) + static_cast(parent)->insert (this); +} + //---------------------------------------------------------------------- FListViewItem::FListViewItem (FListView* parent) : FObject(parent) , column_line() , data_pointer(0) - , alignment(fc::alignLeft) { - parent->insert (this); + // Add the FListViewItem to the parent + if ( parent ) + parent->insert (this); } //---------------------------------------------------------------------- @@ -44,9 +57,19 @@ FListViewItem::FListViewItem ( const std::vector& cols : FObject(parent) , column_line(cols) , data_pointer(data) - , alignment(fc::alignLeft) { - parent->insert (this); + // Replace the control codes characters + std::vector::iterator iter = column_line.begin(); + + while ( iter != column_line.end() ) + { + *iter = iter->replaceControlCodes(); + ++iter; + } + + // Add the FListViewItem to the parent + if ( parent ) + parent->insert (this); } //---------------------------------------------------------------------- @@ -90,22 +113,14 @@ FListView::~FListView() // destructor // public methods of FListView //---------------------------------------------------------------------- -int FListView::addColumn (const FString& label, int width) +fc::text_alignment FListView::getColumnAlignment (int column) { - Header column; - column.name = label; - column.width = width; + // Get the alignment for a column - if ( column.width == USE_MAX_SIZE ) - { - column.fixed_width = false; - column.width = int(label.getLength()); - } - else - column.fixed_width = true; + if ( column < 0 || header.empty() || column > int(header.size()) ) + return fc::alignLeft; - header.push_back (column); - return int(std::distance(header.begin(), header.end())); + return header[uInt(column)].alignment; } //---------------------------------------------------------------------- @@ -125,6 +140,36 @@ void FListView::setGeometry (int x, int y, int w, int h, bool adjust) } } +//---------------------------------------------------------------------- +void FListView::setColumnAlignment (int column, fc::text_alignment align) +{ + // Set the alignment for a column + + if ( column < 0 || header.empty() || column > int(header.size()) ) + return; + + header[uInt(column)].alignment = align; +} + +//---------------------------------------------------------------------- +int FListView::addColumn (const FString& label, int width) +{ + Header column; + column.name = label; + column.width = width; + + if ( column.width == USE_MAX_SIZE ) + { + column.fixed_width = false; + column.width = int(label.getLength()); + } + else + column.fixed_width = true; + + header.push_back (column); + return int(std::distance(header.begin(), header.end())); +} + //---------------------------------------------------------------------- void FListView::insert (FListViewItem* item) { @@ -796,6 +841,32 @@ void FListView::init() setRightPadding(1 + nf_offset); } +//---------------------------------------------------------------------- +uInt FListView::getAlignOffset ( fc::text_alignment align + , uInt txt_length + , uInt width ) +{ + switch ( align ) + { + case fc::alignLeft: + return 0; + + case fc::alignCenter: + if ( txt_length < width ) + return uInt((width - txt_length) / 2); + else + return 0; + + case fc::alignRight: + if ( txt_length < width ) + return width - txt_length; + else + return 0; + } + + return 0; +} + //---------------------------------------------------------------------- void FListView::draw() { @@ -898,19 +969,14 @@ void FListView::drawColumnLabels() headerline.write (txt); if ( txt_length < uInt(column_width) ) - headerline.write (' '); + headerline.write (' '); // tailing space if ( txt_length + tailing_space < uInt(column_width) ) { setColor(); - FString line ( column_width - int(txt_length) - tailing_space + FString line ( uInt(column_width) - tailing_space - txt_length , wchar_t(fc::BoxDrawingsHorizontal) ); - headerline.write (line); - } - else if ( txt_length + tailing_space == uInt(column_width) ) - { - setColor(); - headerline.write (wchar_t(fc::BoxDrawingsHorizontal)); + headerline.write (line); // horizontal line } } else @@ -930,10 +996,10 @@ void FListView::drawColumnLabels() const std::vector& h = headerline.getBuffer(); first = h.begin() + xoffset; - if ( int(h.size()) <= getWidth() - 2 ) + if ( int(h.size()) <= getClientWidth() ) last = h.end() - 1; else - last = h.begin() + getWidth() + xoffset - 2; + last = h.begin() + getClientWidth() + xoffset - 1; const std::vector header_part (first, last); setPrintPos (2, 1); @@ -952,7 +1018,7 @@ void FListView::drawList() isFocus = ((flags & fc::focus) != 0); start = 0; - end = uInt(getHeight()-2); + end = uInt(getHeight() - 2); if ( end > data.size() ) end = uInt(data.size()); @@ -1007,11 +1073,22 @@ void FListView::drawList() FString text = (*iter)->column_line[i]; int width = header[i].width; uInt txt_length = text.getLength(); + fc::text_alignment align = getColumnAlignment(int(i+1)); + uInt align_offset = getAlignOffset (align, txt_length, uInt(width)); - if ( txt_length <= uInt(width) ) + if ( align_offset > 0 ) + line += FString(align_offset, ' '); + + if ( align_offset + txt_length <= uInt(width) ) { line += text.left(width); - line += FString (leading_space + width - int(txt_length), ' '); + line += FString (leading_space + width - int(align_offset + txt_length), ' '); + } + else if ( align == fc::alignRight ) + { + line += FString (".."); + line += text.right(width - ellipsis_length); + line += ' '; } else { diff --git a/src/flistview.h b/src/flistview.h index b080c120..d9b92118 100644 --- a/src/flistview.h +++ b/src/flistview.h @@ -49,6 +49,7 @@ class FListViewItem : public FObject { public: FListViewItem (const FListViewItem&); // copy constructor + FListViewItem (FListViewItem*); FListViewItem (FListView*); FListViewItem ( const std::vector& , FWidget::data_ptr = 0 @@ -71,7 +72,6 @@ class FListViewItem : public FObject // Data Member std::vector column_line; FWidget::data_ptr data_pointer; - fc::text_alignment alignment; }; #pragma pack(pop) @@ -109,36 +109,38 @@ class FListView : public FWidget ~FListView(); // Accessors - const char* getClassName() const; + const char* getClassName() const; + fc::text_alignment getColumnAlignment (int); // Mutators - void setGeometry (int, int, int, int, bool = true); + void setGeometry (int, int, int, int, bool = true); + void setColumnAlignment (int, fc::text_alignment); // Methods - virtual int addColumn (const FString&, int = USE_MAX_SIZE); - void insert (FListViewItem*); - void insert ( const std::vector& - , data_ptr = 0 - , FListView* = 0 ); - void insert ( const std::vector& - , data_ptr = 0 - , FListView* = 0 ); + virtual int addColumn (const FString&, int = USE_MAX_SIZE); + void insert (FListViewItem*); + void insert ( const std::vector& + , data_ptr = 0 + , FListView* = 0 ); + void insert ( const std::vector& + , data_ptr = 0 + , FListView* = 0 ); // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onMouseDoubleClick (FMouseEvent*); - void onWheel (FWheelEvent*); - void onTimer (FTimerEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onMouseDoubleClick (FMouseEvent*); + void onWheel (FWheelEvent*); + void onTimer (FTimerEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); protected: // Methods - void adjustYOffset(); - void adjustSize(); + void adjustYOffset(); + void adjustSize(); private: // Typedef @@ -149,6 +151,7 @@ class FListView : public FWidget : name() , width (0) , fixed_width (-1) + , alignment (fc::alignLeft) { } ~Header() @@ -157,6 +160,7 @@ class FListView : public FWidget FString name; int width; bool fixed_width; + fc::text_alignment alignment; }; typedef std::vector
headerItems; @@ -171,35 +175,36 @@ class FListView : public FWidget FListView& operator = (const FListView&); // Methods - void init(); - void draw(); - void drawColumnLabels(); - void drawList(); - void recalculateHorizontalBar (int); - void recalculateVerticalBar (int); - void processClick(); - void processChanged(); + void init(); + uInt getAlignOffset (fc::text_alignment, uInt, uInt); + void draw(); + void drawColumnLabels(); + void drawList(); + void recalculateHorizontalBar (int); + void recalculateVerticalBar (int); + void processClick(); + void processChanged(); listViewItems::iterator index2iterator (int); // Callback methods - void cb_VBarChange (FWidget*, data_ptr); - void cb_HBarChange (FWidget*, data_ptr); + void cb_VBarChange (FWidget*, data_ptr); + void cb_HBarChange (FWidget*, data_ptr); // Data Members - listViewItems data; - headerItems header; - FTermBuffer headerline; - FScrollbar* vbar; - FScrollbar* hbar; - fc::dragScroll drag_scroll; - bool scroll_timer; - int scroll_repeat; - int scroll_distance; - int current; - int xoffset; - int yoffset; - int nf_offset; - int max_line_width; + listViewItems data; + headerItems header; + FTermBuffer headerline; + FScrollbar* vbar; + FScrollbar* hbar; + fc::dragScroll drag_scroll; + bool scroll_timer; + int scroll_repeat; + int scroll_distance; + int current; + int xoffset; + int yoffset; + int nf_offset; + int max_line_width; }; #pragma pack(pop) diff --git a/src/fstring.cpp b/src/fstring.cpp index 4db01d17..190b7f44 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -170,6 +170,9 @@ FString::FString (const char* s) , bufsize(0) , c_string(0) { + if ( ! s ) + return; + const wchar_t* wc_string; wc_string = c_to_wc_str(s); @@ -187,6 +190,9 @@ FString::FString (const wchar_t c) , bufsize(0) , c_string(0) { + if ( c == 0 ) + return; + wchar_t s[2]; s[0] = c; s[1] = L'\0'; @@ -200,6 +206,9 @@ FString::FString (const char c) , bufsize(0) , c_string(0) { + if ( c == 0 ) + return; + wchar_t s[2]; s[0] = wchar_t(c & 0xff); s[1] = L'\0'; diff --git a/test/listview.cpp b/test/listview.cpp index dab6546f..3ee3e98b 100644 --- a/test/listview.cpp +++ b/test/listview.cpp @@ -49,10 +49,15 @@ Listview::Listview (FWidget* parent) // Add columns to the view listView->addColumn ("City"); listView->addColumn ("Condition"); - listView->addColumn ("Temp.", 7); + listView->addColumn ("Temp."); listView->addColumn ("Humidity"); - listView->addColumn ("Pressure"); - + listView->addColumn ("Pressure", 10); + + // Set right alignment for the third, fourth, and fifth column + listView->setColumnAlignment (3, fc::alignRight); + listView->setColumnAlignment (4, fc::alignRight); + listView->setColumnAlignment (5, fc::alignRight); + // Populate FListView with a list of items std::string weather[][5] = {