FListViewItem now provides checkable list view items

This commit is contained in:
Markus Gans 2018-11-18 01:15:38 +01:00
parent e40a233d64
commit 3953dc19fa
11 changed files with 425 additions and 69 deletions

1
.gitignore vendored
View File

@ -52,6 +52,7 @@ examples/input-dialog
examples/choice examples/choice
examples/listbox examples/listbox
examples/listview examples/listview
examples/checklist
examples/treeview examples/treeview
examples/mandelbrot examples/mandelbrot
examples/keyboard examples/keyboard

View File

@ -1,3 +1,7 @@
2018-11-18 Markus Gans <guru.mail@muenster.de>
* The FListViewItem class now provides checkable list view items
* Adding the checklist example to demonstrate the checkable FListViewItems
2018-11-12 Markus Gans <guru.mail@muenster.de> 2018-11-12 Markus Gans <guru.mail@muenster.de>
* Clicking on the column header in FListView now changes the sort order * Clicking on the column header in FListView now changes the sort order

View File

@ -14,6 +14,7 @@ noinst_PROGRAMS = \
choice \ choice \
listbox \ listbox \
listview \ listview \
checklist \
treeview \ treeview \
opti-move \ opti-move \
termcap \ termcap \
@ -37,6 +38,7 @@ input_dialog_SOURCES = input-dialog.cpp
choice_SOURCES = choice.cpp choice_SOURCES = choice.cpp
listbox_SOURCES = listbox.cpp listbox_SOURCES = listbox.cpp
listview_SOURCES = listview.cpp listview_SOURCES = listview.cpp
checklist_SOURCES = checklist.cpp
treeview_SOURCES = treeview.cpp treeview_SOURCES = treeview.cpp
opti_move_SOURCES = opti-move.cpp opti_move_SOURCES = opti-move.cpp
string_operations_SOURCES = string-operations.cpp string_operations_SOURCES = string-operations.cpp

207
examples/checklist.cpp Normal file
View File

@ -0,0 +1,207 @@
/***********************************************************************
* checklist.cpp - Example for FListView widget with checkboxes *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2017-2018 Markus Gans *
* *
* The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
* as published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* The Final Cut is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <final/final.h>
//----------------------------------------------------------------------
// class CheckList
//----------------------------------------------------------------------
#pragma pack(push)
#pragma pack(1)
class CheckList : public finalcut::FDialog
{
public:
// Constructor
explicit CheckList (finalcut::FWidget* = 0);
// Destructor
~CheckList();
private:
// Disable copy constructor
CheckList (const CheckList&);
// Disable assignment operator (=)
CheckList& operator = (const CheckList&);
// Method
void populate();
// Event handlers
virtual void onKeyPress (finalcut::FKeyEvent*);
virtual void onClose (finalcut::FCloseEvent*);
// Callback method
void cb_showList (finalcut::FWidget*, data_ptr);
// Data Members
finalcut::FListView listView;
finalcut::FStatusBar status_bar;
};
#pragma pack(pop)
//----------------------------------------------------------------------
CheckList::CheckList (finalcut::FWidget* parent)
: finalcut::FDialog(parent)
, listView(this)
, status_bar(this)
{
setText (L"Shopping list");
setShadow();
setGeometry (int(1 + (parent->getWidth() - 30) / 2), 5, 30, 13);
listView.ignorePadding();
listView.setGeometry (1, 2, getWidth(), getHeight() - 1);
// Add columns to the view
listView.addColumn ("Item");
listView.addColumn ("Priority", 12);
// Set the type of sorting
listView.setColumnSortType (1, finalcut::fc::by_name);
listView.setColumnSortType (2, finalcut::fc::by_name);
// Statusbar at the bottom
finalcut::FString separator;
separator << ' ' << wchar_t(finalcut::fc::BoxDrawingsVertical) << ' ';
listView.setStatusbarMessage ( finalcut::FString()
<< "<Q> exit" << separator
<< "<Space> select an item" << separator
<< "<Enter> see your pick list");
// Populate FListView with a list of items
populate();
// Add callback method
listView.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &CheckList::cb_showList)
);
}
//----------------------------------------------------------------------
CheckList::~CheckList() // destructor
{ }
//----------------------------------------------------------------------
void CheckList::populate()
{
std::string list[][2] =
{
{ "Milk", "Highest" },
{ "Cheese", "High" },
{ "Yoghurt", "Medium" },
{ "Bread", "Low" },
{ "Eggs", "High" },
{ "Toothpaste", "Medium" },
{ "Apples", "Lowest" },
{ "Bananas", "Medium" },
{ "Fish", "Medium" },
{ "Lemons", "Low" }
};
const int lastItem = int(sizeof(list) / sizeof(list[0])) - 1;
for (int i = 0; i <= lastItem; i++)
{
const finalcut::FStringList line (&list[i][0], &list[i][0] + 2);
finalcut::FObject::FObjectIterator iter = listView.insert (line);
finalcut::FListViewItem* item = static_cast<finalcut::FListViewItem*>(*iter);
item->setCheckable(true);
}
}
//----------------------------------------------------------------------
void CheckList::onKeyPress (finalcut::FKeyEvent* ev)
{
if ( ! ev )
return;
if ( ev->key() == 'q'
|| ev->key() == finalcut::fc::Fkey_escape
|| ev->key() == finalcut::fc::Fkey_escape_mintty )
{
close();
ev->accept();
}
else
finalcut::FDialog::onKeyPress(ev);
}
//----------------------------------------------------------------------
void CheckList::onClose (finalcut::FCloseEvent* ev)
{
finalcut::FApplication::closeConfirmationDialog (this, ev);
}
//----------------------------------------------------------------------
void CheckList::cb_showList (finalcut::FWidget*, data_ptr)
{
finalcut::FListViewIterator iter = listView.beginOfList();
finalcut::FString shopping_list;
while ( iter != listView.endOfList() )
{
const finalcut::FListViewItem* item = static_cast<finalcut::FListViewItem*>(*iter);
if ( item->isChecked() )
shopping_list << wchar_t(finalcut::fc::Bullet) << ' ' << item->getText(1) << '\n';
++iter;
}
if ( shopping_list.isEmpty() )
return;
// Create and show tooltip for two seconds
finalcut::FToolTip picklist(this);
picklist.setText (shopping_list);
picklist.show();
sleep(2);
}
//----------------------------------------------------------------------
// main part
//----------------------------------------------------------------------
int main (int argc, char* argv[])
{
// Create the application object
finalcut::FApplication app(argc, argv);
// Create main dialog object
CheckList d(&app);
// Set dialog d as main widget
app.setMainWidget(&d);
// Show and start the application
d.show();
return app.exec();
}

View File

@ -70,7 +70,7 @@ Listview::Listview (finalcut::FWidget* parent)
, listView(this) , listView(this)
, Quit(this) , Quit(this)
{ {
// Create FListView object // Set FListView geometry
listView.setGeometry(2, 1, 33, 14); listView.setGeometry(2, 1, 33, 14);
// Add columns to the view // Add columns to the view

View File

@ -130,7 +130,7 @@ class Treeview : public finalcut::FDialog
// Methods // Methods
virtual void adjustSize(); virtual void adjustSize();
// Event handlers // Event handler
void onClose (finalcut::FCloseEvent*); void onClose (finalcut::FCloseEvent*);
// Data Members // Data Members
@ -302,7 +302,7 @@ Treeview::Treeview (finalcut::FWidget* parent)
, listView(this) , listView(this)
, Quit(this) , Quit(this)
{ {
// Create FListView object // Set FListView geometry
listView.setGeometry(2, 1, 53, 14); listView.setGeometry(2, 1, 53, 14);
// Add columns to the view // Add columns to the view

View File

@ -896,7 +896,7 @@ void FListBox::draw()
} }
} }
drawLabel(); drawHeadline();
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
@ -923,7 +923,7 @@ void FListBox::draw()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListBox::drawLabel() void FListBox::drawHeadline()
{ {
if ( text.isNull() || text.isEmpty() ) if ( text.isNull() || text.isEmpty() )
return; return;

View File

@ -167,6 +167,8 @@ FListViewItem::FListViewItem (const FListViewItem& item)
, visible_lines(1) , visible_lines(1)
, expandable(false) , expandable(false)
, is_expand(false) , is_expand(false)
, checkable(false)
, is_checked(false)
{ {
FObject* parent = getParent(); FObject* parent = getParent();
@ -192,6 +194,8 @@ FListViewItem::FListViewItem (FObjectIterator parent_iter)
, visible_lines(1) , visible_lines(1)
, expandable(false) , expandable(false)
, is_expand(false) , is_expand(false)
, checkable(false)
, is_checked(false)
{ {
insert (this, parent_iter); insert (this, parent_iter);
} }
@ -207,6 +211,8 @@ FListViewItem::FListViewItem ( const FStringList& cols
, visible_lines(1) , visible_lines(1)
, expandable(false) , expandable(false)
, is_expand(false) , is_expand(false)
, checkable(false)
, is_checked(false)
{ {
if ( cols.empty() ) if ( cols.empty() )
return; return;
@ -325,7 +331,7 @@ FObject::FObjectIterator FListViewItem::insert ( FListViewItem* child
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListViewItem::expand() void FListViewItem::expand()
{ {
if ( is_expand || ! hasChildren() ) if ( isExpand() || ! hasChildren() )
return; return;
is_expand = true; is_expand = true;
@ -334,7 +340,7 @@ void FListViewItem::expand()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListViewItem::collapse() void FListViewItem::collapse()
{ {
if ( ! is_expand ) if ( ! isExpand() )
return; return;
is_expand = false; is_expand = false;
@ -346,7 +352,7 @@ void FListViewItem::collapse()
template <typename Compare> template <typename Compare>
void FListViewItem::sort (Compare cmp) void FListViewItem::sort (Compare cmp)
{ {
if ( ! expandable ) if ( ! isExpandable() )
return; return;
// Sort the top level // Sort the top level
@ -418,6 +424,20 @@ std::size_t FListViewItem::getVisibleLines()
return visible_lines; return visible_lines;
} }
//----------------------------------------------------------------------
void FListViewItem::setCheckable (bool on)
{
checkable = on;
if ( *root )
{
FListView* root_obj = static_cast<FListView*>(*root);
if ( ! root_obj->hasCheckableItems() && isCheckable() )
root_obj->has_checkable_items = true;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListViewItem::resetVisibleLineCounter() void FListViewItem::resetVisibleLineCounter()
{ {
@ -611,8 +631,10 @@ FListView::FListView (FWidget* parent)
, scroll_timer(false) , scroll_timer(false)
, tree_view(false) , tree_view(false)
, hide_sort_indicator(false) , hide_sort_indicator(false)
, has_checkable_items(false)
, clicked_expander_pos(-1, -1) , clicked_expander_pos(-1, -1)
, clicked_column_pos(-1, -1) , clicked_header_pos(-1, -1)
, clicked_checkbox_item(0)
, xoffset(0) , xoffset(0)
, nf_offset(0) , nf_offset(0)
, max_line_width(1) , max_line_width(1)
@ -802,14 +824,11 @@ FObject::FObjectIterator FListView::insert ( FListViewItem* item
, FObjectIterator parent_iter ) , FObjectIterator parent_iter )
{ {
FObjectIterator item_iter; FObjectIterator item_iter;
int line_width;
int element_count;
if ( parent_iter == FListView::null_iter ) if ( parent_iter == FListView::null_iter )
return FListView::null_iter; return FListView::null_iter;
line_width = determineLineWidth (item); beforeInsertion(item); // preprocessing
recalculateHorizontalBar (line_width);
if ( parent_iter == root ) if ( parent_iter == root )
{ {
@ -835,19 +854,7 @@ FObject::FObjectIterator FListView::insert ( FListViewItem* item
else else
item_iter = FListView::null_iter; item_iter = FListView::null_iter;
if ( itemlist.size() == 1 ) afterInsertion(); // post-processing
{
// Select first item on insert
current_iter = itemlist.begin();
// The visible area of the list begins with the first element
first_visible_line = itemlist.begin();
}
// Sort list by a column (only if activated)
sort();
element_count = int(getCount());
recalculateVerticalBar (element_count);
return item_iter; return item_iter;
} }
@ -964,6 +971,11 @@ void FListView::onKeyPress (FKeyEvent* ev)
ev->accept(); ev->accept();
break; break;
case fc::Fkey_space:
keySpace();
ev->accept();
break;
case fc::Fkey_up: case fc::Fkey_up:
stepBackward(); stepBackward();
ev->accept(); ev->accept();
@ -1059,26 +1071,41 @@ void FListView::onMouseDown (FMouseEvent* ev)
if ( mouse_x > 1 && mouse_x < int(getWidth()) ) if ( mouse_x > 1 && mouse_x < int(getWidth()) )
{ {
if ( mouse_y == 1 ) if ( mouse_y == 1 ) // Header
{ {
clicked_column_pos = ev->getPos(); clicked_header_pos = ev->getPos();
} }
else if ( mouse_y > 1 && mouse_y < int(getHeight()) ) else if ( mouse_y > 1 && mouse_y < int(getHeight()) ) // List
{ {
int indent = 0;
int new_pos = first_visible_line.getPosition() + mouse_y - 2; int new_pos = first_visible_line.getPosition() + mouse_y - 2;
if ( new_pos < int(getCount()) ) if ( new_pos < int(getCount()) )
setRelativePosition (mouse_y - 2); setRelativePosition (mouse_y - 2);
const FListViewItem* item = getCurrentItem();
if ( tree_view ) if ( tree_view )
{ {
const FListViewItem* item = getCurrentItem(); indent = int(item->getDepth() << 1); // indent = 2 * depth
int indent = int(item->getDepth() << 1); // indent = 2 * depth
if ( item->isExpandable() && mouse_x - 2 == indent - xoffset ) if ( item->isExpandable() && mouse_x - 2 == indent - xoffset )
clicked_expander_pos = ev->getPos(); clicked_expander_pos = ev->getPos();
} }
if ( hasCheckableItems() )
{
if ( tree_view )
indent++; // Plus one space
if ( mouse_x >= 3 + indent - xoffset
&& mouse_x <= 5 + indent - xoffset
&& item->isCheckable() )
{
clicked_checkbox_item = item;
}
}
if ( isVisible() ) if ( isVisible() )
drawList(); drawList();
@ -1107,15 +1134,18 @@ void FListView::onMouseUp (FMouseEvent* ev)
if ( mouse_x > 1 && mouse_x < int(getWidth()) ) if ( mouse_x > 1 && mouse_x < int(getWidth()) )
{ {
if ( mouse_y == 1 && clicked_column_pos == ev->getPos() ) if ( mouse_y == 1 && clicked_header_pos == ev->getPos() ) // Header
{ {
mouseColumnClicked(); mouseHeaderClicked();
} }
else if ( mouse_y > 1 && mouse_y < int(getHeight()) ) else if ( mouse_y > 1 && mouse_y < int(getHeight()) ) // List
{ {
int indent = 0;
FListViewItem* item = getCurrentItem();
if ( tree_view ) if ( tree_view )
{ {
FListViewItem* item = getCurrentItem(); indent = int(item->getDepth() << 1); // indent = 2 * depth
if ( item->isExpandable() if ( item->isExpandable()
&& clicked_expander_pos == ev->getPos() ) && clicked_expander_pos == ev->getPos() )
@ -1132,13 +1162,30 @@ void FListView::onMouseUp (FMouseEvent* ev)
} }
} }
if ( hasCheckableItems() )
{
if ( tree_view )
indent++; // Plus one space
if ( mouse_x >= 3 + indent - xoffset
&& mouse_x <= 5 + indent - xoffset
&& clicked_checkbox_item == item )
{
item->setChecked(! item->isChecked());
if ( isVisible() )
draw();
}
}
processChanged(); processChanged();
} }
} }
} }
clicked_expander_pos.setPoint(-1, -1); clicked_expander_pos.setPoint(-1, -1);
clicked_column_pos.setPoint(-1, -1); clicked_header_pos.setPoint(-1, -1);
clicked_checkbox_item = 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1521,7 +1568,7 @@ void FListView::draw()
} }
} }
drawColumnLabels(); drawHeadlines();
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
@ -1548,7 +1595,7 @@ void FListView::draw()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::drawColumnLabels() void FListView::drawHeadlines()
{ {
std::vector<charData>::const_iterator first, last; std::vector<charData>::const_iterator first, last;
headerItems::const_iterator iter; headerItems::const_iterator iter;
@ -1562,6 +1609,9 @@ void FListView::drawColumnLabels()
iter = header.begin(); iter = header.begin();
headerline.clear(); headerline.clear();
if ( hasCheckableItems() )
drawHeaderBorder(4);
while ( iter != header.end() ) while ( iter != header.end() )
{ {
const FString& text = iter->name; const FString& text = iter->name;
@ -1572,7 +1622,7 @@ void FListView::drawColumnLabels()
continue; continue;
} }
drawColumnText(iter); drawHeadlineLabel(iter);
++iter; ++iter;
} }
@ -1643,35 +1693,37 @@ void FListView::drawListLine ( const FListViewItem* item
, bool is_focus , bool is_focus
, bool is_current ) , bool is_current )
{ {
std::size_t indent = item->getDepth() << 1; // indent = 2 * depth
// Set line color and attributes // Set line color and attributes
setLineAttributes (is_current, is_focus); setLineAttributes (is_current, is_focus);
// Print the entry // Print the entry
std::size_t indent = item->getDepth() << 1; // indent = 2 * depth
FString line = getLinePrefix (item, indent); FString line = getLinePrefix (item, indent);
// Print columns // Print columns
if ( ! item->column_list.empty() ) if ( ! item->column_list.empty() )
{ {
for (std::size_t i = 0; i < item->column_list.size(); ) for (std::size_t col = 0; col < item->column_list.size(); )
{ {
static const std::size_t leading_space = 1; static const std::size_t leading_space = 1;
static const std::size_t checkbox_space = 4;
static const std::size_t ellipsis_length = 2; static const std::size_t ellipsis_length = 2;
const FString& text = item->column_list[i]; const FString& text = item->column_list[col];
std::size_t width = std::size_t(header[i].width); std::size_t width = std::size_t(header[col].width);
std::size_t txt_length = text.getLength(); std::size_t txt_length = text.getLength();
// Increment the value of i for the column position // Increment the value of i for the column position
// and the next iteration // and the next iteration
i++; col++;
fc::text_alignment align = getColumnAlignment(int(i)); fc::text_alignment align = getColumnAlignment(int(col));
std::size_t align_offset = getAlignOffset (align, txt_length, width); std::size_t align_offset = getAlignOffset (align, txt_length, width);
if ( tree_view && i == 1 ) if ( tree_view && col == 1 )
{ {
width -= indent; width -= (indent + 1);
width--;
if ( item->isCheckable() )
width -= checkbox_space;
} }
// Insert alignment spaces // Insert alignment spaces
@ -1749,20 +1801,41 @@ inline void FListView::setLineAttributes ( bool is_current
} }
} }
//----------------------------------------------------------------------
inline FString FListView::getCheckBox (const FListViewItem* item)
{
FString checkbox;
if ( isNewFont() )
{
checkbox = ( item->isChecked() ) ? CHECKBOX_ON : CHECKBOX;
checkbox += L' ';
}
else
{
checkbox = L"[ ] ";
if ( item->isChecked() )
checkbox[1] = wchar_t(fc::Times); // Times ×
}
return checkbox;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FString FListView::getLinePrefix ( const FListViewItem* item inline FString FListView::getLinePrefix ( const FListViewItem* item
, std::size_t indent ) , std::size_t indent )
{ {
FString line = ""; FString line;
if ( tree_view ) if ( tree_view )
{ {
if ( indent > 0 ) if ( indent > 0 )
line = FString(indent, L' '); line = FString(indent, L' ');
if ( item->expandable ) if ( item->isExpandable() )
{ {
if ( item->is_expand ) if ( item->isExpand() )
{ {
line += wchar_t(fc::BlackDownPointingTriangle); // ▼ line += wchar_t(fc::BlackDownPointingTriangle); // ▼
line += L' '; line += L' ';
@ -1779,6 +1852,9 @@ inline FString FListView::getLinePrefix ( const FListViewItem* item
else else
line = L" "; line = L" ";
if ( item->isCheckable() )
line += getCheckBox(item);
return line; return line;
} }
@ -1813,7 +1889,7 @@ inline void FListView::drawHeaderBorder (std::size_t length)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::drawColumnText (headerItems::const_iterator& iter) void FListView::drawHeadlineLabel (headerItems::const_iterator& iter)
{ {
// Print lable text // Print lable text
static const std::size_t leading_space = 1; static const std::size_t leading_space = 1;
@ -1932,6 +2008,31 @@ int FListView::determineLineWidth (FListViewItem* item)
return line_width; return line_width;
} }
//----------------------------------------------------------------------
inline void FListView::beforeInsertion (FListViewItem* item)
{
int line_width = determineLineWidth (item);
recalculateHorizontalBar (line_width);
}
//----------------------------------------------------------------------
inline void FListView::afterInsertion()
{
if ( itemlist.size() == 1 )
{
// Select first item on insert
current_iter = itemlist.begin();
// The visible area of the list begins with the first element
first_visible_line = itemlist.begin();
}
// Sort list by a column (only if activated)
sort();
int element_count = int(getCount());
recalculateVerticalBar (element_count);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::recalculateHorizontalBar (int len) void FListView::recalculateHorizontalBar (int len)
{ {
@ -1963,11 +2064,12 @@ void FListView::recalculateVerticalBar (int element_count)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::mouseColumnClicked() void FListView::mouseHeaderClicked()
{ {
int column_start = 2;
int column = 1; int column = 1;
int column_pos = clicked_column_pos.getX() + xoffset; int checkbox_offset = ( hasCheckableItems() ) ? 4 : 0;
int header_start = 2 + checkbox_offset;
int header_pos = clicked_header_pos.getX() + xoffset;
headerItems::const_iterator iter; headerItems::const_iterator iter;
iter = header.begin(); iter = header.begin();
@ -1983,8 +2085,8 @@ void FListView::mouseColumnClicked()
if ( click_width > iter->width ) if ( click_width > iter->width )
click_width = iter->width; click_width = iter->width;
if ( column_pos > column_start if ( header_pos > header_start
&& column_pos <= column_start + click_width ) && header_pos <= header_start + click_width )
{ {
if ( has_sort_indicator && sort_order == fc::ascending ) if ( has_sort_indicator && sort_order == fc::ascending )
setColumnSort (column, fc::descending); setColumnSort (column, fc::descending);
@ -1995,7 +2097,7 @@ void FListView::mouseColumnClicked()
if ( isVisible() ) if ( isVisible() )
{ {
drawColumnLabels(); drawHeadlines();
drawList(); drawList();
updateTerminal(); updateTerminal();
flush_out(); flush_out();
@ -2003,7 +2105,7 @@ void FListView::mouseColumnClicked()
break; break;
} }
column_start += leading_space + iter->width; header_start += leading_space + iter->width;
column++; column++;
++iter; ++iter;
} }
@ -2167,6 +2269,15 @@ void FListView::processChanged()
emitCallback("row-changed"); emitCallback("row-changed");
} }
//----------------------------------------------------------------------
inline void FListView::keySpace()
{
FListViewItem* item = getCurrentItem();
if ( item->isCheckable() )
item->setChecked(! item->isChecked());
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::keyLeft (int& first_line_position_before) inline void FListView::keyLeft (int& first_line_position_before)
{ {
@ -2569,7 +2680,7 @@ void FListView::cb_HBarChange (FWidget*, data_ptr)
if ( isVisible() ) if ( isVisible() )
{ {
drawColumnLabels(); drawHeadlines();
drawList(); drawList();
updateTerminal(); updateTerminal();
flush_out(); flush_out();

View File

@ -245,7 +245,7 @@ class FListBox : public FWidget
// Methods // Methods
void init(); void init();
virtual void draw(); virtual void draw();
void drawLabel(); void drawHeadline();
void drawList(); void drawList();
void drawListLine (int, listBoxItems::iterator, bool); void drawListLine (int, listBoxItems::iterator, bool);
void printLeftBracket (fc::brackets_type); void printLeftBracket (fc::brackets_type);

View File

@ -98,11 +98,14 @@ class FListViewItem : public FObject
FWidget::data_ptr getData() const; FWidget::data_ptr getData() const;
uInt getDepth() const; uInt getDepth() const;
// Mutator // Mutators
void setText (int, const FString&); void setText (int, const FString&);
void setData (FWidget::data_ptr); void setData (FWidget::data_ptr);
void setCheckable (bool);
void setChecked (bool);
// Inquiry // Inquiry
bool isChecked() const;
bool isExpand() const; bool isExpand() const;
// Methods // Methods
@ -114,6 +117,7 @@ class FListViewItem : public FObject
private: private:
// Inquiry // Inquiry
bool isExpandable() const; bool isExpandable() const;
bool isCheckable() const;
// Methods // Methods
template <typename Compare> template <typename Compare>
@ -130,6 +134,8 @@ class FListViewItem : public FObject
std::size_t visible_lines; std::size_t visible_lines;
bool expandable; bool expandable;
bool is_expand; bool is_expand;
bool checkable;
bool is_checked;
// Friend class // Friend class
friend class FListView; friend class FListView;
@ -155,6 +161,14 @@ inline FWidget::data_ptr FListViewItem::getData() const
inline void FListViewItem::setData (FWidget::data_ptr data) inline void FListViewItem::setData (FWidget::data_ptr data)
{ data_pointer = data; } { data_pointer = data; }
//----------------------------------------------------------------------
inline void FListViewItem::setChecked (bool checked)
{ is_checked = checked; }
//----------------------------------------------------------------------
inline bool FListViewItem::isChecked() const
{ return is_checked; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListViewItem::isExpand() const inline bool FListViewItem::isExpand() const
{ return is_expand; } { return is_expand; }
@ -163,6 +177,10 @@ inline bool FListViewItem::isExpand() const
inline bool FListViewItem::isExpandable() const inline bool FListViewItem::isExpandable() const
{ return expandable; } { return expandable; }
//----------------------------------------------------------------------
inline bool FListViewItem::isCheckable() const
{ return checkable; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// class FListViewIterator // class FListViewIterator
@ -352,21 +370,24 @@ class FListView : public FWidget
, std::size_t , std::size_t
, std::size_t ); , std::size_t );
virtual void draw(); virtual void draw();
void drawColumnLabels(); void drawHeadlines();
void drawList(); void drawList();
void drawListLine (const FListViewItem*, bool, bool); void drawListLine (const FListViewItem*, bool, bool);
void setLineAttributes (bool, bool); void setLineAttributes (bool, bool);
FString getCheckBox (const FListViewItem* item);
FString getLinePrefix (const FListViewItem*, std::size_t); FString getLinePrefix (const FListViewItem*, std::size_t);
void drawSortIndicator (std::size_t&, std::size_t); void drawSortIndicator (std::size_t&, std::size_t);
void drawColumnText (headerItems::const_iterator&); void drawHeadlineLabel (headerItems::const_iterator&);
void drawHeaderBorder (std::size_t); void drawHeaderBorder (std::size_t);
void drawColumnEllipsis ( headerItems::const_iterator& void drawColumnEllipsis ( headerItems::const_iterator&
, const FString& ); , const FString& );
void updateDrawing (bool, bool); void updateDrawing (bool, bool);
int determineLineWidth (FListViewItem* item); int determineLineWidth (FListViewItem*);
void beforeInsertion (FListViewItem*);
void afterInsertion();
void recalculateHorizontalBar (int); void recalculateHorizontalBar (int);
void recalculateVerticalBar (int); void recalculateVerticalBar (int);
void mouseColumnClicked(); void mouseHeaderClicked();
void wheelUp (int); void wheelUp (int);
void wheelDown (int); void wheelDown (int);
bool dragScrollUp (int); bool dragScrollUp (int);
@ -377,6 +398,7 @@ class FListView : public FWidget
FObjectIterator appendItem (FListViewItem*); FObjectIterator appendItem (FListViewItem*);
void processClick(); void processClick();
void processChanged(); void processChanged();
void keySpace();
void keyLeft (int&); void keyLeft (int&);
void keyRight (int&); void keyRight (int&);
void keyHome(); void keyHome();
@ -393,6 +415,7 @@ class FListView : public FWidget
void scrollTo (const FPoint &); void scrollTo (const FPoint &);
void scrollTo (int, int); void scrollTo (int, int);
void scrollBy (int, int); void scrollBy (int, int);
bool hasCheckableItems() const;
// Callback methods // Callback methods
void cb_VBarChange (FWidget*, data_ptr); void cb_VBarChange (FWidget*, data_ptr);
@ -415,8 +438,10 @@ class FListView : public FWidget
bool scroll_timer; bool scroll_timer;
bool tree_view; bool tree_view;
bool hide_sort_indicator; bool hide_sort_indicator;
bool has_checkable_items;
FPoint clicked_expander_pos; FPoint clicked_expander_pos;
FPoint clicked_column_pos; FPoint clicked_header_pos;
const FListViewItem* clicked_checkbox_item;
int xoffset; int xoffset;
int nf_offset; int nf_offset;
int max_line_width; int max_line_width;
@ -537,6 +562,10 @@ inline FObject::FObjectIterator FListView::endOfList()
inline void FListView::scrollTo (const FPoint& pos) inline void FListView::scrollTo (const FPoint& pos)
{ scrollTo(pos.getX(), pos.getY()); } { scrollTo(pos.getX(), pos.getY()); }
//----------------------------------------------------------------------
inline bool FListView::hasCheckableItems() const
{ return has_checkable_items; }
} // namespace finalcut } // namespace finalcut
#endif // FLISTVIEW_H #endif // FLISTVIEW_H

View File

@ -35,7 +35,9 @@
#error "Only <final/final.h> can be included directly." #error "Only <final/final.h> can be included directly."
#endif #endif
#if __cplusplus < 199711L #if !defined (__cplusplus)
#error "You need a C++ compiler like g++ or clang++"
#elif __cplusplus > 1 && __cplusplus < 199711L
#error "Your C++ compiler does not support the C++98 standard!" #error "Your C++ compiler does not support the C++98 standard!"
#endif #endif