From 127fa784ccd0b4aff2d417cfd92650b225b392c7 Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Sun, 3 Jul 2016 13:36:49 +0200 Subject: [PATCH] updated to v099r13 release --- cocoa/browser-window.cpp | 8 +- cocoa/header.hpp | 18 +- cocoa/platform.cpp | 10 +- cocoa/platform.hpp | 10 +- cocoa/widget/canvas.cpp | 2 +- cocoa/widget/list-view-cell.cpp | 50 -- cocoa/widget/list-view-column.cpp | 87 ---- cocoa/widget/list-view-header.cpp | 38 -- cocoa/widget/list-view-header.hpp | 17 - cocoa/widget/list-view-item.cpp | 51 -- cocoa/widget/table-view-cell.cpp | 50 ++ ...list-view-cell.hpp => table-view-cell.hpp} | 10 +- cocoa/widget/table-view-column.cpp | 87 ++++ ...-view-column.hpp => table-view-column.hpp} | 10 +- cocoa/widget/table-view-header.cpp | 38 ++ cocoa/widget/table-view-header.hpp | 17 + cocoa/widget/table-view-item.cpp | 51 ++ ...list-view-item.hpp => table-view-item.hpp} | 12 +- .../widget/{list-view.cpp => table-view.cpp} | 158 +++--- .../widget/{list-view.hpp => table-view.hpp} | 36 +- cocoa/widget/viewport.cpp | 2 +- cocoa/window.cpp | 2 +- components.hpp | 18 +- core/action/menu.cpp | 2 +- core/core.cpp | 12 +- core/core.hpp | 475 ++++++++++-------- core/layout.cpp | 2 +- core/menu-bar.cpp | 2 +- core/object.cpp | 70 +-- core/popup-menu.cpp | 2 +- core/shared.hpp | 300 ++++++----- core/widget/combo-edit-item.cpp | 34 ++ core/widget/combo-edit.cpp | 107 ++++ core/widget/list-view-column.cpp | 153 ------ core/widget/list-view-header.cpp | 53 -- core/widget/list-view-item.cpp | 98 ---- core/widget/tab-frame.cpp | 2 +- ...list-view-cell.cpp => table-view-cell.cpp} | 52 +- core/widget/table-view-column.cpp | 153 ++++++ core/widget/table-view-header.cpp | 58 +++ core/widget/table-view-item.cpp | 103 ++++ core/widget/{list-view.cpp => table-view.cpp} | 82 +-- core/widget/tree-view-item.cpp | 6 +- core/widget/tree-view.cpp | 6 +- extension/browser-dialog.cpp | 50 +- extension/extension.cpp | 2 + extension/extension.hpp | 2 + extension/horizontal-layout.cpp | 4 +- extension/list-view-item.cpp | 49 ++ extension/list-view-item.hpp | 24 + extension/list-view.cpp | 51 ++ extension/list-view.hpp | 27 + extension/shared.hpp | 53 ++ extension/vertical-layout.cpp | 4 +- gtk/browser-window.cpp | 2 +- gtk/platform.cpp | 12 +- gtk/platform.hpp | 12 +- gtk/settings.cpp | 4 +- gtk/widget/canvas.cpp | 2 +- gtk/widget/combo-button-item.cpp | 1 - gtk/widget/combo-edit-item.cpp | 33 ++ gtk/widget/combo-edit-item.hpp | 18 + gtk/widget/combo-edit.cpp | 115 +++++ gtk/widget/combo-edit.hpp | 28 ++ gtk/widget/console.cpp | 2 +- gtk/widget/list-view-header.cpp | 41 -- gtk/widget/list-view-header.hpp | 18 - ...list-view-cell.cpp => table-view-cell.cpp} | 28 +- ...list-view-cell.hpp => table-view-cell.hpp} | 10 +- ...-view-column.cpp => table-view-column.cpp} | 52 +- ...-view-column.hpp => table-view-column.hpp} | 10 +- gtk/widget/table-view-header.cpp | 41 ++ gtk/widget/table-view-header.hpp | 18 + ...list-view-item.cpp => table-view-item.cpp} | 26 +- ...list-view-item.hpp => table-view-item.hpp} | 12 +- gtk/widget/{list-view.cpp => table-view.cpp} | 96 ++-- gtk/widget/{list-view.hpp => table-view.hpp} | 14 +- gtk/widget/tree-view.cpp | 4 +- gtk/widget/viewport.cpp | 2 +- gtk/window.cpp | 4 +- qt/platform.cpp | 10 +- qt/platform.hpp | 10 +- qt/qt.hpp | 50 +- qt/qt.moc | 168 +++---- qt/settings.cpp | 4 +- qt/widget/list-view-column.cpp | 99 ---- qt/widget/list-view-header.cpp | 43 -- qt/widget/list-view-header.hpp | 18 - qt/widget/list-view-item.cpp | 64 --- ...list-view-cell.cpp => table-view-cell.cpp} | 28 +- ...list-view-cell.hpp => table-view-cell.hpp} | 8 +- qt/widget/table-view-column.cpp | 99 ++++ ...-view-column.hpp => table-view-column.hpp} | 8 +- qt/widget/table-view-header.cpp | 43 ++ qt/widget/table-view-header.hpp | 18 + qt/widget/table-view-item.cpp | 66 +++ ...list-view-item.hpp => table-view-item.hpp} | 12 +- qt/widget/{list-view.cpp => table-view.cpp} | 114 ++--- qt/widget/{list-view.hpp => table-view.hpp} | 18 +- qt/window.cpp | 8 +- windows/application.cpp | 6 +- windows/browser-window.cpp | 4 +- windows/platform.cpp | 10 +- windows/platform.hpp | 16 +- windows/utility.cpp | 34 +- windows/widget/canvas.cpp | 3 +- windows/widget/list-view-cell.cpp | 72 --- windows/widget/list-view-header.hpp | 18 - windows/widget/tab-frame.cpp | 2 +- windows/widget/table-view-cell.cpp | 72 +++ ...list-view-cell.hpp => table-view-cell.hpp} | 8 +- ...-view-column.cpp => table-view-column.cpp} | 40 +- ...-view-column.hpp => table-view-column.hpp} | 12 +- ...-view-header.cpp => table-view-header.cpp} | 18 +- windows/widget/table-view-header.hpp | 18 + ...list-view-item.cpp => table-view-item.cpp} | 26 +- ...list-view-item.hpp => table-view-item.hpp} | 12 +- .../widget/{list-view.cpp => table-view.cpp} | 73 +-- .../widget/{list-view.hpp => table-view.hpp} | 14 +- windows/window.cpp | 3 +- 120 files changed, 2732 insertions(+), 2042 deletions(-) delete mode 100644 cocoa/widget/list-view-cell.cpp delete mode 100644 cocoa/widget/list-view-column.cpp delete mode 100644 cocoa/widget/list-view-header.cpp delete mode 100644 cocoa/widget/list-view-header.hpp delete mode 100644 cocoa/widget/list-view-item.cpp create mode 100644 cocoa/widget/table-view-cell.cpp rename cocoa/widget/{list-view-cell.hpp => table-view-cell.hpp} (65%) create mode 100644 cocoa/widget/table-view-column.cpp rename cocoa/widget/{list-view-column.hpp => table-view-column.hpp} (78%) create mode 100644 cocoa/widget/table-view-header.cpp create mode 100644 cocoa/widget/table-view-header.hpp create mode 100644 cocoa/widget/table-view-item.cpp rename cocoa/widget/{list-view-item.hpp => table-view-item.hpp} (53%) rename cocoa/widget/{list-view.cpp => table-view.cpp} (67%) rename cocoa/widget/{list-view.hpp => table-view.hpp} (70%) create mode 100644 core/widget/combo-edit-item.cpp create mode 100644 core/widget/combo-edit.cpp delete mode 100644 core/widget/list-view-column.cpp delete mode 100644 core/widget/list-view-header.cpp delete mode 100644 core/widget/list-view-item.cpp rename core/widget/{list-view-cell.cpp => table-view-cell.cpp} (66%) create mode 100644 core/widget/table-view-column.cpp create mode 100644 core/widget/table-view-header.cpp create mode 100644 core/widget/table-view-item.cpp rename core/widget/{list-view.cpp => table-view.cpp} (55%) create mode 100644 extension/list-view-item.cpp create mode 100644 extension/list-view-item.hpp create mode 100644 extension/list-view.cpp create mode 100644 extension/list-view.hpp create mode 100644 gtk/widget/combo-edit-item.cpp create mode 100644 gtk/widget/combo-edit-item.hpp create mode 100644 gtk/widget/combo-edit.cpp create mode 100644 gtk/widget/combo-edit.hpp delete mode 100644 gtk/widget/list-view-header.cpp delete mode 100644 gtk/widget/list-view-header.hpp rename gtk/widget/{list-view-cell.cpp => table-view-cell.cpp} (50%) rename gtk/widget/{list-view-cell.hpp => table-view-cell.hpp} (67%) rename gtk/widget/{list-view-column.cpp => table-view-column.cpp} (67%) rename gtk/widget/{list-view-column.hpp => table-view-column.hpp} (84%) create mode 100644 gtk/widget/table-view-header.cpp create mode 100644 gtk/widget/table-view-header.hpp rename gtk/widget/{list-view-item.cpp => table-view-item.cpp} (63%) rename gtk/widget/{list-view-item.hpp => table-view-item.hpp} (57%) rename gtk/widget/{list-view.cpp => table-view.cpp} (78%) rename gtk/widget/{list-view.hpp => table-view.hpp} (84%) delete mode 100644 qt/widget/list-view-column.cpp delete mode 100644 qt/widget/list-view-header.cpp delete mode 100644 qt/widget/list-view-header.hpp delete mode 100644 qt/widget/list-view-item.cpp rename qt/widget/{list-view-cell.cpp => table-view-cell.cpp} (63%) rename qt/widget/{list-view-cell.hpp => table-view-cell.hpp} (75%) create mode 100644 qt/widget/table-view-column.cpp rename qt/widget/{list-view-column.hpp => table-view-column.hpp} (83%) create mode 100644 qt/widget/table-view-header.cpp create mode 100644 qt/widget/table-view-header.hpp create mode 100644 qt/widget/table-view-item.cpp rename qt/widget/{list-view-item.hpp => table-view-item.hpp} (60%) rename qt/widget/{list-view.cpp => table-view.cpp} (56%) rename qt/widget/{list-view.hpp => table-view.hpp} (57%) delete mode 100644 windows/widget/list-view-cell.cpp delete mode 100644 windows/widget/list-view-header.hpp create mode 100644 windows/widget/table-view-cell.cpp rename windows/widget/{list-view-cell.hpp => table-view-cell.hpp} (74%) rename windows/widget/{list-view-column.cpp => table-view-column.cpp} (58%) rename windows/widget/{list-view-column.hpp => table-view-column.hpp} (71%) rename windows/widget/{list-view-header.cpp => table-view-header.cpp} (51%) create mode 100644 windows/widget/table-view-header.hpp rename windows/widget/{list-view-item.cpp => table-view-item.cpp} (60%) rename windows/widget/{list-view-item.hpp => table-view-item.hpp} (55%) rename windows/widget/{list-view.cpp => table-view.cpp} (85%) rename windows/widget/{list-view.hpp => table-view.hpp} (80%) diff --git a/cocoa/browser-window.cpp b/cocoa/browser-window.cpp index e2e5429..4cc407a 100644 --- a/cocoa/browser-window.cpp +++ b/cocoa/browser-window.cpp @@ -26,8 +26,8 @@ auto pBrowserWindow::open(BrowserWindow::State& state) -> string { @autoreleasepool { NSMutableArray* filters = [[NSMutableArray alloc] init]; for(auto& rule : state.filters) { - string pattern = rule.split("(", 1L)(1).rtrim(")", 1L); - if(!pattern.empty()) [filters addObject:[NSString stringWithUTF8String:pattern]]; + string pattern = rule.split("(", 1L)(1).trimRight(")", 1L); + if(pattern) [filters addObject:[NSString stringWithUTF8String:pattern]]; } NSOpenPanel* panel = [NSOpenPanel openPanel]; if(state.title) [panel setTitle:[NSString stringWithUTF8String:state.title]]; @@ -51,8 +51,8 @@ auto pBrowserWindow::save(BrowserWindow::State& state) -> string { @autoreleasepool { NSMutableArray* filters = [[NSMutableArray alloc] init]; for(auto& rule : state.filters) { - string pattern = rule.split("(", 1L)(1).rtrim(")", 1L); - if(!pattern.empty()) [filters addObject:[NSString stringWithUTF8String:pattern]]; + string pattern = rule.split("(", 1L)(1).trimRight(")", 1L); + if(pattern) [filters addObject:[NSString stringWithUTF8String:pattern]]; } NSSavePanel* panel = [NSSavePanel savePanel]; if(state.title) [panel setTitle:[NSString stringWithUTF8String:state.title]]; diff --git a/cocoa/header.hpp b/cocoa/header.hpp index 776e1d6..8dd9cb9 100644 --- a/cocoa/header.hpp +++ b/cocoa/header.hpp @@ -1,6 +1,22 @@ -#define decimal CocoaDecimal +#define decimal decimal_cocoa +#define int8 int8_cocoa +#define int16 int16_cocoa +#define int32 int32_cocoa +#define int64 int64_cocoa +#define uint8 uint8_cocoa +#define uint16 uint16_cocoa +#define uint32 uint32_cocoa +#define uint64 uint64_cocoa #import #import #undef decimal +#undef int8 +#undef int16 +#undef int32 +#undef int64 +#undef uint8 +#undef uint16 +#undef uint32 +#undef uint64 #include diff --git a/cocoa/platform.cpp b/cocoa/platform.cpp index 1da4474..2058fe5 100644 --- a/cocoa/platform.cpp +++ b/cocoa/platform.cpp @@ -42,16 +42,16 @@ #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" diff --git a/cocoa/platform.hpp b/cocoa/platform.hpp index 324d6c0..66c1e4c 100644 --- a/cocoa/platform.hpp +++ b/cocoa/platform.hpp @@ -54,16 +54,16 @@ namespace hiro { #include "widget/horizontal-slider.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/vertical-scroll-bar.hpp" #include "widget/vertical-slider.hpp" diff --git a/cocoa/widget/canvas.cpp b/cocoa/widget/canvas.cpp index 6f2730e..463574f 100644 --- a/cocoa/widget/canvas.cpp +++ b/cocoa/widget/canvas.cpp @@ -21,7 +21,7 @@ -(BOOL) performDragOperation:(id)sender { lstring paths = DropPaths(sender); - if(paths.empty()) return NO; + if(!paths) return NO; canvas->doDrop(paths); return YES; } diff --git a/cocoa/widget/list-view-cell.cpp b/cocoa/widget/list-view-cell.cpp deleted file mode 100644 index ef43ced..0000000 --- a/cocoa/widget/list-view-cell.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewCell::construct() -> void { -} - -auto pListViewCell::destruct() -> void { -} - -auto pListViewCell::setAlignment(Alignment alignment) -> void { -} - -auto pListViewCell::setBackgroundColor(Color color) -> void { -} - -auto pListViewCell::setCheckable(bool checkable) -> void { -} - -auto pListViewCell::setChecked(bool checked) -> void { -} - -auto pListViewCell::setForegroundColor(Color color) -> void { -} - -auto pListViewCell::setIcon(const image& icon) -> void { -} - -auto pListViewCell::setText(const string& text) -> void { - @autoreleasepool { - if(auto pListView = _grandparent()) { - [[pListView->cocoaView content] reloadData]; - } - } -} - -auto pListViewCell::_grandparent() -> maybe { - if(auto parent = _parent()) return parent->_parent(); -} - -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/cocoa/widget/list-view-column.cpp b/cocoa/widget/list-view-column.cpp deleted file mode 100644 index a2016c1..0000000 --- a/cocoa/widget/list-view-column.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewColumn::construct() -> void { - @autoreleasepool { - if(auto listView = _grandparent()) { - [listView->cocoaView reloadColumns]; - } - } -} - -auto pListViewColumn::destruct() -> void { - @autoreleasepool { - if(auto listView = _grandparent()) { - [listView->cocoaView reloadColumns]; - } - } -} - -auto pListViewColumn::setActive() -> void { -} - -auto pListViewColumn::setAlignment(Alignment alignment) -> void { -} - -auto pListViewColumn::setBackgroundColor(Color color) -> void { -} - -auto pListViewColumn::setEditable(bool editable) -> void { -} - -auto pListViewColumn::setExpandable(bool expandable) -> void { -} - -auto pListViewColumn::setFont(const Font& font) -> void { -} - -auto pListViewColumn::setForegroundColor(Color color) -> void { -} - -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { -} - -auto pListViewColumn::setIcon(const image& icon) -> void { -} - -auto pListViewColumn::setResizable(bool resizable) -> void { -} - -auto pListViewColumn::setSortable(bool sortable) -> void { -} - -auto pListViewColumn::setText(const string& text) -> void { - @autoreleasepool { - if(auto pListView = _grandparent()) { - NSTableColumn* tableColumn = [[pListView->cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:self().offset()] stringValue]]; - [[tableColumn headerCell] setStringValue:[NSString stringWithUTF8STring:text]]; - [[pListView->cocoaView headerView] setNeedsDisplay:YES]; - } - } -} - -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { -} - -auto pListViewColumn::setVisible(bool visible) -> void { -} - -auto pListViewColumn::setWidth(signed width) -> void { -} - -auto pListViewColumn::_grandparent() -> maybe { - if(auto parent = _parent()) return parent->_parent(); - return nothing; -} - -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/cocoa/widget/list-view-header.cpp b/cocoa/widget/list-view-header.cpp deleted file mode 100644 index 2b2756a..0000000 --- a/cocoa/widget/list-view-header.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewHeader::construct() -> void { -} - -auto pListViewHeader::destruct() -> void { -} - -auto pListViewHeader::append(sListViewColumn column) -> void { -} - -auto pListViewHeader::remove(sListViewColumn column) -> void { -} - -auto pListViewHeader::setVisible(bool visible) -> void { - @autoreleasepool { - if(auto pListView = _parent()) { - if(visible) { - [[pListView->cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]]; - } else { - [[pListView->cocoaView content] setHeaderView:nil]; - } - } - } -} - -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/cocoa/widget/list-view-header.hpp b/cocoa/widget/list-view-header.hpp deleted file mode 100644 index b2c1aa8..0000000 --- a/cocoa/widget/list-view-header.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; -}; - -} - -#endif diff --git a/cocoa/widget/list-view-item.cpp b/cocoa/widget/list-view-item.cpp deleted file mode 100644 index 0f04387..0000000 --- a/cocoa/widget/list-view-item.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewItem::construct() -> void { -} - -auto pListViewItem::destruct() -> void { -} - -auto pListViewItem::append(sListViewCell cell) -> void { - @autoreleasepool { - if(auto listView = _parent()) { - [[listView->cocoaView content] reloadData]; - } - } -} - -auto pListViewItem::remove(sListViewCell cell) -> void { - @autoreleasepool { - if(auto listView = _parent()) { - [[listView->cocoaView content] reloadData]; - } - } -} - -auto pListViewItem::setAlignment(Alignment alignment) -> void { -} - -auto pListViewItem::setBackgroundColor(Color color) -> void { -} - -auto pListViewItem::setFocused() -> void { -} - -auto pListViewItem::setForegroundColor(Color color) -> void { -} - -auto pListViewItem::setSelected(bool selected) -> void { -} - -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/cocoa/widget/table-view-cell.cpp b/cocoa/widget/table-view-cell.cpp new file mode 100644 index 0000000..2da1596 --- /dev/null +++ b/cocoa/widget/table-view-cell.cpp @@ -0,0 +1,50 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewCell::construct() -> void { +} + +auto pTableViewCell::destruct() -> void { +} + +auto pTableViewCell::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewCell::setBackgroundColor(Color color) -> void { +} + +auto pTableViewCell::setCheckable(bool checkable) -> void { +} + +auto pTableViewCell::setChecked(bool checked) -> void { +} + +auto pTableViewCell::setForegroundColor(Color color) -> void { +} + +auto pTableViewCell::setIcon(const image& icon) -> void { +} + +auto pTableViewCell::setText(const string& text) -> void { + @autoreleasepool { + if(auto pTableView = _grandparent()) { + [[pTableView->cocoaView content] reloadData]; + } + } +} + +auto pTableViewCell::_grandparent() -> maybe { + if(auto parent = _parent()) return parent->_parent(); +} + +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/cocoa/widget/list-view-cell.hpp b/cocoa/widget/table-view-cell.hpp similarity index 65% rename from cocoa/widget/list-view-cell.hpp rename to cocoa/widget/table-view-cell.hpp index 33b33f3..0843729 100644 --- a/cocoa/widget/list-view-cell.hpp +++ b/cocoa/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -13,8 +13,8 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/cocoa/widget/table-view-column.cpp b/cocoa/widget/table-view-column.cpp new file mode 100644 index 0000000..94fc6a5 --- /dev/null +++ b/cocoa/widget/table-view-column.cpp @@ -0,0 +1,87 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewColumn::construct() -> void { + @autoreleasepool { + if(auto tableView = _grandparent()) { + [tableView->cocoaView reloadColumns]; + } + } +} + +auto pTableViewColumn::destruct() -> void { + @autoreleasepool { + if(auto tableView = _grandparent()) { + [tableView->cocoaView reloadColumns]; + } + } +} + +auto pTableViewColumn::setActive() -> void { +} + +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewColumn::setBackgroundColor(Color color) -> void { +} + +auto pTableViewColumn::setEditable(bool editable) -> void { +} + +auto pTableViewColumn::setExpandable(bool expandable) -> void { +} + +auto pTableViewColumn::setFont(const Font& font) -> void { +} + +auto pTableViewColumn::setForegroundColor(Color color) -> void { +} + +auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { +} + +auto pTableViewColumn::setIcon(const image& icon) -> void { +} + +auto pTableViewColumn::setResizable(bool resizable) -> void { +} + +auto pTableViewColumn::setSortable(bool sortable) -> void { +} + +auto pTableViewColumn::setText(const string& text) -> void { + @autoreleasepool { + if(auto pTableView = _grandparent()) { + NSTableColumn* tableColumn = [[pTableView->cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:self().offset()] stringValue]]; + [[tableColumn headerCell] setStringValue:[NSString stringWithUTF8STring:text]]; + [[pTableView->cocoaView headerView] setNeedsDisplay:YES]; + } + } +} + +auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { +} + +auto pTableViewColumn::setVisible(bool visible) -> void { +} + +auto pTableViewColumn::setWidth(signed width) -> void { +} + +auto pTableViewColumn::_grandparent() -> maybe { + if(auto parent = _parent()) return parent->_parent(); + return nothing; +} + +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/cocoa/widget/list-view-column.hpp b/cocoa/widget/table-view-column.hpp similarity index 78% rename from cocoa/widget/list-view-column.hpp rename to cocoa/widget/table-view-column.hpp index 59b4528..e75045a 100644 --- a/cocoa/widget/list-view-column.hpp +++ b/cocoa/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -21,8 +21,8 @@ struct pListViewColumn : pObject { auto setVisible(bool visible) -> void override; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/cocoa/widget/table-view-header.cpp b/cocoa/widget/table-view-header.cpp new file mode 100644 index 0000000..72d9e99 --- /dev/null +++ b/cocoa/widget/table-view-header.cpp @@ -0,0 +1,38 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewHeader::construct() -> void { +} + +auto pTableViewHeader::destruct() -> void { +} + +auto pTableViewHeader::append(sTableViewColumn column) -> void { +} + +auto pTableViewHeader::remove(sTableViewColumn column) -> void { +} + +auto pTableViewHeader::setVisible(bool visible) -> void { + @autoreleasepool { + if(auto pTableView = _parent()) { + if(visible) { + [[pTableView->cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]]; + } else { + [[pTableView->cocoaView content] setHeaderView:nil]; + } + } + } +} + +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/cocoa/widget/table-view-header.hpp b/cocoa/widget/table-view-header.hpp new file mode 100644 index 0000000..7027afc --- /dev/null +++ b/cocoa/widget/table-view-header.hpp @@ -0,0 +1,17 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; +}; + +} + +#endif diff --git a/cocoa/widget/table-view-item.cpp b/cocoa/widget/table-view-item.cpp new file mode 100644 index 0000000..d419174 --- /dev/null +++ b/cocoa/widget/table-view-item.cpp @@ -0,0 +1,51 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewItem::construct() -> void { +} + +auto pTableViewItem::destruct() -> void { +} + +auto pTableViewItem::append(sTableViewCell cell) -> void { + @autoreleasepool { + if(auto tableView = _parent()) { + [[tableView->cocoaView content] reloadData]; + } + } +} + +auto pTableViewItem::remove(sTableViewCell cell) -> void { + @autoreleasepool { + if(auto tableView = _parent()) { + [[tableView->cocoaView content] reloadData]; + } + } +} + +auto pTableViewItem::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewItem::setBackgroundColor(Color color) -> void { +} + +auto pTableViewItem::setFocused() -> void { +} + +auto pTableViewItem::setForegroundColor(Color color) -> void { +} + +auto pTableViewItem::setSelected(bool selected) -> void { +} + +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/cocoa/widget/list-view-item.hpp b/cocoa/widget/table-view-item.hpp similarity index 53% rename from cocoa/widget/list-view-item.hpp rename to cocoa/widget/table-view-item.hpp index c95ff09..5b2051c 100644 --- a/cocoa/widget/list-view-item.hpp +++ b/cocoa/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/cocoa/widget/list-view.cpp b/cocoa/widget/table-view.cpp similarity index 67% rename from cocoa/widget/list-view.cpp rename to cocoa/widget/table-view.cpp index 987f549..cba4203 100644 --- a/cocoa/widget/list-view.cpp +++ b/cocoa/widget/table-view.cpp @@ -1,11 +1,11 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -@implementation CocoaListView : NSScrollView +@implementation CocoaTableView : NSScrollView --(id) initWith:(hiro::mListView&)listViewReference { +-(id) initWith:(hiro::mTableView&)tableViewReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { - listView = &listViewReference; - content = [[CocoaListViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; + tableView = &tableViewReference; + content = [[CocoaTableViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; [self setDocumentView:content]; [self setBorderType:NSBezelBorder]; @@ -34,7 +34,7 @@ [super dealloc]; } --(CocoaListViewContent*) content { +-(CocoaTableViewContent*) content { return content; } @@ -59,13 +59,13 @@ [content removeTableColumn:[[content tableColumns] lastObject]]; } - if(auto listViewHeader = listView->state.header) { - for(auto& listViewColumn : listViewHeader->state.columns) { - auto column = listViewColumn->offset(); + if(auto tableViewHeader = tableView->state.header) { + for(auto& tableViewColumn : tableViewHeader->state.columns) { + auto column = tableViewColumn->offset(); NSTableColumn* tableColumn = [[NSTableColumn alloc] initWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; - NSTableHeaderCell* headerCell = [[NSTableHeaderCell alloc] initTextCell:[NSString stringWithUTF8String:listViewColumn->state.text]]; - CocoaListViewCell* dataCell = [[CocoaListViewCell alloc] initWith:*listView]; + NSTableHeaderCell* headerCell = [[NSTableHeaderCell alloc] initTextCell:[NSString stringWithUTF8String:tableViewColumn->state.text]]; + CocoaTableViewCell* dataCell = [[CocoaTableViewCell alloc] initWith:*tableView]; [dataCell setEditable:NO]; @@ -79,13 +79,13 @@ } -(NSInteger) numberOfRowsInTableView:(NSTableView*)table { - return listView->state.items.size(); + return tableView->state.items.size(); } -(id) tableView:(NSTableView*)table objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { - if(auto listViewItem = listView->item(row)) { - if(auto listViewCell = listViewItem->cell([[tableColumn identifier] integerValue])) { - NSString* text = [NSString stringWithUTF8String:listViewCell->state.text]; + if(auto tableViewItem = tableView->item(row)) { + if(auto tableViewCell = tableViewItem->cell([[tableColumn identifier] integerValue])) { + NSString* text = [NSString stringWithUTF8String:tableViewCell->state.text]; return @{ @"text":text }; //used by type-ahead } } @@ -105,14 +105,14 @@ } -(void) tableViewSelectionDidChange:(NSNotification*)notification { - for(auto& listViewItem : listView->state.items) { - listViewItem->state.selected = listViewItem->offset() == [content selectedRow]; + for(auto& tableViewItem : tableView->state.items) { + tableViewItem->state.selected = tableViewItem->offset() == [content selectedRow]; } - listView->doChange(); + tableView->doChange(); } -(IBAction) activate:(id)sender { - listView->doActivate(); + tableView->doActivate(); } -(IBAction) doubleAction:(id)sender { @@ -123,7 +123,7 @@ @end -@implementation CocoaListViewContent : NSTableView +@implementation CocoaTableViewContent : NSTableView -(void) keyDown:(NSEvent*)event { auto character = [[event characters] characterAtIndex:0]; @@ -139,11 +139,11 @@ @end -@implementation CocoaListViewCell : NSCell +@implementation CocoaTableViewCell : NSCell --(id) initWith:(hiro::mListView&)listViewReference { +-(id) initWith:(hiro::mTableView&)tableViewReference { if(self = [super initTextCell:@""]) { - listView = &listViewReference; + tableView = &tableViewReference; buttonCell = [[NSButtonCell alloc] initTextCell:@""]; [buttonCell setButtonType:NSSwitchButton]; [buttonCell setControlSize:NSSmallControlSize]; @@ -159,27 +159,27 @@ } -(void) drawWithFrame:(NSRect)frame inView:(NSView*)view { - if(auto listViewItem = listView->item([view rowAtPoint:frame.origin])) { - if(auto listViewCell = listViewItem->cell([view columnAtPoint:frame.origin])) { + if(auto tableViewItem = tableView->item([view rowAtPoint:frame.origin])) { + if(auto tableViewCell = tableViewItem->cell([view columnAtPoint:frame.origin])) { NSColor* backgroundColor = nil; if([self isHighlighted]) backgroundColor = [NSColor alternateSelectedControlColor]; - else if(!listView->enabled(true)) backgroundColor = [NSColor controlBackgroundColor]; - else if(auto color = listViewCell->state.backgroundColor) backgroundColor = NSMakeColor(color); + else if(!tableView->enabled(true)) backgroundColor = [NSColor controlBackgroundColor]; + else if(auto color = tableViewCell->state.backgroundColor) backgroundColor = NSMakeColor(color); else backgroundColor = [NSColor controlBackgroundColor]; [backgroundColor set]; [NSBezierPath fillRect:frame]; - if(listViewCell->state.checkable) { + if(tableViewCell->state.checkable) { [buttonCell setHighlighted:YES]; - [buttonCell setState:(listViewCell->state.checked ? NSOnState : NSOffState)]; + [buttonCell setState:(tableViewCell->state.checked ? NSOnState : NSOffState)]; [buttonCell drawWithFrame:frame inView:view]; frame.origin.x += frame.size.height + 2; frame.size.width -= frame.size.height + 2; } - if(listViewCell->state.icon) { - NSImage* image = NSMakeImage(listViewCell->state.icon, frame.size.height, frame.size.height); + if(tableViewCell->state.icon) { + NSImage* image = NSMakeImage(tableViewCell->state.icon, frame.size.height, frame.size.height); [[NSGraphicsContext currentContext] saveGraphicsState]; NSRect targetRect = NSMakeRect(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height); NSRect sourceRect = NSMakeRect(0, 0, [image size].width, [image size].height); @@ -189,21 +189,21 @@ frame.size.width -= frame.size.height + 2; } - if(listViewCell->state.text) { + if(tableViewCell->state.text) { NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.alignment = NSTextAlignmentCenter; - if(listViewCell->state.alignment.horizontal() < 0.333) paragraphStyle.alignment = NSTextAlignmentLeft; - if(listViewCell->state.alignment.horizontal() > 0.666) paragraphStyle.alignment = NSTextAlignmentRight; + if(tableViewCell->state.alignment.horizontal() < 0.333) paragraphStyle.alignment = NSTextAlignmentLeft; + if(tableViewCell->state.alignment.horizontal() > 0.666) paragraphStyle.alignment = NSTextAlignmentRight; NSColor* foregroundColor = nil; if([self isHighlighted]) foregroundColor = [NSColor alternateSelectedControlTextColor]; - else if(!listView->enabled(true)) foregroundColor = [NSColor disabledControlTextColor]; - else if(auto color = listViewCell->state.foregroundColor) foregroundColor = NSMakeColor(color); + else if(!tableView->enabled(true)) foregroundColor = [NSColor disabledControlTextColor]; + else if(auto color = tableViewCell->state.foregroundColor) foregroundColor = NSMakeColor(color); else foregroundColor = [NSColor textColor]; - NSString* text = [NSString stringWithUTF8String:listViewCell->state.text]; + NSString* text = [NSString stringWithUTF8String:tableViewCell->state.text]; [text drawInRect:frame withAttributes:@{ NSBackgroundColorAttributeName:backgroundColor, NSForegroundColorAttributeName:foregroundColor, - NSFontAttributeName:hiro::pFont::create(listViewCell->font(true)), + NSFontAttributeName:hiro::pFont::create(tableViewCell->font(true)), NSParagraphStyleAttributeName:paragraphStyle }]; } @@ -233,10 +233,10 @@ NSPoint point = [view convertPointFromBase:[nextEvent locationInWindow]]; NSRect rect = NSMakeRect(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height); if(NSMouseInRect(point, rect, [view isFlipped])) { - if(auto listViewItem = listView->item([view rowAtPoint:point])) { - if(auto listViewCell = listViewItem->cell([view columnAtPoint:point])) { - listViewCell->state.checked = !listViewCell->state.checked; - listView->doToggle(listViewCell->instance); + if(auto tableViewItem = tableView->item([view rowAtPoint:point])) { + if(auto tableViewCell = tableViewItem->cell([view columnAtPoint:point])) { + tableViewCell->state.checked = !tableViewCell->state.checked; + tableView->doToggle(tableViewCell->instance); } } } @@ -255,9 +255,9 @@ namespace hiro { -auto pListView::construct() -> void { +auto pTableView::construct() -> void { @autoreleasepool { - cocoaView = cocoaListView = [[CocoaListView alloc] initWith:self()]; + cocoaView = cocoaTableView = [[CocoaTableView alloc] initWith:self()]; pWidget::construct(); setAlignment(state().alignment); @@ -269,14 +269,14 @@ auto pListView::construct() -> void { } } -auto pListView::destruct() -> void { +auto pTableView::destruct() -> void { @autoreleasepool { [cocoaView removeFromSuperview]; [cocoaView release]; } } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { @autoreleasepool { [cocoaView reloadColumns]; @@ -284,25 +284,25 @@ auto pListView::append(sListViewHeader header) -> void { } } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { @autoreleasepool { [[cocoaView content] reloadData]; } } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { @autoreleasepool { [cocoaView reloadColumns]; } } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { @autoreleasepool { [[cocoaView content] reloadData]; } } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { @autoreleasepool { if(auto& header = state().header) { vector widths; @@ -333,71 +333,71 @@ auto pListView::resizeColumns() -> void { } } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { @autoreleasepool { [[cocoaView content] setAllowsMultipleSelection:(batchable ? YES : NO)]; } } -auto pListView::setBordered(bool bordered) -> void { +auto pTableView::setBordered(bool bordered) -> void { } -auto pListView::setEnabled(bool enabled) -> void { +auto pTableView::setEnabled(bool enabled) -> void { pWidget::setEnabled(enabled); @autoreleasepool { [[cocoaView content] setEnabled:enabled]; } } -auto pListView::setFont(const Font& font) -> void { +auto pTableView::setFont(const Font& font) -> void { @autoreleasepool { [cocoaView setFont:pFont::create(font)]; } } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { } -auto pListView::_cellWidth(uint row, uint column) -> uint { +auto pTableView::_cellWidth(uint row, uint column) -> uint { uint width = 8; - if(auto pListViewItem = self().item(row)) { - if(auto pListViewCell = pListViewItem->cell(column)) { - if(pListViewCell->state.checkable) { + if(auto pTableViewItem = self().item(row)) { + if(auto pTableViewCell = pTableViewItem->cell(column)) { + if(pTableViewCell->state.checkable) { width += 24; } - if(auto& icon = pListViewCell->state.icon) { + if(auto& icon = pTableViewCell->state.icon) { width += icon.width() + 2; } - if(auto& text = pListViewCell->state.text) { - width += pFont::size(pListViewCell->font(true), text).width(); + if(auto& text = pTableViewCell->state.text) { + width += pFont::size(pTableViewCell->font(true), text).width(); } } } return width; } -auto pListView::_columnWidth(uint column) -> uint { +auto pTableView::_columnWidth(uint column) -> uint { uint width = 8; if(auto& header = state().header) { - if(auto pListViewColumn = header->column(column)) { - if(auto& icon = pListViewColumn->state.icon) { + if(auto pTableViewColumn = header->column(column)) { + if(auto& icon = pTableViewColumn->state.icon) { width += icon.width() + 2; } - if(auto& text = pListViewColumn->state.text) { - width += pFont::size(pListViewColumn->font(true), text).width(); + if(auto& text = pTableViewColumn->state.text) { + width += pFont::size(pTableViewColumn->font(true), text).width(); } } } return width; } -auto pListView::_width(uint column) -> uint { +auto pTableView::_width(uint column) -> uint { if(auto& header = state().header) { if(auto width = header->column(column).width()) return width; uint width = 1; @@ -412,20 +412,20 @@ auto pListView::_width(uint column) -> uint { } /* -auto pListView::autoSizeColumns() -> void { +auto pTableView::autoSizeColumns() -> void { @autoreleasepool { - if(listView.state.checkable) { + if(tableView.state.checkable) { NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:@"check"]; [tableColumn setWidth:20.0]; } unsigned height = [[cocoaView content] rowHeight]; - for(unsigned column = 0; column < max(1u, listView.state.headerText.size()); column++) { + for(unsigned column = 0; column < max(1u, tableView.state.headerText.size()); column++) { NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; - unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], listView.state.headerText(column)).width + 4; - for(unsigned row = 0; row < listView.state.text.size(); row++) { - unsigned width = pFont::size([cocoaView font], listView.state.text(row)(column)).width + 2; - if(listView.state.image(row)(height).empty() == false) width += height + 2; + unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], tableView.state.headerText(column)).width + 4; + for(unsigned row = 0; row < tableView.state.text.size(); row++) { + unsigned width = pFont::size([cocoaView font], tableView.state.text(row)(column)).width + 2; + if(tableView.state.image(row)(height)) width += height + 2; if(width > minimumWidth) minimumWidth = width; } [tableColumn setWidth:minimumWidth]; @@ -435,7 +435,7 @@ auto pListView::autoSizeColumns() -> void { } } -auto pListView::setSelected(bool selected) -> void { +auto pTableView::setSelected(bool selected) -> void { @autoreleasepool { if(selected == false) { [[cocoaView content] deselectAll:nil]; @@ -443,7 +443,7 @@ auto pListView::setSelected(bool selected) -> void { } } -auto pListView::setSelection(unsigned selection) -> void { +auto pTableView::setSelection(unsigned selection) -> void { @autoreleasepool { [[cocoaView content] selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(selection, 1)] byExtendingSelection:NO]; } diff --git a/cocoa/widget/list-view.hpp b/cocoa/widget/table-view.hpp similarity index 70% rename from cocoa/widget/list-view.hpp rename to cocoa/widget/table-view.hpp index e1f3fba..548587e 100644 --- a/cocoa/widget/list-view.hpp +++ b/cocoa/widget/table-view.hpp @@ -1,16 +1,16 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -@class CocoaListViewContent; +@class CocoaTableViewContent; -@interface CocoaListView : NSScrollView { +@interface CocoaTableView : NSScrollView { @public - hiro::mListView* listView; - CocoaListViewContent* content; + hiro::mTableView* tableView; + CocoaTableViewContent* content; NSFont* font; } --(id) initWith:(hiro::mListView&)listView; +-(id) initWith:(hiro::mTableView&)tableView; -(void) dealloc; --(CocoaListViewContent*) content; +-(CocoaTableViewContent*) content; -(NSFont*) font; -(void) setFont:(NSFont*)font; -(void) reloadColumns; @@ -24,16 +24,16 @@ -(IBAction) doubleAction:(id)sender; @end -@interface CocoaListViewContent : NSTableView { +@interface CocoaTableViewContent : NSTableView { } -(void) keyDown:(NSEvent*)event; @end -@interface CocoaListViewCell : NSCell { - hiro::mListView* listView; +@interface CocoaTableViewCell : NSCell { + hiro::mTableView* tableView; NSButtonCell* buttonCell; } --(id) initWith:(hiro::mListView&)listViewReference; +-(id) initWith:(hiro::mTableView&)tableViewReference; -(NSString*) stringValue; -(void) drawWithFrame:(NSRect)frame inView:(NSView*)view; -(NSUInteger) hitTestForEvent:(NSEvent*)event inRect:(NSRect)frame ofView:(NSView*)view; @@ -43,13 +43,13 @@ namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader header) -> void; - auto append(sListViewItem item) -> void; - auto remove(sListViewHeader header) -> void; - auto remove(sListViewItem item) -> void; + auto append(sTableViewHeader header) -> void; + auto append(sTableViewItem item) -> void; + auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -63,7 +63,7 @@ struct pListView : pWidget { auto _columnWidth(uint column) -> uint; auto _width(uint column) -> uint; - CocoaListView* cocoaListView = nullptr; + CocoaTableView* cocoaTableView = nullptr; }; } diff --git a/cocoa/widget/viewport.cpp b/cocoa/widget/viewport.cpp index c03202d..52fcf14 100644 --- a/cocoa/widget/viewport.cpp +++ b/cocoa/widget/viewport.cpp @@ -24,7 +24,7 @@ -(BOOL) performDragOperation:(id)sender { lstring paths = DropPaths(sender); - if(paths.empty()) return NO; + if(!paths) return NO; viewport->doDrop(paths); return YES; } diff --git a/cocoa/window.cpp b/cocoa/window.cpp index 0debae8..b87b00a 100644 --- a/cocoa/window.cpp +++ b/cocoa/window.cpp @@ -122,7 +122,7 @@ -(BOOL) performDragOperation:(id)sender { lstring paths = DropPaths(sender); - if(paths.empty()) return NO; + if(!paths) return NO; window->doDrop(paths); return YES; } diff --git a/components.hpp b/components.hpp index cd48b86..6efaaf6 100644 --- a/components.hpp +++ b/components.hpp @@ -54,6 +54,7 @@ #define Hiro_CheckButton #define Hiro_CheckLabel #define Hiro_ComboButton +#define Hiro_ComboEdit #define Hiro_Console #define Hiro_Frame #define Hiro_HexEdit @@ -62,23 +63,22 @@ #define Hiro_IconView #define Hiro_Label #define Hiro_LineEdit -#define Hiro_ListView #define Hiro_ProgressBar #define Hiro_RadioButton #define Hiro_RadioLabel #define Hiro_SourceEdit #define Hiro_TabFrame +#define Hiro_TableView #define Hiro_TextEdit #define Hiro_TreeView #define Hiro_VerticalScrollBar #define Hiro_VerticalSlider #define Hiro_Viewport -#define Hiro_FixedLayout -#define Hiro_HorizontalLayout -#define Hiro_VerticalLayout +//platform-specific exclusions #if defined(HIRO_WINDOWS) || defined(HIRO_COCOA) || defined(HIRO_QT) + #undef Hiro_ComboEdit #undef Hiro_Console #undef Hiro_IconView #undef Hiro_SourceEdit @@ -89,6 +89,16 @@ #undef Hiro_HexEdit #endif +//extensions + +#define Hiro_FixedLayout +#define Hiro_HorizontalLayout +#define Hiro_VerticalLayout + +#if defined(Hiro_TableView) + #define Hiro_ListView +#endif + #if defined(Hiro_Button) && defined(Hiro_Canvas) && defined(Hiro_Label) #define Hiro_MessageDialog #endif diff --git a/core/action/menu.cpp b/core/action/menu.cpp index 45bea2e..37678cd 100644 --- a/core/action/menu.cpp +++ b/core/action/menu.cpp @@ -48,7 +48,7 @@ auto mMenu::remove(sAction action) -> type& { } auto mMenu::reset() -> type& { - while(state.actions) remove(state.actions.last()); + while(state.actions) remove(state.actions.right()); return *this; } diff --git a/core/core.cpp b/core/core.cpp index d6fd5e1..f7eea11 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -77,6 +77,8 @@ namespace hiro { #include "widget/check-label.cpp" #include "widget/combo-button.cpp" #include "widget/combo-button-item.cpp" + #include "widget/combo-edit.cpp" + #include "widget/combo-edit-item.cpp" #include "widget/console.cpp" #include "widget/frame.cpp" #include "widget/hex-edit.cpp" @@ -86,17 +88,17 @@ namespace hiro { #include "widget/icon-view-item.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" - #include "widget/list-view.cpp" - #include "widget/list-view-header.cpp" - #include "widget/list-view-column.cpp" - #include "widget/list-view-item.cpp" - #include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/source-edit.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" + #include "widget/table-view.cpp" + #include "widget/table-view-header.cpp" + #include "widget/table-view-column.cpp" + #include "widget/table-view-item.cpp" + #include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/tree-view.cpp" #include "widget/tree-view-item.cpp" diff --git a/core/core.hpp b/core/core.hpp index c33f9d5..d69bc08 100644 --- a/core/core.hpp +++ b/core/core.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ Declare(CheckButton) Declare(CheckLabel) Declare(ComboButton) Declare(ComboButtonItem) +Declare(ComboEdit) +Declare(ComboEditItem) Declare(Console) Declare(Frame) Declare(HexEdit) @@ -67,17 +70,17 @@ Declare(IconView) Declare(IconViewItem) Declare(Label) Declare(LineEdit) -Declare(ListView) -Declare(ListViewHeader) -Declare(ListViewColumn) -Declare(ListViewItem) -Declare(ListViewCell) Declare(ProgressBar) Declare(RadioButton) Declare(RadioLabel) Declare(SourceEdit) Declare(TabFrame) Declare(TabFrameItem) +Declare(TableView) +Declare(TableViewHeader) +Declare(TableViewColumn) +Declare(TableViewItem) +Declare(TableViewCell) Declare(TextEdit) Declare(TreeView) Declare(TreeViewItem) @@ -572,18 +575,19 @@ struct mObject { auto offset() const -> signed; auto parent() const -> mObject*; auto parentComboButton(bool recursive = false) const -> mComboButton*; + auto parentComboEdit(bool recursive = false) const -> mComboEdit*; auto parentFrame(bool recursive = false) const -> mFrame*; auto parentIconView(bool recursive = false) const -> mIconView*; auto parentLayout(bool recursive = false) const -> mLayout*; - auto parentListView(bool recursive = false) const -> mListView*; - auto parentListViewHeader(bool recursive = false) const -> mListViewHeader*; - auto parentListViewItem(bool recursive = false) const -> mListViewItem*; auto parentMenu(bool recursive = false) const -> mMenu*; auto parentMenuBar(bool recursive = false) const -> mMenuBar*; auto parentPopupMenu(bool recursive = false) const -> mPopupMenu*; auto parentSizable(bool recursive = false) const -> mSizable*; auto parentTabFrame(bool recursive = false) const -> mTabFrame*; auto parentTabFrameItem(bool recursive = false) const -> mTabFrameItem*; + auto parentTableView(bool recursive = false) const -> mTableView*; + auto parentTableViewHeader(bool recursive = false) const -> mTableViewHeader*; + auto parentTableViewItem(bool recursive = false) const -> mTableViewItem*; auto parentTreeView(bool recursive = false) const -> mTreeView*; auto parentTreeViewItem(bool recursive = false) const -> mTreeViewItem*; auto parentWidget(bool recursive = false) const -> mWidget*; @@ -1116,6 +1120,61 @@ struct mComboButtonItem : mObject { }; #endif +#if defined(Hiro_ComboEdit) +struct mComboEdit : mWidget { + Declare(ComboEdit) + using mObject::remove; + + auto append(sComboEditItem item) -> type&; + auto backgroundColor() const -> Color; + auto doActivate() const -> void; + auto doChange() const -> void; + auto foregroundColor() const -> Color; + auto item(uint position) const -> ComboEditItem; + auto itemCount() const -> uint; + auto items() const -> vector; + auto onActivate(const function& callback = {}) -> type&; + auto onChange(const function& callback = {}) -> type&; + auto remove(sComboEditItem item) -> type&; + auto reset() -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override; + auto setText(const string& text = "") -> type&; + auto text() const -> string; + +//private: + struct State { + Color backgroundColor; + Color foregroundColor; + vector items; + function onActivate; + function onChange; + string text; + } state; + + auto destruct() -> void override; +}; +#endif + +#if defined(Hiro_ComboEdit) +struct mComboEditItem : mObject { + Declare(ComboEditItem) + + auto icon() const -> image; + auto remove() -> type& override; + auto setIcon(const image& icon = {}) -> type&; + auto setText(const string& text = "") -> type&; + auto text() const -> string; + +//private: + struct State { + image icon; + string text; + } state; +}; +#endif + #if defined(Hiro_Console) struct mConsole : mWidget { Declare(Console) @@ -1356,205 +1415,6 @@ struct mLineEdit : mWidget { }; #endif -#if defined(Hiro_ListView) -struct mListView : mWidget { - Declare(ListView) - using mObject::remove; - - auto alignment() const -> Alignment; - auto append(sListViewHeader column) -> type&; - auto append(sListViewItem item) -> type&; - auto backgroundColor() const -> Color; - auto batchable() const -> bool; - auto batched() const -> vector; - auto bordered() const -> bool; - auto doActivate() const -> void; - auto doChange() const -> void; - auto doContext() const -> void; - auto doEdit(sListViewCell cell) const -> void; - auto doSort(sListViewColumn column) const -> void; - auto doToggle(sListViewCell cell) const -> void; - auto foregroundColor() const -> Color; - auto header() const -> ListViewHeader; - auto item(unsigned position) const -> ListViewItem; - auto itemCount() const -> unsigned; - auto items() const -> vector; - auto onActivate(const function& callback = {}) -> type&; - auto onChange(const function& callback = {}) -> type&; - auto onContext(const function& callback = {}) -> type&; - auto onEdit(const function& callback = {}) -> type&; - auto onSort(const function& callback = {}) -> type&; - auto onToggle(const function& callback = {}) -> type&; - auto remove(sListViewHeader column) -> type&; - auto remove(sListViewItem item) -> type&; - auto reset() -> type&; - auto resizeColumns() -> type&; - auto selected() const -> ListViewItem; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setBatchable(bool batchable = true) -> type&; - auto setBordered(bool bordered = true) -> type&; - auto setForegroundColor(Color color = {}) -> type&; - auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - -//private: - struct State { - unsigned activeColumn = 0; - Alignment alignment; - Color backgroundColor; - bool batchable = false; - bool bordered = false; - Color foregroundColor; - sListViewHeader header; - vector items; - function onActivate; - function onChange; - function onContext; - function onEdit; - function onSort; - function onToggle; - } state; - - auto destruct() -> void override; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewHeader : mObject { - Declare(ListViewHeader) - - auto append(sListViewColumn column) -> type&; - auto column(unsigned position) const -> ListViewColumn; - auto columnCount() const -> unsigned; - auto columns() const -> vector; - auto remove() -> type& override; - auto remove(sListViewColumn column) -> type&; - auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - -//private: - struct State { - vector columns; - } state; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewColumn : mObject { - Declare(ListViewColumn) - - auto active() const -> bool; - auto alignment() const -> Alignment; - auto backgroundColor() const -> Color; - auto editable() const -> bool; - auto expandable() const -> bool; - auto foregroundColor() const -> Color; - auto horizontalAlignment() const -> double; - auto icon() const -> image; - auto remove() -> type& override; - auto resizable() const -> bool; - auto setActive() -> type&; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setEditable(bool editable = true) -> type&; - auto setExpandable(bool expandable = true) -> type&; - auto setForegroundColor(Color color = {}) -> type&; - auto setHorizontalAlignment(double alignment = 0.0) -> type&; - auto setIcon(const image& icon = {}) -> type&; - auto setResizable(bool resizable = true) -> type&; - auto setSortable(bool sortable = true) -> type&; - auto setText(const string& text = "") -> type&; - auto setVerticalAlignment(double alignment = 0.5) -> type&; - auto setVisible(bool visible = true) -> type&; - auto setWidth(signed width = 0) -> type&; - auto sortable() const -> bool; - auto text() const -> string; - auto verticalAlignment() const -> double; - auto width() const -> signed; - -//private: - struct State { - Alignment alignment; - Color backgroundColor; - bool editable = false; - bool expandable = false; - Color foregroundColor; - double horizontalAlignment = 0.0; - image icon; - bool resizable = true; - bool sortable = false; - string text; - double verticalAlignment = 0.5; - bool visible = true; - signed width = 0; - } state; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewItem : mObject { - Declare(ListViewItem) - - auto alignment() const -> Alignment; - auto append(sListViewCell cell) -> type&; - auto backgroundColor() const -> Color; - auto cell(unsigned position) const -> ListViewCell; - auto cellCount() const -> unsigned; - auto cells() const -> vector; - auto foregroundColor() const -> Color; - auto remove() -> type& override; - auto remove(sListViewCell cell) -> type&; - auto selected() const -> bool; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setFocused() -> type& override; - auto setForegroundColor(Color color = {}) -> type&; - auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - auto setSelected(bool selected = true) -> type&; - -//private: - struct State { - Alignment alignment; - Color backgroundColor; - vector cells; - Color foregroundColor; - bool selected = false; - } state; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewCell : mObject { - Declare(ListViewCell) - - auto alignment(bool recursive = false) const -> Alignment; - auto backgroundColor(bool recursive = false) const -> Color; - auto checkable() const -> bool; - auto checked() const -> bool; - auto font(bool recursive = false) const -> Font; - auto foregroundColor(bool recursive = false) const -> Color; - auto icon() const -> image; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setCheckable(bool checkable = true) -> type&; - auto setChecked(bool checked = true) -> type&; - auto setForegroundColor(Color color = {}) -> type&; - auto setIcon(const image& icon = {}) -> type&; - auto setText(const string& text = "") -> type&; - auto text() const -> string; - -//private: - struct State { - Alignment alignment; - Color backgroundColor; - bool checkable = false; - bool checked = false; - Color foregroundColor; - image icon; - string text; - } state; -}; -#endif - #if defined(Hiro_ProgressBar) struct mProgressBar : mWidget { Declare(ProgressBar) @@ -1718,6 +1578,207 @@ struct mTabFrameItem : mObject { }; #endif +#if defined(Hiro_TableView) +struct mTableView : mWidget { + Declare(TableView) + using mObject::remove; + + auto alignment() const -> Alignment; + auto append(sTableViewHeader column) -> type&; + auto append(sTableViewItem item) -> type&; + auto backgroundColor() const -> Color; + auto batchable() const -> bool; + auto batched() const -> vector; + auto bordered() const -> bool; + auto doActivate() const -> void; + auto doChange() const -> void; + auto doContext() const -> void; + auto doEdit(sTableViewCell cell) const -> void; + auto doSort(sTableViewColumn column) const -> void; + auto doToggle(sTableViewCell cell) const -> void; + auto foregroundColor() const -> Color; + auto header() const -> TableViewHeader; + auto item(unsigned position) const -> TableViewItem; + auto itemCount() const -> unsigned; + auto items() const -> vector; + auto onActivate(const function& callback = {}) -> type&; + auto onChange(const function& callback = {}) -> type&; + auto onContext(const function& callback = {}) -> type&; + auto onEdit(const function& callback = {}) -> type&; + auto onSort(const function& callback = {}) -> type&; + auto onToggle(const function& callback = {}) -> type&; + auto remove(sTableViewHeader column) -> type&; + auto remove(sTableViewItem item) -> type&; + auto reset() -> type&; + auto resizeColumns() -> type&; + auto selected() const -> TableViewItem; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setBatchable(bool batchable = true) -> type&; + auto setBordered(bool bordered = true) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; + +//private: + struct State { + unsigned activeColumn = 0; + Alignment alignment; + Color backgroundColor; + bool batchable = false; + bool bordered = false; + Color foregroundColor; + sTableViewHeader header; + vector items; + function onActivate; + function onChange; + function onContext; + function onEdit; + function onSort; + function onToggle; + } state; + + auto destruct() -> void override; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewHeader : mObject { + Declare(TableViewHeader) + + auto append(sTableViewColumn column) -> type&; + auto column(unsigned position) const -> TableViewColumn; + auto columnCount() const -> unsigned; + auto columns() const -> vector; + auto remove() -> type& override; + auto remove(sTableViewColumn column) -> type&; + auto reset() -> type&; + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; + +//private: + struct State { + vector columns; + } state; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewColumn : mObject { + Declare(TableViewColumn) + + auto active() const -> bool; + auto alignment() const -> Alignment; + auto backgroundColor() const -> Color; + auto editable() const -> bool; + auto expandable() const -> bool; + auto foregroundColor() const -> Color; + auto horizontalAlignment() const -> double; + auto icon() const -> image; + auto remove() -> type& override; + auto resizable() const -> bool; + auto setActive() -> type&; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setEditable(bool editable = true) -> type&; + auto setExpandable(bool expandable = true) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setHorizontalAlignment(double alignment = 0.0) -> type&; + auto setIcon(const image& icon = {}) -> type&; + auto setResizable(bool resizable = true) -> type&; + auto setSortable(bool sortable = true) -> type&; + auto setText(const string& text = "") -> type&; + auto setVerticalAlignment(double alignment = 0.5) -> type&; + auto setVisible(bool visible = true) -> type&; + auto setWidth(signed width = 0) -> type&; + auto sortable() const -> bool; + auto text() const -> string; + auto verticalAlignment() const -> double; + auto width() const -> signed; + +//private: + struct State { + Alignment alignment; + Color backgroundColor; + bool editable = false; + bool expandable = false; + Color foregroundColor; + double horizontalAlignment = 0.0; + image icon; + bool resizable = true; + bool sortable = false; + string text; + double verticalAlignment = 0.5; + bool visible = true; + signed width = 0; + } state; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewItem : mObject { + Declare(TableViewItem) + + auto alignment() const -> Alignment; + auto append(sTableViewCell cell) -> type&; + auto backgroundColor() const -> Color; + auto cell(unsigned position) const -> TableViewCell; + auto cellCount() const -> unsigned; + auto cells() const -> vector; + auto foregroundColor() const -> Color; + auto remove() -> type& override; + auto remove(sTableViewCell cell) -> type&; + auto reset() -> type&; + auto selected() const -> bool; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setFocused() -> type& override; + auto setForegroundColor(Color color = {}) -> type&; + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; + auto setSelected(bool selected = true) -> type&; + +//private: + struct State { + Alignment alignment; + Color backgroundColor; + vector cells; + Color foregroundColor; + bool selected = false; + } state; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewCell : mObject { + Declare(TableViewCell) + + auto alignment(bool recursive = false) const -> Alignment; + auto backgroundColor(bool recursive = false) const -> Color; + auto checkable() const -> bool; + auto checked() const -> bool; + auto font(bool recursive = false) const -> Font; + auto foregroundColor(bool recursive = false) const -> Color; + auto icon() const -> image; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setCheckable(bool checkable = true) -> type&; + auto setChecked(bool checked = true) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setIcon(const image& icon = {}) -> type&; + auto setText(const string& text = "") -> type&; + auto text() const -> string; + +//private: + struct State { + Alignment alignment; + Color backgroundColor; + bool checkable = false; + bool checked = false; + Color foregroundColor; + image icon; + string text; + } state; +}; +#endif + #if defined(Hiro_TextEdit) struct mTextEdit : mWidget { Declare(TextEdit) diff --git a/core/layout.cpp b/core/layout.cpp index cf4a94e..bb0518d 100644 --- a/core/layout.cpp +++ b/core/layout.cpp @@ -41,7 +41,7 @@ auto mLayout::remove(sSizable sizable) -> type& { } auto mLayout::reset() -> type& { - while(state.sizables) remove(state.sizables.last()); + while(state.sizables) remove(state.sizables.right()); return *this; } diff --git a/core/menu-bar.cpp b/core/menu-bar.cpp index 329f082..280814b 100644 --- a/core/menu-bar.cpp +++ b/core/menu-bar.cpp @@ -50,7 +50,7 @@ auto mMenuBar::remove(sMenu menu) -> type& { } auto mMenuBar::reset() -> type& { - while(state.menus) remove(state.menus.last()); + while(state.menus) remove(state.menus.right()); return *this; } diff --git a/core/object.cpp b/core/object.cpp index 810e9e0..cb29bbd 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -100,6 +100,16 @@ auto mObject::parentComboButton(bool recursive) const -> mComboButton* { } #endif +#if defined(Hiro_ComboEdit) +auto mObject::parentComboEdit(bool recursive) const -> mComboEdit* { + if(auto comboEdit = dynamic_cast(parent())) return comboEdit; + if(recursive) { + if(auto object = parent()) return object->parentComboEdit(true); + } + return nullptr; +} +#endif + #if defined(Hiro_Frame) auto mObject::parentFrame(bool recursive) const -> mFrame* { if(auto frame = dynamic_cast(parent())) return frame; @@ -130,36 +140,6 @@ auto mObject::parentLayout(bool recursive) const -> mLayout* { } #endif -#if defined(Hiro_ListView) -auto mObject::parentListView(bool recursive) const -> mListView* { - if(auto listView = dynamic_cast(parent())) return listView; - if(recursive) { - if(auto object = parent()) return object->parentListView(true); - } - return nullptr; -} -#endif - -#if defined(Hiro_ListView) -auto mObject::parentListViewHeader(bool recursive) const -> mListViewHeader* { - if(auto listViewHeader = dynamic_cast(parent())) return listViewHeader; - if(recursive) { - if(auto object = parent()) return object->parentListViewHeader(true); - } - return nullptr; -} -#endif - -#if defined(Hiro_ListView) -auto mObject::parentListViewItem(bool recursive) const -> mListViewItem* { - if(auto listViewItem = dynamic_cast(parent())) return listViewItem; - if(recursive) { - if(auto object = parent()) return object->parentListViewItem(true); - } - return nullptr; -} -#endif - #if defined(Hiro_Menu) auto mObject::parentMenu(bool recursive) const -> mMenu* { if(auto menu = dynamic_cast(parent())) return menu; @@ -220,6 +200,36 @@ auto mObject::parentTabFrameItem(bool recursive) const -> mTabFrameItem* { } #endif +#if defined(Hiro_TableView) +auto mObject::parentTableView(bool recursive) const -> mTableView* { + if(auto tableView = dynamic_cast(parent())) return tableView; + if(recursive) { + if(auto object = parent()) return object->parentTableView(true); + } + return nullptr; +} +#endif + +#if defined(Hiro_TableView) +auto mObject::parentTableViewHeader(bool recursive) const -> mTableViewHeader* { + if(auto tableViewHeader = dynamic_cast(parent())) return tableViewHeader; + if(recursive) { + if(auto object = parent()) return object->parentTableViewHeader(true); + } + return nullptr; +} +#endif + +#if defined(Hiro_TableView) +auto mObject::parentTableViewItem(bool recursive) const -> mTableViewItem* { + if(auto tableViewItem = dynamic_cast(parent())) return tableViewItem; + if(recursive) { + if(auto object = parent()) return object->parentTableViewItem(true); + } + return nullptr; +} +#endif + #if defined(Hiro_TreeView) auto mObject::parentTreeView(bool recursive) const -> mTreeView* { if(auto treeView = dynamic_cast(parent())) return treeView; diff --git a/core/popup-menu.cpp b/core/popup-menu.cpp index f064df7..f2a3879 100644 --- a/core/popup-menu.cpp +++ b/core/popup-menu.cpp @@ -45,7 +45,7 @@ auto mPopupMenu::remove(sAction action) -> type& { } auto mPopupMenu::reset() -> type& { - while(state.actions) remove(state.actions.last()); + while(state.actions) remove(state.actions.right()); return *this; } diff --git a/core/shared.hpp b/core/shared.hpp index 947e091..54e2d5e 100644 --- a/core/shared.hpp +++ b/core/shared.hpp @@ -86,7 +86,7 @@ struct Group : sGroup { template auto objects() const -> vector { vector objects; for(auto object : self().objects()) { - if(auto cast = object.cast()) objects.append(cast); + if(auto casted = object.cast()) objects.append(casted); } return objects; } @@ -321,6 +321,42 @@ struct ComboButton : sComboButton { }; #endif +#if defined(Hiro_ComboEdit) +struct ComboEditItem : sComboEditItem { + DeclareSharedObject(ComboEditItem) + using internalType = mComboEditItem; + + auto icon() const { return self().icon(); } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto text() const { return self().text(); } +}; +#endif + +#if defined(Hiro_ComboEdit) +struct ComboEdit : sComboEdit { + DeclareSharedWidget(ComboEdit) + using internalType = mComboEdit; + + auto append(sComboEditItem item) { return self().append(item), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto doActivate() const { return self().doActivate(); } + auto doChange() const { return self().doChange(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto item(uint position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } + auto items() const { return self().items(); } + auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } + auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } + auto remove(sComboEditItem item) { return self().remove(item), *this; } + auto reset() { return self().reset(), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto text() const { return self().text(); } +}; +#endif + #if defined(Hiro_Console) struct Console : sConsole { DeclareSharedWidget(Console) @@ -485,136 +521,6 @@ struct LineEdit : sLineEdit { }; #endif -#if defined(Hiro_ListView) -struct ListViewColumn : sListViewColumn { - DeclareSharedObject(ListViewColumn) - using internalType = mListViewColumn; - - auto active() const { return self().active(); } - auto alignment() const { return self().alignment(); } - auto backgroundColor() const { return self().backgroundColor(); } - auto editable() const { return self().editable(); } - auto expandable() const { return self().expandable(); } - auto foregroundColor() const { return self().foregroundColor(); } - auto horizontalAlignment() const { return self().horizontalAlignment(); } - auto icon() const { return self().icon(); } - auto resizable() const { return self().resizable(); } - auto setActive() { return self().setActive(), *this; } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setEditable(bool editable = true) { return self().setEditable(editable), *this; } - auto setExpandable(bool expandable = true) { return self().setExpandable(expandable), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } - auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; } - auto setSortable(bool sortable = true) { return self().setSortable(sortable), *this; } - auto setText(const string& text = "") { return self().setText(text), *this; } - auto setWidth(signed width = 0) { return self().setWidth(width), *this; } - auto sortable() const { return self().sortable(); } - auto text() const { return self().text(); } - auto verticalAlignment() const { return self().verticalAlignment(); } - auto width() const { return self().width(); } -}; -#endif - -#if defined(Hiro_ListView) -struct ListViewHeader : sListViewHeader { - DeclareSharedObject(ListViewHeader) - using internalType = mListViewHeader; - - auto append(sListViewColumn column) { return self().append(column), *this; } - auto column(unsigned position) const { return self().column(position); } - auto columnCount() const { return self().columnCount(); } - auto columns() const { return self().columns(); } - auto remove(sListViewColumn column) { return self().remove(column), *this; } -}; -#endif - -#if defined(Hiro_ListView) -struct ListViewCell : sListViewCell { - DeclareSharedObject(ListViewCell) - using internalType = mListViewCell; - - auto alignment() const { return self().alignment(); } - auto backgroundColor() const { return self().backgroundColor(); } - auto checkable() const { return self().checkable(); } - auto checked() const { return self().checked(); } - auto foregroundColor() const { return self().foregroundColor(); } - auto icon() const { return self().icon(); } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setCheckable(bool checkable = true) const { return self().setCheckable(checkable), *this; } - auto setChecked(bool checked = true) const { return self().setChecked(checked), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } - auto setText(const string& text = "") { return self().setText(text), *this; } - auto text() const { return self().text(); } -}; -#endif - -#if defined(Hiro_ListView) -struct ListViewItem : sListViewItem { - DeclareSharedObject(ListViewItem) - using internalType = mListViewItem; - - auto alignment() const { return self().alignment(); } - auto append(sListViewCell cell) { return self().append(cell), *this; } - auto backgroundColor() const { return self().backgroundColor(); } - auto cell(unsigned position) const { return self().cell(position); } - auto cellCount() const { return self().cellCount(); } - auto cells() const { return self().cells(); } - auto foregroundColor() const { return self().foregroundColor(); } - auto remove(sListViewCell cell) { return self().remove(cell), *this; } - auto selected() const { return self().selected(); } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setSelected(bool selected = true) { return self().setSelected(selected), *this; } -}; -#endif - -#if defined(Hiro_ListView) -struct ListView : sListView { - DeclareSharedWidget(ListView) - using internalType = mListView; - - auto alignment() const { return self().alignment(); } - auto append(sListViewHeader header) { return self().append(header), *this; } - auto append(sListViewItem item) { return self().append(item), *this; } - auto backgroundColor() const { return self().backgroundColor(); } - auto batchable() const { return self().batchable(); } - auto batched() const { return self().batched(); } - auto bordered() const { return self().bordered(); } - auto doActivate() const { return self().doActivate(); } - auto doChange() const { return self().doChange(); } - auto doContext() const { return self().doContext(); } - auto doEdit(sListViewCell cell) const { return self().doEdit(cell); } - auto doSort(sListViewColumn column) const { return self().doSort(column); } - auto doToggle(sListViewCell cell) const { return self().doToggle(cell); } - auto foregroundColor() const { return self().foregroundColor(); } - auto header() const { return self().header(); } - auto item(unsigned position) const { return self().item(position); } - auto itemCount() const { return self().itemCount(); } - auto items() const { return self().items(); } - auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } - auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } - auto onContext(const function& callback = {}) { return self().onContext(callback), *this; } - auto onEdit(const function& callback = {}) { return self().onEdit(callback), *this; } - auto onSort(const function& callback = {}) { return self().onSort(callback), *this; } - auto onToggle(const function& callback = {}) { return self().onToggle(callback), *this; } - auto remove(sListViewHeader header) { return self().remove(header), *this; } - auto remove(sListViewItem item) { return self().remove(item), *this; } - auto reset() { return self().reset(), *this; } - auto resizeColumns() { return self().resizeColumns(), *this; } - auto selected() const { return self().selected(); } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; } - auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } -}; -#endif - #if defined(Hiro_ProgressBar) struct ProgressBar : sProgressBar { DeclareSharedWidget(ProgressBar) @@ -722,6 +628,138 @@ struct TabFrame : sTabFrame { }; #endif +#if defined(Hiro_TableView) +struct TableViewColumn : sTableViewColumn { + DeclareSharedObject(TableViewColumn) + using internalType = mTableViewColumn; + + auto active() const { return self().active(); } + auto alignment() const { return self().alignment(); } + auto backgroundColor() const { return self().backgroundColor(); } + auto editable() const { return self().editable(); } + auto expandable() const { return self().expandable(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto horizontalAlignment() const { return self().horizontalAlignment(); } + auto icon() const { return self().icon(); } + auto resizable() const { return self().resizable(); } + auto setActive() { return self().setActive(), *this; } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setEditable(bool editable = true) { return self().setEditable(editable), *this; } + auto setExpandable(bool expandable = true) { return self().setExpandable(expandable), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; } + auto setSortable(bool sortable = true) { return self().setSortable(sortable), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto setWidth(signed width = 0) { return self().setWidth(width), *this; } + auto sortable() const { return self().sortable(); } + auto text() const { return self().text(); } + auto verticalAlignment() const { return self().verticalAlignment(); } + auto width() const { return self().width(); } +}; +#endif + +#if defined(Hiro_TableView) +struct TableViewHeader : sTableViewHeader { + DeclareSharedObject(TableViewHeader) + using internalType = mTableViewHeader; + + auto append(sTableViewColumn column) { return self().append(column), *this; } + auto column(unsigned position) const { return self().column(position); } + auto columnCount() const { return self().columnCount(); } + auto columns() const { return self().columns(); } + auto remove(sTableViewColumn column) { return self().remove(column), *this; } + auto reset() { return self().reset(), *this; } +}; +#endif + +#if defined(Hiro_TableView) +struct TableViewCell : sTableViewCell { + DeclareSharedObject(TableViewCell) + using internalType = mTableViewCell; + + auto alignment() const { return self().alignment(); } + auto backgroundColor() const { return self().backgroundColor(); } + auto checkable() const { return self().checkable(); } + auto checked() const { return self().checked(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto icon() const { return self().icon(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setCheckable(bool checkable = true) const { return self().setCheckable(checkable), *this; } + auto setChecked(bool checked = true) const { return self().setChecked(checked), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto text() const { return self().text(); } +}; +#endif + +#if defined(Hiro_TableView) +struct TableViewItem : sTableViewItem { + DeclareSharedObject(TableViewItem) + using internalType = mTableViewItem; + + auto alignment() const { return self().alignment(); } + auto append(sTableViewCell cell) { return self().append(cell), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto cell(unsigned position) const { return self().cell(position); } + auto cellCount() const { return self().cellCount(); } + auto cells() const { return self().cells(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto remove(sTableViewCell cell) { return self().remove(cell), *this; } + auto reset() { return self().reset(), *this; } + auto selected() const { return self().selected(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setSelected(bool selected = true) { return self().setSelected(selected), *this; } +}; +#endif + +#if defined(Hiro_TableView) +struct TableView : sTableView { + DeclareSharedWidget(TableView) + using internalType = mTableView; + + auto alignment() const { return self().alignment(); } + auto append(sTableViewHeader header) { return self().append(header), *this; } + auto append(sTableViewItem item) { return self().append(item), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto batchable() const { return self().batchable(); } + auto batched() const { return self().batched(); } + auto bordered() const { return self().bordered(); } + auto doActivate() const { return self().doActivate(); } + auto doChange() const { return self().doChange(); } + auto doContext() const { return self().doContext(); } + auto doEdit(sTableViewCell cell) const { return self().doEdit(cell); } + auto doSort(sTableViewColumn column) const { return self().doSort(column); } + auto doToggle(sTableViewCell cell) const { return self().doToggle(cell); } + auto foregroundColor() const { return self().foregroundColor(); } + auto header() const { return self().header(); } + auto item(unsigned position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } + auto items() const { return self().items(); } + auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } + auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } + auto onContext(const function& callback = {}) { return self().onContext(callback), *this; } + auto onEdit(const function& callback = {}) { return self().onEdit(callback), *this; } + auto onSort(const function& callback = {}) { return self().onSort(callback), *this; } + auto onToggle(const function& callback = {}) { return self().onToggle(callback), *this; } + auto remove(sTableViewHeader header) { return self().remove(header), *this; } + auto remove(sTableViewItem item) { return self().remove(item), *this; } + auto reset() { return self().reset(), *this; } + auto resizeColumns() { return self().resizeColumns(), *this; } + auto selected() const { return self().selected(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; } + auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } +}; +#endif + #if defined(Hiro_TextEdit) struct TextEdit : sTextEdit { DeclareSharedWidget(TextEdit) diff --git a/core/widget/combo-edit-item.cpp b/core/widget/combo-edit-item.cpp new file mode 100644 index 0000000..98bb2ee --- /dev/null +++ b/core/widget/combo-edit-item.cpp @@ -0,0 +1,34 @@ +#if defined(Hiro_ComboEdit) + +auto mComboEditItem::allocate() -> pObject* { + return new pComboEditItem(*this); +} + +// + +auto mComboEditItem::icon() const -> image { + return state.icon; +} + +auto mComboEditItem::remove() -> type& { + if(auto comboEdit = parentComboEdit()) comboEdit->remove(*this); + return *this; +} + +auto mComboEditItem::setIcon(const image& icon) -> type& { + state.icon = icon; + signal(setIcon, icon); + return *this; +} + +auto mComboEditItem::setText(const string& text) -> type& { + state.text = text; + signal(setText, text); + return *this; +} + +auto mComboEditItem::text() const -> string { + return state.text; +} + +#endif diff --git a/core/widget/combo-edit.cpp b/core/widget/combo-edit.cpp new file mode 100644 index 0000000..1071cd0 --- /dev/null +++ b/core/widget/combo-edit.cpp @@ -0,0 +1,107 @@ +#if defined(Hiro_ComboEdit) + +auto mComboEdit::allocate() -> pObject* { + return new pComboEdit(*this); +} + +auto mComboEdit::destruct() -> void { + mWidget::destruct(); +} + +// + +auto mComboEdit::append(sComboEditItem item) -> type& { + state.items.append(item); + item->setParent(this, itemCount() - 1); + signal(append, item); + return *this; +} + +auto mComboEdit::backgroundColor() const -> Color { + return state.backgroundColor; +} + +auto mComboEdit::doActivate() const -> void { + if(state.onActivate) return state.onActivate(); +} + +auto mComboEdit::doChange() const -> void { + if(state.onChange) return state.onChange(); +} + +auto mComboEdit::foregroundColor() const -> Color { + return state.foregroundColor; +} + +auto mComboEdit::item(uint position) const -> ComboEditItem { + if(position < itemCount()) return state.items[position]; + return {}; +} + +auto mComboEdit::itemCount() const -> uint { + return state.items.size(); +} + +auto mComboEdit::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + +auto mComboEdit::onActivate(const function& callback) -> type& { + state.onActivate = callback; + return *this; +} + +auto mComboEdit::onChange(const function& callback) -> type& { + state.onChange = callback; + return *this; +} + +auto mComboEdit::remove(sComboEditItem item) -> type& { + signal(remove, item); + state.items.remove(item->offset()); + for(auto n : range(item->offset(), itemCount())) { + state.items[n]->adjustOffset(-1); + } + item->setParent(); + return *this; +} + +auto mComboEdit::reset() -> type& { + signal(reset); + for(auto& item : state.items) item->setParent(); + state.items.reset(); + return *this; +} + +auto mComboEdit::setBackgroundColor(Color color) -> type& { + state.backgroundColor = color; + signal(setBackgroundColor, color); + return *this; +} + +auto mComboEdit::setForegroundColor(Color color) -> type& { + state.foregroundColor = color; + signal(setForegroundColor, color); + return *this; +} + +auto mComboEdit::setParent(mObject* parent, int offset) -> type& { + for(auto& item : state.items) item->destruct(); + mObject::setParent(parent, offset); + for(auto& item : state.items) item->setParent(this, item->offset()); + return *this; +} + +auto mComboEdit::setText(const string& text) -> type& { + state.text = text; + signal(setText, text); + return *this; +} + +auto mComboEdit::text() const -> string { + return state.text; +} + +#endif diff --git a/core/widget/list-view-column.cpp b/core/widget/list-view-column.cpp deleted file mode 100644 index e23e67d..0000000 --- a/core/widget/list-view-column.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#if defined(Hiro_ListView) - -auto mListViewColumn::allocate() -> pObject* { - return new pListViewColumn(*this); -} - -// - -auto mListViewColumn::active() const -> bool { - if(auto listView = parentListView()) return listView->state.activeColumn == offset(); - return false; -} - -auto mListViewColumn::alignment() const -> Alignment { - return state.alignment; -} - -auto mListViewColumn::backgroundColor() const -> Color { - return state.backgroundColor; -} - -auto mListViewColumn::editable() const -> bool { - return state.editable; -} - -auto mListViewColumn::expandable() const -> bool { - return state.expandable; -} - -auto mListViewColumn::foregroundColor() const -> Color { - return state.foregroundColor; -} - -auto mListViewColumn::horizontalAlignment() const -> double { - return state.horizontalAlignment; -} - -auto mListViewColumn::icon() const -> image { - return state.icon; -} - -auto mListViewColumn::remove() -> type& { - if(auto listView = parentListViewHeader()) listView->remove(*this); - return *this; -} - -auto mListViewColumn::resizable() const -> bool { - return state.resizable; -} - -auto mListViewColumn::setActive() -> type& { - if(auto listView = parentListView()) listView->state.activeColumn = offset(); - signal(setActive); - return *this; -} - -auto mListViewColumn::setAlignment(Alignment alignment) -> type& { - state.alignment = alignment; - signal(setAlignment, alignment); - return *this; -} - -auto mListViewColumn::setBackgroundColor(Color color) -> type& { - state.backgroundColor = color; - signal(setBackgroundColor, color); - return *this; -} - -auto mListViewColumn::setEditable(bool editable) -> type& { - state.editable = editable; - signal(setEditable, editable); - return *this; -} - -auto mListViewColumn::setExpandable(bool expandable) -> type& { - state.expandable = expandable; - signal(setExpandable, expandable); - return *this; -} - -auto mListViewColumn::setForegroundColor(Color color) -> type& { - state.foregroundColor = color; - signal(setForegroundColor, color); - return *this; -} - -auto mListViewColumn::setHorizontalAlignment(double alignment) -> type& { - alignment = max(0.0, min(1.0, alignment)); - state.horizontalAlignment = alignment; - signal(setHorizontalAlignment, alignment); - return *this; -} - -auto mListViewColumn::setIcon(const image& icon) -> type& { - state.icon = icon; - signal(setIcon, icon); - return *this; -} - -auto mListViewColumn::setResizable(bool resizable) -> type& { - state.resizable = resizable; - signal(setResizable, resizable); - return *this; -} - -auto mListViewColumn::setSortable(bool sortable) -> type& { - state.sortable = sortable; - signal(setSortable, sortable); - return *this; -} - -auto mListViewColumn::setText(const string& text) -> type& { - state.text = text; - signal(setText, text); - return *this; -} - -auto mListViewColumn::setVerticalAlignment(double alignment) -> type& { - alignment = max(0.0, min(1.0, alignment)); - state.verticalAlignment = alignment; - signal(setVerticalAlignment, alignment); - return *this; -} - -auto mListViewColumn::setVisible(bool visible) -> type& { - state.visible = visible; - signal(setVisible, visible); - return *this; -} - -auto mListViewColumn::setWidth(signed width) -> type& { - state.width = max(0, width); - signal(setWidth, width); - return *this; -} - -auto mListViewColumn::sortable() const -> bool { - return state.sortable; -} - -auto mListViewColumn::text() const -> string { - return state.text; -} - -auto mListViewColumn::verticalAlignment() const -> double { - return state.verticalAlignment; -} - -auto mListViewColumn::width() const -> signed { - return state.width; -} - -#endif diff --git a/core/widget/list-view-header.cpp b/core/widget/list-view-header.cpp deleted file mode 100644 index 9469ef3..0000000 --- a/core/widget/list-view-header.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#if defined(Hiro_ListView) - -auto mListViewHeader::allocate() -> pObject* { - return new pListViewHeader(*this); -} - -// - -auto mListViewHeader::append(sListViewColumn column) -> type& { - state.columns.append(column); - column->setParent(this, columnCount() - 1); - signal(append, column); - return *this; -} - -auto mListViewHeader::column(unsigned position) const -> ListViewColumn { - if(position < columnCount()) return state.columns[position]; - return {}; -} - -auto mListViewHeader::columnCount() const -> unsigned { - return state.columns.size(); -} - -auto mListViewHeader::columns() const -> vector { - vector columns; - for(auto& column : state.columns) columns.append(column); - return columns; -} - -auto mListViewHeader::remove() -> type& { - if(auto listView = parentListView()) listView->remove(*this); - return *this; -} - -auto mListViewHeader::remove(sListViewColumn column) -> type& { - signal(remove, column); - state.columns.remove(column->offset()); - for(auto n : range(column->offset(), columnCount())) { - state.columns[n]->adjustOffset(-1); - } - column->setParent(); - return *this; -} - -auto mListViewHeader::setParent(mObject* parent, signed offset) -> type& { - for(auto& column : state.columns) column->destruct(); - mObject::setParent(parent, offset); - for(auto& column : state.columns) column->setParent(this, column->offset()); - return *this; -} - -#endif diff --git a/core/widget/list-view-item.cpp b/core/widget/list-view-item.cpp deleted file mode 100644 index 4b9a0d3..0000000 --- a/core/widget/list-view-item.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#if defined(Hiro_ListView) - -auto mListViewItem::allocate() -> pObject* { - return new pListViewItem(*this); -} - -// - -auto mListViewItem::alignment() const -> Alignment { - return state.alignment; -} - -auto mListViewItem::append(sListViewCell cell) -> type& { - state.cells.append(cell); - cell->setParent(this, cellCount() - 1); - signal(append, cell); - return *this; -} - -auto mListViewItem::backgroundColor() const -> Color { - return state.backgroundColor; -} - -auto mListViewItem::cell(unsigned position) const -> ListViewCell { - if(position < cellCount()) return state.cells[position]; - return {}; -} - -auto mListViewItem::cellCount() const -> unsigned { - return state.cells.size(); -} - -auto mListViewItem::cells() const -> vector { - vector cells; - for(auto& cell : state.cells) cells.append(cell); - return cells; -} - -auto mListViewItem::foregroundColor() const -> Color { - return state.foregroundColor; -} - -auto mListViewItem::remove() -> type& { - if(auto listView = parentListView()) listView->remove(*this); - return *this; -} - -auto mListViewItem::remove(sListViewCell cell) -> type& { - signal(remove, cell); - state.cells.remove(cell->offset()); - for(auto n : range(cell->offset(), cellCount())) { - state.cells[n]->adjustOffset(-1); - } - cell->setParent(); - return *this; -} - -auto mListViewItem::selected() const -> bool { - return state.selected; -} - -auto mListViewItem::setAlignment(Alignment alignment) -> type& { - state.alignment = alignment; - signal(setAlignment, alignment); - return *this; -} - -auto mListViewItem::setBackgroundColor(Color color) -> type& { - state.backgroundColor = color; - signal(setBackgroundColor, color); - return *this; -} - -auto mListViewItem::setFocused() -> type& { - signal(setFocused); - return *this; -} - -auto mListViewItem::setForegroundColor(Color color) -> type& { - state.foregroundColor = color; - signal(setForegroundColor, color); - return *this; -} - -auto mListViewItem::setParent(mObject* parent, signed offset) -> type& { - for(auto& cell : state.cells) cell->destruct(); - mObject::setParent(parent, offset); - for(auto& cell : state.cells) cell->setParent(this, cell->offset()); - return *this; -} - -auto mListViewItem::setSelected(bool selected) -> type& { - state.selected = selected; - signal(setSelected, selected); - return *this; -} - -#endif diff --git a/core/widget/tab-frame.cpp b/core/widget/tab-frame.cpp index 1ac78bf..58bbec7 100644 --- a/core/widget/tab-frame.cpp +++ b/core/widget/tab-frame.cpp @@ -77,7 +77,7 @@ auto mTabFrame::remove(sTabFrameItem item) -> type& { } auto mTabFrame::reset() -> type& { - while(state.items) remove(state.items.last()); + while(state.items) remove(state.items.right()); return *this; } diff --git a/core/widget/list-view-cell.cpp b/core/widget/table-view-cell.cpp similarity index 66% rename from core/widget/list-view-cell.cpp rename to core/widget/table-view-cell.cpp index f9c4d01..aee788f 100644 --- a/core/widget/list-view-cell.cpp +++ b/core/widget/table-view-cell.cpp @@ -1,17 +1,17 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -auto mListViewCell::allocate() -> pObject* { - return new pListViewCell(*this); +auto mTableViewCell::allocate() -> pObject* { + return new pTableViewCell(*this); } // -auto mListViewCell::alignment(bool recursive) const -> Alignment { +auto mTableViewCell::alignment(bool recursive) const -> Alignment { if(auto alignment = state.alignment) return alignment; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto alignment = parent->state.alignment) return alignment; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -26,12 +26,12 @@ auto mListViewCell::alignment(bool recursive) const -> Alignment { return {}; } -auto mListViewCell::backgroundColor(bool recursive) const -> Color { +auto mTableViewCell::backgroundColor(bool recursive) const -> Color { if(auto color = state.backgroundColor) return color; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto color = parent->state.backgroundColor) return color; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -46,20 +46,20 @@ auto mListViewCell::backgroundColor(bool recursive) const -> Color { return {}; } -auto mListViewCell::checkable() const -> bool { +auto mTableViewCell::checkable() const -> bool { return state.checkable; } -auto mListViewCell::checked() const -> bool { +auto mTableViewCell::checked() const -> bool { return state.checkable && state.checked; } -auto mListViewCell::font(bool recursive) const -> Font { +auto mTableViewCell::font(bool recursive) const -> Font { if(auto font = mObject::font()) return font; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto font = parent->font()) return font; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -74,12 +74,12 @@ auto mListViewCell::font(bool recursive) const -> Font { return {}; } -auto mListViewCell::foregroundColor(bool recursive) const -> Color { +auto mTableViewCell::foregroundColor(bool recursive) const -> Color { if(auto color = state.foregroundColor) return color; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto color = parent->state.foregroundColor) return color; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -94,54 +94,54 @@ auto mListViewCell::foregroundColor(bool recursive) const -> Color { return state.foregroundColor; } -auto mListViewCell::icon() const -> image { +auto mTableViewCell::icon() const -> image { return state.icon; } -auto mListViewCell::setAlignment(Alignment alignment) -> type& { +auto mTableViewCell::setAlignment(Alignment alignment) -> type& { state.alignment = alignment; signal(setAlignment, alignment); return *this; } -auto mListViewCell::setBackgroundColor(Color color) -> type& { +auto mTableViewCell::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); return *this; } -auto mListViewCell::setCheckable(bool checkable) -> type& { +auto mTableViewCell::setCheckable(bool checkable) -> type& { state.checkable = checkable; signal(setCheckable, checkable); return *this; } -auto mListViewCell::setChecked(bool checked) -> type& { +auto mTableViewCell::setChecked(bool checked) -> type& { setCheckable(true); state.checked = checked; signal(setChecked, checked); return *this; } -auto mListViewCell::setForegroundColor(Color color) -> type& { +auto mTableViewCell::setForegroundColor(Color color) -> type& { state.foregroundColor = color; signal(setForegroundColor, color); return *this; } -auto mListViewCell::setIcon(const image& icon) -> type& { +auto mTableViewCell::setIcon(const image& icon) -> type& { state.icon = icon; signal(setIcon, icon); return *this; } -auto mListViewCell::setText(const string& text) -> type& { +auto mTableViewCell::setText(const string& text) -> type& { state.text = text; signal(setText, text); return *this; } -auto mListViewCell::text() const -> string { +auto mTableViewCell::text() const -> string { return state.text; } diff --git a/core/widget/table-view-column.cpp b/core/widget/table-view-column.cpp new file mode 100644 index 0000000..cee2f8a --- /dev/null +++ b/core/widget/table-view-column.cpp @@ -0,0 +1,153 @@ +#if defined(Hiro_TableView) + +auto mTableViewColumn::allocate() -> pObject* { + return new pTableViewColumn(*this); +} + +// + +auto mTableViewColumn::active() const -> bool { + if(auto tableView = parentTableView()) return tableView->state.activeColumn == offset(); + return false; +} + +auto mTableViewColumn::alignment() const -> Alignment { + return state.alignment; +} + +auto mTableViewColumn::backgroundColor() const -> Color { + return state.backgroundColor; +} + +auto mTableViewColumn::editable() const -> bool { + return state.editable; +} + +auto mTableViewColumn::expandable() const -> bool { + return state.expandable; +} + +auto mTableViewColumn::foregroundColor() const -> Color { + return state.foregroundColor; +} + +auto mTableViewColumn::horizontalAlignment() const -> double { + return state.horizontalAlignment; +} + +auto mTableViewColumn::icon() const -> image { + return state.icon; +} + +auto mTableViewColumn::remove() -> type& { + if(auto tableView = parentTableViewHeader()) tableView->remove(*this); + return *this; +} + +auto mTableViewColumn::resizable() const -> bool { + return state.resizable; +} + +auto mTableViewColumn::setActive() -> type& { + if(auto tableView = parentTableView()) tableView->state.activeColumn = offset(); + signal(setActive); + return *this; +} + +auto mTableViewColumn::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); + return *this; +} + +auto mTableViewColumn::setBackgroundColor(Color color) -> type& { + state.backgroundColor = color; + signal(setBackgroundColor, color); + return *this; +} + +auto mTableViewColumn::setEditable(bool editable) -> type& { + state.editable = editable; + signal(setEditable, editable); + return *this; +} + +auto mTableViewColumn::setExpandable(bool expandable) -> type& { + state.expandable = expandable; + signal(setExpandable, expandable); + return *this; +} + +auto mTableViewColumn::setForegroundColor(Color color) -> type& { + state.foregroundColor = color; + signal(setForegroundColor, color); + return *this; +} + +auto mTableViewColumn::setHorizontalAlignment(double alignment) -> type& { + alignment = max(0.0, min(1.0, alignment)); + state.horizontalAlignment = alignment; + signal(setHorizontalAlignment, alignment); + return *this; +} + +auto mTableViewColumn::setIcon(const image& icon) -> type& { + state.icon = icon; + signal(setIcon, icon); + return *this; +} + +auto mTableViewColumn::setResizable(bool resizable) -> type& { + state.resizable = resizable; + signal(setResizable, resizable); + return *this; +} + +auto mTableViewColumn::setSortable(bool sortable) -> type& { + state.sortable = sortable; + signal(setSortable, sortable); + return *this; +} + +auto mTableViewColumn::setText(const string& text) -> type& { + state.text = text; + signal(setText, text); + return *this; +} + +auto mTableViewColumn::setVerticalAlignment(double alignment) -> type& { + alignment = max(0.0, min(1.0, alignment)); + state.verticalAlignment = alignment; + signal(setVerticalAlignment, alignment); + return *this; +} + +auto mTableViewColumn::setVisible(bool visible) -> type& { + state.visible = visible; + signal(setVisible, visible); + return *this; +} + +auto mTableViewColumn::setWidth(signed width) -> type& { + state.width = max(0, width); + signal(setWidth, width); + return *this; +} + +auto mTableViewColumn::sortable() const -> bool { + return state.sortable; +} + +auto mTableViewColumn::text() const -> string { + return state.text; +} + +auto mTableViewColumn::verticalAlignment() const -> double { + return state.verticalAlignment; +} + +auto mTableViewColumn::width() const -> signed { + return state.width; +} + +#endif diff --git a/core/widget/table-view-header.cpp b/core/widget/table-view-header.cpp new file mode 100644 index 0000000..cfc0dde --- /dev/null +++ b/core/widget/table-view-header.cpp @@ -0,0 +1,58 @@ +#if defined(Hiro_TableView) + +auto mTableViewHeader::allocate() -> pObject* { + return new pTableViewHeader(*this); +} + +// + +auto mTableViewHeader::append(sTableViewColumn column) -> type& { + state.columns.append(column); + column->setParent(this, columnCount() - 1); + signal(append, column); + return *this; +} + +auto mTableViewHeader::column(unsigned position) const -> TableViewColumn { + if(position < columnCount()) return state.columns[position]; + return {}; +} + +auto mTableViewHeader::columnCount() const -> unsigned { + return state.columns.size(); +} + +auto mTableViewHeader::columns() const -> vector { + vector columns; + for(auto& column : state.columns) columns.append(column); + return columns; +} + +auto mTableViewHeader::remove() -> type& { + if(auto tableView = parentTableView()) tableView->remove(*this); + return *this; +} + +auto mTableViewHeader::remove(sTableViewColumn column) -> type& { + signal(remove, column); + state.columns.remove(column->offset()); + for(auto n : range(column->offset(), columnCount())) { + state.columns[n]->adjustOffset(-1); + } + column->setParent(); + return *this; +} + +auto mTableViewHeader::reset() -> type& { + for(auto n : rrange(state.columns)) remove(state.columns[n]); + return *this; +} + +auto mTableViewHeader::setParent(mObject* parent, signed offset) -> type& { + for(auto& column : state.columns) column->destruct(); + mObject::setParent(parent, offset); + for(auto& column : state.columns) column->setParent(this, column->offset()); + return *this; +} + +#endif diff --git a/core/widget/table-view-item.cpp b/core/widget/table-view-item.cpp new file mode 100644 index 0000000..2fc8e2a --- /dev/null +++ b/core/widget/table-view-item.cpp @@ -0,0 +1,103 @@ +#if defined(Hiro_TableView) + +auto mTableViewItem::allocate() -> pObject* { + return new pTableViewItem(*this); +} + +// + +auto mTableViewItem::alignment() const -> Alignment { + return state.alignment; +} + +auto mTableViewItem::append(sTableViewCell cell) -> type& { + state.cells.append(cell); + cell->setParent(this, cellCount() - 1); + signal(append, cell); + return *this; +} + +auto mTableViewItem::backgroundColor() const -> Color { + return state.backgroundColor; +} + +auto mTableViewItem::cell(unsigned position) const -> TableViewCell { + if(position < cellCount()) return state.cells[position]; + return {}; +} + +auto mTableViewItem::cellCount() const -> unsigned { + return state.cells.size(); +} + +auto mTableViewItem::cells() const -> vector { + vector cells; + for(auto& cell : state.cells) cells.append(cell); + return cells; +} + +auto mTableViewItem::foregroundColor() const -> Color { + return state.foregroundColor; +} + +auto mTableViewItem::remove() -> type& { + if(auto tableView = parentTableView()) tableView->remove(*this); + return *this; +} + +auto mTableViewItem::remove(sTableViewCell cell) -> type& { + signal(remove, cell); + state.cells.remove(cell->offset()); + for(auto n : range(cell->offset(), cellCount())) { + state.cells[n]->adjustOffset(-1); + } + cell->setParent(); + return *this; +} + +auto mTableViewItem::reset() -> type& { + for(auto n : rrange(state.cells)) remove(state.cells[n]); + return *this; +} + +auto mTableViewItem::selected() const -> bool { + return state.selected; +} + +auto mTableViewItem::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); + return *this; +} + +auto mTableViewItem::setBackgroundColor(Color color) -> type& { + state.backgroundColor = color; + signal(setBackgroundColor, color); + return *this; +} + +auto mTableViewItem::setFocused() -> type& { + signal(setFocused); + return *this; +} + +auto mTableViewItem::setForegroundColor(Color color) -> type& { + state.foregroundColor = color; + signal(setForegroundColor, color); + return *this; +} + +auto mTableViewItem::setParent(mObject* parent, signed offset) -> type& { + for(auto& cell : state.cells) cell->destruct(); + mObject::setParent(parent, offset); + for(auto& cell : state.cells) cell->setParent(this, cell->offset()); + return *this; +} + +auto mTableViewItem::setSelected(bool selected) -> type& { + state.selected = selected; + signal(setSelected, selected); + return *this; +} + +#endif diff --git a/core/widget/list-view.cpp b/core/widget/table-view.cpp similarity index 55% rename from core/widget/list-view.cpp rename to core/widget/table-view.cpp index 14a8ccb..8390b62 100644 --- a/core/widget/list-view.cpp +++ b/core/widget/table-view.cpp @@ -1,10 +1,10 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -auto mListView::allocate() -> pObject* { - return new pListView(*this); +auto mTableView::allocate() -> pObject* { + return new pTableView(*this); } -auto mListView::destruct() -> void { +auto mTableView::destruct() -> void { for(auto& item : state.items) item->destruct(); if(auto& header = state.header) header->destruct(); mWidget::destruct(); @@ -12,11 +12,11 @@ auto mListView::destruct() -> void { // -auto mListView::alignment() const -> Alignment { +auto mTableView::alignment() const -> Alignment { return state.alignment; } -auto mListView::append(sListViewHeader header) -> type& { +auto mTableView::append(sTableViewHeader header) -> type& { if(auto& header = state.header) remove(header); state.header = header; header->setParent(this, 0); @@ -24,118 +24,118 @@ auto mListView::append(sListViewHeader header) -> type& { return *this; } -auto mListView::append(sListViewItem item) -> type& { +auto mTableView::append(sTableViewItem item) -> type& { state.items.append(item); item->setParent(this, itemCount() - 1); signal(append, item); return *this; } -auto mListView::backgroundColor() const -> Color { +auto mTableView::backgroundColor() const -> Color { return state.backgroundColor; } -auto mListView::batchable() const -> bool { +auto mTableView::batchable() const -> bool { return state.batchable; } -auto mListView::batched() const -> vector { - vector items; +auto mTableView::batched() const -> vector { + vector items; for(auto& item : state.items) { if(item->selected()) items.append(item); } return items; } -auto mListView::bordered() const -> bool { +auto mTableView::bordered() const -> bool { return state.bordered; } -auto mListView::doActivate() const -> void { +auto mTableView::doActivate() const -> void { if(state.onActivate) return state.onActivate(); } -auto mListView::doChange() const -> void { +auto mTableView::doChange() const -> void { if(state.onChange) return state.onChange(); } -auto mListView::doContext() const -> void { +auto mTableView::doContext() const -> void { if(state.onContext) return state.onContext(); } -auto mListView::doEdit(sListViewCell cell) const -> void { +auto mTableView::doEdit(sTableViewCell cell) const -> void { if(state.onEdit) return state.onEdit(cell); } -auto mListView::doSort(sListViewColumn column) const -> void { +auto mTableView::doSort(sTableViewColumn column) const -> void { if(state.onSort) return state.onSort(column); } -auto mListView::doToggle(sListViewCell cell) const -> void { +auto mTableView::doToggle(sTableViewCell cell) const -> void { if(state.onToggle) return state.onToggle(cell); } -auto mListView::foregroundColor() const -> Color { +auto mTableView::foregroundColor() const -> Color { return state.foregroundColor; } -auto mListView::header() const -> ListViewHeader { +auto mTableView::header() const -> TableViewHeader { return state.header; } -auto mListView::item(unsigned position) const -> ListViewItem { +auto mTableView::item(unsigned position) const -> TableViewItem { if(position < itemCount()) return state.items[position]; return {}; } -auto mListView::itemCount() const -> unsigned { +auto mTableView::itemCount() const -> unsigned { return state.items.size(); } -auto mListView::items() const -> vector { - vector items; +auto mTableView::items() const -> vector { + vector items; for(auto& item : state.items) items.append(item); return items; } -auto mListView::onActivate(const function& callback) -> type& { +auto mTableView::onActivate(const function& callback) -> type& { state.onActivate = callback; return *this; } -auto mListView::onChange(const function& callback) -> type& { +auto mTableView::onChange(const function& callback) -> type& { state.onChange = callback; return *this; } -auto mListView::onContext(const function& callback) -> type& { +auto mTableView::onContext(const function& callback) -> type& { state.onContext = callback; return *this; } -auto mListView::onEdit(const function& callback) -> type& { +auto mTableView::onEdit(const function& callback) -> type& { state.onEdit = callback; return *this; } -auto mListView::onSort(const function& callback) -> type& { +auto mTableView::onSort(const function& callback) -> type& { state.onSort = callback; return *this; } -auto mListView::onToggle(const function& callback) -> type& { +auto mTableView::onToggle(const function& callback) -> type& { state.onToggle = callback; return *this; } -auto mListView::remove(sListViewHeader header) -> type& { +auto mTableView::remove(sTableViewHeader header) -> type& { signal(remove, header); header->setParent(); state.header.reset(); return *this; } -auto mListView::remove(sListViewItem item) -> type& { +auto mTableView::remove(sTableViewItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); for(auto n : range(item->offset(), itemCount())) { @@ -145,55 +145,55 @@ auto mListView::remove(sListViewItem item) -> type& { return *this; } -auto mListView::reset() -> type& { +auto mTableView::reset() -> type& { for(auto n : rrange(state.items)) remove(state.items[n]); if(auto& header = state.header) remove(header); return *this; } -auto mListView::resizeColumns() -> type& { +auto mTableView::resizeColumns() -> type& { signal(resizeColumns); return *this; } -auto mListView::selected() const -> ListViewItem { +auto mTableView::selected() const -> TableViewItem { for(auto& item : state.items) { if(item->selected()) return item; } return {}; } -auto mListView::setAlignment(Alignment alignment) -> type& { +auto mTableView::setAlignment(Alignment alignment) -> type& { state.alignment = alignment; signal(setAlignment, alignment); return *this; } -auto mListView::setBackgroundColor(Color color) -> type& { +auto mTableView::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); return *this; } -auto mListView::setBatchable(bool batchable) -> type& { +auto mTableView::setBatchable(bool batchable) -> type& { state.batchable = batchable; signal(setBatchable, batchable); return *this; } -auto mListView::setBordered(bool bordered) -> type& { +auto mTableView::setBordered(bool bordered) -> type& { state.bordered = bordered; signal(setBordered, bordered); return *this; } -auto mListView::setForegroundColor(Color color) -> type& { +auto mTableView::setForegroundColor(Color color) -> type& { state.foregroundColor = color; signal(setForegroundColor, color); return *this; } -auto mListView::setParent(mObject* parent, signed offset) -> type& { +auto mTableView::setParent(mObject* parent, signed offset) -> type& { for(auto n : rrange(state.items)) state.items[n]->destruct(); if(auto& header = state.header) header->destruct(); mObject::setParent(parent, offset); diff --git a/core/widget/tree-view-item.cpp b/core/widget/tree-view-item.cpp index 75724a0..f26e9af 100644 --- a/core/widget/tree-view-item.cpp +++ b/core/widget/tree-view-item.cpp @@ -57,11 +57,11 @@ auto mTreeViewItem::icon() const -> image { } auto mTreeViewItem::item(const string& path) const -> TreeViewItem { - if(path.empty()) return {}; + if(!path) return {}; auto paths = path.split("/"); - unsigned position = paths.takeFirst().natural(); + unsigned position = paths.takeLeft().natural(); if(position >= itemCount()) return {}; - if(paths.empty()) return state.items[position]; + if(!paths) return state.items[position]; return state.items[position]->item(paths.merge("/")); } diff --git a/core/widget/tree-view.cpp b/core/widget/tree-view.cpp index a62d211..006608c 100644 --- a/core/widget/tree-view.cpp +++ b/core/widget/tree-view.cpp @@ -43,11 +43,11 @@ auto mTreeView::foregroundColor() const -> Color { } auto mTreeView::item(const string& path) const -> TreeViewItem { - if(path.empty()) return {}; + if(!path) return {}; auto paths = path.split("/"); - unsigned position = paths.takeFirst().natural(); + unsigned position = paths.takeLeft().natural(); if(position >= itemCount()) return {}; - if(paths.empty()) return state.items[position]; + if(!paths) return state.items[position]; return state.items[position]->item(paths.merge("/")); } diff --git a/extension/browser-dialog.cpp b/extension/browser-dialog.cpp index 56a784a..46eb958 100644 --- a/extension/browser-dialog.cpp +++ b/extension/browser-dialog.cpp @@ -30,12 +30,12 @@ private: }; //accept button clicked, or enter pressed on file name line edit -//also called by list view activate after special case handling +//also called by table view activate after special case handling auto BrowserDialogWindow::accept() -> void { auto batched = view.batched(); if(state.action == "openFile" && batched) { - string name = batched.first()->cell(0)->text(); + string name = batched.left()->cell(0)->text(); if(isFolder(name)) return setPath({state.path, name}); state.response.append(string{state.path, name}); } @@ -48,14 +48,14 @@ auto BrowserDialogWindow::accept() -> void { } if(state.action == "openFolder" && batched) { - string name = batched.first()->cell(0)->text(); + string name = batched.left()->cell(0)->text(); if(!isMatch(name)) return setPath({state.path, name}); state.response.append(string{state.path, name, "/"}); } if(state.action == "saveFile") { string name = fileName.text(); - if(!name && batched) name = batched.first()->cell(0)->text(); + if(!name && batched) name = batched.left()->cell(0)->text(); if(!name || isFolder(name)) return; if(file::exists({state.path, name})) { if(MessageDialog("File already exists; overwrite it?").question() != "Yes") return; @@ -64,14 +64,14 @@ auto BrowserDialogWindow::accept() -> void { } if(state.action == "selectFolder" && batched) { - string name = batched.first()->cell(0)->text(); + string name = batched.left()->cell(0)->text(); if(isFolder(name)) state.response.append(string{state.path, name, "/"}); } if(state.response) window.setModal(false); } -//list view item double-clicked, or enter pressed on selected list view item +//table view item double-clicked, or enter pressed on selected table view item auto BrowserDialogWindow::activate() -> void { auto selectedItem = view.selected(); @@ -89,7 +89,7 @@ auto BrowserDialogWindow::activate() -> void { accept(); } -//list view item changed +//table view item changed auto BrowserDialogWindow::change() -> void { fileName.setText(""); if(state.action == "saveFile") { @@ -119,13 +119,13 @@ auto BrowserDialogWindow::run() -> lstring { layout.setMargin(5); pathName.onActivate([&] { setPath(pathName.text()); }); pathRefresh.setBordered(false).setIcon(Icon::Action::Refresh).onActivate([&] { setPath(state.path); }); - pathHome.setBordered(false).setIcon(Icon::Go::Home).onActivate([&] { setPath(userpath()); }); + pathHome.setBordered(false).setIcon(Icon::Go::Home).onActivate([&] { setPath(Path::user()); }); pathUp.setBordered(false).setIcon(Icon::Go::Up).onActivate([&] { setPath(dirname(state.path)); }); view.setBatchable(state.action == "openFiles").onActivate([&] { activate(); }).onChange([&] { change(); }); filterList.setVisible(state.action != "selectFolder").onChange([&] { setPath(state.path); }); for(auto& filter : state.filters) { auto part = filter.split("|", 1L); - filterList.append(ComboButtonItem().setText(part.first())); + filterList.append(ComboButtonItem().setText(part.left())); } fileName.setVisible(state.action == "saveFile").onActivate([&] { accept(); }); acceptButton.onActivate([&] { accept(); }); @@ -137,18 +137,16 @@ auto BrowserDialogWindow::run() -> lstring { if(!state.filters) state.filters.append("All|*"); for(auto& filter : state.filters) { auto part = filter.split("|", 1L); - filters.append(part.last().split(":")); + filters.append(part.right().split(":")); } setPath(state.path); window.onClose([&] { window.setModal(false); }); - window.onSize([&] { view.resizeColumns(); }); window.setTitle(state.title); window.setSize({640, 480}); window.setCentered(state.parent); window.setVisible(); - view.resizeColumns(); view.setFocused(); window.setModal(); window.setVisible(false); @@ -162,35 +160,29 @@ auto BrowserDialogWindow::setPath(string path) -> void { pathName.setText(state.path = path); view.reset(); - view.append(ListViewHeader().setVisible(false) - .append(ListViewColumn().setExpandable()) - ); auto contents = directory::icontents(path); bool folderMode = state.action == "openFolder"; for(auto content : contents) { if(!content.endsWith("/")) continue; - content.rtrim("/"); + content.trimRight("/"); if(folderMode && isMatch(content)) continue; - view.append(ListViewItem() - .append(ListViewCell().setText(content).setIcon(Icon::Emblem::Folder)) - ); + view.append(ListViewItem().setText(content).setIcon(Icon::Emblem::Folder)); } for(auto content : contents) { if(content.endsWith("/") != folderMode) continue; //file mode shows files; folder mode shows folders - content.rtrim("/"); + content.trimRight("/"); if(!isMatch(content)) continue; - view.append(ListViewItem() - .append(ListViewCell().setText(content).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File)) - ); + view.append(ListViewItem().setText(content).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File)); } Application::processEvents(); - view.resizeColumns().setFocused().doChange(); + view->resizeColumns(); //todo: on Windows, adding items may add vertical scrollbar; this hack corrects column width + view.setFocused().doChange(); } // @@ -201,7 +193,7 @@ BrowserDialog::BrowserDialog() { auto BrowserDialog::openFile() -> string { state.action = "openFile"; if(!state.title) state.title = "Open File"; - if(auto result = _run()) return result.first(); + if(auto result = _run()) return result.left(); return {}; } @@ -215,21 +207,21 @@ auto BrowserDialog::openFiles() -> lstring { auto BrowserDialog::openFolder() -> string { state.action = "openFolder"; if(!state.title) state.title = "Open Folder"; - if(auto result = _run()) return result.first(); + if(auto result = _run()) return result.left(); return {}; } auto BrowserDialog::saveFile() -> string { state.action = "saveFile"; if(!state.title) state.title = "Save File"; - if(auto result = _run()) return result.first(); + if(auto result = _run()) return result.left(); return {}; } auto BrowserDialog::selectFolder() -> string { state.action = "selectFolder"; if(!state.title) state.title = "Select Folder"; - if(auto result = _run()) return result.first(); + if(auto result = _run()) return result.left(); return {}; } @@ -254,7 +246,7 @@ auto BrowserDialog::setTitle(const string& title) -> type& { } auto BrowserDialog::_run() -> lstring { - if(!state.path) state.path = userpath(); + if(!state.path) state.path = Path::user(); return BrowserDialogWindow(state).run(); } diff --git a/extension/extension.cpp b/extension/extension.cpp index aa46d45..a18e44c 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -6,6 +6,8 @@ namespace hiro { #include "fixed-layout.cpp" #include "horizontal-layout.cpp" #include "vertical-layout.cpp" + #include "list-view-item.cpp" + #include "list-view.cpp" #include "browser-dialog.cpp" #include "message-dialog.cpp" } diff --git a/extension/extension.hpp b/extension/extension.hpp index f3655ab..3f20bf8 100644 --- a/extension/extension.hpp +++ b/extension/extension.hpp @@ -3,6 +3,8 @@ namespace hiro { #include "fixed-layout.hpp" #include "horizontal-layout.hpp" #include "vertical-layout.hpp" + #include "list-view-item.hpp" + #include "list-view.hpp" #include "shared.hpp" #include "browser-dialog.hpp" #include "message-dialog.hpp" diff --git a/extension/horizontal-layout.cpp b/extension/horizontal-layout.cpp index c120c17..c17f842 100644 --- a/extension/horizontal-layout.cpp +++ b/extension/horizontal-layout.cpp @@ -26,7 +26,7 @@ auto mHorizontalLayout::minimumSize() const -> Size { } else { width += child.width; } - if(&child != &properties.last()) width += child.spacing; + if(&child != &properties.right()) width += child.spacing; } for(auto n : range(sizableCount())) { @@ -94,7 +94,7 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& { for(auto& child : properties) { if(child.width == Size::Maximum) maximumWidthCounter++; if(child.width != Size::Maximum) minimumWidth += child.width; - if(&child != &properties.last()) minimumWidth += child.spacing; + if(&child != &properties.right()) minimumWidth += child.spacing; } for(auto& child : properties) { diff --git a/extension/list-view-item.cpp b/extension/list-view-item.cpp new file mode 100644 index 0000000..51b09e7 --- /dev/null +++ b/extension/list-view-item.cpp @@ -0,0 +1,49 @@ +#if defined(Hiro_ListView) + +mListViewItem::mListViewItem() { + append(TableViewCell()); +} + +auto mListViewItem::checkable() const -> bool { + return cell(0).checkable(); +} + +auto mListViewItem::checked() const -> bool { + return cell(0).checked(); +} + +auto mListViewItem::icon() const -> image { + return cell(0).icon(); +} + +auto mListViewItem::reset() -> type& { + mTableViewItem::reset(); + append(TableViewCell()); + return *this; +} + +auto mListViewItem::setCheckable(bool checkable) -> type& { + cell(0).setCheckable(checkable); + return *this; +} + +auto mListViewItem::setChecked(bool checked) -> type& { + cell(0).setChecked(checked); + return *this; +} + +auto mListViewItem::setIcon(const image& icon) -> type& { + cell(0).setIcon(icon); + return *this; +} + +auto mListViewItem::setText(const string& text) -> type& { + cell(0).setText(text); + return *this; +} + +auto mListViewItem::text() const -> string { + return cell(0).text(); +} + +#endif diff --git a/extension/list-view-item.hpp b/extension/list-view-item.hpp new file mode 100644 index 0000000..cc26c93 --- /dev/null +++ b/extension/list-view-item.hpp @@ -0,0 +1,24 @@ +#if defined(Hiro_ListView) + +struct ListViewItem; +struct mListViewItem; +using sListViewItem = shared_pointer; + +struct mListViewItem : mTableViewItem { + using type = mListViewItem; + using mTableViewItem::append; + using mTableViewItem::remove; + + mListViewItem(); + auto checkable() const -> bool; + auto checked() const -> bool; + auto icon() const -> image; + auto reset() -> type&; + auto setCheckable(bool checkable) -> type&; + auto setChecked(bool checked) -> type&; + auto setIcon(const image& icon = {}) -> type&; + auto setText(const string& text) -> type&; + auto text() const -> string; +}; + +#endif diff --git a/extension/list-view.cpp b/extension/list-view.cpp new file mode 100644 index 0000000..07d5115 --- /dev/null +++ b/extension/list-view.cpp @@ -0,0 +1,51 @@ +#if defined(Hiro_ListView) + +mListView::mListView() { + mTableView::onToggle([&](TableViewCell cell) { + if(auto item = cell->parentTableViewItem()) { + if(auto shared = item->instance.acquire()) { + doToggle(ListViewItem{shared}); + } + } + }); + append(TableViewHeader().setVisible(false).append(TableViewColumn().setExpandable())); +} + +auto mListView::batched() const -> vector { + auto batched = mTableView::batched(); + vector result; + for(auto item : batched) result.append(ListViewItem{item}); + return result; +} + +auto mListView::doToggle(ListViewItem item) const -> void { + if(state.onToggle) state.onToggle(item); +} + +auto mListView::item(uint position) const -> ListViewItem { + return ListViewItem{mTableView::item(position)}; +} + +auto mListView::items() const -> vector { + auto items = mTableView::items(); + vector result; + for(auto item : items) result.append(ListViewItem{item}); + return result; +} + +auto mListView::onToggle(const function& callback) -> type& { + state.onToggle = callback; + return *this; +} + +auto mListView::reset() -> type& { + mTableView::reset(); + append(TableViewHeader().setVisible(false).append(TableViewColumn().setExpandable())); + return *this; +} + +auto mListView::selected() const -> ListViewItem { + return ListViewItem{mTableView::selected()}; +} + +#endif diff --git a/extension/list-view.hpp b/extension/list-view.hpp new file mode 100644 index 0000000..3650983 --- /dev/null +++ b/extension/list-view.hpp @@ -0,0 +1,27 @@ +#if defined(Hiro_ListView) + +struct ListView; +struct mListView; +using sListView = shared_pointer; + +struct mListView : mTableView { + using type = mListView; + using mTableView::append; + using mTableView::remove; + + mListView(); + auto batched() const -> vector; + auto doToggle(ListViewItem) const -> void; + auto item(uint position) const -> ListViewItem; + auto items() const -> vector; + auto onToggle(const function& callback) -> type&; + auto reset() -> type& override; + auto selected() const -> ListViewItem; + +//private: + struct State { + function onToggle; + } state; +}; + +#endif diff --git a/extension/shared.hpp b/extension/shared.hpp index de05c1c..318355d 100644 --- a/extension/shared.hpp +++ b/extension/shared.hpp @@ -33,3 +33,56 @@ struct VerticalLayout : sVerticalLayout { auto setSpacing(signed spacing = 5) { return self().setSpacing(spacing), *this; } }; #endif + +#if defined(Hiro_ListView) +struct ListViewItem : sListViewItem { + DeclareSharedObject(ListViewItem) + + auto alignment() const { return self().alignment(); } + auto backgroundColor() const { return self().backgroundColor(); } + auto checkable() const { return self().checkable(); } + auto checked() const { return self().checked(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto icon() const { return self().icon(); } + auto reset() { return self().reset(), *this; } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setCheckable(bool checkable = true) { return self().setCheckable(checkable), *this; } + auto setChecked(bool checked = true) { return self().setChecked(checked), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto text() const { return self().text(); } +}; +#endif + +#if defined(Hiro_ListView) +struct ListView : sListView { + DeclareSharedWidget(ListView) + + auto alignment() const { return self().alignment(); } + auto append(sListViewItem item) { return self().append(item), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto batchable() const { return self().batchable(); } + auto batched() const { return self().batched(); } + auto doActivate() const { return self().doActivate(); } + auto doChange() const { return self().doChange(); } + auto doContext() const { return self().doContext(); } + auto doToggle(ListViewItem item) const { return self().doToggle(item); } + auto foregroundColor() const { return self().foregroundColor(); } + auto item(uint position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } + auto items() const { return self().items(); } + auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } + auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } + auto onContext(const function& callback = {}) { return self().onContext(callback), *this; } + auto onToggle(const function& callback = {}) { return self().onToggle(callback), *this; } + auto remove(sListViewItem item) { return self().remove(item), *this; } + auto reset() { return self().reset(), *this; } + auto selected() { return self().selected(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } +}; +#endif diff --git a/extension/vertical-layout.cpp b/extension/vertical-layout.cpp index d5a2867..601fe58 100644 --- a/extension/vertical-layout.cpp +++ b/extension/vertical-layout.cpp @@ -35,7 +35,7 @@ auto mVerticalLayout::minimumSize() const -> Size { } else { height += child.height; } - if(&child != &properties.last()) height += child.spacing; + if(&child != &properties.right()) height += child.spacing; } return {settings.margin * 2 + width, settings.margin * 2 + height}; @@ -94,7 +94,7 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& { for(auto& child : properties) { if(child.height == Size::Maximum) maximumHeightCounter++; if(child.height != Size::Maximum) minimumHeight += child.height; - if(&child != &properties.last()) minimumHeight += child.spacing; + if(&child != &properties.right()) minimumHeight += child.spacing; } for(auto& child : properties) { diff --git a/gtk/browser-window.cpp b/gtk/browser-window.cpp index 947feb1..8b49e08 100644 --- a/gtk/browser-window.cpp +++ b/gtk/browser-window.cpp @@ -6,7 +6,7 @@ static auto BrowserWindow_addFilters(GtkWidget* dialog, lstring filters) -> void for(auto& filter : filters) { GtkFileFilter* gtkFilter = gtk_file_filter_new(); gtk_file_filter_set_name(gtkFilter, filter); - lstring patterns = filter.split("(", 1L)(1).rtrim(")", 1L).split(",").strip(); + lstring patterns = filter.split("(", 1L)(1).trimRight(")", 1L).split(",").strip(); for(auto& pattern : patterns) gtk_file_filter_add_pattern(gtkFilter, pattern); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), gtkFilter); } diff --git a/gtk/platform.cpp b/gtk/platform.cpp index 72a42b4..0092d3e 100644 --- a/gtk/platform.cpp +++ b/gtk/platform.cpp @@ -35,6 +35,8 @@ #include "widget/check-label.cpp" #include "widget/combo-button.cpp" #include "widget/combo-button-item.cpp" +#include "widget/combo-edit.cpp" +#include "widget/combo-edit-item.cpp" #include "widget/console.cpp" #include "widget/frame.cpp" #include "widget/hex-edit.cpp" @@ -44,17 +46,17 @@ #include "widget/icon-view-item.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/source-edit.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/tree-view.cpp" #include "widget/tree-view-item.cpp" diff --git a/gtk/platform.hpp b/gtk/platform.hpp index 828959e..839a2c7 100644 --- a/gtk/platform.hpp +++ b/gtk/platform.hpp @@ -46,6 +46,8 @@ namespace hiro { #include "widget/check-label.hpp" #include "widget/combo-button.hpp" #include "widget/combo-button-item.hpp" +#include "widget/combo-edit.hpp" +#include "widget/combo-edit-item.hpp" #include "widget/console.hpp" #include "widget/frame.hpp" #include "widget/hex-edit.hpp" @@ -55,17 +57,17 @@ namespace hiro { #include "widget/icon-view-item.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/source-edit.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/tree-view.hpp" #include "widget/tree-view-item.hpp" diff --git a/gtk/settings.cpp b/gtk/settings.cpp index 53a03d5..594f127 100644 --- a/gtk/settings.cpp +++ b/gtk/settings.cpp @@ -13,12 +13,12 @@ Settings::Settings() { } auto Settings::load() -> void { - string path = {configpath(), "hiro/"}; + string path = {Path::config(), "hiro/"}; Configuration::Document::load({path, "gtk.bml"}); } auto Settings::save() -> void { - string path = {configpath(), "hiro/"}; + string path = {Path::config(), "hiro/"}; directory::create(path, 0755); Configuration::Document::save({path, "gtk.bml"}); } diff --git a/gtk/widget/canvas.cpp b/gtk/widget/canvas.cpp index ca9fc7a..4bf2fe5 100644 --- a/gtk/widget/canvas.cpp +++ b/gtk/widget/canvas.cpp @@ -6,7 +6,7 @@ static auto Canvas_drop(GtkWidget* widget, GdkDragContext* context, signed x, si GtkSelectionData* data, unsigned type, unsigned timestamp, pCanvas* p) -> void { if(!p->state().droppable) return; lstring paths = DropPaths(data); - if(paths.empty()) return; + if(!paths) return; p->self().doDrop(paths); } diff --git a/gtk/widget/combo-button-item.cpp b/gtk/widget/combo-button-item.cpp index 01ca947..1e81dbf 100644 --- a/gtk/widget/combo-button-item.cpp +++ b/gtk/widget/combo-button-item.cpp @@ -10,7 +10,6 @@ auto pComboButtonItem::destruct() -> void { auto pComboButtonItem::setIcon(const image& icon) -> void { if(auto parent = _parent()) { - auto size = pFont::size(self().font(true), " ").height(); auto pixbuf = CreatePixbuf(icon, true); gtk_list_store_set(parent->gtkListStore, >kIter, 0, pixbuf, -1); } diff --git a/gtk/widget/combo-edit-item.cpp b/gtk/widget/combo-edit-item.cpp new file mode 100644 index 0000000..bfea2bb --- /dev/null +++ b/gtk/widget/combo-edit-item.cpp @@ -0,0 +1,33 @@ +#if defined(Hiro_ComboEdit) + +namespace hiro { + +auto pComboEditItem::construct() -> void { +} + +auto pComboEditItem::destruct() -> void { +} + +auto pComboEditItem::setIcon(const image& icon) -> void { + if(auto parent = _parent()) { + auto pixbuf = CreatePixbuf(icon, true); + gtk_list_store_set(parent->gtkListStore, >kIter, 0, pixbuf, -1); + } +} + +auto pComboEditItem::setText(const string& text) -> void { + if(auto parent = _parent()) { + gtk_list_store_set(parent->gtkListStore, >kIter, 1, text.data(), -1); + } +} + +auto pComboEditItem::_parent() -> maybe { + if(auto parent = self().parentComboEdit()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/gtk/widget/combo-edit-item.hpp b/gtk/widget/combo-edit-item.hpp new file mode 100644 index 0000000..fe7f1cd --- /dev/null +++ b/gtk/widget/combo-edit-item.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_ComboEdit) + +namespace hiro { + +struct pComboEditItem : pObject { + Declare(ComboEditItem, Object) + + auto setIcon(const image& icon) -> void; + auto setText(const string& text) -> void; + + auto _parent() -> maybe; + + GtkTreeIter gtkIter; +}; + +} + +#endif diff --git a/gtk/widget/combo-edit.cpp b/gtk/widget/combo-edit.cpp new file mode 100644 index 0000000..49fe755 --- /dev/null +++ b/gtk/widget/combo-edit.cpp @@ -0,0 +1,115 @@ +#if defined(Hiro_ComboEdit) + +namespace hiro { + +static auto ComboEdit_activate(GtkComboBox* comboBox, pComboEdit* p) -> void { p->self().doActivate(); } +static auto ComboEdit_change(GtkComboBox* comboBox, pComboEdit* p) -> void { p->_updateText(); } + +auto pComboEdit::construct() -> void { + gtkListStore = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING); + gtkTreeModel = GTK_TREE_MODEL(gtkListStore); + gtkWidget = gtk_combo_box_new_with_model_and_entry(gtkTreeModel); + gtkComboBox = GTK_COMBO_BOX(gtkWidget); + + gtk_cell_layout_clear(GTK_CELL_LAYOUT(gtkWidget)); + gtkCellIcon = gtk_cell_renderer_pixbuf_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkWidget), gtkCellIcon, false); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkWidget), gtkCellIcon, "pixbuf", 0, nullptr); + gtkCellText = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkWidget), gtkCellText, true); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkWidget), gtkCellText, "text", 1, nullptr); + + //we must call gtk_combo_box_set_entry_text_column(1) in order for GtkComboBoxEntry to pull text + //however, this API call throws a Gtk-CRITICAL assertion that column 1 is not a cell renderer + //this is, however, incorrect. it *is* a renderer, and the API call works as expected + //so in order to suppress the error message, we redirect stderr to /dev/null temporarily + int stdErr = dup(STDERR_FILENO); + int devNull = open("/dev/null", 0); + dup2(devNull, STDERR_FILENO); + gtk_combo_box_set_entry_text_column(gtkComboBox, 1); + dup2(stdErr, STDERR_FILENO); + close(devNull); + close(stdErr); + + setBackgroundColor(state().backgroundColor); + setForegroundColor(state().foregroundColor); + for(auto& item : state().items) append(item); + + g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN(gtkComboBox))), "activate", G_CALLBACK(ComboEdit_activate), (gpointer)this); + g_signal_connect(G_OBJECT(gtkWidget), "changed", G_CALLBACK(ComboEdit_change), (gpointer)this); + + pWidget::construct(); +} + +auto pComboEdit::destruct() -> void { + gtk_widget_destroy(gtkWidget); +} + +auto pComboEdit::append(sComboEditItem item) -> void { + lock(); + if(auto self = item->self()) { + gtk_list_store_append(gtkListStore, &self->gtkIter); + self->setIcon(item->state.icon); + self->setText(item->state.text); + } + unlock(); +} + +auto pComboEdit::minimumSize() const -> Size { + auto font = self().font(true); + int maximumWidth = 0; + for(auto& item : state().items) { + maximumWidth = max(maximumWidth, + (item->state.icon ? pFont::size(font, " ").height() + 2 : 0) + + pFont::size(font, item->state.text).width() + ); + } + return {maximumWidth + 40, pFont::size(font, " ").height() + 12}; +} + +auto pComboEdit::remove(sComboEditItem item) -> void { + lock(); + if(auto delegate = item->self()) { + gtk_list_store_remove(gtkListStore, &delegate->gtkIter); + } + unlock(); +} + +auto pComboEdit::reset() -> void { + lock(); + gtk_list_store_clear(gtkListStore); + unlock(); +} + +auto pComboEdit::setBackgroundColor(Color color) -> void { + GdkColor gdkColor = CreateColor(color); + gtk_widget_modify_base(gtk_bin_get_child(GTK_BIN(gtkComboBox)), GTK_STATE_NORMAL, color ? &gdkColor : nullptr); +} + +auto pComboEdit::setForegroundColor(Color color) -> void { + GdkColor gdkColor = CreateColor(color); + gtk_widget_modify_text(gtk_bin_get_child(GTK_BIN(gtkComboBox)), GTK_STATE_NORMAL, color ? &gdkColor : nullptr); +} + +auto pComboEdit::setFont(const Font& font) -> void { + pWidget::setFont(font); + auto fontDescription = pFont::create(font); + g_object_set(G_OBJECT(gtkCellText), "font-desc", fontDescription, nullptr); +} + +auto pComboEdit::setText(const string& text) -> void { + lock(); + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(gtkComboBox))), text); + unlock(); +} + +auto pComboEdit::_updateText() -> void { + string text = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(gtkComboBox)))); + if(text == state().text) return; + state().text = text; + if(!locked()) self().doChange(); +} + +} + +#endif diff --git a/gtk/widget/combo-edit.hpp b/gtk/widget/combo-edit.hpp new file mode 100644 index 0000000..78808bb --- /dev/null +++ b/gtk/widget/combo-edit.hpp @@ -0,0 +1,28 @@ +#if defined(Hiro_ComboEdit) + +namespace hiro { + +struct pComboEdit : pWidget { + Declare(ComboEdit, Widget) + + auto append(sComboEditItem item) -> void; + auto minimumSize() const -> Size override; + auto remove(sComboEditItem item) -> void; + auto reset() -> void; + auto setBackgroundColor(Color color) -> void; + auto setForegroundColor(Color color) -> void; + auto setFont(const Font& font) -> void override; + auto setText(const string& text) -> void; + + auto _updateText() -> void; + + GtkListStore* gtkListStore = nullptr; + GtkTreeModel* gtkTreeModel = nullptr; + GtkComboBox* gtkComboBox = nullptr; + GtkCellRenderer* gtkCellIcon = nullptr; + GtkCellRenderer* gtkCellText = nullptr; +}; + +} + +#endif diff --git a/gtk/widget/console.cpp b/gtk/widget/console.cpp index 2a687bf..954f0f1 100644 --- a/gtk/widget/console.cpp +++ b/gtk/widget/console.cpp @@ -83,7 +83,7 @@ auto pConsole::_keyPress(unsigned scancode, unsigned mask) -> bool { gtk_text_buffer_insert(textBuffer, &end, string{"\n", state().prompt}, -1); self().doActivate(s); if(s) history.prepend(s); - if(history.size() > 128) history.removeLast(); + if(history.size() > 128) history.removeRight(); historyOffset = 0; _seekToEnd(); return true; diff --git a/gtk/widget/list-view-header.cpp b/gtk/widget/list-view-header.cpp deleted file mode 100644 index 569a753..0000000 --- a/gtk/widget/list-view-header.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewHeader::construct() -> void { - _setState(); -} - -auto pListViewHeader::destruct() -> void { -} - -auto pListViewHeader::append(sListViewColumn column) -> void { - _setState(); -} - -auto pListViewHeader::remove(sListViewColumn column) -> void { -} - -auto pListViewHeader::setVisible(bool visible) -> void { - _setState(); -} - -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -auto pListViewHeader::_setState() -> void { - if(auto parent = _parent()) { - gtk_tree_view_set_headers_visible(parent->gtkTreeView, self().visible()); - for(auto& column : state().columns) { - if(auto self = column->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/gtk/widget/list-view-header.hpp b/gtk/widget/list-view-header.hpp deleted file mode 100644 index a46855b..0000000 --- a/gtk/widget/list-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/gtk/widget/list-view-cell.cpp b/gtk/widget/table-view-cell.cpp similarity index 50% rename from gtk/widget/list-view-cell.cpp rename to gtk/widget/table-view-cell.cpp index 94e22bc..3316775 100644 --- a/gtk/widget/list-view-cell.cpp +++ b/gtk/widget/table-view-cell.cpp @@ -1,51 +1,51 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewCell::construct() -> void { +auto pTableViewCell::construct() -> void { _setState(); } -auto pListViewCell::destruct() -> void { +auto pTableViewCell::destruct() -> void { } -auto pListViewCell::setAlignment(Alignment alignment) -> void { +auto pTableViewCell::setAlignment(Alignment alignment) -> void { } -auto pListViewCell::setBackgroundColor(Color color) -> void { +auto pTableViewCell::setBackgroundColor(Color color) -> void { } -auto pListViewCell::setCheckable(bool checkable) -> void { +auto pTableViewCell::setCheckable(bool checkable) -> void { } -auto pListViewCell::setChecked(bool checked) -> void { +auto pTableViewCell::setChecked(bool checked) -> void { _setState(); } -auto pListViewCell::setForegroundColor(Color color) -> void { +auto pTableViewCell::setForegroundColor(Color color) -> void { } -auto pListViewCell::setIcon(const image& icon) -> void { +auto pTableViewCell::setIcon(const image& icon) -> void { _setState(); } -auto pListViewCell::setText(const string& text) -> void { +auto pTableViewCell::setText(const string& text) -> void { _setState(); } -auto pListViewCell::_grandparent() -> maybe { +auto pTableViewCell::_grandparent() -> maybe { if(auto parent = _parent()) return parent->_parent(); return nothing; } -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewCell::_setState() -> void { +auto pTableViewCell::_setState() -> void { if(auto parent = _parent()) { if(auto grandparent = _grandparent()) { grandparent->lock(); diff --git a/gtk/widget/list-view-cell.hpp b/gtk/widget/table-view-cell.hpp similarity index 67% rename from gtk/widget/list-view-cell.hpp rename to gtk/widget/table-view-cell.hpp index 2fd0082..d8c7bae 100644 --- a/gtk/widget/list-view-cell.hpp +++ b/gtk/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -13,8 +13,8 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/gtk/widget/list-view-column.cpp b/gtk/widget/table-view-column.cpp similarity index 67% rename from gtk/widget/list-view-column.cpp rename to gtk/widget/table-view-column.cpp index 0584207..f9e966b 100644 --- a/gtk/widget/list-view-column.cpp +++ b/gtk/widget/table-view-column.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewColumn::construct() -> void { +auto pTableViewColumn::construct() -> void { if(auto grandparent = _grandparent()) { auto handle = grandparent.data(); unsigned offset = self().offset(); @@ -23,21 +23,21 @@ auto pListViewColumn::construct() -> void { gtkCellToggle = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellToggle, false); gtk_tree_view_column_set_attributes(gtkColumn, gtkCellToggle, "active", 3 * offset + 0, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellToggle), (GtkTreeCellDataFunc)ListView_dataFunc, (gpointer)handle, nullptr); + gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellToggle), (GtkTreeCellDataFunc)TableView_dataFunc, (gpointer)handle, nullptr); gtkCellIcon = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellIcon, false); gtk_tree_view_column_set_attributes(gtkColumn, gtkCellIcon, "pixbuf", 3 * offset + 1, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellIcon), (GtkTreeCellDataFunc)ListView_dataFunc, (gpointer)handle, nullptr); + gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellIcon), (GtkTreeCellDataFunc)TableView_dataFunc, (gpointer)handle, nullptr); gtkCellText = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellText, true); //text must expand to cell width for horizontal alignment to work gtk_tree_view_column_set_attributes(gtkColumn, gtkCellText, "text", 3 * offset + 2, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellText), (GtkTreeCellDataFunc)ListView_dataFunc, (gpointer)handle, nullptr); + gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellText), (GtkTreeCellDataFunc)TableView_dataFunc, (gpointer)handle, nullptr); - g_signal_connect(G_OBJECT(gtkColumn), "clicked", G_CALLBACK(ListView_headerActivate), (gpointer)handle); - g_signal_connect(G_OBJECT(gtkCellText), "edited", G_CALLBACK(ListView_edit), (gpointer)handle); - g_signal_connect(G_OBJECT(gtkCellToggle), "toggled", G_CALLBACK(ListView_toggle), (gpointer)handle); + g_signal_connect(G_OBJECT(gtkColumn), "clicked", G_CALLBACK(TableView_headerActivate), (gpointer)handle); + g_signal_connect(G_OBJECT(gtkCellText), "edited", G_CALLBACK(TableView_edit), (gpointer)handle); + g_signal_connect(G_OBJECT(gtkCellToggle), "toggled", G_CALLBACK(TableView_toggle), (gpointer)handle); gtk_tree_view_append_column(grandparent->gtkTreeView, gtkColumn); gtk_widget_show_all(gtkHeader); @@ -47,7 +47,7 @@ auto pListViewColumn::construct() -> void { } } -auto pListViewColumn::destruct() -> void { +auto pTableViewColumn::destruct() -> void { if(auto grandparent = _grandparent()) { gtk_tree_view_remove_column(grandparent->gtkTreeView, gtkColumn); gtkColumn = nullptr; @@ -55,33 +55,33 @@ auto pListViewColumn::destruct() -> void { } } -auto pListViewColumn::setActive() -> void { +auto pTableViewColumn::setActive() -> void { _setState(); } -auto pListViewColumn::setAlignment(Alignment alignment) -> void { +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { } -auto pListViewColumn::setBackgroundColor(Color color) -> void { +auto pTableViewColumn::setBackgroundColor(Color color) -> void { } -auto pListViewColumn::setEditable(bool editable) -> void { +auto pTableViewColumn::setEditable(bool editable) -> void { g_object_set(G_OBJECT(gtkCellText), "editable", editable ? true : false, nullptr); } -auto pListViewColumn::setExpandable(bool expandable) -> void { +auto pTableViewColumn::setExpandable(bool expandable) -> void { if(auto grandparent = _grandparent()) { grandparent->resizeColumns(); } } -auto pListViewColumn::setFont(const Font& font) -> void { +auto pTableViewColumn::setFont(const Font& font) -> void { } -auto pListViewColumn::setForegroundColor(Color color) -> void { +auto pTableViewColumn::setForegroundColor(Color color) -> void { } -auto pListViewColumn::setIcon(const image& icon) -> void { +auto pTableViewColumn::setIcon(const image& icon) -> void { if(icon) { gtk_image_set_from_pixbuf(GTK_IMAGE(gtkHeaderIcon), CreatePixbuf(icon)); } else { @@ -89,41 +89,41 @@ auto pListViewColumn::setIcon(const image& icon) -> void { } } -auto pListViewColumn::setResizable(bool resizable) -> void { +auto pTableViewColumn::setResizable(bool resizable) -> void { _setState(); } -auto pListViewColumn::setSortable(bool sortable) -> void { +auto pTableViewColumn::setSortable(bool sortable) -> void { _setState(); } -auto pListViewColumn::setText(const string& text) -> void { +auto pTableViewColumn::setText(const string& text) -> void { _setState(); } -auto pListViewColumn::setVisible(bool visible) -> void { +auto pTableViewColumn::setVisible(bool visible) -> void { _setState(); } -auto pListViewColumn::setWidth(signed width) -> void { +auto pTableViewColumn::setWidth(signed width) -> void { if(auto grandparent = _grandparent()) { grandparent->resizeColumns(); } } -auto pListViewColumn::_grandparent() -> maybe { +auto pTableViewColumn::_grandparent() -> maybe { if(auto parent = _parent()) return parent->_parent(); return nothing; } -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewColumn::_setState() -> void { +auto pTableViewColumn::_setState() -> void { if(auto grandparent = _grandparent()) { gtk_tree_view_set_search_column(grandparent->gtkTreeView, 3 * self().offset() + 2); gtk_tree_view_column_set_resizable(gtkColumn, state().resizable); diff --git a/gtk/widget/list-view-column.hpp b/gtk/widget/table-view-column.hpp similarity index 84% rename from gtk/widget/list-view-column.hpp rename to gtk/widget/table-view-column.hpp index 1cc4b18..882f7a1 100644 --- a/gtk/widget/list-view-column.hpp +++ b/gtk/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -21,8 +21,8 @@ struct pListViewColumn : pObject { auto setVisible(bool visible) -> void override; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; GtkTreeViewColumn* gtkColumn = nullptr; diff --git a/gtk/widget/table-view-header.cpp b/gtk/widget/table-view-header.cpp new file mode 100644 index 0000000..f8488fe --- /dev/null +++ b/gtk/widget/table-view-header.cpp @@ -0,0 +1,41 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewHeader::construct() -> void { + _setState(); +} + +auto pTableViewHeader::destruct() -> void { +} + +auto pTableViewHeader::append(sTableViewColumn column) -> void { + _setState(); +} + +auto pTableViewHeader::remove(sTableViewColumn column) -> void { +} + +auto pTableViewHeader::setVisible(bool visible) -> void { + _setState(); +} + +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pTableViewHeader::_setState() -> void { + if(auto parent = _parent()) { + gtk_tree_view_set_headers_visible(parent->gtkTreeView, self().visible()); + for(auto& column : state().columns) { + if(auto self = column->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/gtk/widget/table-view-header.hpp b/gtk/widget/table-view-header.hpp new file mode 100644 index 0000000..814f3ac --- /dev/null +++ b/gtk/widget/table-view-header.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/gtk/widget/list-view-item.cpp b/gtk/widget/table-view-item.cpp similarity index 63% rename from gtk/widget/list-view-item.cpp rename to gtk/widget/table-view-item.cpp index c70aad5..56b628c 100644 --- a/gtk/widget/list-view-item.cpp +++ b/gtk/widget/table-view-item.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewItem::construct() -> void { +auto pTableViewItem::construct() -> void { if(auto parent = _parent()) { parent->lock(); gtk_list_store_append(parent->gtkListStore, >kIter); @@ -11,7 +11,7 @@ auto pListViewItem::construct() -> void { } } -auto pListViewItem::destruct() -> void { +auto pTableViewItem::destruct() -> void { if(auto parent = _parent()) { parent->lock(); gtk_list_store_remove(parent->gtkListStore, >kIter); @@ -20,19 +20,19 @@ auto pListViewItem::destruct() -> void { } } -auto pListViewItem::append(sListViewCell cell) -> void { +auto pTableViewItem::append(sTableViewCell cell) -> void { } -auto pListViewItem::remove(sListViewCell cell) -> void { +auto pTableViewItem::remove(sTableViewCell cell) -> void { } -auto pListViewItem::setAlignment(Alignment alignment) -> void { +auto pTableViewItem::setAlignment(Alignment alignment) -> void { } -auto pListViewItem::setBackgroundColor(Color color) -> void { +auto pTableViewItem::setBackgroundColor(Color color) -> void { } -auto pListViewItem::setFocused() -> void { +auto pTableViewItem::setFocused() -> void { if(auto parent = _parent()) { GtkTreePath* path = gtk_tree_path_new_from_string(string{self().offset()}); gtk_tree_view_set_cursor(parent->gtkTreeView, path, nullptr, false); @@ -41,21 +41,21 @@ auto pListViewItem::setFocused() -> void { } } -auto pListViewItem::setForegroundColor(Color color) -> void { +auto pTableViewItem::setForegroundColor(Color color) -> void { } -auto pListViewItem::setSelected(bool selected) -> void { +auto pTableViewItem::setSelected(bool selected) -> void { _setState(); } -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewItem::_setState() -> void { +auto pTableViewItem::_setState() -> void { if(auto parent = _parent()) { parent->lock(); if(state().selected) { diff --git a/gtk/widget/list-view-item.hpp b/gtk/widget/table-view-item.hpp similarity index 57% rename from gtk/widget/list-view-item.hpp rename to gtk/widget/table-view-item.hpp index 2194879..8289d68 100644 --- a/gtk/widget/list-view-item.hpp +++ b/gtk/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; GtkTreeIter gtkIter; diff --git a/gtk/widget/list-view.cpp b/gtk/widget/table-view.cpp similarity index 78% rename from gtk/widget/list-view.cpp rename to gtk/widget/table-view.cpp index 5947a37..aa88fd7 100644 --- a/gtk/widget/list-view.cpp +++ b/gtk/widget/table-view.cpp @@ -1,21 +1,21 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -static auto ListView_activate(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, pListView* p) -> void { return p->_doActivate(); } -static auto ListView_buttonEvent(GtkTreeView* treeView, GdkEventButton* event, pListView* p) -> signed { return p->_doEvent(event); } -static auto ListView_change(GtkTreeSelection*, pListView* p) -> void { return p->_doChange(); } -static auto ListView_edit(GtkCellRendererText* renderer, const char* path, const char* text, pListView* p) -> void { return p->_doEdit(renderer, path, text); } -static auto ListView_headerActivate(GtkTreeViewColumn* column, pListView* p) -> void { return p->_doHeaderActivate(column); } -static auto ListView_mouseMoveEvent(GtkWidget*, GdkEvent*, pListView* p) -> signed { return p->_doMouseMove(); } -static auto ListView_popup(GtkTreeView*, pListView* p) -> void { return p->_doContext(); } +static auto TableView_activate(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, pTableView* p) -> void { return p->_doActivate(); } +static auto TableView_buttonEvent(GtkTreeView* treeView, GdkEventButton* event, pTableView* p) -> signed { return p->_doEvent(event); } +static auto TableView_change(GtkTreeSelection*, pTableView* p) -> void { return p->_doChange(); } +static auto TableView_edit(GtkCellRendererText* renderer, const char* path, const char* text, pTableView* p) -> void { return p->_doEdit(renderer, path, text); } +static auto TableView_headerActivate(GtkTreeViewColumn* column, pTableView* p) -> void { return p->_doHeaderActivate(column); } +static auto TableView_mouseMoveEvent(GtkWidget*, GdkEvent*, pTableView* p) -> signed { return p->_doMouseMove(); } +static auto TableView_popup(GtkTreeView*, pTableView* p) -> void { return p->_doContext(); } -static auto ListView_dataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, pListView* p) -> void { return p->_doDataFunc(column, renderer, iter); } -static auto ListView_toggle(GtkCellRendererToggle* toggle, const char* path, pListView* p) -> void { return p->_doToggle(toggle, path); } +static auto TableView_dataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, pTableView* p) -> void { return p->_doDataFunc(column, renderer, iter); } +static auto TableView_toggle(GtkCellRendererToggle* toggle, const char* path, pTableView* p) -> void { return p->_doToggle(toggle, path); } //gtk_tree_view_set_rules_hint(gtkTreeView, true); -auto pListView::construct() -> void { +auto pTableView::construct() -> void { gtkWidget = gtk_scrolled_window_new(0, 0); gtkScrolledWindow = GTK_SCROLLED_WINDOW(gtkWidget); gtk_scrolled_window_set_policy(gtkScrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); @@ -35,38 +35,38 @@ auto pListView::construct() -> void { setFont(self().font(true)); setForegroundColor(state().foregroundColor); - g_signal_connect(G_OBJECT(gtkTreeView), "button-press-event", G_CALLBACK(ListView_buttonEvent), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "button-release-event", G_CALLBACK(ListView_buttonEvent), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "motion-notify-event", G_CALLBACK(ListView_mouseMoveEvent), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "popup-menu", G_CALLBACK(ListView_popup), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "row-activated", G_CALLBACK(ListView_activate), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeSelection), "changed", G_CALLBACK(ListView_change), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "button-press-event", G_CALLBACK(TableView_buttonEvent), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "button-release-event", G_CALLBACK(TableView_buttonEvent), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "motion-notify-event", G_CALLBACK(TableView_mouseMoveEvent), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "popup-menu", G_CALLBACK(TableView_popup), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "row-activated", G_CALLBACK(TableView_activate), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeSelection), "changed", G_CALLBACK(TableView_change), (gpointer)this); pWidget::construct(); } -auto pListView::destruct() -> void { +auto pTableView::destruct() -> void { gtk_widget_destroy(gtkWidgetChild); gtk_widget_destroy(gtkWidget); } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { } -auto pListView::focused() const -> bool { +auto pTableView::focused() const -> bool { return GTK_WIDGET_HAS_FOCUS(gtkTreeView); } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { lock(); if(auto& header = state().header) { @@ -102,23 +102,23 @@ auto pListView::resizeColumns() -> void { unlock(); } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { GdkColor gdkColor = CreateColor(color); gtk_widget_modify_base(gtkWidgetChild, GTK_STATE_NORMAL, color ? &gdkColor : nullptr); } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { gtk_tree_selection_set_mode(gtkTreeSelection, batchable ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE); } -auto pListView::setBordered(bool bordered) -> void { +auto pTableView::setBordered(bool bordered) -> void { gtk_tree_view_set_grid_lines(gtkTreeView, bordered ? GTK_TREE_VIEW_GRID_LINES_BOTH : GTK_TREE_VIEW_GRID_LINES_NONE); } -auto pListView::setFocused() -> void { +auto pTableView::setFocused() -> void { //gtk_widget_grab_focus() will select the first item if nothing is currently selected //this behavior is undesirable. detect selection state first, and restore if required lock(); @@ -128,18 +128,18 @@ auto pListView::setFocused() -> void { unlock(); } -auto pListView::setFont(const Font& font) -> void { +auto pTableView::setFont(const Font& font) -> void { if(auto& header = state().header) { if(auto self = header->self()) self->_setState(); } } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { GdkColor gdkColor = CreateColor(color); gtk_widget_modify_text(gtkWidgetChild, GTK_STATE_NORMAL, color ? &gdkColor : nullptr); } -auto pListView::setGeometry(Geometry geometry) -> void { +auto pTableView::setGeometry(Geometry geometry) -> void { pWidget::setGeometry(geometry); if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -148,7 +148,7 @@ auto pListView::setGeometry(Geometry geometry) -> void { } } -auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { +auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { unsigned width = 8; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { @@ -166,7 +166,7 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { return width; } -auto pListView::_columnWidth(unsigned _column) -> unsigned { +auto pTableView::_columnWidth(unsigned _column) -> unsigned { unsigned width = 8; if(auto& header = state().header) { if(auto column = header->column(_column)) { @@ -181,7 +181,7 @@ auto pListView::_columnWidth(unsigned _column) -> unsigned { return width; } -auto pListView::_createModel() -> void { +auto pTableView::_createModel() -> void { gtk_tree_view_set_model(gtkTreeView, nullptr); gtkListStore = nullptr; gtkTreeModel = nullptr; @@ -204,19 +204,19 @@ auto pListView::_createModel() -> void { gtk_tree_view_set_model(gtkTreeView, gtkTreeModel); } -auto pListView::_doActivate() -> void { +auto pTableView::_doActivate() -> void { if(!locked()) self().doActivate(); } -auto pListView::_doChange() -> void { +auto pTableView::_doChange() -> void { if(!locked()) _updateSelected(); } -auto pListView::_doContext() -> void { +auto pTableView::_doContext() -> void { if(!locked()) self().doContext(); } -auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { +auto pTableView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter); auto row = natural(path); g_free(path); @@ -266,7 +266,7 @@ auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* rende } } -auto pListView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* path, const char* text) -> void { +auto pTableView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* path, const char* text) -> void { if(auto& header = state().header) { for(auto& column : header->state.columns) { if(auto delegate = column->self()) { @@ -287,12 +287,12 @@ auto pListView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* pa } } -auto pListView::_doEvent(GdkEventButton* event) -> signed { +auto pTableView::_doEvent(GdkEventButton* event) -> signed { GtkTreePath* path = nullptr; gtk_tree_view_get_path_at_pos(gtkTreeView, event->x, event->y, &path, nullptr, nullptr, nullptr); if(event->type == GDK_BUTTON_PRESS) { - //when clicking in empty space below the last list view item; GTK+ does not deselect all items; + //when clicking in empty space below the last table view item; GTK+ does not deselect all items; //below code enables this functionality, to match behavior with all other UI toolkits (and because it's very convenient to have) if(path == nullptr && gtk_tree_selection_count_selected_rows(gtkTreeSelection) > 0) { for(auto& item : state().items) item->setSelected(false); @@ -316,7 +316,7 @@ auto pListView::_doEvent(GdkEventButton* event) -> signed { return false; } -auto pListView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void { +auto pTableView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void { if(auto& header = state().header) { for(auto& column : header->state.columns) { if(auto delegate = column->self()) { @@ -330,15 +330,15 @@ auto pListView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void } //GtkTreeView::cursor-changed and GtkTreeSelection::changed do not send signals for changes during rubber-banding selection -//so here we capture motion-notify-event, and if the selections have changed, invoke ListView::onChange -auto pListView::_doMouseMove() -> signed { +//so here we capture motion-notify-event, and if the selections have changed, invoke TableView::onChange +auto pTableView::_doMouseMove() -> signed { if(gtk_tree_view_is_rubber_banding_active(gtkTreeView)) { if(!locked()) _updateSelected(); } return false; } -auto pListView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const char* path) -> void { +auto pTableView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const char* path) -> void { if(auto& header = state().header) { for(auto& column : header->state.columns) { if(auto delegate = column->self()) { @@ -361,7 +361,7 @@ auto pListView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const ch //if different, invoke the onChange callback unless locked, and cache current selection //this prevents firing an onChange event when the actual selection has not changed //this is particularly important for the motion-notify-event binding -auto pListView::_updateSelected() -> void { +auto pTableView::_updateSelected() -> void { vector selected; GList* list = gtk_tree_selection_get_selected_rows(gtkTreeSelection, >kTreeModel); @@ -402,7 +402,7 @@ auto pListView::_updateSelected() -> void { if(!locked()) self().doChange(); } -auto pListView::_width(unsigned column) -> unsigned { +auto pTableView::_width(unsigned column) -> unsigned { if(auto& header = state().header) { if(auto width = header->column(column).width()) return width; unsigned width = 1; diff --git a/gtk/widget/list-view.hpp b/gtk/widget/table-view.hpp similarity index 84% rename from gtk/widget/list-view.hpp rename to gtk/widget/table-view.hpp index 1df15df..71a482e 100644 --- a/gtk/widget/list-view.hpp +++ b/gtk/widget/table-view.hpp @@ -1,15 +1,15 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader column) -> void; - auto append(sListViewItem item) -> void; + auto append(sTableViewHeader column) -> void; + auto append(sTableViewItem item) -> void; auto focused() const -> bool override; - auto remove(sListViewHeader column) -> void; - auto remove(sListViewItem item) -> void; + auto remove(sTableViewHeader column) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; diff --git a/gtk/widget/tree-view.cpp b/gtk/widget/tree-view.cpp index 44e2fa5..1411b8f 100644 --- a/gtk/widget/tree-view.cpp +++ b/gtk/widget/tree-view.cpp @@ -133,10 +133,10 @@ auto pTreeView::_doDataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer auto parts = string{path}.split(":"); g_free(path); - auto item = self().item(parts.takeFirst().natural()); + auto item = self().item(parts.takeLeft().natural()); if(!item) return; while(parts) { - item = item.item(parts.takeFirst().natural()); + item = item.item(parts.takeLeft().natural()); if(!item) return; } diff --git a/gtk/widget/viewport.cpp b/gtk/widget/viewport.cpp index 8d52e90..d9c224d 100644 --- a/gtk/widget/viewport.cpp +++ b/gtk/widget/viewport.cpp @@ -6,7 +6,7 @@ static auto Viewport_dropEvent(GtkWidget* widget, GdkDragContext* context, signe GtkSelectionData* data, unsigned type, unsigned timestamp, pViewport* p) -> void { if(!p->state().droppable) return; lstring paths = DropPaths(data); - if(paths.empty()) return; + if(!paths) return; p->self().doDrop(paths); } diff --git a/gtk/window.cpp b/gtk/window.cpp index ef816ba..4a034f5 100644 --- a/gtk/window.cpp +++ b/gtk/window.cpp @@ -82,7 +82,7 @@ static auto Window_drop(GtkWidget* widget, GdkDragContext* context, signed x, si GtkSelectionData* data, unsigned type, unsigned timestamp, pWindow* p) -> void { if(!p->state().droppable) return; lstring paths = DropPaths(data); - if(paths.empty()) return; + if(!paths) return; p->self().doDrop(paths); } @@ -136,7 +136,7 @@ auto pWindow::construct() -> void { //if program was given a name, try and set the window taskbar icon from one of the pixmaps folders if(!Application::state.name); - else if(_setIcon({userpath(), ".local/share/icons/"})); + else if(_setIcon({Path::user(), ".local/share/icons/"})); else if(_setIcon("/usr/local/share/pixmaps/")); else if(_setIcon("/usr/share/pixmaps/")); diff --git a/qt/platform.cpp b/qt/platform.cpp index e529b91..d062a0a 100644 --- a/qt/platform.cpp +++ b/qt/platform.cpp @@ -47,16 +47,16 @@ #include "widget/icon-view.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" diff --git a/qt/platform.hpp b/qt/platform.hpp index 2f223cd..c54b563 100644 --- a/qt/platform.hpp +++ b/qt/platform.hpp @@ -48,16 +48,16 @@ #include "widget/horizontal-slider.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/vertical-scroll-bar.hpp" #include "widget/vertical-slider.hpp" diff --git a/qt/qt.hpp b/qt/qt.hpp index df41bda..15e7c7d 100644 --- a/qt/qt.hpp +++ b/qt/qt.hpp @@ -1,3 +1,5 @@ +//moc-qt4 -i -o qt.moc qt.hpp + /* Qt requires moc in order to bind callbacks, which causes many complications. @@ -194,30 +196,6 @@ public slots: }; #endif -#if defined(Hiro_ListView) -struct QtListView : public QTreeWidget { - Q_OBJECT -public: - QtListView(pListView& p) : p(p) {} - auto mousePressEvent(QMouseEvent*) -> void override; - auto resizeEvent(QResizeEvent*) -> void override; - auto showEvent(QShowEvent*) -> void override; - pListView& p; -public slots: - void onActivate(); - void onChange(); - void onContext(); - void onSort(int column); - void onToggle(QTreeWidgetItem* item, int column); -}; - -struct QtListViewDelegate : public QStyledItemDelegate { - QtListViewDelegate(pListView& p); - auto paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void; - pListView& p; -}; -#endif - #if defined(Hiro_RadioLabel) struct QtRadioLabel : public QRadioButton { Q_OBJECT @@ -252,6 +230,30 @@ public slots: }; #endif +#if defined(Hiro_TableView) +struct QtTableView : public QTreeWidget { + Q_OBJECT +public: + QtTableView(pTableView& p) : p(p) {} + auto mousePressEvent(QMouseEvent*) -> void override; + auto resizeEvent(QResizeEvent*) -> void override; + auto showEvent(QShowEvent*) -> void override; + pTableView& p; +public slots: + void onActivate(); + void onChange(); + void onContext(); + void onSort(int column); + void onToggle(QTreeWidgetItem* item, int column); +}; + +struct QtTableViewDelegate : public QStyledItemDelegate { + QtTableViewDelegate(pTableView& p); + auto paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void; + pTableView& p; +}; +#endif + #if defined(Hiro_TextEdit) struct QtTextEdit : public QTextEdit { Q_OBJECT diff --git a/qt/qt.moc b/qt/qt.moc index c3014c8..4cfb678 100644 --- a/qt/qt.moc +++ b/qt/qt.moc @@ -1031,90 +1031,6 @@ int hiro::QtLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) } return _id; } -static const uint qt_meta_data_hiro__QtListView[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 5, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 17, 30, 30, 30, 0x0a, - 31, 30, 30, 30, 0x0a, - 42, 30, 30, 30, 0x0a, - 54, 66, 30, 30, 0x0a, - 73, 104, 30, 30, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_hiro__QtListView[] = { - "hiro::QtListView\0onActivate()\0\0" - "onChange()\0onContext()\0onSort(int)\0" - "column\0onToggle(QTreeWidgetItem*,int)\0" - "item,column\0" -}; - -void hiro::QtListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - QtListView *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - case 1: _t->onChange(); break; - case 2: _t->onContext(); break; - case 3: _t->onSort((*reinterpret_cast< int(*)>(_a[1]))); break; - case 4: _t->onToggle((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; - default: ; - } - } -} - -const QMetaObjectExtraData hiro::QtListView::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject hiro::QtListView::staticMetaObject = { - { &QTreeWidget::staticMetaObject, qt_meta_stringdata_hiro__QtListView, - qt_meta_data_hiro__QtListView, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &hiro::QtListView::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *hiro::QtListView::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *hiro::QtListView::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_hiro__QtListView)) - return static_cast(const_cast< QtListView*>(this)); - return QTreeWidget::qt_metacast(_clname); -} - -int hiro::QtListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QTreeWidget::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 5) - qt_static_metacall(this, _c, _id, _a); - _id -= 5; - } - return _id; -} static const uint qt_meta_data_hiro__QtRadioLabel[] = { // content: @@ -1337,6 +1253,90 @@ int hiro::QtTabFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a) } return _id; } +static const uint qt_meta_data_hiro__QtTableView[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 5, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 18, 31, 31, 31, 0x0a, + 32, 31, 31, 31, 0x0a, + 43, 31, 31, 31, 0x0a, + 55, 67, 31, 31, 0x0a, + 74, 105, 31, 31, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtTableView[] = { + "hiro::QtTableView\0onActivate()\0\0" + "onChange()\0onContext()\0onSort(int)\0" + "column\0onToggle(QTreeWidgetItem*,int)\0" + "item,column\0" +}; + +void hiro::QtTableView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtTableView *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + case 1: _t->onChange(); break; + case 2: _t->onContext(); break; + case 3: _t->onSort((*reinterpret_cast< int(*)>(_a[1]))); break; + case 4: _t->onToggle((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + default: ; + } + } +} + +const QMetaObjectExtraData hiro::QtTableView::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtTableView::staticMetaObject = { + { &QTreeWidget::staticMetaObject, qt_meta_stringdata_hiro__QtTableView, + qt_meta_data_hiro__QtTableView, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtTableView::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtTableView::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtTableView::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtTableView)) + return static_cast(const_cast< QtTableView*>(this)); + return QTreeWidget::qt_metacast(_clname); +} + +int hiro::QtTableView::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QTreeWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 5) + qt_static_metacall(this, _c, _id, _a); + _id -= 5; + } + return _id; +} static const uint qt_meta_data_hiro__QtTextEdit[] = { // content: diff --git a/qt/settings.cpp b/qt/settings.cpp index cbf2d56..484ccf3 100644 --- a/qt/settings.cpp +++ b/qt/settings.cpp @@ -13,12 +13,12 @@ Settings::Settings() { } auto Settings::load() -> void { - string path{configpath(), "hiro/"}; + string path{Path::config(), "hiro/"}; Configuration::Document::load({path, "qt.bml"}); } auto Settings::save() -> void { - string path{configpath(), "hiro/"}; + string path{Path::config(), "hiro/"}; directory::create(path, 0755); Configuration::Document::save({path, "qt.bml"}); } diff --git a/qt/widget/list-view-column.cpp b/qt/widget/list-view-column.cpp deleted file mode 100644 index 1ba29f2..0000000 --- a/qt/widget/list-view-column.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewColumn::construct() -> void { -} - -auto pListViewColumn::destruct() -> void { -} - -auto pListViewColumn::setActive() -> void { - //unsupported -} - -auto pListViewColumn::setAlignment(Alignment alignment) -> void { - _setState(); -} - -auto pListViewColumn::setBackgroundColor(Color color) -> void { - _setState(); -} - -auto pListViewColumn::setEditable(bool editable) -> void { - //unsupported -} - -auto pListViewColumn::setExpandable(bool expandable) -> void { - _setState(); -} - -auto pListViewColumn::setFont(const Font& font) -> void { - _setState(); -} - -auto pListViewColumn::setForegroundColor(Color color) -> void { - _setState(); -} - -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { - _setState(); -} - -auto pListViewColumn::setIcon(const image& icon) -> void { - //unsupported -} - -auto pListViewColumn::setResizable(bool resizable) -> void { - _setState(); -} - -auto pListViewColumn::setSortable(bool sortable) -> void { - _setState(); -} - -auto pListViewColumn::setText(const string& text) -> void { - _setState(); -} - -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { - _setState(); -} - -auto pListViewColumn::setVisible(bool visible) -> void { - _setState(); -} - -auto pListViewColumn::setWidth(signed width) -> void { - _setState(); -} - -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pListViewColumn::_setState() -> void { - if(auto header = _parent()) { - if(auto parent = header->_parent()) { - parent->qtListView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); - bool clickable = false; - for(auto& column : header->state().columns) clickable |= column->state.sortable; - parent->qtListView->header()->setClickable(clickable); - parent->qtListView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text)); - parent->qtListView->setColumnHidden(self().offset(), !self().visible()); - - for(auto& item : parent->state().items) { - if(auto cell = item->cell(self().offset())) { - if(auto self = cell->self()) self->_setState(); - } - } - } - } -} - -} - -#endif diff --git a/qt/widget/list-view-header.cpp b/qt/widget/list-view-header.cpp deleted file mode 100644 index ead448a..0000000 --- a/qt/widget/list-view-header.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewHeader::construct() -> void { -} - -auto pListViewHeader::destruct() -> void { -} - -auto pListViewHeader::append(sListViewColumn column) -> void { - _setState(); -} - -auto pListViewHeader::remove(sListViewColumn column) -> void { - _setState(); -} - -auto pListViewHeader::setVisible(bool visible) -> void { - _setState(); -} - -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pListViewHeader::_setState() -> void { - if(auto parent = _parent()) { - //parent->qtListView->setAlternatingRowColors(self().columnCount() >= 2); - parent->qtListView->setColumnCount(self().columnCount()); - parent->qtListView->setHeaderHidden(!self().visible()); - for(auto& column : state().columns) { - if(auto self = column->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/qt/widget/list-view-header.hpp b/qt/widget/list-view-header.hpp deleted file mode 100644 index a46855b..0000000 --- a/qt/widget/list-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/qt/widget/list-view-item.cpp b/qt/widget/list-view-item.cpp deleted file mode 100644 index b3e7106..0000000 --- a/qt/widget/list-view-item.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewItem::construct() -> void { -} - -auto pListViewItem::destruct() -> void { - if(auto parent = _parent()) parent->lock(); - if(qtItem) { - delete qtItem; - qtItem = nullptr; - } - if(auto parent = _parent()) parent->unlock(); -} - -auto pListViewItem::append(sListViewCell cell) -> void { -} - -auto pListViewItem::remove(sListViewCell cell) -> void { -} - -auto pListViewItem::setAlignment(Alignment alignment) -> void { - _setState(); -} - -auto pListViewItem::setBackgroundColor(Color color) -> void { - _setState(); -} - -auto pListViewItem::setFont(const Font& font) -> void { - _setState(); -} - -auto pListViewItem::setForegroundColor(Color color) -> void { - _setState(); -} - -auto pListViewItem::setSelected(bool selected) -> void { - _setState(); -} - -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pListViewItem::_setState() -> void { - if(auto parent = _parent()) { - qtItem->setSelected(state().selected); - if(state().selected) { - parent->qtListView->setCurrentItem(qtItem); - } - for(auto& cell : state().cells) { - if(auto self = cell->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/qt/widget/list-view-cell.cpp b/qt/widget/table-view-cell.cpp similarity index 63% rename from qt/widget/list-view-cell.cpp rename to qt/widget/table-view-cell.cpp index 6469ca6..29138a7 100644 --- a/qt/widget/list-view-cell.cpp +++ b/qt/widget/table-view-cell.cpp @@ -1,53 +1,53 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewCell::construct() -> void { +auto pTableViewCell::construct() -> void { } -auto pListViewCell::destruct() -> void { +auto pTableViewCell::destruct() -> void { } -auto pListViewCell::setAlignment(Alignment alignment) -> void { +auto pTableViewCell::setAlignment(Alignment alignment) -> void { _setState(); } -auto pListViewCell::setBackgroundColor(Color color) -> void { +auto pTableViewCell::setBackgroundColor(Color color) -> void { _setState(); } -auto pListViewCell::setCheckable(bool checkable) -> void { +auto pTableViewCell::setCheckable(bool checkable) -> void { _setState(); } -auto pListViewCell::setChecked(bool checked) -> void { +auto pTableViewCell::setChecked(bool checked) -> void { _setState(); } -auto pListViewCell::setFont(const string& font) -> void { +auto pTableViewCell::setFont(const string& font) -> void { _setState(); } -auto pListViewCell::setForegroundColor(Color color) -> void { +auto pTableViewCell::setForegroundColor(Color color) -> void { _setState(); } -auto pListViewCell::setIcon(const image& icon) -> void { +auto pTableViewCell::setIcon(const image& icon) -> void { _setState(); } -auto pListViewCell::setText(const string& text) -> void { +auto pTableViewCell::setText(const string& text) -> void { _setState(); } -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { if(auto delegate = parent->self()) return *delegate; } return nothing; } -auto pListViewCell::_setState() -> void { +auto pTableViewCell::_setState() -> void { if(auto parent = _parent()) { if(auto grandparent = parent->_parent()) { grandparent->lock(); diff --git a/qt/widget/list-view-cell.hpp b/qt/widget/table-view-cell.hpp similarity index 75% rename from qt/widget/list-view-cell.hpp rename to qt/widget/table-view-cell.hpp index 4eddcc5..14ffec7 100644 --- a/qt/widget/list-view-cell.hpp +++ b/qt/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -14,7 +14,7 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/qt/widget/table-view-column.cpp b/qt/widget/table-view-column.cpp new file mode 100644 index 0000000..a05a25c --- /dev/null +++ b/qt/widget/table-view-column.cpp @@ -0,0 +1,99 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewColumn::construct() -> void { +} + +auto pTableViewColumn::destruct() -> void { +} + +auto pTableViewColumn::setActive() -> void { + //unsupported +} + +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { + _setState(); +} + +auto pTableViewColumn::setBackgroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewColumn::setEditable(bool editable) -> void { + //unsupported +} + +auto pTableViewColumn::setExpandable(bool expandable) -> void { + _setState(); +} + +auto pTableViewColumn::setFont(const Font& font) -> void { + _setState(); +} + +auto pTableViewColumn::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { + _setState(); +} + +auto pTableViewColumn::setIcon(const image& icon) -> void { + //unsupported +} + +auto pTableViewColumn::setResizable(bool resizable) -> void { + _setState(); +} + +auto pTableViewColumn::setSortable(bool sortable) -> void { + _setState(); +} + +auto pTableViewColumn::setText(const string& text) -> void { + _setState(); +} + +auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { + _setState(); +} + +auto pTableViewColumn::setVisible(bool visible) -> void { + _setState(); +} + +auto pTableViewColumn::setWidth(signed width) -> void { + _setState(); +} + +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pTableViewColumn::_setState() -> void { + if(auto header = _parent()) { + if(auto parent = header->_parent()) { + parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); + bool clickable = false; + for(auto& column : header->state().columns) clickable |= column->state.sortable; + parent->qtTableView->header()->setClickable(clickable); + parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text)); + parent->qtTableView->setColumnHidden(self().offset(), !self().visible()); + + for(auto& item : parent->state().items) { + if(auto cell = item->cell(self().offset())) { + if(auto self = cell->self()) self->_setState(); + } + } + } + } +} + +} + +#endif diff --git a/qt/widget/list-view-column.hpp b/qt/widget/table-view-column.hpp similarity index 83% rename from qt/widget/list-view-column.hpp rename to qt/widget/table-view-column.hpp index f130ea4..f3933e1 100644 --- a/qt/widget/list-view-column.hpp +++ b/qt/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -21,7 +21,7 @@ struct pListViewColumn : pObject { auto setVisible(bool visible) -> void; auto setWidth(signed width) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/qt/widget/table-view-header.cpp b/qt/widget/table-view-header.cpp new file mode 100644 index 0000000..2a835c1 --- /dev/null +++ b/qt/widget/table-view-header.cpp @@ -0,0 +1,43 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewHeader::construct() -> void { +} + +auto pTableViewHeader::destruct() -> void { +} + +auto pTableViewHeader::append(sTableViewColumn column) -> void { + _setState(); +} + +auto pTableViewHeader::remove(sTableViewColumn column) -> void { + _setState(); +} + +auto pTableViewHeader::setVisible(bool visible) -> void { + _setState(); +} + +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pTableViewHeader::_setState() -> void { + if(auto parent = _parent()) { + //parent->qtTableView->setAlternatingRowColors(self().columnCount() >= 2); + parent->qtTableView->setColumnCount(self().columnCount()); + parent->qtTableView->setHeaderHidden(!self().visible()); + for(auto& column : state().columns) { + if(auto self = column->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/qt/widget/table-view-header.hpp b/qt/widget/table-view-header.hpp new file mode 100644 index 0000000..814f3ac --- /dev/null +++ b/qt/widget/table-view-header.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/qt/widget/table-view-item.cpp b/qt/widget/table-view-item.cpp new file mode 100644 index 0000000..8635b0f --- /dev/null +++ b/qt/widget/table-view-item.cpp @@ -0,0 +1,66 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewItem::construct() -> void { +} + +auto pTableViewItem::destruct() -> void { + if(auto parent = _parent()) parent->lock(); + if(qtItem) { + delete qtItem; + qtItem = nullptr; + } + if(auto parent = _parent()) parent->unlock(); +} + +auto pTableViewItem::append(sTableViewCell cell) -> void { + _setState(); +} + +auto pTableViewItem::remove(sTableViewCell cell) -> void { + _setState(); +} + +auto pTableViewItem::setAlignment(Alignment alignment) -> void { + _setState(); +} + +auto pTableViewItem::setBackgroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewItem::setFont(const Font& font) -> void { + _setState(); +} + +auto pTableViewItem::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewItem::setSelected(bool selected) -> void { + _setState(); +} + +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pTableViewItem::_setState() -> void { + if(auto parent = _parent()) { + qtItem->setSelected(state().selected); + if(state().selected) { + parent->qtTableView->setCurrentItem(qtItem); + } + for(auto& cell : state().cells) { + if(auto self = cell->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/qt/widget/list-view-item.hpp b/qt/widget/table-view-item.hpp similarity index 60% rename from qt/widget/list-view-item.hpp rename to qt/widget/table-view-item.hpp index eb51d30..a05509a 100644 --- a/qt/widget/list-view-item.hpp +++ b/qt/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFont(const Font& font) -> void override; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; QTreeWidgetItem* qtItem = nullptr; diff --git a/qt/widget/list-view.cpp b/qt/widget/table-view.cpp similarity index 56% rename from qt/widget/list-view.cpp rename to qt/widget/table-view.cpp index 3bd27a3..36532b3 100644 --- a/qt/widget/list-view.cpp +++ b/qt/widget/table-view.cpp @@ -1,23 +1,23 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListView::construct() -> void { - qtWidget = qtListView = new QtListView(*this); - qtListView->setAllColumnsShowFocus(true); - qtListView->setContextMenuPolicy(Qt::CustomContextMenu); - qtListView->setRootIsDecorated(false); - qtListView->setHeaderHidden(true); - qtListView->header()->setMovable(false); +auto pTableView::construct() -> void { + qtWidget = qtTableView = new QtTableView(*this); + qtTableView->setAllColumnsShowFocus(true); + qtTableView->setContextMenuPolicy(Qt::CustomContextMenu); + qtTableView->setRootIsDecorated(false); + qtTableView->setHeaderHidden(true); + qtTableView->header()->setMovable(false); - qtListViewDelegate = new QtListViewDelegate(*this); - qtListView->setItemDelegate(qtListViewDelegate); + qtTableViewDelegate = new QtTableViewDelegate(*this); + qtTableView->setItemDelegate(qtTableViewDelegate); - qtListView->connect(qtListView, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(onActivate())); - qtListView->connect(qtListView, SIGNAL(itemSelectionChanged()), SLOT(onChange())); - qtListView->connect(qtListView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onContext())); - qtListView->connect(qtListView->header(), SIGNAL(sectionClicked(int)), SLOT(onSort(int))); - qtListView->connect(qtListView, SIGNAL(itemChanged(QTreeWidgetItem*, int)), SLOT(onToggle(QTreeWidgetItem*, int))); + qtTableView->connect(qtTableView, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(onActivate())); + qtTableView->connect(qtTableView, SIGNAL(itemSelectionChanged()), SLOT(onChange())); + qtTableView->connect(qtTableView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onContext())); + qtTableView->connect(qtTableView->header(), SIGNAL(sectionClicked(int)), SLOT(onSort(int))); + qtTableView->connect(qtTableView, SIGNAL(itemChanged(QTreeWidgetItem*, int)), SLOT(onToggle(QTreeWidgetItem*, int))); setBackgroundColor(state().backgroundColor); setBatchable(state().batchable); @@ -27,14 +27,14 @@ auto pListView::construct() -> void { pWidget::construct(); } -auto pListView::destruct() -> void { - delete qtListViewDelegate; - delete qtListView; - qtWidget = qtListView = nullptr; - qtListViewDelegate = nullptr; +auto pTableView::destruct() -> void { + delete qtTableViewDelegate; + delete qtTableView; + qtWidget = qtTableView = nullptr; + qtTableViewDelegate = nullptr; } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { lock(); if(auto self = header->self()) { self->_setState(); @@ -42,22 +42,22 @@ auto pListView::append(sListViewHeader header) -> void { unlock(); } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { lock(); if(auto self = item->self()) { - self->qtItem = new QTreeWidgetItem(qtListView); + self->qtItem = new QTreeWidgetItem(qtTableView); self->_setState(); } unlock(); } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { lock(); if(auto& header = state().header) { @@ -72,7 +72,7 @@ auto pListView::resizeColumns() -> void { } signed maximumWidth = self().geometry().width() - 6; - if(auto scrollBar = qtListView->verticalScrollBar()) { + if(auto scrollBar = qtTableView->verticalScrollBar()) { if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width(); } @@ -84,50 +84,50 @@ auto pListView::resizeColumns() -> void { for(auto column : range(header->columnCount())) { signed width = widths[column]; if(header->column(column).expandable()) width += expandWidth; - qtListView->setColumnWidth(column, width); + qtTableView->setColumnWidth(column, width); } } unlock(); } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { if(color) { - QPalette palette = qtListView->palette(); + QPalette palette = qtTableView->palette(); palette.setColor(QPalette::Base, QColor(color.red(), color.green(), color.blue())); palette.setColor(QPalette::AlternateBase, QColor(max(0, (signed)color.red() - 17), max(0, (signed)color.green() - 17), max(0, (signed)color.blue() - 17))); - qtListView->setPalette(palette); - qtListView->setAutoFillBackground(true); + qtTableView->setPalette(palette); + qtTableView->setAutoFillBackground(true); } else { //todo: set default color } } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { lock(); - qtListView->setSelectionMode(batchable ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection); + qtTableView->setSelectionMode(batchable ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection); unlock(); } -auto pListView::setBordered(bool bordered) -> void { - qtListView->repaint(); +auto pTableView::setBordered(bool bordered) -> void { + qtTableView->repaint(); } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { if(color) { - QPalette palette = qtListView->palette(); + QPalette palette = qtTableView->palette(); palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue())); - qtListView->setPalette(palette); + qtTableView->setPalette(palette); } else { //todo: set default color } } //called on resize/show events -auto pListView::_onSize() -> void { +auto pTableView::_onSize() -> void { //resize columns only if at least one column is expandable if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -136,7 +136,7 @@ auto pListView::_onSize() -> void { } } -auto pListView::_width(unsigned column) -> unsigned { +auto pTableView::_width(unsigned column) -> unsigned { if(auto& header = state().header) { if(auto width = header->column(column).width()) return width; unsigned width = 1; @@ -150,12 +150,12 @@ auto pListView::_width(unsigned column) -> unsigned { return 1; } -auto pListView::_widthOfColumn(unsigned _column) -> unsigned { +auto pTableView::_widthOfColumn(unsigned _column) -> unsigned { unsigned width = 8; if(auto& header = state().header) { if(auto column = header->column(_column)) { if(auto& icon = column->state.icon) { - width += icon.width() + 2; + width += icon.width() + 4; } if(auto& text = column->state.text) { width += pFont::size(column->font(true), text).width(); @@ -165,15 +165,15 @@ auto pListView::_widthOfColumn(unsigned _column) -> unsigned { return width; } -auto pListView::_widthOfCell(unsigned _row, unsigned _column) -> unsigned { +auto pTableView::_widthOfCell(unsigned _row, unsigned _column) -> unsigned { unsigned width = 8; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(cell->state.checkable) { - width += 16 + 2; + width += 16 + 4; } if(auto& icon = cell->state.icon) { - width += icon.width() + 2; + width += icon.width() + 4; } if(auto& text = cell->state.text) { width += pFont::size(cell->font(true), text).width(); @@ -183,11 +183,11 @@ auto pListView::_widthOfCell(unsigned _row, unsigned _column) -> unsigned { return width; } -auto QtListView::onActivate() -> void { +auto QtTableView::onActivate() -> void { if(!p.locked()) p.self().doActivate(); } -auto QtListView::onChange() -> void { +auto QtTableView::onChange() -> void { for(auto& item : p.state().items) { item->state.selected = false; if(auto self = item->self()) { @@ -197,11 +197,11 @@ auto QtListView::onChange() -> void { if(!p.locked()) p.self().doChange(); } -auto QtListView::onContext() -> void { +auto QtTableView::onContext() -> void { if(!p.locked()) p.self().doContext(); } -auto QtListView::onSort(int columnNumber) -> void { +auto QtTableView::onSort(int columnNumber) -> void { if(auto& header = p.state().header) { if(auto column = header->column(columnNumber)) { if(!p.locked() && column.sortable()) p.self().doSort(column); @@ -209,7 +209,7 @@ auto QtListView::onSort(int columnNumber) -> void { } } -auto QtListView::onToggle(QTreeWidgetItem* qtItem, int column) -> void { +auto QtTableView::onToggle(QTreeWidgetItem* qtItem, int column) -> void { for(auto& item : p.state().items) { if(auto self = item->self()) { if(qtItem == self->qtItem) { @@ -222,25 +222,25 @@ auto QtListView::onToggle(QTreeWidgetItem* qtItem, int column) -> void { } } -auto QtListView::mousePressEvent(QMouseEvent* event) -> void { +auto QtTableView::mousePressEvent(QMouseEvent* event) -> void { QTreeWidget::mousePressEvent(event); if(event->button() == Qt::RightButton) onContext(); } -auto QtListView::resizeEvent(QResizeEvent* event) -> void { +auto QtTableView::resizeEvent(QResizeEvent* event) -> void { QTreeWidget::resizeEvent(event); p._onSize(); } -auto QtListView::showEvent(QShowEvent* event) -> void { +auto QtTableView::showEvent(QShowEvent* event) -> void { QTreeWidget::showEvent(event); p._onSize(); } -QtListViewDelegate::QtListViewDelegate(pListView& p) : QStyledItemDelegate(p.qtListView), p(p) { +QtTableViewDelegate::QtTableViewDelegate(pTableView& p) : QStyledItemDelegate(p.qtTableView), p(p) { } -auto QtListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void { +auto QtTableViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void { QStyledItemDelegate::paint(painter, option, index); if(p.state().bordered) { QPen pen; diff --git a/qt/widget/list-view.hpp b/qt/widget/table-view.hpp similarity index 57% rename from qt/widget/list-view.hpp rename to qt/widget/table-view.hpp index 20bac6b..f36f640 100644 --- a/qt/widget/list-view.hpp +++ b/qt/widget/table-view.hpp @@ -1,14 +1,14 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader header) -> void; - auto append(sListViewItem item) -> void; - auto remove(sListViewHeader header) -> void; - auto remove(sListViewItem item) -> void; + auto append(sTableViewHeader header) -> void; + auto append(sTableViewItem item) -> void; + auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -21,8 +21,8 @@ struct pListView : pWidget { auto _widthOfColumn(unsigned column) -> unsigned; auto _widthOfCell(unsigned row, unsigned column) -> unsigned; - QtListView* qtListView = nullptr; - QtListViewDelegate* qtListViewDelegate = nullptr; + QtTableView* qtTableView = nullptr; + QtTableViewDelegate* qtTableViewDelegate = nullptr; }; } diff --git a/qt/window.cpp b/qt/window.cpp index 5ae1120..fe5fb79 100644 --- a/qt/window.cpp +++ b/qt/window.cpp @@ -8,8 +8,8 @@ auto pWindow::construct() -> void { //if program was given a name, try and set the window taskbar icon to a matching pixmap image if(auto name = Application::state.name) { - if(file::exists({userpath(), ".local/share/icons/", name, ".png"})) { - qtWindow->setWindowIcon(QIcon(QString::fromUtf8(string{userpath(), ".local/share/icons/", name, ".png"}))); + if(file::exists({Path::user(), ".local/share/icons/", name, ".png"})) { + qtWindow->setWindowIcon(QIcon(QString::fromUtf8(string{Path::user(), ".local/share/icons/", name, ".png"}))); } else if(file::exists({"/usr/local/share/pixmaps/", name, ".png"})) { qtWindow->setWindowIcon(QIcon(QString::fromUtf8(string{"/usr/local/share/pixmaps/", name, ".png"}))); } else if(file::exists({"/usr/share/pixmaps/", name, ".png"})) { @@ -195,10 +195,10 @@ auto pWindow::setVisible(bool visible) -> void { } /* - if(widget.font().empty() && !window.state.widgetFont.empty()) { + if(!widget.font() && window.state.widgetFont) { widget.setFont(window.state.widgetFont); } - if(widget.font().empty()) widget.p.setFont(Font::sans(8)); + if(!widget.font()) widget.p.setFont(Font::sans(8)); if(GetParentWidget(&widget)) { widget.p.qtWidget->setParent(GetParentWidget(&widget)->p.container(widget)); } else { diff --git a/windows/application.cpp b/windows/application.cpp index 67d2908..9b80eba 100644 --- a/windows/application.cpp +++ b/windows/application.cpp @@ -163,10 +163,10 @@ static auto Application_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM if(msg == WM_KEYDOWN) { if(0); - #if defined(Hiro_ListView) - else if(auto listView = dynamic_cast(object)) { + #if defined(Hiro_TableView) + else if(auto tableView = dynamic_cast(object)) { if(wparam == VK_RETURN) { - if(listView->selected()) return true; //returning true generates LVN_ITEMACTIVATE message + if(tableView->selected()) return true; //returning true generates LVN_ITEMACTIVATE message } } #endif diff --git a/windows/browser-window.cpp b/windows/browser-window.cpp index c439c93..a43bfaf 100644 --- a/windows/browser-window.cpp +++ b/windows/browser-window.cpp @@ -21,7 +21,7 @@ static auto BrowserWindow_fileDialog(bool save, BrowserWindow::State& state) -> for(auto& filter : state.filters) { lstring part = filter.split("("); if(part.size() != 2) continue; - part[1].rtrim(")", 1L); + part[1].trimRight(")", 1L); part[1].replace(" ", ""); part[1].transform(",", ";"); filters.append(filter, "\t", part[1], "\t"); @@ -38,7 +38,7 @@ static auto BrowserWindow_fileDialog(bool save, BrowserWindow::State& state) -> p++; } - if(path.empty() == false) { + if(path) { //clear COMDLG32 MRU (most recently used) file list //this is required in order for lpstrInitialDir to be honored in Windows 7 and above registry::remove("HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/ComDlg32/LastVisitedPidlMRU/"); diff --git a/windows/platform.cpp b/windows/platform.cpp index 42dac19..799c8a4 100644 --- a/windows/platform.cpp +++ b/windows/platform.cpp @@ -41,11 +41,11 @@ #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" diff --git a/windows/platform.hpp b/windows/platform.hpp index 7c6be74..36a4e1e 100644 --- a/windows/platform.hpp +++ b/windows/platform.hpp @@ -10,9 +10,9 @@ struct pWidget; struct AppMessage { enum : unsigned { None = WM_APP, - ListView_doPaint, - ListView_onActivate, - ListView_onChange, + TableView_doPaint, + TableView_onActivate, + TableView_onChange, }; }; @@ -70,16 +70,16 @@ static vector windows; #include "widget/horizontal-slider.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/vertical-scroll-bar.hpp" #include "widget/vertical-slider.hpp" diff --git a/windows/utility.cpp b/windows/utility.cpp index ff1b77e..31ca0f6 100644 --- a/windows/utility.cpp +++ b/windows/utility.cpp @@ -298,31 +298,31 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms auto object = (mObject*)GetWindowLongPtr((HWND)header->hwndFrom, GWLP_USERDATA); if(!object) break; - #if defined(Hiro_ListView) - if(auto listView = dynamic_cast(object)) { + #if defined(Hiro_TableView) + if(auto tableView = dynamic_cast(object)) { if(header->code == LVN_ITEMACTIVATE) { - listView->self()->onActivate(lparam); + tableView->self()->onActivate(lparam); break; } if(header->code == LVN_ITEMCHANGED) { - listView->self()->onChange(lparam); + tableView->self()->onChange(lparam); break; } if(header->code == LVN_COLUMNCLICK) { - if(isWindowCallback) listView->self()->onSort(lparam); + if(isWindowCallback) tableView->self()->onSort(lparam); break; } if(header->code == NM_CLICK || header->code == NM_DBLCLK) { - //onToggle performs the test to ensure the ListViewItem clicked was checkable - if(isWindowCallback) listView->self()->onToggle(lparam); + //onToggle performs the test to ensure the TableViewItem clicked was checkable + if(isWindowCallback) tableView->self()->onToggle(lparam); break; } if(header->code == NM_RCLICK) { - if(isWindowCallback) listView->self()->onContext(lparam); + if(isWindowCallback) tableView->self()->onContext(lparam); break; } if(header->code == NM_CUSTOMDRAW) { - return listView->self()->onCustomDraw(lparam); + return tableView->self()->onCustomDraw(lparam); } } #endif @@ -339,21 +339,21 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms break; } - #if defined(Hiro_ListView) - case AppMessage::ListView_doPaint: { - if(auto listView = (mListView*)lparam) { - if(auto self = listView->self()) InvalidateRect(self->hwnd, nullptr, true); + #if defined(Hiro_TableView) + case AppMessage::TableView_doPaint: { + if(auto tableView = (mTableView*)lparam) { + if(auto self = tableView->self()) InvalidateRect(self->hwnd, nullptr, true); } break; } - case AppMessage::ListView_onActivate: { - if(auto listView = (mListView*)lparam) listView->doActivate(); + case AppMessage::TableView_onActivate: { + if(auto tableView = (mTableView*)lparam) tableView->doActivate(); break; } - case AppMessage::ListView_onChange: { - if(auto listView = (mListView*)lparam) listView->doChange(); + case AppMessage::TableView_onChange: { + if(auto tableView = (mTableView*)lparam) tableView->doChange(); } #endif diff --git a/windows/widget/canvas.cpp b/windows/widget/canvas.cpp index f4f2312..72278cb 100644 --- a/windows/widget/canvas.cpp +++ b/windows/widget/canvas.cpp @@ -151,7 +151,8 @@ auto pCanvas::_rasterize() -> void { } if(width <= 0 || height <= 0) return; - pixels.reallocate(width * height); + pixels.reset(); + pixels.resize(width * height); if(auto& icon = state().icon) { memory::copy(pixels.data(), icon.data(), width * height * sizeof(uint32)); diff --git a/windows/widget/list-view-cell.cpp b/windows/widget/list-view-cell.cpp deleted file mode 100644 index 0b912aa..0000000 --- a/windows/widget/list-view-cell.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewCell::construct() -> void { -} - -auto pListViewCell::destruct() -> void { -} - -auto pListViewCell::setAlignment(Alignment alignment) -> void { -} - -auto pListViewCell::setBackgroundColor(Color color) -> void { - _repaint(); -} - -auto pListViewCell::setCheckable(bool checkable) -> void { - _repaint(); -} - -auto pListViewCell::setChecked(bool checked) -> void { - _repaint(); -} - -auto pListViewCell::setForegroundColor(Color color) -> void { - _repaint(); -} - -auto pListViewCell::setIcon(const image& icon) -> void { - _repaint(); -} - -auto pListViewCell::setText(const string& text) -> void { - _repaint(); -} - -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -auto pListViewCell::_repaint() -> void { - if(auto parent = _parent()) { - if(auto listView = parent->_parent()) { - //ListView uses a custom drawing routine; so we need to tell the control to repaint itself manually - PostMessageOnce(listView->_parentHandle(), AppMessage::ListView_doPaint, 0, (LPARAM)&listView->reference); - } - } -} - -auto pListViewCell::_setState() -> void { - if(auto item = _parent()) { - if(auto parent = item->_parent()) { - parent->lock(); - wchar_t text[] = L""; - LVITEM lvItem; - lvItem.mask = LVIF_TEXT; - lvItem.iItem = item->self().offset(); - lvItem.iSubItem = self().offset(); - lvItem.pszText = text; - ListView_SetItem(parent->hwnd, &lvItem); - parent->unlock(); - } - } -} - -} - -#endif diff --git a/windows/widget/list-view-header.hpp b/windows/widget/list-view-header.hpp deleted file mode 100644 index a46855b..0000000 --- a/windows/widget/list-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/windows/widget/tab-frame.cpp b/windows/widget/tab-frame.cpp index 09c246d..58abbd2 100644 --- a/windows/widget/tab-frame.cpp +++ b/windows/widget/tab-frame.cpp @@ -135,7 +135,7 @@ auto pTabFrame::onDrawItem(LPARAM lparam) -> void { string text = tabFrame.state.text[selection]; Size size = pFont::size(hfont, text); unsigned width = item->rcItem.right - item->rcItem.left + 1; - if(!tabFrame.state.image[selection].empty()) { + if(tabFrame.state.image[selection]) { width += size.height + 2; ImageList_Draw(imageList, selection, item->hDC, item->rcItem.left + (width - size.width) / 2 - (size.height + 3), item->rcItem.top + 2, ILD_NORMAL); } diff --git a/windows/widget/table-view-cell.cpp b/windows/widget/table-view-cell.cpp new file mode 100644 index 0000000..3d373ca --- /dev/null +++ b/windows/widget/table-view-cell.cpp @@ -0,0 +1,72 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewCell::construct() -> void { +} + +auto pTableViewCell::destruct() -> void { +} + +auto pTableViewCell::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewCell::setBackgroundColor(Color color) -> void { + _repaint(); +} + +auto pTableViewCell::setCheckable(bool checkable) -> void { + _repaint(); +} + +auto pTableViewCell::setChecked(bool checked) -> void { + _repaint(); +} + +auto pTableViewCell::setForegroundColor(Color color) -> void { + _repaint(); +} + +auto pTableViewCell::setIcon(const image& icon) -> void { + _repaint(); +} + +auto pTableViewCell::setText(const string& text) -> void { + _repaint(); +} + +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pTableViewCell::_repaint() -> void { + if(auto parent = _parent()) { + if(auto tableView = parent->_parent()) { + //TableView uses a custom drawing routine; so we need to tell the control to repaint itself manually + PostMessageOnce(tableView->_parentHandle(), AppMessage::TableView_doPaint, 0, (LPARAM)&tableView->reference); + } + } +} + +auto pTableViewCell::_setState() -> void { + if(auto item = _parent()) { + if(auto parent = item->_parent()) { + parent->lock(); + wchar_t text[] = L""; + LVITEM lvItem; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = item->self().offset(); + lvItem.iSubItem = self().offset(); + lvItem.pszText = text; + ListView_SetItem(parent->hwnd, &lvItem); + parent->unlock(); + } + } +} + +} + +#endif diff --git a/windows/widget/list-view-cell.hpp b/windows/widget/table-view-cell.hpp similarity index 74% rename from windows/widget/list-view-cell.hpp rename to windows/widget/table-view-cell.hpp index d5c6292..229dc43 100644 --- a/windows/widget/list-view-cell.hpp +++ b/windows/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -13,7 +13,7 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _repaint() -> void; auto _setState() -> void; }; diff --git a/windows/widget/list-view-column.cpp b/windows/widget/table-view-column.cpp similarity index 58% rename from windows/widget/list-view-column.cpp rename to windows/widget/table-view-column.cpp index ef2871b..76fb61d 100644 --- a/windows/widget/list-view-column.cpp +++ b/windows/widget/table-view-column.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewColumn::construct() -> void { +auto pTableViewColumn::construct() -> void { if(auto grandparent = _grandparent()) { grandparent->lock(); wchar_t text[] = L""; @@ -17,7 +17,7 @@ auto pListViewColumn::construct() -> void { } } -auto pListViewColumn::destruct() -> void { +auto pTableViewColumn::destruct() -> void { if(auto grandparent = _grandparent()) { grandparent->lock(); ListView_DeleteColumn(grandparent->hwnd, self().offset()); @@ -25,65 +25,65 @@ auto pListViewColumn::destruct() -> void { } } -auto pListViewColumn::setActive() -> void { +auto pTableViewColumn::setActive() -> void { //unsupported } -auto pListViewColumn::setAlignment(Alignment alignment) -> void { +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { } -auto pListViewColumn::setBackgroundColor(Color color) -> void { +auto pTableViewColumn::setBackgroundColor(Color color) -> void { } -auto pListViewColumn::setEditable(bool editable) -> void { +auto pTableViewColumn::setEditable(bool editable) -> void { //unsupported } -auto pListViewColumn::setExpandable(bool expandable) -> void { +auto pTableViewColumn::setExpandable(bool expandable) -> void { } -auto pListViewColumn::setForegroundColor(Color color) -> void { +auto pTableViewColumn::setForegroundColor(Color color) -> void { } -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { +auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { _setState(); } -auto pListViewColumn::setIcon(const image& icon) -> void { +auto pTableViewColumn::setIcon(const image& icon) -> void { _setState(); } -auto pListViewColumn::setResizable(bool resizable) -> void { +auto pTableViewColumn::setResizable(bool resizable) -> void { _setState(); } -auto pListViewColumn::setSortable(bool sortable) -> void { +auto pTableViewColumn::setSortable(bool sortable) -> void { } -auto pListViewColumn::setText(const string& text) -> void { +auto pTableViewColumn::setText(const string& text) -> void { _setState(); } -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { +auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { } -auto pListViewColumn::setWidth(signed width) -> void { +auto pTableViewColumn::setWidth(signed width) -> void { _setState(); } -auto pListViewColumn::_grandparent() -> maybe { +auto pTableViewColumn::_grandparent() -> maybe { if(auto parent = _parent()) return parent->_parent(); return nothing; } -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewColumn::_setState() -> void { +auto pTableViewColumn::_setState() -> void { if(auto grandparent = _grandparent()) { grandparent->lock(); grandparent->_setIcons(); diff --git a/windows/widget/list-view-column.hpp b/windows/widget/table-view-column.hpp similarity index 71% rename from windows/widget/list-view-column.hpp rename to windows/widget/table-view-column.hpp index 2c00c65..91c503f 100644 --- a/windows/widget/list-view-column.hpp +++ b/windows/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -19,11 +19,11 @@ struct pListViewColumn : pObject { auto setVerticalAlignment(double alignment) -> void; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; - signed _width = 128; //computed width (via ListView::resizeColumns) + signed _width = 128; //computed width (via TableView::resizeColumns) }; } diff --git a/windows/widget/list-view-header.cpp b/windows/widget/table-view-header.cpp similarity index 51% rename from windows/widget/list-view-header.cpp rename to windows/widget/table-view-header.cpp index fbce80c..71f02a4 100644 --- a/windows/widget/list-view-header.cpp +++ b/windows/widget/table-view-header.cpp @@ -1,32 +1,32 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewHeader::construct() -> void { +auto pTableViewHeader::construct() -> void { _setState(); } -auto pListViewHeader::destruct() -> void { +auto pTableViewHeader::destruct() -> void { } -auto pListViewHeader::append(sListViewColumn column) -> void { +auto pTableViewHeader::append(sTableViewColumn column) -> void { } -auto pListViewHeader::remove(sListViewColumn column) -> void { +auto pTableViewHeader::remove(sTableViewColumn column) -> void { } -auto pListViewHeader::setVisible(bool visible) -> void { +auto pTableViewHeader::setVisible(bool visible) -> void { _setState(); } -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewHeader::_setState() -> void { +auto pTableViewHeader::_setState() -> void { if(auto parent = _parent()) { auto style = GetWindowLong(parent->hwnd, GWL_STYLE); self().visible() ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER; diff --git a/windows/widget/table-view-header.hpp b/windows/widget/table-view-header.hpp new file mode 100644 index 0000000..814f3ac --- /dev/null +++ b/windows/widget/table-view-header.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/windows/widget/list-view-item.cpp b/windows/widget/table-view-item.cpp similarity index 60% rename from windows/widget/list-view-item.cpp rename to windows/widget/table-view-item.cpp index b956286..be42bfe 100644 --- a/windows/widget/list-view-item.cpp +++ b/windows/widget/table-view-item.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewItem::construct() -> void { +auto pTableViewItem::construct() -> void { if(auto parent = _parent()) { parent->lock(); wchar_t text[] = L""; @@ -17,7 +17,7 @@ auto pListViewItem::construct() -> void { } } -auto pListViewItem::destruct() -> void { +auto pTableViewItem::destruct() -> void { if(auto parent = _parent()) { parent->lock(); ListView_DeleteItem(parent->hwnd, self().offset()); @@ -25,19 +25,19 @@ auto pListViewItem::destruct() -> void { } } -auto pListViewItem::append(sListViewCell cell) -> void { +auto pTableViewItem::append(sTableViewCell cell) -> void { } -auto pListViewItem::remove(sListViewCell cell) -> void { +auto pTableViewItem::remove(sTableViewCell cell) -> void { } -auto pListViewItem::setAlignment(Alignment alignment) -> void { +auto pTableViewItem::setAlignment(Alignment alignment) -> void { } -auto pListViewItem::setBackgroundColor(Color color) -> void { +auto pTableViewItem::setBackgroundColor(Color color) -> void { } -auto pListViewItem::setFocused() -> void { +auto pTableViewItem::setFocused() -> void { if(auto parent = _parent()) { parent->lock(); ListView_SetItemState(parent->hwnd, self().offset(), LVIS_FOCUSED, LVIS_FOCUSED); @@ -45,21 +45,21 @@ auto pListViewItem::setFocused() -> void { } } -auto pListViewItem::setForegroundColor(Color color) -> void { +auto pTableViewItem::setForegroundColor(Color color) -> void { } -auto pListViewItem::setSelected(bool selected) -> void { +auto pTableViewItem::setSelected(bool selected) -> void { _setState(); } -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewItem::_setState() -> void { +auto pTableViewItem::_setState() -> void { if(auto parent = _parent()) { parent->lock(); ListView_SetItemState(parent->hwnd, self().offset(), state().selected ? LVIS_SELECTED : 0, LVIS_SELECTED); diff --git a/windows/widget/list-view-item.hpp b/windows/widget/table-view-item.hpp similarity index 55% rename from windows/widget/list-view-item.hpp rename to windows/widget/table-view-item.hpp index bc0d3c2..00b5a97 100644 --- a/windows/widget/list-view-item.hpp +++ b/windows/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/windows/widget/list-view.cpp b/windows/widget/table-view.cpp similarity index 85% rename from windows/widget/list-view.cpp rename to windows/widget/table-view.cpp index fa561b2..8ee4e22 100644 --- a/windows/widget/list-view.cpp +++ b/windows/widget/table-view.cpp @@ -1,12 +1,12 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -static auto CALLBACK ListView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { +static auto CALLBACK TableView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { if(auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA)) { - if(auto listView = dynamic_cast(object)) { - if(auto self = listView->self()) { - if(!listView->enabled(true)) { + if(auto tableView = dynamic_cast(object)) { + if(auto self = tableView->self()) { + if(!tableView->enabled(true)) { if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) { //WC_LISTVIEW responds to key messages even when its HWND is disabled //the control should be inactive when disabled; so we intercept the messages here @@ -21,7 +21,7 @@ static auto CALLBACK ListView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPA return DefWindowProc(hwnd, msg, wparam, lparam); } -auto pListView::construct() -> void { +auto pTableView::construct() -> void { hwnd = CreateWindowEx( WS_EX_CLIENTEDGE | LVS_EX_DOUBLEBUFFER, WC_LISTVIEW, L"", WS_CHILD | WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS, @@ -29,7 +29,7 @@ auto pListView::construct() -> void { ); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&reference); windowProc = (WindowProc)GetWindowLongPtr(hwnd, GWLP_WNDPROC); - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)&ListView_windowProc); + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)&TableView_windowProc); ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES); pWidget::_setState(); setBackgroundColor(state().backgroundColor); @@ -40,28 +40,29 @@ auto pListView::construct() -> void { resizeColumns(); } -auto pListView::destruct() -> void { +auto pTableView::destruct() -> void { if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; } DestroyWindow(hwnd); } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { + resizeColumns(); } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { LVCOLUMN lvColumn{LVCF_WIDTH}; while(ListView_GetColumn(hwnd, 0, &lvColumn)) { ListView_DeleteColumn(hwnd, 0); } } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { lock(); if(auto& header = state().header) { @@ -101,28 +102,28 @@ auto pListView::resizeColumns() -> void { unlock(); } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { if(!color) color = {255, 255, 255}; ListView_SetBkColor(hwnd, RGB(color.red(), color.green(), color.blue())); } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { auto style = GetWindowLong(hwnd, GWL_STYLE); !batchable ? style |= LVS_SINGLESEL : style &=~ LVS_SINGLESEL; SetWindowLong(hwnd, GWL_STYLE, style); } -auto pListView::setBordered(bool bordered) -> void { +auto pTableView::setBordered(bool bordered) -> void { //rendered via onCustomDraw } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { } -auto pListView::setGeometry(Geometry geometry) -> void { +auto pTableView::setGeometry(Geometry geometry) -> void { pWidget::setGeometry(geometry); if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -131,17 +132,17 @@ auto pListView::setGeometry(Geometry geometry) -> void { } } -auto pListView::onActivate(LPARAM lparam) -> void { +auto pTableView::onActivate(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; if(ListView_GetSelectedCount(hwnd) == 0) return; if(!locked()) { //LVN_ITEMACTIVATE is not re-entrant until DispatchMessage() completes //thus, we don't call self().doActivate() here - PostMessageOnce(_parentHandle(), AppMessage::ListView_onActivate, 0, (LPARAM)&reference); + PostMessageOnce(_parentHandle(), AppMessage::TableView_onActivate, 0, (LPARAM)&reference); } } -auto pListView::onChange(LPARAM lparam) -> void { +auto pTableView::onChange(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; if(!(nmlistview->uChanged & LVIF_STATE)) return; @@ -157,16 +158,16 @@ auto pListView::onChange(LPARAM lparam) -> void { //state event change messages are sent for every item //so when doing a batch select/deselect; this can generate several messages //we use a delayed AppMessage so that only one callback event is fired off - PostMessageOnce(_parentHandle(), AppMessage::ListView_onChange, 0, (LPARAM)&reference); + PostMessageOnce(_parentHandle(), AppMessage::TableView_onChange, 0, (LPARAM)&reference); } } -auto pListView::onContext(LPARAM lparam) -> void { +auto pTableView::onContext(LPARAM lparam) -> void { auto nmitemactivate = (LPNMITEMACTIVATE)lparam; return self().doContext(); } -auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { +auto pTableView::onCustomDraw(LPARAM lparam) -> LRESULT { auto lvcd = (LPNMLVCUSTOMDRAW)lparam; switch(lvcd->nmcd.dwDrawStage) { @@ -275,7 +276,7 @@ auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { return CDRF_SKIPDEFAULT; } -auto pListView::onSort(LPARAM lparam) -> void { +auto pTableView::onSort(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; if(auto& header = state().header) { if(auto column = header->column(nmlistview->iSubItem)) { @@ -284,7 +285,7 @@ auto pListView::onSort(LPARAM lparam) -> void { } } -auto pListView::onToggle(LPARAM lparam) -> void { +auto pTableView::onToggle(LPARAM lparam) -> void { auto itemActivate = (LPNMITEMACTIVATE)lparam; LVHITTESTINFO hitTestInfo{0}; hitTestInfo.pt = itemActivate->ptAction; @@ -295,12 +296,12 @@ auto pListView::onToggle(LPARAM lparam) -> void { cell->state.checked = !cell->state.checked; if(!locked()) self().doToggle(cell); //todo: try to find a way to only repaint this cell instead of the entire control to reduce flickering - PostMessageOnce(_parentHandle(), AppMessage::ListView_doPaint, 0, (LPARAM)&reference); + PostMessageOnce(_parentHandle(), AppMessage::TableView_doPaint, 0, (LPARAM)&reference); } } } -auto pListView::_backgroundColor(unsigned _row, unsigned _column) -> Color { +auto pTableView::_backgroundColor(unsigned _row, unsigned _column) -> Color { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(auto color = cell->backgroundColor()) return color; @@ -315,7 +316,7 @@ auto pListView::_backgroundColor(unsigned _row, unsigned _column) -> Color { return {255, 255, 255}; } -auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { +auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { unsigned width = 6; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { @@ -333,7 +334,7 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { return width; } -auto pListView::_columnWidth(unsigned _column) -> unsigned { +auto pTableView::_columnWidth(unsigned _column) -> unsigned { unsigned width = 12; if(auto header = state().header) { if(auto column = header->column(_column)) { @@ -348,7 +349,7 @@ auto pListView::_columnWidth(unsigned _column) -> unsigned { return width; } -auto pListView::_font(unsigned _row, unsigned _column) -> Font { +auto pTableView::_font(unsigned _row, unsigned _column) -> Font { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(auto font = cell->font()) return font; @@ -362,7 +363,7 @@ auto pListView::_font(unsigned _row, unsigned _column) -> Font { return {}; } -auto pListView::_foregroundColor(unsigned _row, unsigned _column) -> Color { +auto pTableView::_foregroundColor(unsigned _row, unsigned _column) -> Color { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(auto color = cell->foregroundColor()) return color; @@ -376,7 +377,7 @@ auto pListView::_foregroundColor(unsigned _row, unsigned _column) -> Color { return {0, 0, 0}; } -auto pListView::_setIcons() -> void { +auto pTableView::_setIcons() -> void { ListView_SetImageList(hwnd, nullptr, LVSIL_SMALL); if(imageList) ImageList_Destroy(imageList); imageList = ImageList_Create(16, 16, ILC_COLOR32, 1, 0); @@ -408,7 +409,7 @@ auto pListView::_setIcons() -> void { DeleteObject(bitmap); } -auto pListView::_setSortable() -> void { +auto pTableView::_setSortable() -> void { bool sortable = false; if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -422,7 +423,7 @@ auto pListView::_setSortable() -> void { SetWindowLong(hwnd, GWL_STYLE, style); } -auto pListView::_width(unsigned column) -> unsigned { +auto pTableView::_width(unsigned column) -> unsigned { if(auto& header = state().header) { if(auto width = header->state.columns[column]->width()) return width; unsigned width = 1; diff --git a/windows/widget/list-view.hpp b/windows/widget/table-view.hpp similarity index 80% rename from windows/widget/list-view.hpp rename to windows/widget/table-view.hpp index 3e3af01..65fa610 100644 --- a/windows/widget/list-view.hpp +++ b/windows/widget/table-view.hpp @@ -1,14 +1,14 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader header) -> void; - auto append(sListViewItem item) -> void; - auto remove(sListViewHeader header) -> void; - auto remove(sListViewItem item) -> void; + auto append(sTableViewHeader header) -> void; + auto append(sTableViewItem item) -> void; + auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; diff --git a/windows/window.cpp b/windows/window.cpp index 393020f..77f53ee 100644 --- a/windows/window.cpp +++ b/windows/window.cpp @@ -177,8 +177,7 @@ auto pWindow::onClose() -> void { auto pWindow::onDrop(WPARAM wparam) -> void { lstring paths = DropPaths(wparam); - if(paths.empty()) return; - self().doDrop(paths); + if(paths) self().doDrop(paths); } auto pWindow::onEraseBackground() -> bool {