From 4344b916b6a73b09e59c21bba5963dab6eee21d9 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 18 Aug 2015 20:18:00 +1000 Subject: [PATCH] Update to v094r40 release. byuu says: Changelog: - updated to newest hiro API - SFC performance profile builds once again - hiro: Qt port completed Errata 1: the hiro/Qt target won't run tomoko just yet. Starts by crashing inside InputSettings because hiro/Qt isn't forcefully selecting the first item added to a ComboButton just yet. Even with a monkey patch to get around that, the UI is incredibly unstable. Lots of geometry calculation bugs, and a crash when you try and access certain folders in the browser dialog. Lots of work left to be done there, sadly. Errata 2: the hiro/Windows port has black backgrounds on all ListView items. It's because I need to test for unassigned colors and grab the default Windows brush colors in those cases. Note: alternating row colors on multi-column ListView widgets is gone now. Not a bug. May add it back later, but I'm not sure. It doesn't interact nicely with per-cell background colors. Things left to do: First, I have to fix the Windows and Qt target bugs. Next, I need to go through and revise the hiro API even more (nothing too major.) Next, I need to update icarus to use the new hiro API, and add support for the SFC games database. Next, I have to rewrite my TSV->BML cheat code tool. Next, I need to post a final WIP of higan+icarus publicly and wait a few days. Next, I need to fix any bugs reported from the final WIP that I can. Finally, I should be able to release v095. --- emulator/emulator.hpp | 2 +- hiro/components.hpp | 16 +- hiro/core/action/menu-radio-item.cpp | 2 +- hiro/core/action/menu.cpp | 14 +- hiro/core/alignment.cpp | 40 + hiro/core/core.cpp | 2 + hiro/core/core.hpp | 180 +- hiro/core/group.cpp | 12 +- hiro/core/hotkey.cpp | 8 +- hiro/core/keyboard.cpp | 6 +- hiro/core/layout.cpp | 14 +- hiro/core/menu-bar.cpp | 14 +- hiro/core/object.cpp | 10 + hiro/core/popup-menu.cpp | 21 +- hiro/core/shared.hpp | 96 +- hiro/core/widget/combo-button.cpp | 14 +- hiro/core/widget/hex-edit.cpp | 20 +- hiro/core/widget/icon-view.cpp | 16 +- hiro/core/widget/label.cpp | 22 +- hiro/core/widget/list-view-cell.cpp | 105 +- hiro/core/widget/list-view-column.cpp | 28 +- hiro/core/widget/list-view-header.cpp | 53 + hiro/core/widget/list-view-item.cpp | 40 +- hiro/core/widget/list-view.cpp | 143 +- hiro/core/widget/radio-button.cpp | 2 +- hiro/core/widget/radio-label.cpp | 2 +- hiro/core/widget/tab-frame.cpp | 14 +- hiro/core/widget/tree-view-item.cpp | 14 +- hiro/core/widget/tree-view.cpp | 14 +- hiro/core/window.cpp | 21 +- hiro/extension/browser-dialog.cpp | 24 +- hiro/extension/fixed-layout.cpp | 8 +- hiro/extension/horizontal-layout.cpp | 14 +- hiro/extension/vertical-layout.cpp | 14 +- hiro/gtk/menu-bar.cpp | 4 +- hiro/gtk/menu-bar.hpp | 4 +- hiro/gtk/platform.cpp | 1 + hiro/gtk/platform.hpp | 1 + hiro/gtk/settings.cpp | 22 +- hiro/gtk/settings.hpp | 4 +- hiro/gtk/widget/hex-edit.cpp | 64 +- hiro/gtk/widget/hex-edit.hpp | 2 +- hiro/gtk/widget/icon-view.cpp | 8 +- hiro/gtk/widget/label.cpp | 25 +- hiro/gtk/widget/label.hpp | 5 +- hiro/gtk/widget/list-view-cell.cpp | 48 +- hiro/gtk/widget/list-view-cell.hpp | 7 +- hiro/gtk/widget/list-view-column.cpp | 148 +- hiro/gtk/widget/list-view-column.hpp | 11 +- hiro/gtk/widget/list-view-header.cpp | 41 + hiro/gtk/widget/list-view-header.hpp | 18 + hiro/gtk/widget/list-view-item.cpp | 45 +- hiro/gtk/widget/list-view-item.hpp | 6 +- hiro/gtk/widget/list-view.cpp | 331 ++-- hiro/gtk/widget/list-view.hpp | 24 +- hiro/gtk/widget/tab-frame.cpp | 4 +- hiro/qt/action/action.cpp | 46 +- hiro/qt/action/action.hpp | 20 + hiro/qt/action/check-item.cpp | 28 - hiro/qt/action/item.cpp | 26 - hiro/qt/action/menu-check-item.cpp | 46 + hiro/qt/action/menu-check-item.hpp | 18 + hiro/qt/action/menu-item.cpp | 44 + hiro/qt/action/menu-item.hpp | 18 + hiro/qt/action/menu-radio-item.cpp | 65 + hiro/qt/action/menu-radio-item.hpp | 20 + hiro/qt/action/menu-separator.cpp | 25 + hiro/qt/action/menu-separator.hpp | 13 + hiro/qt/action/menu.cpp | 96 +- hiro/qt/action/menu.hpp | 21 + hiro/qt/action/radio-item.cpp | 42 - hiro/qt/action/separator.cpp | 14 - hiro/qt/application.cpp | 33 +- hiro/qt/application.hpp | 21 + hiro/qt/browser-window.cpp | 18 +- hiro/qt/browser-window.hpp | 13 + hiro/qt/desktop.cpp | 10 +- hiro/qt/desktop.hpp | 12 + hiro/qt/font.cpp | 22 +- hiro/qt/font.hpp | 17 + hiro/qt/group.cpp | 13 + hiro/qt/group.hpp | 11 + hiro/qt/hotkey.cpp | 13 + hiro/qt/hotkey.hpp | 11 + hiro/qt/keyboard.cpp | 170 +- hiro/qt/keyboard.hpp | 16 + hiro/qt/layout.cpp | 19 + hiro/qt/layout.hpp | 13 + hiro/qt/menu-bar.cpp | 46 + hiro/qt/menu-bar.hpp | 20 + hiro/qt/message-window.cpp | 50 +- hiro/qt/message-window.hpp | 14 + hiro/qt/monitor.cpp | 12 +- hiro/qt/monitor.hpp | 13 + hiro/qt/mouse.cpp | 10 +- hiro/qt/mouse.hpp | 12 + hiro/qt/object.cpp | 35 + hiro/qt/object.hpp | 31 + hiro/qt/platform.cpp | 31 +- hiro/qt/platform.hpp | 137 ++ hiro/qt/platform.moc | 1816 ------------------- hiro/qt/platform.moc.hpp | 876 --------- hiro/qt/popup-menu.cpp | 74 +- hiro/qt/popup-menu.hpp | 20 + hiro/qt/qt.hpp | 303 ++++ hiro/qt/qt.moc | 1624 +++++++++++++++++ hiro/qt/settings.cpp | 26 +- hiro/qt/settings.hpp | 20 + hiro/qt/sizable.cpp | 20 + hiro/qt/sizable.hpp | 14 + hiro/qt/status-bar.cpp | 45 + hiro/qt/status-bar.hpp | 19 + hiro/qt/timer.cpp | 34 +- hiro/qt/timer.hpp | 16 + hiro/qt/utility.cpp | 51 +- hiro/qt/widget/button.cpp | 86 +- hiro/qt/widget/button.hpp | 19 + hiro/qt/widget/canvas.cpp | 231 +-- hiro/qt/widget/canvas.hpp | 31 + hiro/qt/widget/check-button.cpp | 111 +- hiro/qt/widget/check-button.hpp | 22 + hiro/qt/widget/check-label.cpp | 63 +- hiro/qt/widget/check-label.hpp | 19 + hiro/qt/widget/combo-button-item.cpp | 49 + hiro/qt/widget/combo-button-item.hpp | 18 + hiro/qt/widget/combo-button.cpp | 81 +- hiro/qt/widget/combo-button.hpp | 18 + hiro/qt/widget/console.cpp | 6 +- hiro/qt/widget/frame.cpp | 68 +- hiro/qt/widget/frame.hpp | 20 + hiro/qt/widget/hex-edit.cpp | 265 +-- hiro/qt/widget/hex-edit.hpp | 29 + hiro/qt/widget/horizontal-scroller.cpp | 63 +- hiro/qt/widget/horizontal-scroller.hpp | 19 + hiro/qt/widget/horizontal-slider.cpp | 53 +- hiro/qt/widget/horizontal-slider.hpp | 19 + hiro/qt/widget/icon-view.cpp | 6 +- hiro/qt/widget/label.cpp | 38 +- hiro/qt/widget/label.hpp | 17 + hiro/qt/widget/line-edit.cpp | 105 +- hiro/qt/widget/line-edit.hpp | 21 + hiro/qt/widget/list-view-cell.cpp | 69 + hiro/qt/widget/list-view-cell.hpp | 23 + hiro/qt/widget/list-view-column.cpp | 99 + hiro/qt/widget/list-view-column.hpp | 30 + hiro/qt/widget/list-view-header.cpp | 43 + hiro/qt/widget/list-view-header.hpp | 18 + hiro/qt/widget/list-view-item.cpp | 62 + hiro/qt/widget/list-view-item.hpp | 24 + hiro/qt/widget/list-view.cpp | 532 +++--- hiro/qt/widget/list-view.hpp | 31 + hiro/qt/widget/progress-bar.cpp | 33 +- hiro/qt/widget/progress-bar.hpp | 18 + hiro/qt/widget/radio-button.cpp | 146 +- hiro/qt/widget/radio-button.hpp | 23 + hiro/qt/widget/radio-label.cpp | 96 +- hiro/qt/widget/radio-label.hpp | 20 + hiro/qt/widget/tab-frame-item.cpp | 78 + hiro/qt/widget/tab-frame-item.hpp | 26 + hiro/qt/widget/tab-frame.cpp | 107 +- hiro/qt/widget/tab-frame.hpp | 20 + hiro/qt/widget/text-edit.cpp | 124 +- hiro/qt/widget/text-edit.hpp | 23 + hiro/qt/widget/vertical-scroller.cpp | 63 +- hiro/qt/widget/vertical-scroller.hpp | 19 + hiro/qt/widget/vertical-slider.cpp | 54 +- hiro/qt/widget/vertical-slider.hpp | 19 + hiro/qt/widget/viewport.cpp | 67 +- hiro/qt/widget/viewport.hpp | 18 + hiro/qt/widget/widget.cpp | 95 +- hiro/qt/widget/widget.hpp | 20 + hiro/qt/window.cpp | 487 +++-- hiro/qt/window.hpp | 41 + hiro/windows/platform.cpp | 1 + hiro/windows/platform.hpp | 1 + hiro/windows/utility.cpp | 4 + hiro/windows/widget/hex-edit.cpp | 36 +- hiro/windows/widget/hex-edit.hpp | 2 +- hiro/windows/widget/label.cpp | 9 +- hiro/windows/widget/label.hpp | 3 +- hiro/windows/widget/list-view-cell.cpp | 33 +- hiro/windows/widget/list-view-cell.hpp | 4 + hiro/windows/widget/list-view-column.cpp | 42 +- hiro/windows/widget/list-view-column.hpp | 5 +- hiro/windows/widget/list-view-header.cpp | 42 + hiro/windows/widget/list-view-header.hpp | 18 + hiro/windows/widget/list-view-item.cpp | 49 +- hiro/windows/widget/list-view-item.hpp | 4 +- hiro/windows/widget/list-view.cpp | 390 ++-- hiro/windows/widget/list-view.hpp | 18 +- sfc/alt/cpu/cpu.cpp | 7 +- sfc/alt/cpu/cpu.hpp | 1 - target-tomoko/presentation/presentation.cpp | 2 +- target-tomoko/settings/hotkeys.cpp | 9 +- target-tomoko/settings/input.cpp | 9 +- target-tomoko/settings/settings.cpp | 2 +- target-tomoko/tools/cheat-database.cpp | 25 +- target-tomoko/tools/cheat-editor.cpp | 24 +- target-tomoko/tools/state-manager.cpp | 7 +- target-tomoko/tools/tools.cpp | 2 +- 200 files changed, 7246 insertions(+), 5659 deletions(-) create mode 100644 hiro/core/alignment.cpp create mode 100644 hiro/core/widget/list-view-header.cpp create mode 100644 hiro/gtk/widget/list-view-header.cpp create mode 100644 hiro/gtk/widget/list-view-header.hpp create mode 100644 hiro/qt/action/action.hpp delete mode 100644 hiro/qt/action/check-item.cpp delete mode 100644 hiro/qt/action/item.cpp create mode 100644 hiro/qt/action/menu-check-item.cpp create mode 100644 hiro/qt/action/menu-check-item.hpp create mode 100644 hiro/qt/action/menu-item.cpp create mode 100644 hiro/qt/action/menu-item.hpp create mode 100644 hiro/qt/action/menu-radio-item.cpp create mode 100644 hiro/qt/action/menu-radio-item.hpp create mode 100644 hiro/qt/action/menu-separator.cpp create mode 100644 hiro/qt/action/menu-separator.hpp create mode 100644 hiro/qt/action/menu.hpp delete mode 100644 hiro/qt/action/radio-item.cpp delete mode 100644 hiro/qt/action/separator.cpp create mode 100644 hiro/qt/application.hpp create mode 100644 hiro/qt/browser-window.hpp create mode 100644 hiro/qt/desktop.hpp create mode 100644 hiro/qt/font.hpp create mode 100644 hiro/qt/group.cpp create mode 100644 hiro/qt/group.hpp create mode 100644 hiro/qt/hotkey.cpp create mode 100644 hiro/qt/hotkey.hpp create mode 100644 hiro/qt/keyboard.hpp create mode 100644 hiro/qt/layout.cpp create mode 100644 hiro/qt/layout.hpp create mode 100644 hiro/qt/menu-bar.cpp create mode 100644 hiro/qt/menu-bar.hpp create mode 100644 hiro/qt/message-window.hpp create mode 100644 hiro/qt/monitor.hpp create mode 100644 hiro/qt/mouse.hpp create mode 100644 hiro/qt/object.cpp create mode 100644 hiro/qt/object.hpp create mode 100644 hiro/qt/platform.hpp delete mode 100644 hiro/qt/platform.moc delete mode 100644 hiro/qt/platform.moc.hpp create mode 100644 hiro/qt/popup-menu.hpp create mode 100644 hiro/qt/qt.hpp create mode 100644 hiro/qt/qt.moc create mode 100644 hiro/qt/settings.hpp create mode 100644 hiro/qt/sizable.cpp create mode 100644 hiro/qt/sizable.hpp create mode 100644 hiro/qt/status-bar.cpp create mode 100644 hiro/qt/status-bar.hpp create mode 100644 hiro/qt/timer.hpp create mode 100644 hiro/qt/widget/button.hpp create mode 100644 hiro/qt/widget/canvas.hpp create mode 100644 hiro/qt/widget/check-button.hpp create mode 100644 hiro/qt/widget/check-label.hpp create mode 100644 hiro/qt/widget/combo-button-item.cpp create mode 100644 hiro/qt/widget/combo-button-item.hpp create mode 100644 hiro/qt/widget/combo-button.hpp create mode 100644 hiro/qt/widget/frame.hpp create mode 100644 hiro/qt/widget/hex-edit.hpp create mode 100644 hiro/qt/widget/horizontal-scroller.hpp create mode 100644 hiro/qt/widget/horizontal-slider.hpp create mode 100644 hiro/qt/widget/label.hpp create mode 100644 hiro/qt/widget/line-edit.hpp create mode 100644 hiro/qt/widget/list-view-cell.cpp create mode 100644 hiro/qt/widget/list-view-cell.hpp create mode 100644 hiro/qt/widget/list-view-column.cpp create mode 100644 hiro/qt/widget/list-view-column.hpp create mode 100644 hiro/qt/widget/list-view-header.cpp create mode 100644 hiro/qt/widget/list-view-header.hpp create mode 100644 hiro/qt/widget/list-view-item.cpp create mode 100644 hiro/qt/widget/list-view-item.hpp create mode 100644 hiro/qt/widget/list-view.hpp create mode 100644 hiro/qt/widget/progress-bar.hpp create mode 100644 hiro/qt/widget/radio-button.hpp create mode 100644 hiro/qt/widget/radio-label.hpp create mode 100644 hiro/qt/widget/tab-frame-item.cpp create mode 100644 hiro/qt/widget/tab-frame-item.hpp create mode 100644 hiro/qt/widget/tab-frame.hpp create mode 100644 hiro/qt/widget/text-edit.hpp create mode 100644 hiro/qt/widget/vertical-scroller.hpp create mode 100644 hiro/qt/widget/vertical-slider.hpp create mode 100644 hiro/qt/widget/viewport.hpp create mode 100644 hiro/qt/widget/widget.hpp create mode 100644 hiro/qt/window.hpp create mode 100644 hiro/windows/widget/list-view-header.cpp create mode 100644 hiro/windows/widget/list-view-header.hpp diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index 5c122adc..bfea967b 100644 --- a/emulator/emulator.hpp +++ b/emulator/emulator.hpp @@ -8,7 +8,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "094.39"; + static const string Version = "094.40"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/hiro/components.hpp b/hiro/components.hpp index 6c03415d..eb85db7d 100644 --- a/hiro/components.hpp +++ b/hiro/components.hpp @@ -12,6 +12,7 @@ #define Hiro_Application #define Hiro_Color +#define Hiro_Alignment #define Hiro_Position #define Hiro_Size #define Hiro_Geometry @@ -50,22 +51,22 @@ #define Hiro_CheckButton #define Hiro_CheckLabel #define Hiro_ComboButton -//#define Hiro_Console +#define Hiro_Console #define Hiro_Frame #define Hiro_HexEdit #define Hiro_HorizontalScroller #define Hiro_HorizontalSlider -//#define Hiro_IconView +#define Hiro_IconView #define Hiro_Label #define Hiro_LineEdit #define Hiro_ListView #define Hiro_ProgressBar #define Hiro_RadioButton #define Hiro_RadioLabel -//#define Hiro_SourceView +#define Hiro_SourceView #define Hiro_TabFrame #define Hiro_TextEdit -//#define Hiro_TreeView +#define Hiro_TreeView #define Hiro_VerticalScroller #define Hiro_VerticalSlider #define Hiro_Viewport @@ -81,3 +82,10 @@ #if defined(Hiro_Button) && defined(Hiro_ComboButton) && defined(Hiro_LineEdit) && defined(Hiro_ListView) && defined(Hiro_MessageDialog) #define Hiro_BrowserDialog #endif + +#if defined(HIRO_WINDOWS) || defined(HIRO_QT) + #undef Hiro_Console + #undef Hiro_IconView + #undef Hiro_SourceView + #undef Hiro_TreeView +#endif diff --git a/hiro/core/action/menu-radio-item.cpp b/hiro/core/action/menu-radio-item.cpp index 73fa34f3..36d4eada 100644 --- a/hiro/core/action/menu-radio-item.cpp +++ b/hiro/core/action/menu-radio-item.cpp @@ -41,7 +41,7 @@ auto mMenuRadioItem::setChecked() -> type& { auto mMenuRadioItem::setGroup(sGroup group) -> type& { state.group = group; signal(setGroup, group); - if(group && group->objects() == 1) setChecked(); + if(group && group->objectCount() == 1) setChecked(); return *this; } diff --git a/hiro/core/action/menu.cpp b/hiro/core/action/menu.cpp index 018fd376..97f3f797 100644 --- a/hiro/core/action/menu.cpp +++ b/hiro/core/action/menu.cpp @@ -12,17 +12,23 @@ auto mMenu::destruct() -> void { // auto mMenu::action(unsigned position) const -> Action { - if(position < actions()) return state.actions[position]; + if(position < actionCount()) return state.actions[position]; return {}; } -auto mMenu::actions() const -> unsigned { +auto mMenu::actionCount() const -> unsigned { return state.actions.size(); } +auto mMenu::actions() const -> vector { + vector actions; + for(auto& action : state.actions) actions.append(action); + return actions; +} + auto mMenu::append(sAction action) -> type& { state.actions.append(action); - action->setParent(this, actions() - 1); + action->setParent(this, actionCount() - 1); signal(append, *action); return *this; } @@ -34,7 +40,7 @@ auto mMenu::icon() const -> image { auto mMenu::remove(sAction action) -> type& { signal(remove, *action); state.actions.remove(action->offset()); - for(auto n : range(action->offset(), actions())) { + for(auto n : range(action->offset(), actionCount())) { state.actions[n]->adjustOffset(-1); } action->setParent(); diff --git a/hiro/core/alignment.cpp b/hiro/core/alignment.cpp new file mode 100644 index 00000000..c682d000 --- /dev/null +++ b/hiro/core/alignment.cpp @@ -0,0 +1,40 @@ +#if defined(Hiro_Alignment) + +Alignment::Alignment() { + setAlignment(-1.0, -1.0); +} + +Alignment::Alignment(double horizontal, double vertical) { + setAlignment(horizontal, vertical); +} + +Alignment::operator bool() const { + return state.horizontal >= 0.0 && state.horizontal <= 1.0 + && state.vertical >= 0.0 && state.vertical <= 1.0; +} + +auto Alignment::horizontal() const -> double { + return state.horizontal; +} + +auto Alignment::setAlignment(double horizontal, double vertical) -> type& { + state.horizontal = horizontal; + state.vertical = vertical; + return *this; +} + +auto Alignment::setHorizontal(double horizontal) -> type& { + state.horizontal = horizontal; + return *this; +} + +auto Alignment::setVertical(double vertical) -> type& { + state.vertical = vertical; + return *this; +} + +auto Alignment::vertical() const -> double { + return state.vertical; +} + +#endif diff --git a/hiro/core/core.cpp b/hiro/core/core.cpp index 5eb9a790..db203bb6 100644 --- a/hiro/core/core.cpp +++ b/hiro/core/core.cpp @@ -33,6 +33,7 @@ using namespace nall; namespace hiro { #include "application.cpp" #include "color.cpp" + #include "alignment.cpp" #include "position.cpp" #include "size.cpp" #include "geometry.cpp" @@ -81,6 +82,7 @@ namespace hiro { #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" diff --git a/hiro/core/core.hpp b/hiro/core/core.hpp index 5980a531..0557834f 100644 --- a/hiro/core/core.hpp +++ b/hiro/core/core.hpp @@ -64,6 +64,7 @@ Declare(IconViewItem) Declare(Label) Declare(LineEdit) Declare(ListView) +Declare(ListViewHeader) Declare(ListViewColumn) Declare(ListViewItem) Declare(ListViewCell) @@ -85,6 +86,7 @@ Declare(Viewport) enum class Edge : unsigned { Top, Bottom, Left, Right }; enum class Orientation : unsigned { Horizontal, Vertical }; +enum class Placement : unsigned { Top, Bottom, Left, Right }; #if defined(Hiro_Application) struct Application { @@ -174,6 +176,31 @@ struct Color { }; #endif +#if defined(Hiro_Alignment) +struct Alignment { + using type = Alignment; + + Alignment(); + Alignment(double horizontal, double vertical = 0.5); + + explicit operator bool() const; + auto operator==(const Alignment& source) const -> bool; + auto operator!=(const Alignment& source) const -> bool; + + auto horizontal() const -> double; + auto setAlignment(double horizontal = -1.0, double vertical = 0.5) -> type&; + auto setHorizontal(double horizontal) -> type&; + auto setVertical(double vertical) -> type&; + auto vertical() const -> double; + +//private: + struct State { + double horizontal; + double vertical; + } state; +}; +#endif + #if defined(Hiro_Position) struct Position { using type = Position; @@ -421,6 +448,7 @@ struct mObject { 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*; @@ -466,7 +494,8 @@ struct mGroup : mObject { auto append(sObject object) -> type&; auto object(unsigned offset) const -> Object; - auto objects() const -> unsigned; + auto objectCount() const -> unsigned; + auto objects() const -> vector; auto remove(sObject object) -> type&; //private: @@ -484,10 +513,10 @@ struct mHotkey : mObject { auto doRelease() const -> void; auto onPress(const function& callback = {}) -> type&; auto onRelease(const function& callback = {}) -> type&; - auto parent() const -> wObject; + auto owner() const -> wObject; auto remove() -> type& override; auto sequence() const -> string; - auto setParent(sObject parent) -> type&; + auto setOwner(sObject owner) -> type&; auto setSequence(const string& sequence = "") -> type&; //private: @@ -496,7 +525,7 @@ struct mHotkey : mObject { vector keys; function onPress; function onRelease; - wObject parent; + wObject owner; string sequence; } state; }; @@ -552,6 +581,7 @@ struct mWindow : mObject { auto remove(sStatusBar statusBar) -> type&; auto reset() -> type& override; auto resizable() const -> bool; + auto setAlignment(Alignment alignment) -> type&; auto setBackgroundColor(Color color = {}) -> type&; auto setCentered(sWindow parent = {}) -> type&; auto setDroppable(bool droppable = true) -> type&; @@ -561,7 +591,6 @@ struct mWindow : mObject { auto setFullScreen(bool fullScreen = true) -> type&; auto setGeometry(Geometry geometry) -> type&; auto setModal(bool modal = true) -> type&; - auto setPlacement(double x, double y) -> type&; auto setPosition(Position position) -> type&; auto setResizable(bool resizable = true) -> type&; auto setSize(Size size) -> type&; @@ -614,7 +643,8 @@ struct mMenuBar : mObject { auto append(sMenu menu) -> type&; auto menu(unsigned position) const -> Menu; - auto menus() const -> unsigned; + auto menuCount() const -> unsigned; + auto menus() const -> vector; auto remove() -> type& override; auto remove(sMenu menu) -> type&; auto reset() -> type&; @@ -635,11 +665,12 @@ struct mPopupMenu : mObject { using mObject::remove; auto action(unsigned position) const -> Action; - auto actions() const -> unsigned; + auto actionCount() const -> unsigned; + auto actions() const -> vector; auto append(sAction action) -> type&; auto remove(sAction action) -> type&; auto reset() -> type&; -//TODO setParent + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setVisible(bool visible = true) -> type& override; //private: @@ -669,7 +700,8 @@ struct mMenu : mAction { using mObject::remove; auto action(unsigned position) const -> Action; - auto actions() const -> unsigned; + auto actionCount() const -> unsigned; + auto actions() const -> vector; auto append(sAction action) -> type&; auto icon() const -> image; auto remove(sAction action) -> type&; @@ -788,7 +820,8 @@ struct mLayout : mSizable { virtual auto reset() -> type&; auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto sizable(unsigned position) const -> Sizable; - auto sizables() const -> unsigned; + auto sizableCount() const -> unsigned; + auto sizables() const -> vector; //private: struct State { @@ -905,7 +938,7 @@ struct mCheckButton : mWidget { //private: struct State { - bool bordered = false; + bool bordered = true; bool checked = false; image icon; function onToggle; @@ -943,7 +976,8 @@ struct mComboButton : mWidget { auto append(sComboButtonItem item) -> type&; auto doChange() const -> void; auto item(unsigned position) const -> ComboButtonItem; - auto items() const -> unsigned; + auto itemCount() const -> unsigned; + auto items() const -> vector; auto onChange(const function& callback = {}) -> type&; auto remove(sComboButtonItem item) -> type&; auto reset() -> type&; @@ -1033,31 +1067,31 @@ struct mFrame : mWidget { struct mHexEdit : mWidget { Declare(HexEdit) + auto address() const -> unsigned; auto backgroundColor() const -> Color; auto columns() const -> unsigned; auto doRead(unsigned offset) const -> uint8_t; auto doWrite(unsigned offset, uint8_t data) const -> void; auto foregroundColor() const -> Color; auto length() const -> unsigned; - auto offset() const -> unsigned; auto onRead(const function& callback = {}) -> type&; auto onWrite(const function& callback = {}) -> type&; auto rows() const -> unsigned; + auto setAddress(unsigned address = 0) -> type&; auto setBackgroundColor(Color color = {}) -> type&; auto setColumns(unsigned columns = 16) -> type&; auto setForegroundColor(Color color = {}) -> type&; auto setLength(unsigned length) -> type&; - auto setOffset(unsigned offset) -> type&; auto setRows(unsigned rows = 16) -> type&; auto update() -> type&; //private: struct State { + unsigned address = 0; Color backgroundColor; unsigned columns = 16; Color foregroundColor; unsigned length = 0; - unsigned offset = 0; function onRead; function onWrite; unsigned rows = 16; @@ -1118,7 +1152,8 @@ struct mIconView : mWidget { auto flow() const -> Orientation; auto foregroundColor() const -> Color; auto item(unsigned position) const -> IconViewItem; - auto items() const -> unsigned; + auto itemCount() const -> unsigned; + auto items() const -> vector; auto multiSelect() const -> bool; auto onActivate(const function& callback = {}) -> type&; auto onChange(const function& callback = {}) -> type&; @@ -1178,18 +1213,15 @@ struct mIconViewItem : mObject { struct mLabel : mWidget { Declare(Label) - auto horizontalAlignment() const -> double; - auto setHorizontalAlignment(double alignment = 0.0) -> type&; + auto alignment() const -> Alignment; + auto setAlignment(Alignment alignment = {}) -> type&; auto setText(const string& text = "") -> type&; - auto setVerticalAlignment(double alignment = 0.5) -> type&; auto text() const -> string; - auto verticalAlignment() const -> double; //private: struct State { - double horizontalAlignment = 0.0; + Alignment alignment; string text; - double verticalAlignment = 0.5; } state; }; #endif @@ -1228,80 +1260,90 @@ struct mListView : mWidget { Declare(ListView) using mObject::remove; - auto append(sListViewColumn column) -> type&; + auto alignment() const -> Alignment; + auto append(sListViewHeader column) -> type&; auto append(sListViewItem item) -> type&; auto backgroundColor() const -> Color; auto batchable() const -> bool; - auto checkable() const -> bool; - auto checkAll() -> type&; - auto checked() const -> vector; - auto column(unsigned position) const -> ListViewColumn; - auto columns() const -> unsigned; + 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(sListViewItem item) const -> void; + auto doToggle(sListViewCell cell) const -> void; auto foregroundColor() const -> Color; - auto gridVisible() const -> bool; - auto headerVisible() const -> bool; + auto header() const -> ListViewHeader; auto item(unsigned position) const -> ListViewItem; - auto items() const -> unsigned; + 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(sListViewColumn column) -> type&; + auto onToggle(const function& callback = {}) -> type&; + auto remove(sListViewHeader column) -> type&; auto remove(sListViewItem item) -> type&; auto reset() -> type&; auto resizeColumns() -> type&; - auto selectAll() -> type&; auto selected() const -> ListViewItem; - auto selectedItems() const -> vector; + auto setAlignment(Alignment alignment = {}) -> type&; auto setBackgroundColor(Color color = {}) -> type&; auto setBatchable(bool batchable = true) -> type&; - auto setCheckable(bool checkable = true) -> type&; + auto setBordered(bool bordered = true) -> type&; auto setForegroundColor(Color color = {}) -> type&; auto setGridVisible(bool visible = true) -> type&; - auto setHeaderVisible(bool visible = true) -> type&; auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - auto setSortable(bool sortable = true) -> type&; - auto sortable() const -> bool; - auto uncheckAll() -> type&; - auto unselectAll() -> type&; //private: struct State { unsigned activeColumn = 0; + Alignment alignment; Color backgroundColor; bool batchable = false; - bool checkable = false; - vector columns; + bool bordered = false; Color foregroundColor; - bool gridVisible = false; - bool headerVisible = false; + sListViewHeader header; vector items; function onActivate; function onChange; function onContext; function onEdit; function onSort; - function onToggle; - bool sortable = false; + 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; @@ -1311,32 +1353,35 @@ struct mListViewColumn : mObject { 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 setFont(const string& font = "") -> 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; - string font; Color foregroundColor; double horizontalAlignment = 0.0; image icon; bool resizable = true; + bool sortable = false; string text; double verticalAlignment = 0.5; bool visible = true; @@ -1349,19 +1394,18 @@ struct mListViewColumn : mObject { 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 cells() const -> unsigned; - auto checkable() const -> bool; - auto checked() const -> bool; + 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 setCheckable(bool checkable = true) -> type&; - auto setChecked(bool checked = true) -> type&; auto setFocused() -> type& override; auto setForegroundColor(Color color = {}) -> type&; auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; @@ -1369,10 +1413,9 @@ struct mListViewItem : mObject { //private: struct State { + Alignment alignment; Color backgroundColor; vector cells; - bool checkable = true; - bool checked = false; Color foregroundColor; bool selected = false; } state; @@ -1383,10 +1426,17 @@ struct mListViewItem : mObject { struct mListViewCell : mObject { Declare(ListViewCell) - auto backgroundColor() const -> Color; - auto foregroundColor() const -> Color; + 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 -> string; + 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&; @@ -1394,7 +1444,10 @@ struct mListViewCell : mObject { //private: struct State { + Alignment alignment; Color backgroundColor; + bool checkable = false; + bool checked = false; Color foregroundColor; image icon; string text; @@ -1508,7 +1561,8 @@ struct mTabFrame : mWidget { auto doMove(sTabFrameItem from, sTabFrameItem to) const -> void; auto edge() const -> Edge; auto item(unsigned position) const -> TabFrameItem; - auto items() const -> unsigned; + auto itemCount() const -> unsigned; + auto items() const -> vector; auto onChange(const function& callback = {}) -> type&; auto onClose(const function& callback = {}) -> type&; auto onMove(const function& callback = {}) -> type&; @@ -1617,7 +1671,8 @@ struct mTreeView : mWidget { auto expand() -> type&; auto foregroundColor() const -> Color; auto item(const string& path) const -> TreeViewItem; - auto items() const -> unsigned; + 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&; @@ -1655,7 +1710,8 @@ struct mTreeViewItem : mObject { auto checked() const -> bool; auto icon() const -> image; auto item(const string& path) const -> TreeViewItem; - auto items() const -> unsigned; + auto itemCount() const -> unsigned; + auto items() const -> vector; auto path() const -> string; auto remove() -> type& override; auto remove(sTreeViewItem item) -> type&; diff --git a/hiro/core/group.cpp b/hiro/core/group.cpp index 25c00deb..e7691b6d 100644 --- a/hiro/core/group.cpp +++ b/hiro/core/group.cpp @@ -15,7 +15,7 @@ auto mGroup::append(sObject object) -> type& { } auto mGroup::object(unsigned position) const -> Object { - if(position < state.objects.size()) { + if(position < objectCount()) { if(auto object = state.objects[position].acquire()) { return object; } @@ -23,10 +23,18 @@ auto mGroup::object(unsigned position) const -> Object { return {}; } -auto mGroup::objects() const -> unsigned { +auto mGroup::objectCount() const -> unsigned { return state.objects.size(); } +auto mGroup::objects() const -> vector { + vector objects; + for(auto& weak : state.objects) { + if(auto object = weak.acquire()) objects.append(object); + } + return objects; +} + auto mGroup::remove(sObject object) -> type& { object->setGroup(); for(auto offset : range(state.objects)) { diff --git a/hiro/core/hotkey.cpp b/hiro/core/hotkey.cpp index 6795ad2f..8a4d71cd 100644 --- a/hiro/core/hotkey.cpp +++ b/hiro/core/hotkey.cpp @@ -24,8 +24,8 @@ auto mHotkey::onRelease(const function& callback) -> type& { return *this; } -auto mHotkey::parent() const -> wObject { - return state.parent; +auto mHotkey::owner() const -> wObject { + return state.owner; } auto mHotkey::remove() -> type& { @@ -37,8 +37,8 @@ auto mHotkey::sequence() const -> string { return state.sequence; } -auto mHotkey::setParent(sObject parent) -> type& { - state.parent = parent; +auto mHotkey::setOwner(sObject owner) -> type& { + state.owner = owner; return *this; } diff --git a/hiro/core/keyboard.cpp b/hiro/core/keyboard.cpp index 41ad1e01..82f3bbc9 100644 --- a/hiro/core/keyboard.cpp +++ b/hiro/core/keyboard.cpp @@ -48,9 +48,9 @@ auto Keyboard::poll() -> vector { active = false; break; } - if(auto parent = hotkey->state.parent.acquire()) { - //todo: set active = false if parent no longer exists - active &= parent->focused(); + if(auto owner = hotkey->state.owner.acquire()) { + //todo: set active = false if owner no longer exists + active &= owner->focused(); } if(hotkey->state.active != active) { hotkey->state.active = active; diff --git a/hiro/core/layout.cpp b/hiro/core/layout.cpp index ffeeefe0..cf4a94e8 100644 --- a/hiro/core/layout.cpp +++ b/hiro/core/layout.cpp @@ -13,7 +13,7 @@ auto mLayout::destruct() -> void { auto mLayout::append(sSizable sizable) -> type& { state.sizables.append(sizable); - sizable->setParent(this, sizables() - 1); + sizable->setParent(this, sizableCount() - 1); setGeometry(geometry()); return *this; } @@ -33,7 +33,7 @@ auto mLayout::remove(sSizable sizable) -> type& { auto offset = sizable->offset(); sizable->setParent(); state.sizables.remove(offset); - for(auto n : range(offset, sizables())) { + for(auto n : range(offset, sizableCount())) { state.sizables[n]->adjustOffset(-1); } setGeometry(geometry()); @@ -53,12 +53,18 @@ auto mLayout::setParent(mObject* parent, signed offset) -> type& { } auto mLayout::sizable(unsigned position) const -> Sizable { - if(position < sizables()) return state.sizables[position]; + if(position < sizableCount()) return state.sizables[position]; return {}; } -auto mLayout::sizables() const -> unsigned { +auto mLayout::sizableCount() const -> unsigned { return state.sizables.size(); } +auto mLayout::sizables() const -> vector { + vector sizables; + for(auto& sizable : sizables) sizables.append(sizable); + return sizables; +} + #endif diff --git a/hiro/core/menu-bar.cpp b/hiro/core/menu-bar.cpp index fec4e748..c977c7f0 100644 --- a/hiro/core/menu-bar.cpp +++ b/hiro/core/menu-bar.cpp @@ -13,20 +13,26 @@ auto mMenuBar::destruct() -> void { auto mMenuBar::append(sMenu menu) -> type& { state.menus.append(menu); - menu->setParent(this, menus() - 1); + menu->setParent(this, menuCount() - 1); signal(append, menu); return *this; } auto mMenuBar::menu(unsigned position) const -> Menu { - if(position < menus()) return state.menus[position]; + if(position < menuCount()) return state.menus[position]; return {}; } -auto mMenuBar::menus() const -> unsigned { +auto mMenuBar::menuCount() const -> unsigned { return state.menus.size(); } +auto mMenuBar::menus() const -> vector { + vector menus; + for(auto& menu : state.menus) menus.append(menu); + return menus; +} + auto mMenuBar::remove() -> type& { if(auto window = parentWindow()) window->remove(window->menuBar()); return *this; @@ -36,7 +42,7 @@ auto mMenuBar::remove(sMenu menu) -> type& { signed offset = menu->offset(); signal(remove, *menu); state.menus.remove(offset); - for(auto n : range(offset, menus())) { + for(auto n : range(offset, menuCount())) { state.menus[n]->adjustOffset(-1); } menu->setParent(); diff --git a/hiro/core/object.cpp b/hiro/core/object.cpp index 126369ba..c378a1c3 100644 --- a/hiro/core/object.cpp +++ b/hiro/core/object.cpp @@ -136,6 +136,16 @@ auto mObject::parentListView(bool recursive) const -> mListView* { } #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; diff --git a/hiro/core/popup-menu.cpp b/hiro/core/popup-menu.cpp index 2c9c5423..17a08388 100644 --- a/hiro/core/popup-menu.cpp +++ b/hiro/core/popup-menu.cpp @@ -12,17 +12,23 @@ auto mPopupMenu::destruct() -> void { // auto mPopupMenu::action(unsigned position) const -> Action { - if(position < actions()) return state.actions[position]; + if(position < actionCount()) return state.actions[position]; return {}; } -auto mPopupMenu::actions() const -> unsigned { +auto mPopupMenu::actionCount() const -> unsigned { return state.actions.size(); } +auto mPopupMenu::actions() const -> vector { + vector actions; + for(auto& action : state.actions) actions.append(action); + return actions; +} + auto mPopupMenu::append(sAction action) -> type& { state.actions.append(action); - action->setParent(this, actions() - 1); + action->setParent(this, actionCount() - 1); signal(append, action); return *this; } @@ -31,7 +37,7 @@ auto mPopupMenu::remove(sAction action) -> type& { signed offset = action->offset(); signal(remove, action); state.actions.remove(offset); - for(auto n : range(offset, actions())) { + for(auto n : range(offset, actionCount())) { state.actions[n]->adjustOffset(-1); } action->setParent(); @@ -43,6 +49,13 @@ auto mPopupMenu::reset() -> type& { return *this; } +auto mPopupMenu::setParent(mObject* parent, signed offset) -> type& { + for(auto& action : state.actions) action->destruct(); + mObject::setParent(parent, offset); + for(auto& action : state.actions) action->construct(); + return *this; +} + auto mPopupMenu::setVisible(bool visible) -> type& { signal(setVisible, visible); return *this; diff --git a/hiro/core/shared.hpp b/hiro/core/shared.hpp index 00c3a671..910d6dc9 100644 --- a/hiro/core/shared.hpp +++ b/hiro/core/shared.hpp @@ -18,7 +18,13 @@ auto enabled(bool recursive = false) const { return self().enabled(recursive); } \ auto focused() const { return self().focused(); } \ auto font(bool recursive = false) const { return self().font(recursive); } \ - auto offset() { return self().offset(); } \ + auto offset() const { return self().offset(); } \ + auto parent() const { \ + if(auto object = self().parent()) { \ + if(auto instance = object->instance.acquire()) return Object(instance); \ + } \ + return Object(); \ + } \ auto remove() { return self().remove(), *this; } \ auto setEnabled(bool enabled = true) { return self().setEnabled(enabled), *this; } \ auto setFocused() { return self().setFocused(), *this; } \ @@ -41,6 +47,7 @@ auto remove(sSizable sizable) { return self().remove(sizable), *this; } \ auto reset() { return self().reset(), *this; } \ auto sizable(unsigned position) { return self().sizable(position); } \ + auto sizableCount() const { return self().sizableCount(); } \ auto sizables() const { return self().sizables(); } \ #define DeclareSharedWidget(Name) \ @@ -61,6 +68,7 @@ struct Group : sGroup { auto append(sObject object) -> type& { return self().append(object), *this; } auto object(unsigned position) const { return self().object(position); } + auto objectCount() const { return self().objectCount(); } auto objects() const { return self().objects(); } auto remove(sObject object) -> type& { return self().remove(object), *this; } @@ -81,9 +89,9 @@ struct Hotkey : sHotkey { auto doRelease() const { return self().doRelease(); } auto onPress(const function& callback = {}) { return self().onPress(callback), *this; } auto onRelease(const function& callback = {}) { return self().onRelease(callback), *this; } - auto parent() const { return self().parent(); } + auto owner() const { return self().owner(); } auto sequence() const { return self().sequence(); } - auto setParent(sObject object) { return self().setParent(object), *this; } + auto setOwner(sObject owner) { return self().setOwner(owner), *this; } auto setSequence(const string& sequence = "") { return self().setSequence(sequence), *this; } }; #endif @@ -110,6 +118,7 @@ struct Menu : sMenu { DeclareSharedAction(Menu) auto action(unsigned position) const { return self().action(position); } + auto actionCount() const { return self().actionCount(); } auto actions() const { return self().actions(); } auto append(sAction action) { return self().append(action), *this; } auto icon() const { return self().icon(); } @@ -285,6 +294,7 @@ struct ComboButton : sComboButton { auto append(sComboButtonItem item) { return self().append(item), *this; } auto doChange() const { return self().doChange(); } auto item(unsigned position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } auto items() const { return self().items(); } auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } auto remove(sComboButtonItem item) { return self().remove(item), *this; } @@ -328,21 +338,21 @@ struct Frame : sFrame { struct HexEdit : sHexEdit { DeclareSharedWidget(HexEdit) + auto address() const { return self().address(); } auto backgroundColor() const { return self().backgroundColor(); } auto columns() const { return self().columns(); } auto doRead(unsigned offset) const { return self().doRead(offset); } auto doWrite(unsigned offset, uint8_t data) const { return self().doWrite(offset, data); } auto foregroundColor() const { return self().foregroundColor(); } auto length() const { return self().length(); } - auto offset() const { return self().offset(); } auto onRead(const function& callback = {}) { return self().onRead(callback), *this; } auto onWrite(const function& callback = {}) { return self().onWrite(callback), *this; } auto rows() const { return self().rows(); } + auto setAddress(unsigned address) { return self().setAddress(address), *this; } auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } auto setColumns(unsigned columns = 16) { return self().setColumns(columns), *this; } auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } auto setLength(unsigned length) { return self().setLength(length), *this; } - auto setOffset(unsigned offset) { return self().setOffset(offset), *this; } auto setRows(unsigned rows = 16) { return self().setRows(rows), *this; } auto update() { return self().update(), *this; } }; @@ -399,6 +409,7 @@ struct IconView : sIconView { auto flow() const { return self().flow(); } auto foregroundColor() const { return self().foregroundColor(); } auto item(unsigned position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } auto items() const { return self().items(); } auto multiSelect() const { return self().multiSelect(); } auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } @@ -422,12 +433,10 @@ struct IconView : sIconView { struct Label : sLabel { DeclareSharedWidget(Label) - auto horizontalAlignment() const { return self().horizontalAlignment(); } - auto setHorizontalAlignment(double alignment = 0.0) { return self().setHorizontalAlignment(alignment), *this; } + auto alignment() const { return self().alignment(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } auto setText(const string& text = "") { return self().setText(text), *this; } - auto setVerticalAlignment(double alignment = 0.5) { return self().setVerticalAlignment(alignment), *this; } auto text() const { return self().text(); } - auto verticalAlignment() const { return self().verticalAlignment(); } }; #endif @@ -455,6 +464,7 @@ struct ListViewColumn : sListViewColumn { DeclareSharedObject(ListViewColumn) 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(); } @@ -463,6 +473,7 @@ struct ListViewColumn : sListViewColumn { 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; } @@ -470,23 +481,43 @@ struct ListViewColumn : sListViewColumn { auto setHorizontalAlignment(double alignment = 0.0) { return self().setHorizontalAlignment(alignment), *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 setVerticalAlignment(double alignment = 0.5) { return self().setVerticalAlignment(alignment), *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) + + 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) + 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; } @@ -498,18 +529,17 @@ struct ListViewCell : sListViewCell { struct ListViewItem : sListViewItem { DeclareSharedObject(ListViewItem) + 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 checkable() const { return self().checkable(); } - auto checked() const { return self().checked(); } 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 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 setSelected(bool selected = true) { return self().setSelected(selected), *this; } }; @@ -519,49 +549,40 @@ struct ListViewItem : sListViewItem { struct ListView : sListView { DeclareSharedWidget(ListView) - auto append(sListViewColumn column) { return self().append(column), *this; } + 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 checkable() const { return self().checkable(); } - auto checkAll() { return self().checkAll(), *this; } - auto checked() const { return self().checked(); } - auto column(unsigned position) { return self().column(position); } - auto columns() const { return self().columns(); } + 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(sListViewItem item) const { return self().doToggle(item); } + auto doToggle(sListViewCell cell) const { return self().doToggle(cell); } auto foregroundColor() const { return self().foregroundColor(); } - auto gridVisible() const { return self().gridVisible(); } - auto headerVisible() const { return self().headerVisible(); } - auto item(unsigned position) { return self().item(position); } + 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(sListViewColumn column) { return self().remove(column), *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 selectAll() { return self().selectAll(), *this; } auto selected() const { return self().selected(); } - auto selectedItems() const { return self().selectedItems(); } + 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 setCheckable(bool checkable = true) { return self().setCheckable(checkable), *this; } + auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; } auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setGridVisible(bool visible = true) { return self().setGridVisible(visible), *this; } - auto setHeaderVisible(bool visible = true) { return self().setHeaderVisible(visible), *this; } - auto setSortable(bool sortable = true) { return self().setSortable(sortable), *this; } - auto sortable() const { return self().sortable(); } - auto uncheckAll() { return self().uncheckAll(), *this; } - auto unselectAll() { return self().unselectAll(), *this; } }; #endif @@ -655,6 +676,7 @@ struct TabFrame : sTabFrame { auto doMove(sTabFrameItem from, sTabFrameItem to) const { return self().doMove(from, to); } auto edge() const { return self().edge(); } auto item(unsigned position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } auto items() const { return self().items(); } auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } auto onClose(const function& callback = {}) { return self().onClose(callback), *this; } @@ -697,6 +719,7 @@ struct TreeViewItem : sTreeViewItem { auto checked() const { return self().checked(); } auto icon() const { return self().icon(); } auto item(const string& path) const { return self().item(path); } + auto itemCount() const { return self().itemCount(); } auto items() const { return self().items(); } auto path() const { return self().path(); } auto remove(sTreeViewItem item) { return self().remove(item), *this; } @@ -724,6 +747,7 @@ struct TreeView : sTreeView { auto expand() { return self().expand(), *this; } auto foregroundColor() const { return self().foregroundColor(); } auto item(const string& path) const { return self().item(path); } + 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; } @@ -798,6 +822,7 @@ struct PopupMenu : sPopupMenu { DeclareSharedObject(PopupMenu) auto action(unsigned position) const { return self().action(position); } + auto actionCount() const { return self().actionCount(); } auto actions() const { return self().actions(); } auto append(sAction action) { return self().append(action), *this; } auto remove(sAction action) { return self().remove(action), *this; } @@ -811,6 +836,7 @@ struct MenuBar : sMenuBar { auto append(sMenu menu) { return self().append(menu), *this; } auto menu(unsigned position) const { return self().menu(position); } + auto menuCount() const { return self().menuCount(); } auto menus() const { return self().menus(); } auto remove(sMenu menu) { return self().remove(menu), *this; } auto reset() { return self().reset(), *this; } @@ -849,6 +875,7 @@ struct Window : sWindow { auto remove(sStatusBar statusBar) { return self().remove(statusBar), *this; } auto reset() { return self().reset(), *this; } auto resizable() const { return self().resizable(); } + auto setAlignment(Alignment alignment) { return self().setAlignment(alignment), *this; } auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } auto setCentered(sWindow parent = {}) { return self().setCentered(parent), *this; } auto setDroppable(bool droppable = true) { return self().setDroppable(droppable), *this; } @@ -858,7 +885,6 @@ struct Window : sWindow { auto setFullScreen(bool fullScreen = true) { return self().setFullScreen(fullScreen), *this; } auto setGeometry(Geometry geometry) { return self().setGeometry(geometry), *this; } auto setModal(bool modal = true) { return self().setModal(modal), *this; } - auto setPlacement(double x, double y) { return self().setPlacement(x, y), *this; } auto setPosition(Position position) { return self().setPosition(position), *this; } auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; } auto setSize(Size size) { return self().setSize(size), *this; } diff --git a/hiro/core/widget/combo-button.cpp b/hiro/core/widget/combo-button.cpp index 2d1ffca5..cc5b101e 100644 --- a/hiro/core/widget/combo-button.cpp +++ b/hiro/core/widget/combo-button.cpp @@ -13,7 +13,7 @@ auto mComboButton::destruct() -> void { auto mComboButton::append(sComboButtonItem item) -> type& { state.items.append(item); - item->setParent(this, items() - 1); + item->setParent(this, itemCount() - 1); signal(append, item); return *this; } @@ -23,14 +23,20 @@ auto mComboButton::doChange() const -> void { } auto mComboButton::item(unsigned position) const -> ComboButtonItem { - if(position < items()) return state.items[position]; + if(position < itemCount()) return state.items[position]; return {}; } -auto mComboButton::items() const -> unsigned { +auto mComboButton::itemCount() const -> unsigned { return state.items.size(); } +auto mComboButton::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + auto mComboButton::onChange(const function& callback) -> type& { state.onChange = callback; return *this; @@ -39,7 +45,7 @@ auto mComboButton::onChange(const function& callback) -> type& { auto mComboButton::remove(sComboButtonItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); - for(auto n : range(item->offset(), items())) { + for(auto n : range(item->offset(), itemCount())) { state.items[n]->adjustOffset(-1); } item->setParent(); diff --git a/hiro/core/widget/hex-edit.cpp b/hiro/core/widget/hex-edit.cpp index 7c70e6cf..986072c0 100644 --- a/hiro/core/widget/hex-edit.cpp +++ b/hiro/core/widget/hex-edit.cpp @@ -6,6 +6,10 @@ auto mHexEdit::allocate() -> pObject* { // +auto mHexEdit::address() const -> unsigned { + return state.address; +} + auto mHexEdit::backgroundColor() const -> Color { return state.backgroundColor; } @@ -31,10 +35,6 @@ auto mHexEdit::length() const -> unsigned { return state.length; } -auto mHexEdit::offset() const -> unsigned { - return state.offset; -} - auto mHexEdit::onRead(const function& callback) -> type& { state.onRead = callback; return *this; @@ -49,6 +49,12 @@ auto mHexEdit::rows() const -> unsigned { return state.rows; } +auto mHexEdit::setAddress(unsigned address) -> type& { + state.address = address; + signal(setAddress, address); + return *this; +} + auto mHexEdit::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); @@ -73,12 +79,6 @@ auto mHexEdit::setLength(unsigned length) -> type& { return *this; } -auto mHexEdit::setOffset(unsigned offset) -> type& { - state.offset = offset; - signal(setOffset, offset); - return *this; -} - auto mHexEdit::setRows(unsigned rows) -> type& { state.rows = rows; signal(setRows, rows); diff --git a/hiro/core/widget/icon-view.cpp b/hiro/core/widget/icon-view.cpp index 1fba9052..184601b3 100644 --- a/hiro/core/widget/icon-view.cpp +++ b/hiro/core/widget/icon-view.cpp @@ -13,7 +13,7 @@ auto mIconView::destruct() -> void { auto mIconView::append(sIconViewItem item) -> type& { state.items.append(item); - item->setParent(this, items() - 1); + item->setParent(this, itemCount() - 1); signal(append, item); return *this; } @@ -43,14 +43,20 @@ auto mIconView::foregroundColor() const -> Color { } auto mIconView::item(unsigned position) const -> IconViewItem { - if(position < items()) return state.items[position]; + if(position < itemCount()) return state.items[position]; return {}; } -auto mIconView::items() const -> unsigned { +auto mIconView::itemCount() const -> unsigned { return state.items.size(); } +auto mIconView::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + auto mIconView::multiSelect() const -> bool { return state.multiSelect; } @@ -77,7 +83,7 @@ auto mIconView::orientation() const -> Orientation { auto mIconView::remove(sIconViewItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); - for(auto n : range(item->offset(), items())) { + for(auto n : range(item->offset(), itemCount())) { state.items[n]->adjustOffset(-1); } item->setParent(); @@ -142,7 +148,7 @@ auto mIconView::setSelected(const vector& selections) -> type& { if(selectAll) return signal(setItemSelectedAll), *this; if(!selections) return signal(setItemSelectedNone), *this; for(auto& position : selections) { - if(position >= items()) continue; + if(position >= itemCount()) continue; state.items[position]->state.selected = true; } signal(setItemSelected, selections); diff --git a/hiro/core/widget/label.cpp b/hiro/core/widget/label.cpp index 31e1f7ed..fe15699f 100644 --- a/hiro/core/widget/label.cpp +++ b/hiro/core/widget/label.cpp @@ -6,14 +6,13 @@ auto mLabel::allocate() -> pObject* { // -auto mLabel::horizontalAlignment() const -> double { - return state.horizontalAlignment; +auto mLabel::alignment() const -> Alignment { + return state.alignment; } -auto mLabel::setHorizontalAlignment(double alignment) -> type& { - alignment = max(0.0, min(1.0, alignment)); - state.horizontalAlignment = alignment; - signal(setHorizontalAlignment, alignment); +auto mLabel::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); return *this; } @@ -23,19 +22,8 @@ auto mLabel::setText(const string& text) -> type& { return *this; } -auto mLabel::setVerticalAlignment(double alignment) -> type& { - alignment = max(0.0, min(1.0, alignment)); - state.verticalAlignment = alignment; - signal(setVerticalAlignment, alignment); - return *this; -} - auto mLabel::text() const -> string { return state.text; } -auto mLabel::verticalAlignment() const -> double { - return state.verticalAlignment; -} - #endif diff --git a/hiro/core/widget/list-view-cell.cpp b/hiro/core/widget/list-view-cell.cpp index 52ec080f..bcfc6483 100644 --- a/hiro/core/widget/list-view-cell.cpp +++ b/hiro/core/widget/list-view-cell.cpp @@ -6,11 +6,91 @@ auto mListViewCell::allocate() -> pObject* { // -auto mListViewCell::backgroundColor() const -> Color { - return state.backgroundColor; +auto mListViewCell::alignment(bool recursive) const -> Alignment { + if(auto alignment = state.alignment) return alignment; + if(recursive) { + if(auto parent = parentListViewItem()) { + if(auto alignment = parent->state.alignment) return alignment; + if(auto grandparent = parent->parentListView()) { + if(auto header = grandparent->state.header) { + if(offset() < header->columnCount()) { + if(auto column = header->state.columns[offset()]) { + if(auto alignment = column->state.alignment) return alignment; + } + } + } + if(auto alignment = grandparent->state.alignment) return alignment; + } + } + } + return {}; } -auto mListViewCell::foregroundColor() const -> Color { +auto mListViewCell::backgroundColor(bool recursive) const -> Color { + if(auto color = state.backgroundColor) return color; + if(recursive) { + if(auto parent = parentListViewItem()) { + if(auto color = parent->state.backgroundColor) return color; + if(auto grandparent = parent->parentListView()) { + if(auto header = grandparent->state.header) { + if(offset() < header->columnCount()) { + if(auto column = header->state.columns[offset()]) { + if(auto color = column->state.backgroundColor) return color; + } + } + } + if(auto color = grandparent->state.backgroundColor) return color; + } + } + } + return {}; +} + +auto mListViewCell::checkable() const -> bool { + return state.checkable; +} + +auto mListViewCell::checked() const -> bool { + return state.checkable && state.checked; +} + +auto mListViewCell::font(bool recursive) const -> string { + if(auto font = mObject::font()) return font; + if(recursive) { + if(auto parent = parentListViewItem()) { + if(auto font = parent->font()) return font; + if(auto grandparent = parent->parentListView()) { + if(auto header = grandparent->state.header) { + if(offset() < header->columnCount()) { + if(auto column = header->state.columns[offset()]) { + if(auto font = column->font()) return font; + } + } + } + if(auto font = grandparent->font(true)) return font; + } + } + } + return {}; +} + +auto mListViewCell::foregroundColor(bool recursive) const -> Color { + if(auto color = state.foregroundColor) return color; + if(recursive) { + if(auto parent = parentListViewItem()) { + if(auto color = parent->state.foregroundColor) return color; + if(auto grandparent = parent->parentListView()) { + if(auto header = grandparent->state.header) { + if(offset() < header->columnCount()) { + if(auto column = header->state.columns[offset()]) { + if(auto color = column->state.foregroundColor) return color; + } + } + } + if(auto color = grandparent->state.foregroundColor) return color; + } + } + } return state.foregroundColor; } @@ -18,12 +98,31 @@ auto mListViewCell::icon() const -> image { return state.icon; } +auto mListViewCell::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); + return *this; +} + auto mListViewCell::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); return *this; } +auto mListViewCell::setCheckable(bool checkable) -> type& { + state.checkable = checkable; + signal(setCheckable, checkable); + return *this; +} + +auto mListViewCell::setChecked(bool checked) -> type& { + setCheckable(true); + state.checked = checked; + signal(setChecked, checked); + return *this; +} + auto mListViewCell::setForegroundColor(Color color) -> type& { state.foregroundColor = color; signal(setForegroundColor, color); diff --git a/hiro/core/widget/list-view-column.cpp b/hiro/core/widget/list-view-column.cpp index 50769534..e23e67df 100644 --- a/hiro/core/widget/list-view-column.cpp +++ b/hiro/core/widget/list-view-column.cpp @@ -11,6 +11,10 @@ auto mListViewColumn::active() const -> bool { return false; } +auto mListViewColumn::alignment() const -> Alignment { + return state.alignment; +} + auto mListViewColumn::backgroundColor() const -> Color { return state.backgroundColor; } @@ -36,7 +40,7 @@ auto mListViewColumn::icon() const -> image { } auto mListViewColumn::remove() -> type& { - if(auto listView = parentListView()) listView->remove(*this); + if(auto listView = parentListViewHeader()) listView->remove(*this); return *this; } @@ -50,6 +54,12 @@ auto mListViewColumn::setActive() -> type& { 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); @@ -68,12 +78,6 @@ auto mListViewColumn::setExpandable(bool expandable) -> type& { return *this; } -auto mListViewColumn::setFont(const string& font) -> type& { - state.font = font; - signal(setFont, this->font(true)); - return *this; -} - auto mListViewColumn::setForegroundColor(Color color) -> type& { state.foregroundColor = color; signal(setForegroundColor, color); @@ -99,6 +103,12 @@ auto mListViewColumn::setResizable(bool resizable) -> type& { 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); @@ -124,6 +134,10 @@ auto mListViewColumn::setWidth(signed width) -> type& { return *this; } +auto mListViewColumn::sortable() const -> bool { + return state.sortable; +} + auto mListViewColumn::text() const -> string { return state.text; } diff --git a/hiro/core/widget/list-view-header.cpp b/hiro/core/widget/list-view-header.cpp new file mode 100644 index 00000000..9469ef37 --- /dev/null +++ b/hiro/core/widget/list-view-header.cpp @@ -0,0 +1,53 @@ +#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/hiro/core/widget/list-view-item.cpp b/hiro/core/widget/list-view-item.cpp index 87209bb9..4b9a0d3e 100644 --- a/hiro/core/widget/list-view-item.cpp +++ b/hiro/core/widget/list-view-item.cpp @@ -6,9 +6,13 @@ auto mListViewItem::allocate() -> pObject* { // +auto mListViewItem::alignment() const -> Alignment { + return state.alignment; +} + auto mListViewItem::append(sListViewCell cell) -> type& { state.cells.append(cell); - cell->setParent(this, cells() - 1); + cell->setParent(this, cellCount() - 1); signal(append, cell); return *this; } @@ -18,20 +22,18 @@ auto mListViewItem::backgroundColor() const -> Color { } auto mListViewItem::cell(unsigned position) const -> ListViewCell { - if(position < cells()) return state.cells[position]; + if(position < cellCount()) return state.cells[position]; return {}; } -auto mListViewItem::cells() const -> unsigned { +auto mListViewItem::cellCount() const -> unsigned { return state.cells.size(); } -auto mListViewItem::checkable() const -> bool { - return state.checkable; -} - -auto mListViewItem::checked() const -> bool { - return state.checkable && state.checked; +auto mListViewItem::cells() const -> vector { + vector cells; + for(auto& cell : state.cells) cells.append(cell); + return cells; } auto mListViewItem::foregroundColor() const -> Color { @@ -46,7 +48,7 @@ auto mListViewItem::remove() -> type& { auto mListViewItem::remove(sListViewCell cell) -> type& { signal(remove, cell); state.cells.remove(cell->offset()); - for(auto n : range(cell->offset(), cells())) { + for(auto n : range(cell->offset(), cellCount())) { state.cells[n]->adjustOffset(-1); } cell->setParent(); @@ -57,24 +59,18 @@ 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::setCheckable(bool checkable) -> type& { - state.checkable = checkable; - signal(setCheckable, checkable); - return *this; -} - -auto mListViewItem::setChecked(bool checked) -> type& { - state.checked = checked; - signal(setChecked, checked); - return *this; -} - auto mListViewItem::setFocused() -> type& { signal(setFocused); return *this; diff --git a/hiro/core/widget/list-view.cpp b/hiro/core/widget/list-view.cpp index 4e1009df..fe072c48 100644 --- a/hiro/core/widget/list-view.cpp +++ b/hiro/core/widget/list-view.cpp @@ -6,22 +6,27 @@ auto mListView::allocate() -> pObject* { auto mListView::destruct() -> void { for(auto& item : state.items) item->destruct(); - for(auto& column : state.columns) column->destruct(); + if(auto& header = state.header) header->destruct(); mWidget::destruct(); } // -auto mListView::append(sListViewColumn column) -> type& { - state.columns.append(column); - column->setParent(this, columns() - 1); - signal(append, column); +auto mListView::alignment() const -> Alignment { + return state.alignment; +} + +auto mListView::append(sListViewHeader header) -> type& { + if(auto& header = state.header) remove(header); + state.header = header; + header->setParent(this, 0); + signal(append, header); return *this; } auto mListView::append(sListViewItem item) -> type& { state.items.append(item); - item->setParent(this, items() - 1); + item->setParent(this, itemCount() - 1); signal(append, item); return *this; } @@ -34,31 +39,16 @@ auto mListView::batchable() const -> bool { return state.batchable; } -auto mListView::checkable() const -> bool { - return state.checkable; -} - -auto mListView::checkAll() -> type& { - for(auto& item : state.items) item->state.checked = true; - signal(checkAll); - return *this; -} - -auto mListView::checked() const -> vector { +auto mListView::batched() const -> vector { vector items; for(auto& item : state.items) { - if(item->checked()) items.append(item); + if(item->selected()) items.append(item); } return items; } -auto mListView::column(unsigned position) const -> ListViewColumn { - if(position < columns()) return state.columns[position]; - return {}; -} - -auto mListView::columns() const -> unsigned { - return state.columns.size(); +auto mListView::bordered() const -> bool { + return state.bordered; } auto mListView::doActivate() const -> void { @@ -81,31 +71,33 @@ auto mListView::doSort(sListViewColumn column) const -> void { if(state.onSort) return state.onSort(column); } -auto mListView::doToggle(sListViewItem item) const -> void { - if(state.onToggle) return state.onToggle(item); +auto mListView::doToggle(sListViewCell cell) const -> void { + if(state.onToggle) return state.onToggle(cell); } auto mListView::foregroundColor() const -> Color { return state.foregroundColor; } -auto mListView::gridVisible() const -> bool { - return state.gridVisible; -} - -auto mListView::headerVisible() const -> bool { - return state.headerVisible; +auto mListView::header() const -> ListViewHeader { + return state.header; } auto mListView::item(unsigned position) const -> ListViewItem { - if(position < items()) return state.items[position]; + if(position < itemCount()) return state.items[position]; return {}; } -auto mListView::items() const -> unsigned { +auto mListView::itemCount() const -> unsigned { return state.items.size(); } +auto mListView::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + auto mListView::onActivate(const function& callback) -> type& { state.onActivate = callback; return *this; @@ -131,27 +123,22 @@ auto mListView::onSort(const function& callback) -> type& return *this; } -auto mListView::onToggle(const function& callback) -> type& { +auto mListView::onToggle(const function& callback) -> type& { state.onToggle = callback; return *this; } -auto mListView::remove(sListViewColumn column) -> type& { - signal(remove, column); - for(auto& item : state.items) item->setParent(); - state.items.reset(); - state.columns.remove(column->offset()); - for(auto n : range(column->offset(), columns())) { - state.columns[n]->adjustOffset(-1); - } - column->setParent(); +auto mListView::remove(sListViewHeader header) -> type& { + signal(remove, header); + header->setParent(); + state.header.reset(); return *this; } auto mListView::remove(sListViewItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); - for(auto n : range(item->offset(), items())) { + for(auto n : range(item->offset(), itemCount())) { state.items[n]->adjustOffset(-1); } item->setParent(); @@ -162,8 +149,8 @@ auto mListView::reset() -> type& { signal(reset); for(auto& item : state.items) item->setParent(); state.items.reset(); - for(auto& column : state.columns) column->setParent(); - state.columns.reset(); + if(auto& header = state.header) header->setParent(); + state.header.reset(); return *this; } @@ -172,12 +159,6 @@ auto mListView::resizeColumns() -> type& { return *this; } -auto mListView::selectAll() -> type& { - for(auto& item : state.items) item->state.selected = true; - signal(selectAll); - return *this; -} - auto mListView::selected() const -> ListViewItem { for(auto& item : state.items) { if(item->selected()) return item; @@ -185,12 +166,10 @@ auto mListView::selected() const -> ListViewItem { return {}; } -auto mListView::selectedItems() const -> vector { - vector items; - for(auto& item : state.items) { - if(item->selected()) items.append(item); - } - return items; +auto mListView::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); + return *this; } auto mListView::setBackgroundColor(Color color) -> type& { @@ -205,9 +184,9 @@ auto mListView::setBatchable(bool batchable) -> type& { return *this; } -auto mListView::setCheckable(bool checkable) -> type& { - state.checkable = checkable; - signal(setCheckable, checkable); +auto mListView::setBordered(bool bordered) -> type& { + state.bordered = bordered; + signal(setBordered, bordered); return *this; } @@ -217,47 +196,13 @@ auto mListView::setForegroundColor(Color color) -> type& { return *this; } -auto mListView::setGridVisible(bool visible) -> type& { - state.gridVisible = visible; - signal(setGridVisible, visible); - return *this; -} - -auto mListView::setHeaderVisible(bool visible) -> type& { - state.headerVisible = visible; - signal(setHeaderVisible, visible); - return *this; -} - auto mListView::setParent(mObject* parent, signed offset) -> type& { for(auto& item : state.items) item->destruct(); - for(auto& column : state.columns) column->destruct(); + if(auto& header = state.header) header->destruct(); mObject::setParent(parent, offset); - for(auto& column : state.columns) column->setParent(this, column->offset()); + if(auto& header = state.header) header->setParent(this, 0); for(auto& item : state.items) item->setParent(this, item->offset()); return *this; } -auto mListView::setSortable(bool sortable) -> type& { - state.sortable = sortable; - signal(setSortable, sortable); - return *this; -} - -auto mListView::sortable() const -> bool { - return state.sortable; -} - -auto mListView::uncheckAll() -> type& { - for(auto& item : state.items) item->state.checked = false; - signal(uncheckAll); - return *this; -} - -auto mListView::unselectAll() -> type& { - for(auto& item : state.items) item->state.selected = false; - signal(unselectAll); - return *this; -} - #endif diff --git a/hiro/core/widget/radio-button.cpp b/hiro/core/widget/radio-button.cpp index cab12ffd..e504972a 100644 --- a/hiro/core/widget/radio-button.cpp +++ b/hiro/core/widget/radio-button.cpp @@ -59,7 +59,7 @@ auto mRadioButton::setChecked() -> type& { auto mRadioButton::setGroup(sGroup group) -> type& { state.group = group; signal(setGroup, group); - if(group && group->objects() == 1) setChecked(); + if(group && group->objectCount() == 1) setChecked(); return *this; } diff --git a/hiro/core/widget/radio-label.cpp b/hiro/core/widget/radio-label.cpp index ecab7391..a4f45ac2 100644 --- a/hiro/core/widget/radio-label.cpp +++ b/hiro/core/widget/radio-label.cpp @@ -41,7 +41,7 @@ auto mRadioLabel::setChecked() -> type& { auto mRadioLabel::setGroup(sGroup group) -> type& { state.group = group; signal(setGroup, group); - if(group && group->objects() == 1) setChecked(); + if(group && group->objectCount() == 1) setChecked(); return *this; } diff --git a/hiro/core/widget/tab-frame.cpp b/hiro/core/widget/tab-frame.cpp index be2a5a5c..d344a629 100644 --- a/hiro/core/widget/tab-frame.cpp +++ b/hiro/core/widget/tab-frame.cpp @@ -13,7 +13,7 @@ auto mTabFrame::destruct() -> void { auto mTabFrame::append(sTabFrameItem item) -> type& { state.items.append(item); - item->setParent(this, items() - 1); + item->setParent(this, itemCount() - 1); signal(append, item); return *this; } @@ -35,14 +35,20 @@ auto mTabFrame::edge() const -> Edge { } auto mTabFrame::item(unsigned position) const -> TabFrameItem { - if(position < items()) return state.items[position]; + if(position < itemCount()) return state.items[position]; return {}; } -auto mTabFrame::items() const -> unsigned { +auto mTabFrame::itemCount() const -> unsigned { return state.items.size(); } +auto mTabFrame::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + auto mTabFrame::onChange(const function& callback) -> type& { state.onChange = callback; return *this; @@ -63,7 +69,7 @@ auto mTabFrame::remove(sTabFrameItem item) -> type& { item->setParent(); signal(remove, item); state.items.remove(item->offset()); - for(auto n : range(offset, items())) { + for(auto n : range(offset, itemCount())) { state.items[n]->adjustOffset(-1); } return *this; diff --git a/hiro/core/widget/tree-view-item.cpp b/hiro/core/widget/tree-view-item.cpp index c7d5c112..e3f720a1 100644 --- a/hiro/core/widget/tree-view-item.cpp +++ b/hiro/core/widget/tree-view-item.cpp @@ -13,7 +13,7 @@ auto mTreeViewItem::destruct() -> void { auto mTreeViewItem::append(sTreeViewItem item) -> type& { state.items.append(item); - item->setParent(this, items() - 1); + item->setParent(this, itemCount() - 1); signal(append, item); return *this; } @@ -30,15 +30,21 @@ auto mTreeViewItem::item(const string& path) const -> TreeViewItem { if(path.empty()) return {}; auto paths = path.split("/"); unsigned position = decimal(paths.takeFirst()); - if(position >= items()) return {}; + if(position >= itemCount()) return {}; if(paths.empty()) return state.items[position]; return state.items[position]->item(paths.merge("/")); } -auto mTreeViewItem::items() const -> unsigned { +auto mTreeViewItem::itemCount() const -> unsigned { return state.items.size(); } +auto mTreeViewItem::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + auto mTreeViewItem::path() const -> string { if(auto treeViewItem = parentTreeViewItem()) return {treeViewItem->path(), "/", offset()}; return {offset()}; @@ -53,7 +59,7 @@ auto mTreeViewItem::remove() -> type& { auto mTreeViewItem::remove(sTreeViewItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); - for(auto n : range(item->offset(), items())) { + for(auto n : range(item->offset(), itemCount())) { state.items[n]->adjustOffset(-1); } item->setParent(); diff --git a/hiro/core/widget/tree-view.cpp b/hiro/core/widget/tree-view.cpp index 81433d8a..d93351e0 100644 --- a/hiro/core/widget/tree-view.cpp +++ b/hiro/core/widget/tree-view.cpp @@ -13,7 +13,7 @@ auto mTreeView::destruct() -> void { auto mTreeView::append(sTreeViewItem item) -> type& { state.items.append(item); - item->setParent(this, items() - 1); + item->setParent(this, itemCount() - 1); signal(append, item); return *this; } @@ -60,15 +60,21 @@ auto mTreeView::item(const string& path) const -> TreeViewItem { if(path.empty()) return {}; auto paths = path.split("/"); unsigned position = decimal(paths.takeFirst()); - if(position >= items()) return {}; + if(position >= itemCount()) return {}; if(paths.empty()) return state.items[position]; return state.items[position]->item(paths.merge("/")); } -auto mTreeView::items() const -> unsigned { +auto mTreeView::itemCount() const -> unsigned { return state.items.size(); } +auto mTreeView::items() const -> vector { + vector items; + for(auto& item : state.items) items.append(item); + return items; +} + auto mTreeView::onActivate(const function& callback) -> type& { state.onActivate = callback; return *this; @@ -92,7 +98,7 @@ auto mTreeView::onToggle(const function& callback) -> type auto mTreeView::remove(sTreeViewItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); - for(auto n : range(item->offset(), items())) { + for(auto n : range(item->offset(), itemCount())) { state.items[n]->adjustOffset(-1); } item->setParent(); diff --git a/hiro/core/window.cpp b/hiro/core/window.cpp index 6a4e13b2..1eeed7df 100644 --- a/hiro/core/window.cpp +++ b/hiro/core/window.cpp @@ -162,6 +162,16 @@ auto mWindow::resizable() const -> bool { return state.resizable; } +auto mWindow::setAlignment(Alignment alignment) -> type& { + if(!alignment) alignment = {0.0, 0.0}; + auto workspace = Desktop::workspace(); + auto geometry = frameGeometry(); + signed left = alignment.horizontal() * (workspace.width() - geometry.width()); + signed top = alignment.vertical() * (workspace.height() - geometry.height()); + setFramePosition({left, top}); + return *this; +} + auto mWindow::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); @@ -229,17 +239,6 @@ auto mWindow::setModal(bool modal) -> type& { return *this; } -auto mWindow::setPlacement(double x, double y) -> type& { - x = max(0.0, min(1.0, x)); - y = max(0.0, min(1.0, y)); - auto workspace = Desktop::workspace(); - auto geometry = frameGeometry(); - signed left = x * (workspace.width() - geometry.width()); - signed top = y * (workspace.height() - geometry.height()); - setFramePosition({left, top}); - return *this; -} - auto mWindow::setPosition(Position position) -> type& { return setGeometry({ position.x(), position.y(), diff --git a/hiro/extension/browser-dialog.cpp b/hiro/extension/browser-dialog.cpp index c71baa37..2de7b70a 100644 --- a/hiro/extension/browser-dialog.cpp +++ b/hiro/extension/browser-dialog.cpp @@ -32,30 +32,30 @@ private: //accept button clicked, or enter pressed on file name line edit //also called by list view activate after special case handling auto BrowserDialogWindow::accept() -> void { - auto selectedItems = view.selectedItems(); + auto batched = view.batched(); - if(state.action == "openFile" && selectedItems) { - string name = selectedItems.first()->cell(0)->text(); + if(state.action == "openFile" && batched) { + string name = batched.first()->cell(0)->text(); if(isFolder(name)) return setPath({state.path, name}); state.response.append(string{state.path, name}); } if(state.action == "openFiles") { - for(auto selectedItem : selectedItems) { - string name = selectedItem->cell(0)->text(); + for(auto item : batched) { + string name = item->cell(0)->text(); state.response.append(string{state.path, name, isFolder(name) ? "/" : ""}); } } - if(state.action == "openFolder" && selectedItems) { - string name = selectedItems.first()->cell(0)->text(); + if(state.action == "openFolder" && batched) { + string name = batched.first()->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 && selectedItems) name = selectedItems.first()->cell(0)->text(); + if(!name && batched) name = batched.first()->cell(0)->text(); if(!name || isFolder(name)) return; if(file::exists({state.path, name})) { if(MessageDialog("File already exists; overwrite it?").question() != "Yes") return; @@ -63,8 +63,8 @@ auto BrowserDialogWindow::accept() -> void { state.response.append(string{state.path, name}); } - if(state.action == "selectFolder" && selectedItems) { - string name = selectedItems.first()->cell(0)->text(); + if(state.action == "selectFolder" && batched) { + string name = batched.first()->cell(0)->text(); if(isFolder(name)) state.response.append(string{state.path, name, "/"}); } @@ -162,7 +162,9 @@ auto BrowserDialogWindow::setPath(string path) -> void { pathName.setText(state.path = path); view.reset(); - view.append(ListViewColumn().setExpandable()); + view.append(ListViewHeader().setVisible(false) + .append(ListViewColumn().setExpandable()) + ); auto contents = directory::icontents(path); bool folderMode = state.action == "openFolder"; diff --git a/hiro/extension/fixed-layout.cpp b/hiro/extension/fixed-layout.cpp index 8db8f5e3..cbabcbd0 100644 --- a/hiro/extension/fixed-layout.cpp +++ b/hiro/extension/fixed-layout.cpp @@ -9,7 +9,7 @@ auto mFixedLayout::append(sSizable sizable, Geometry geometry) -> type& { auto mFixedLayout::minimumSize() const -> Size { signed width = Size::Minimum, height = Size::Minimum; - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { width = max(width, sizable(n)->minimumSize().width()); height = max(height, sizable(n)->minimumSize().height()); } @@ -30,7 +30,7 @@ auto mFixedLayout::reset() -> type& { auto mFixedLayout::setEnabled(bool enabled) -> type& { mLayout::setEnabled(enabled); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setEnabled(sizable(n)->enabled()); } return *this; @@ -38,7 +38,7 @@ auto mFixedLayout::setEnabled(bool enabled) -> type& { auto mFixedLayout::setFont(const string& font) -> type& { mLayout::setFont(font); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setFont(sizable(n)->font()); } return *this; @@ -46,7 +46,7 @@ auto mFixedLayout::setFont(const string& font) -> type& { auto mFixedLayout::setVisible(bool visible) -> type& { mLayout::setVisible(visible); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setVisible(sizable(n)->visible()); } return *this; diff --git a/hiro/extension/horizontal-layout.cpp b/hiro/extension/horizontal-layout.cpp index fe49974e..a3fe9344 100644 --- a/hiro/extension/horizontal-layout.cpp +++ b/hiro/extension/horizontal-layout.cpp @@ -9,7 +9,7 @@ auto mHorizontalLayout::append(sSizable sizable, Size size, signed spacing) -> t auto mHorizontalLayout::minimumSize() const -> Size { signed width = 0, height = 0; - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; if(child.width == Size::Minimum || child.width == Size::Maximum) { width += sizable(n)->minimumSize().width(); @@ -19,7 +19,7 @@ auto mHorizontalLayout::minimumSize() const -> Size { if(&child != &properties.last()) width += child.spacing; } - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; if(child.height == Size::Minimum || child.height == Size::Maximum) { height = max(height, sizable(n)->minimumSize().height()); @@ -50,7 +50,7 @@ auto mHorizontalLayout::setAlignment(double alignment) -> type& { auto mHorizontalLayout::setEnabled(bool enabled) -> type& { mLayout::setEnabled(enabled); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setEnabled(sizable(n)->enabled()); } return *this; @@ -58,7 +58,7 @@ auto mHorizontalLayout::setEnabled(bool enabled) -> type& { auto mHorizontalLayout::setFont(const string& font) -> type& { mLayout::setFont(font); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setFont(sizable(n)->font()); } return *this; @@ -68,7 +68,7 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& { mLayout::setGeometry(containerGeometry); auto properties = this->properties; - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; if(child.width == Size::Minimum) child.width = sizable(n)->minimumSize().width(); if(child.height == Size::Minimum) child.height = sizable(n)->minimumSize().height(); @@ -95,7 +95,7 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& { signed maximumHeight = 0; for(auto& child : properties) maximumHeight = max(maximumHeight, child.height); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; signed pivot = (maximumHeight - child.height) * settings.alignment; Geometry childGeometry = {geometry.x(), geometry.y() + pivot, child.width, child.height}; @@ -120,7 +120,7 @@ auto mHorizontalLayout::setSpacing(signed spacing) -> type& { auto mHorizontalLayout::setVisible(bool visible) -> type& { mLayout::setVisible(visible); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setVisible(sizable(n)->visible()); } return *this; diff --git a/hiro/extension/vertical-layout.cpp b/hiro/extension/vertical-layout.cpp index 8bce011b..1c799a02 100644 --- a/hiro/extension/vertical-layout.cpp +++ b/hiro/extension/vertical-layout.cpp @@ -9,7 +9,7 @@ auto mVerticalLayout::append(sSizable sizable, Size size, signed spacing) -> typ auto mVerticalLayout::minimumSize() const -> Size { signed width = 0, height = 0; - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; if(child.width == Size::Minimum || child.width == Size::Maximum) { width = max(width, sizable(n)->minimumSize().width()); @@ -18,7 +18,7 @@ auto mVerticalLayout::minimumSize() const -> Size { width = max(width, child.width); } - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; if(child.height == Size::Minimum || child.height == Size::Maximum) { height += sizable(n)->minimumSize().height(); @@ -50,7 +50,7 @@ auto mVerticalLayout::setAlignment(double alignment) -> type& { auto mVerticalLayout::setEnabled(bool enabled) -> type& { mLayout::setEnabled(enabled); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setEnabled(sizable(n)->enabled()); } return *this; @@ -58,7 +58,7 @@ auto mVerticalLayout::setEnabled(bool enabled) -> type& { auto mVerticalLayout::setFont(const string& font) -> type& { mLayout::setFont(font); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setFont(sizable(n)->font()); } return *this; @@ -68,7 +68,7 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& { mLayout::setGeometry(containerGeometry); auto properties = this->properties; - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; if(child.width == Size::Minimum) child.width = sizable(n)->minimumSize().width(); if(child.height == Size::Minimum) child.height = sizable(n)->minimumSize().height(); @@ -95,7 +95,7 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& { signed maximumWidth = 0; for(auto& child : properties) maximumWidth = max(maximumWidth, child.width); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { auto& child = properties[sizable(n)->offset()]; signed pivot = (maximumWidth - child.width) * settings.alignment; Geometry childGeometry = {geometry.x() + pivot, geometry.y(), child.width, child.height}; @@ -122,7 +122,7 @@ auto mVerticalLayout::setSpacing(signed spacing) -> type& { auto mVerticalLayout::setVisible(bool visible) -> type& { mLayout::setVisible(visible); - for(auto n : range(sizables())) { + for(auto n : range(sizableCount())) { sizable(n)->setVisible(sizable(n)->visible()); } return *this; diff --git a/hiro/gtk/menu-bar.cpp b/hiro/gtk/menu-bar.cpp index ce7b765c..eb7b2e37 100644 --- a/hiro/gtk/menu-bar.cpp +++ b/hiro/gtk/menu-bar.cpp @@ -8,7 +8,7 @@ auto pMenuBar::construct() -> void { auto pMenuBar::destruct() -> void { } -auto pMenuBar::append(shared_pointer menu) -> void { +auto pMenuBar::append(sMenu menu) -> void { if(auto parent = _parent()) { parent->_append(*menu); if(menu->self()) { @@ -18,7 +18,7 @@ auto pMenuBar::append(shared_pointer menu) -> void { } } -auto pMenuBar::remove(shared_pointer menu) -> void { +auto pMenuBar::remove(sMenu menu) -> void { } auto pMenuBar::setEnabled(bool enabled) -> void { diff --git a/hiro/gtk/menu-bar.hpp b/hiro/gtk/menu-bar.hpp index 1bafd7dd..6fd9801b 100644 --- a/hiro/gtk/menu-bar.hpp +++ b/hiro/gtk/menu-bar.hpp @@ -5,8 +5,8 @@ namespace hiro { struct pMenuBar : pObject { Declare(MenuBar, Object) - auto append(shared_pointer menu) -> void; - auto remove(shared_pointer menu) -> void; + auto append(sMenu menu) -> void; + auto remove(sMenu menu) -> void; auto setEnabled(bool enabled) -> void override; auto setFont(const string& font) -> void override; auto setVisible(bool visible) -> void override; diff --git a/hiro/gtk/platform.cpp b/hiro/gtk/platform.cpp index c77ee092..cec3032f 100644 --- a/hiro/gtk/platform.cpp +++ b/hiro/gtk/platform.cpp @@ -46,6 +46,7 @@ #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" diff --git a/hiro/gtk/platform.hpp b/hiro/gtk/platform.hpp index 354e96cc..d99086b7 100644 --- a/hiro/gtk/platform.hpp +++ b/hiro/gtk/platform.hpp @@ -57,6 +57,7 @@ namespace hiro { #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" diff --git a/hiro/gtk/settings.cpp b/hiro/gtk/settings.cpp index 77cbf767..53a03d59 100644 --- a/hiro/gtk/settings.cpp +++ b/hiro/gtk/settings.cpp @@ -1,16 +1,5 @@ namespace hiro { -void Settings::load() { - string path = {configpath(), "hiro/"}; - Configuration::Document::load({path, "gtk.bml"}); -} - -void Settings::save() { - string path = {configpath(), "hiro/"}; - directory::create(path, 0755); - Configuration::Document::save({path, "gtk.bml"}); -} - Settings::Settings() { geometry.append(geometry.frameX = 4, "FrameX"); geometry.append(geometry.frameY = 24, "FrameY"); @@ -23,4 +12,15 @@ Settings::Settings() { append(window, "Window"); } +auto Settings::load() -> void { + string path = {configpath(), "hiro/"}; + Configuration::Document::load({path, "gtk.bml"}); +} + +auto Settings::save() -> void { + string path = {configpath(), "hiro/"}; + directory::create(path, 0755); + Configuration::Document::save({path, "gtk.bml"}); +} + } diff --git a/hiro/gtk/settings.hpp b/hiro/gtk/settings.hpp index df69ac2d..8bcd1ed6 100644 --- a/hiro/gtk/settings.hpp +++ b/hiro/gtk/settings.hpp @@ -16,9 +16,9 @@ struct Settings : Configuration::Document { unsigned backgroundColor; } window; - void load(); - void save(); Settings(); + auto load() -> void; + auto save() -> void; }; static Settings* settings = nullptr; diff --git a/hiro/gtk/widget/hex-edit.cpp b/hiro/gtk/widget/hex-edit.cpp index fe128353..49ae7977 100644 --- a/hiro/gtk/widget/hex-edit.cpp +++ b/hiro/gtk/widget/hex-edit.cpp @@ -52,12 +52,12 @@ auto pHexEdit::construct() -> void { gtk_widget_show(subWidget); gtk_widget_show(container); + setAddress(state().address); setBackgroundColor(state().backgroundColor); setColumns(state().columns); setForegroundColor(state().foregroundColor); setRows(state().rows); setLength(state().length); - setOffset(state().offset); update(); g_signal_connect(G_OBJECT(subWidget), "key-press-event", G_CALLBACK(HexEdit_keyPress), (gpointer)this); @@ -80,6 +80,12 @@ auto pHexEdit::focused() const -> bool { return GTK_WIDGET_HAS_FOCUS(subWidget) || GTK_WIDGET_HAS_FOCUS(scrollBar); } +auto pHexEdit::setAddress(unsigned address) -> void { + setScroll(); + updateScroll(); + update(); +} + auto pHexEdit::setBackgroundColor(Color color) -> void { GdkColor gdkColor = CreateColor(color); gtk_widget_modify_base(subWidget, GTK_STATE_NORMAL, color ? &gdkColor : nullptr); @@ -100,12 +106,6 @@ auto pHexEdit::setLength(unsigned length) -> void { update(); } -auto pHexEdit::setOffset(unsigned offset) -> void { - setScroll(); - updateScroll(); - update(); -} - auto pHexEdit::setRows(unsigned rows) -> void { setScroll(); update(); @@ -120,16 +120,16 @@ auto pHexEdit::update() -> void { unsigned position = cursorPosition(); string output; - unsigned offset = state().offset; + unsigned address = state().address; for(auto row : range(state().rows)) { - output.append(hex(offset, 8L)); + output.append(hex(address, 8L)); output.append(" "); string hexdata; string ansidata = " "; for(auto column : range(state().columns)) { - if(offset < state().length) { - uint8_t data = self().doRead(offset++); + if(address < state().length) { + uint8_t data = self().doRead(address++); hexdata.append(hex(data, 2L)); hexdata.append(" "); ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.'); @@ -141,7 +141,7 @@ auto pHexEdit::update() -> void { output.append(hexdata); output.append(ansidata); - if(offset >= state().length) break; + if(address >= state().length) break; if(row != state().rows - 1) output.append("\n"); } @@ -179,9 +179,9 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool { if(scancode == GDK_Up) { if(cursorY != 0) return false; - signed newOffset = state().offset - state().columns; - if(newOffset >= 0) { - self().setOffset(newOffset); + signed newAddress = state().address - state().columns; + if(newAddress >= 0) { + self().setAddress(newAddress); update(); } return true; @@ -191,34 +191,34 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool { if(cursorY >= rows() - 1) return true; if(cursorY != state().rows - 1) return false; - signed newOffset = state().offset + state().columns; - if(newOffset + state().columns * state().rows - (state().columns - 1) <= state().length) { - self().setOffset(newOffset); + signed newAddress = state().address + state().columns; + if(newAddress + state().columns * state().rows - (state().columns - 1) <= state().length) { + self().setAddress(newAddress); update(); } return true; } if(scancode == GDK_Page_Up) { - signed newOffset = state().offset - state().columns * state().rows; - if(newOffset >= 0) { - self().setOffset(newOffset); + signed newAddress = state().address - state().columns * state().rows; + if(newAddress >= 0) { + self().setAddress(newAddress); } else { - self().setOffset(0); + self().setAddress(0); } update(); return true; } if(scancode == GDK_Page_Down) { - signed newOffset = state().offset + state().columns * state().rows; + signed newAddress = state().address + state().columns * state().rows; for(auto n : range(state().rows)) { - if(newOffset + state().columns * state().rows - (state().columns - 1) <= state().length) { - self().setOffset(newOffset); + if(newAddress + state().columns * state().rows - (state().columns - 1) <= state().length) { + self().setAddress(newAddress); update(); break; } - newOffset -= state().columns; + newAddress -= state().columns; } return true; } @@ -238,10 +238,10 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool { cursorX /= 3; if(cursorX < state().columns) { //not in ANSI region - unsigned offset = state().offset + (cursorY * state().columns + cursorX); + unsigned address = state().address + (cursorY * state().columns + cursorX); - if(offset >= state().length) return false; //do not edit past end of data - uint8_t data = self().doRead(offset); + if(address >= state().length) return false; //do not edit past end of data + uint8_t data = self().doRead(address); //write modified value if(cursorNibble == 1) { @@ -249,7 +249,7 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool { } else { data = (data & 0x0f) | (scancode << 4); } - self().doWrite(offset, data); + self().doWrite(address, data); //auto-advance cursor to next nibble/byte position++; @@ -278,7 +278,7 @@ auto pHexEdit::rowsScrollable() -> signed { auto pHexEdit::scroll(signed position) -> void { if(position > rowsScrollable()) position = rowsScrollable(); if(position < 0) position = 0; - self().setOffset(position * state().columns); + self().setAddress(position * state().columns); } auto pHexEdit::setCursorPosition(unsigned position) -> void { @@ -304,7 +304,7 @@ auto pHexEdit::setScroll() -> void { } auto pHexEdit::updateScroll() -> void { - unsigned row = state().offset / state().columns; + unsigned row = state().address / state().columns; gtk_range_set_value(GTK_RANGE(scrollBar), row); } diff --git a/hiro/gtk/widget/hex-edit.hpp b/hiro/gtk/widget/hex-edit.hpp index 8273ce93..54d835de 100644 --- a/hiro/gtk/widget/hex-edit.hpp +++ b/hiro/gtk/widget/hex-edit.hpp @@ -6,11 +6,11 @@ struct pHexEdit : pWidget { Declare(HexEdit, Widget) auto focused() const -> bool override; + auto setAddress(unsigned address) -> void; auto setBackgroundColor(Color color) -> void; auto setColumns(unsigned columns) -> void; auto setForegroundColor(Color color) -> void; auto setLength(unsigned length) -> void; - auto setOffset(unsigned offset) -> void; auto setRows(unsigned rows) -> void; auto update() -> void; diff --git a/hiro/gtk/widget/icon-view.cpp b/hiro/gtk/widget/icon-view.cpp index f200d440..f4d6bcdd 100644 --- a/hiro/gtk/widget/icon-view.cpp +++ b/hiro/gtk/widget/icon-view.cpp @@ -116,7 +116,7 @@ auto pIconView::setGeometry(Geometry geometry) -> void { } auto pIconView::setItemIcon(unsigned position, const image& icon) -> void { - if(position >= self().items()) return; + if(position >= self().itemCount()) return; GtkTreeIter iter; if(gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, string{position})) { if(icon) { @@ -129,7 +129,7 @@ auto pIconView::setItemIcon(unsigned position, const image& icon) -> void { } auto pIconView::setItemSelected(unsigned position, bool selected) -> void { - if(position >= self().items()) return; + if(position >= self().itemCount()) return; lock(); GtkTreePath* path = gtk_tree_path_new_from_string(string{position}); if(selected) { @@ -165,7 +165,7 @@ auto pIconView::setItemSelectedNone() -> void { } auto pIconView::setItemText(unsigned position, const string& text) -> void { - if(position >= self().items()) return; + if(position >= self().itemCount()) return; GtkTreeIter iter; if(gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, string{position})) { gtk_list_store_set(store, &iter, 1, (const char*)text, -1); @@ -216,7 +216,7 @@ auto pIconView::_updateSelected() -> void { currentSelection = selected; for(auto& item : state().items) item->state.selected = false; for(auto& position : currentSelection) { - if(position >= self().items()) continue; + if(position >= self().itemCount()) continue; state().items[position]->state.selected = true; } diff --git a/hiro/gtk/widget/label.cpp b/hiro/gtk/widget/label.cpp index 195acf87..446a17b3 100644 --- a/hiro/gtk/widget/label.cpp +++ b/hiro/gtk/widget/label.cpp @@ -5,7 +5,7 @@ namespace hiro { auto pLabel::construct() -> void { gtkWidget = gtk_label_new(""); - _setAlignment(); + setAlignment(state().alignment); setText(state().text); pWidget::construct(); @@ -16,30 +16,23 @@ auto pLabel::destruct() -> void { } auto pLabel::minimumSize() const -> Size { - Size size = pFont::size(self().font(true), state().text); + auto size = pFont::size(self().font(true), state().text); return {size.width(), size.height()}; } -auto pLabel::setHorizontalAlignment(double alignment) -> void { - _setAlignment(); +auto pLabel::setAlignment(Alignment alignment) -> void { + if(!alignment) alignment = {0.0, 0.5}; + gtk_misc_set_alignment(GTK_MISC(gtkWidget), alignment.horizontal(), alignment.vertical()); + auto justify = GTK_JUSTIFY_CENTER; + if(alignment.horizontal() < 0.333) justify = GTK_JUSTIFY_LEFT; + if(alignment.horizontal() > 0.666) justify = GTK_JUSTIFY_RIGHT; + gtk_label_set_justify(GTK_LABEL(gtkWidget), justify); } auto pLabel::setText(const string& text) -> void { gtk_label_set_text(GTK_LABEL(gtkWidget), text); } -auto pLabel::setVerticalAlignment(double alignment) -> void { - _setAlignment(); -} - -auto pLabel::_setAlignment() -> void { - gtk_misc_set_alignment(GTK_MISC(gtkWidget), state().horizontalAlignment, state().verticalAlignment); - auto justify = GTK_JUSTIFY_CENTER; - if(state().horizontalAlignment < 0.333) justify = GTK_JUSTIFY_LEFT; - if(state().horizontalAlignment > 0.666) justify = GTK_JUSTIFY_RIGHT; - gtk_label_set_justify(GTK_LABEL(gtkWidget), justify); -} - } #endif diff --git a/hiro/gtk/widget/label.hpp b/hiro/gtk/widget/label.hpp index 0b570477..91e99f6d 100644 --- a/hiro/gtk/widget/label.hpp +++ b/hiro/gtk/widget/label.hpp @@ -6,11 +6,8 @@ struct pLabel : pWidget { Declare(Label, Widget) auto minimumSize() const -> Size override; - auto setHorizontalAlignment(double alignment) -> void; + auto setAlignment(Alignment alignment) -> void; auto setText(const string& text) -> void; - auto setVerticalAlignment(double alignment) -> void; - - auto _setAlignment() -> void; }; } diff --git a/hiro/gtk/widget/list-view-cell.cpp b/hiro/gtk/widget/list-view-cell.cpp index da3fb167..94e22bcc 100644 --- a/hiro/gtk/widget/list-view-cell.cpp +++ b/hiro/gtk/widget/list-view-cell.cpp @@ -3,36 +3,58 @@ namespace hiro { auto pListViewCell::construct() -> void { + _setState(); } 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 { + _setState(); +} + auto pListViewCell::setForegroundColor(Color color) -> void { } auto pListViewCell::setIcon(const image& icon) -> void { - if(auto item = _parent()) { - if(auto view = item->_parent()) { - gtk_list_store_set(view->gtkListStore, &item->gtkIter, 1 + self().offset() * 2, CreatePixbuf(icon), -1); - } - } + _setState(); } auto pListViewCell::setText(const string& text) -> void { - if(auto item = _parent()) { - if(auto view = item->_parent()) { - gtk_list_store_set(view->gtkListStore, &item->gtkIter, 1 + self().offset() * 2 + 1, text.data(), -1); - } - } + _setState(); } -auto pListViewCell::_parent() -> pListViewItem* { - if(auto parent = self().parentListViewItem()) return parent->self(); - return nullptr; +auto pListViewCell::_grandparent() -> maybe { + if(auto parent = _parent()) return parent->_parent(); + return nothing; +} + +auto pListViewCell::_parent() -> maybe { + if(auto parent = self().parentListViewItem()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pListViewCell::_setState() -> void { + if(auto parent = _parent()) { + if(auto grandparent = _grandparent()) { + grandparent->lock(); + gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 0, state().checked, -1); + gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 1, CreatePixbuf(state().icon), -1); + gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 2, state().text.data(), -1); + grandparent->unlock(); + } + } } } diff --git a/hiro/gtk/widget/list-view-cell.hpp b/hiro/gtk/widget/list-view-cell.hpp index 4b32de14..2fd00821 100644 --- a/hiro/gtk/widget/list-view-cell.hpp +++ b/hiro/gtk/widget/list-view-cell.hpp @@ -5,12 +5,17 @@ namespace hiro { struct pListViewCell : pObject { Declare(ListViewCell, Object) + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; + auto setCheckable(bool checkable) -> void; + auto setChecked(bool checked) -> void; auto setForegroundColor(Color color) -> void; auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _parent() -> pListViewItem*; + auto _grandparent() -> maybe; + auto _parent() -> maybe; + auto _setState() -> void; }; } diff --git a/hiro/gtk/widget/list-view-column.cpp b/hiro/gtk/widget/list-view-column.cpp index a37b76d4..4ea0436f 100644 --- a/hiro/gtk/widget/list-view-column.cpp +++ b/hiro/gtk/widget/list-view-column.cpp @@ -3,91 +3,82 @@ namespace hiro { auto pListViewColumn::construct() -> void { - unsigned offset = self().offset(); + if(auto grandparent = _grandparent()) { + auto handle = grandparent.data(); + unsigned offset = self().offset(); - gtkHeader = gtk_hbox_new(false, 0); + gtkHeader = gtk_hbox_new(false, 0); - gtkHeaderIcon = gtk_image_new(); - gtk_box_pack_start(GTK_BOX(gtkHeader), gtkHeaderIcon, false, false, 0); + gtkHeaderIcon = gtk_image_new(); + gtk_box_pack_start(GTK_BOX(gtkHeader), gtkHeaderIcon, false, false, 0); - gtkHeaderText = gtk_label_new(state().text); - gtk_box_pack_start(GTK_BOX(gtkHeader), gtkHeaderText, true, false, 2); + gtkHeaderText = gtk_label_new(state().text); + gtk_box_pack_start(GTK_BOX(gtkHeader), gtkHeaderText, true, false, 2); - gtkColumn = gtk_tree_view_column_new(); - gtk_tree_view_column_set_sizing(gtkColumn, GTK_TREE_VIEW_COLUMN_FIXED); - gtk_tree_view_column_set_title(gtkColumn, ""); - gtk_tree_view_column_set_widget(gtkColumn, gtkHeader); + gtkColumn = gtk_tree_view_column_new(); + gtk_tree_view_column_set_sizing(gtkColumn, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_title(gtkColumn, ""); + gtk_tree_view_column_set_widget(gtkColumn, gtkHeader); - if(offset == 0) { gtkCellToggle = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellToggle, false); - gtk_tree_view_column_set_attributes(gtkColumn, gtkCellToggle, "active", 0, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellToggle), (GtkTreeCellDataFunc)ListView_cellRendererToggleDataFunc, (gpointer)_parent(), nullptr); + 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); + + 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); + + 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); + + 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); + + gtk_tree_view_append_column(grandparent->gtkTreeView, gtkColumn); + gtk_widget_show_all(gtkHeader); + grandparent->_createModel(); + + _setState(); } - - gtkCellIcon = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(gtkColumn, gtkCellIcon, false); - gtk_tree_view_column_set_attributes(gtkColumn, gtkCellIcon, "pixbuf", 1 + offset * 2 + 0, nullptr); - - gtkCellText = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(gtkColumn, gtkCellText, false); - gtk_tree_view_column_set_attributes(gtkColumn, gtkCellText, "text", 1 + offset * 2 + 1, nullptr); - - g_signal_connect(G_OBJECT(gtkColumn), "clicked", G_CALLBACK(ListView_headerActivate), (gpointer)_parent()); - g_signal_connect(G_OBJECT(gtkCellText), "edited", G_CALLBACK(ListView_edit), (gpointer)_parent()); - if(gtkCellToggle) g_signal_connect(G_OBJECT(gtkCellToggle), "toggled", G_CALLBACK(ListView_toggle), (gpointer)_parent()); } auto pListViewColumn::destruct() -> void { + if(auto grandparent = _grandparent()) { + gtk_tree_view_remove_column(grandparent->gtkTreeView, gtkColumn); + gtkColumn = nullptr; + grandparent->_createModel(); + } } auto pListViewColumn::setActive() -> void { - if(auto parent = _parent()) { - gtk_tree_view_set_search_column(parent->gtkTreeView, 1 + self().offset() * 2 + 1); - } + _setState(); +} + +auto pListViewColumn::setAlignment(Alignment alignment) -> void { } auto pListViewColumn::setBackgroundColor(Color color) -> void { - if(color) { - GdkColor gdkColor = CreateColor(color); - if(gtkCellToggle) g_object_set(G_OBJECT(gtkCellToggle), "cell-background-gdk", &gdkColor, nullptr); - g_object_set(G_OBJECT(gtkCellIcon), "cell-background-gdk", &gdkColor, nullptr); - g_object_set(G_OBJECT(gtkCellText), "cell-background-gdk", &gdkColor, nullptr); - } else { - if(gtkCellToggle) g_object_set(G_OBJECT(gtkCellToggle), "cell-background-set", FALSE, nullptr); - g_object_set(G_OBJECT(gtkCellIcon), "cell-background-set", FALSE, nullptr); - g_object_set(G_OBJECT(gtkCellText), "cell-background-set", FALSE, nullptr); - } } auto pListViewColumn::setEditable(bool editable) -> void { - g_object_set(G_OBJECT(gtkCellText), "editable", editable ? TRUE : FALSE, nullptr); + g_object_set(G_OBJECT(gtkCellText), "editable", editable ? true : false, nullptr); } auto pListViewColumn::setExpandable(bool expandable) -> void { - if(auto parent = _parent()) { - parent->resizeColumns(); + if(auto grandparent = _grandparent()) { + grandparent->resizeColumns(); } } auto pListViewColumn::setFont(const string& font) -> void { - pFont::setFont(gtkHeaderText, font); - auto fontDescription = pFont::create(font); - g_object_set(G_OBJECT(gtkCellText), "font-desc", fontDescription, nullptr); - pango_font_description_free(fontDescription); } auto pListViewColumn::setForegroundColor(Color color) -> void { - if(color) { - GdkColor gdkColor = CreateColor(color); - g_object_set(G_OBJECT(gtkCellText), "foreground-gdk", &gdkColor, nullptr); - } else { - g_object_set(G_OBJECT(gtkCellText), "foreground-set", FALSE, nullptr); - } -} - -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { - _setAlignment(); } auto pListViewColumn::setIcon(const image& icon) -> void { @@ -99,40 +90,47 @@ auto pListViewColumn::setIcon(const image& icon) -> void { } auto pListViewColumn::setResizable(bool resizable) -> void { - gtk_tree_view_column_set_resizable(gtkColumn, resizable); + _setState(); +} + +auto pListViewColumn::setSortable(bool sortable) -> void { + _setState(); } auto pListViewColumn::setText(const string& text) -> void { - gtk_label_set_text(GTK_LABEL(gtkHeaderText), text); -} - -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { - _setAlignment(); + _setState(); } auto pListViewColumn::setVisible(bool visible) -> void { - gtk_tree_view_column_set_visible(gtkColumn, visible); + _setState(); } auto pListViewColumn::setWidth(signed width) -> void { - if(auto parent = _parent()) { - parent->resizeColumns(); + if(auto grandparent = _grandparent()) { + grandparent->resizeColumns(); } } -auto pListViewColumn::_parent() -> pListView* { - if(auto parent = self().parentListView()) return parent->self(); - return nullptr; +auto pListViewColumn::_grandparent() -> maybe { + if(auto parent = _parent()) return parent->_parent(); + return nothing; } -auto pListViewColumn::_setAlignment() -> void { - gtk_tree_view_column_set_alignment(gtkColumn, state().horizontalAlignment); - gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(gtkCellText), state().horizontalAlignment, state().verticalAlignment); - //set multi-line text alignment - auto pangoAlignment = PANGO_ALIGN_CENTER; - if(state().horizontalAlignment < 0.333) pangoAlignment = PANGO_ALIGN_LEFT; - if(state().horizontalAlignment > 0.666) pangoAlignment = PANGO_ALIGN_RIGHT; - g_object_set(G_OBJECT(gtkCellText), "alignment", pangoAlignment, nullptr); +auto pListViewColumn::_parent() -> maybe { + if(auto parent = self().parentListViewHeader()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pListViewColumn::_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); + gtk_tree_view_column_set_clickable(gtkColumn, state().sortable); + gtk_label_set_text(GTK_LABEL(gtkHeaderText), state().text); + gtk_tree_view_column_set_visible(gtkColumn, self().visible()); + } } } diff --git a/hiro/gtk/widget/list-view-column.hpp b/hiro/gtk/widget/list-view-column.hpp index df23eb65..2e2d37ee 100644 --- a/hiro/gtk/widget/list-view-column.hpp +++ b/hiro/gtk/widget/list-view-column.hpp @@ -6,21 +6,24 @@ struct pListViewColumn : pObject { Declare(ListViewColumn, Object) auto setActive() -> void; + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setEditable(bool editable) -> void; auto setExpandable(bool expandable) -> void; auto setFont(const string& font) -> void override; auto setForegroundColor(Color color) -> void; - auto setHorizontalAlignment(double alignment) -> void; + auto setHorizontalAlignment(double) -> void {} auto setIcon(const image& icon) -> void; auto setResizable(bool resizable) -> void; + auto setSortable(bool sortable) -> void; auto setText(const string& text) -> void; - auto setVerticalAlignment(double alignment) -> void; + auto setVerticalAlignment(double) -> void {} auto setVisible(bool visible) -> void override; auto setWidth(signed width) -> void; - auto _parent() -> pListView*; - auto _setAlignment() -> void; + auto _grandparent() -> maybe; + auto _parent() -> maybe; + auto _setState() -> void; GtkTreeViewColumn* gtkColumn = nullptr; GtkWidget* gtkHeader = nullptr; diff --git a/hiro/gtk/widget/list-view-header.cpp b/hiro/gtk/widget/list-view-header.cpp new file mode 100644 index 00000000..569a753d --- /dev/null +++ b/hiro/gtk/widget/list-view-header.cpp @@ -0,0 +1,41 @@ +#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/hiro/gtk/widget/list-view-header.hpp b/hiro/gtk/widget/list-view-header.hpp new file mode 100644 index 00000000..a46855bb --- /dev/null +++ b/hiro/gtk/widget/list-view-header.hpp @@ -0,0 +1,18 @@ +#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/hiro/gtk/widget/list-view-item.cpp b/hiro/gtk/widget/list-view-item.cpp index 2efaa9e7..c70aad51 100644 --- a/hiro/gtk/widget/list-view-item.cpp +++ b/hiro/gtk/widget/list-view-item.cpp @@ -3,9 +3,21 @@ namespace hiro { auto pListViewItem::construct() -> void { + if(auto parent = _parent()) { + parent->lock(); + gtk_list_store_append(parent->gtkListStore, >kIter); + _setState(); + parent->unlock(); + } } auto pListViewItem::destruct() -> void { + if(auto parent = _parent()) { + parent->lock(); + gtk_list_store_remove(parent->gtkListStore, >kIter); + parent->_updateSelected(); + parent->unlock(); + } } auto pListViewItem::append(sListViewCell cell) -> void { @@ -14,18 +26,12 @@ auto pListViewItem::append(sListViewCell cell) -> void { auto pListViewItem::remove(sListViewCell cell) -> void { } +auto pListViewItem::setAlignment(Alignment alignment) -> void { +} + auto pListViewItem::setBackgroundColor(Color color) -> void { } -auto pListViewItem::setCheckable(bool checkable) -> void { -} - -auto pListViewItem::setChecked(bool checked) -> void { - if(auto parent = _parent()) { - gtk_list_store_set(parent->gtkListStore, >kIter, 0, checked, -1); - } -} - auto pListViewItem::setFocused() -> void { if(auto parent = _parent()) { GtkTreePath* path = gtk_tree_path_new_from_string(string{self().offset()}); @@ -39,23 +45,32 @@ auto pListViewItem::setForegroundColor(Color color) -> void { } auto pListViewItem::setSelected(bool selected) -> void { + _setState(); +} + +auto pListViewItem::_parent() -> maybe { + if(auto parent = self().parentListView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pListViewItem::_setState() -> void { if(auto parent = _parent()) { parent->lock(); - if(selected) { + if(state().selected) { gtk_tree_selection_select_iter(parent->gtkTreeSelection, >kIter); } else { gtk_tree_selection_unselect_iter(parent->gtkTreeSelection, >kIter); } parent->_updateSelected(); + for(auto& cell : state().cells) { + if(auto self = cell->self()) self->_setState(); + } parent->unlock(); } } -auto pListViewItem::_parent() -> pListView* { - if(auto parent = self().parentListView()) return parent->self(); - return nullptr; -} - } #endif diff --git a/hiro/gtk/widget/list-view-item.hpp b/hiro/gtk/widget/list-view-item.hpp index 51542b18..21948797 100644 --- a/hiro/gtk/widget/list-view-item.hpp +++ b/hiro/gtk/widget/list-view-item.hpp @@ -7,14 +7,14 @@ struct pListViewItem : pObject { auto append(sListViewCell cell) -> void; auto remove(sListViewCell cell) -> void; + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; - auto setCheckable(bool checkable) -> void; - auto setChecked(bool checked) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> pListView*; + auto _parent() -> maybe; + auto _setState() -> void; GtkTreeIter gtkIter; }; diff --git a/hiro/gtk/widget/list-view.cpp b/hiro/gtk/widget/list-view.cpp index d6e2df9e..7f4ccd65 100644 --- a/hiro/gtk/widget/list-view.cpp +++ b/hiro/gtk/widget/list-view.cpp @@ -10,8 +10,10 @@ static auto ListView_headerActivate(GtkTreeViewColumn* column, pListView* p) -> 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 ListView_cellRendererToggleDataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, pListView* p) -> void { return p->_doCellRendererToggleDataFunc(renderer, iter); } -static auto ListView_toggle(GtkCellRendererToggle*, const char* path, pListView* p) -> void { return p->_doToggle(path); } +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); } + +//gtk_tree_view_set_rules_hint(gtkTreeView, true); auto pListView::construct() -> void { gtkWidget = gtk_scrolled_window_new(0, 0); @@ -29,12 +31,9 @@ auto pListView::construct() -> void { setBackgroundColor(state().backgroundColor); setBatchable(state().batchable); - setCheckable(state().checkable); + setBordered(state().bordered); setFont(self().font(true)); setForegroundColor(state().foregroundColor); - setGridVisible(state().gridVisible); - setHeaderVisible(state().headerVisible); - setSortable(state().sortable); 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); @@ -51,68 +50,25 @@ auto pListView::destruct() -> void { gtk_widget_destroy(gtkWidget); } -auto pListView::append(sListViewColumn column) -> void { - gtk_tree_view_append_column(gtkTreeView, column->self()->gtkColumn); - gtk_widget_show_all(column->self()->gtkHeader); - column->setBackgroundColor(column->backgroundColor()); - column->setEditable(column->editable()); - column->setFont(column->font()); - column->setForegroundColor(column->foregroundColor()); - column->setHorizontalAlignment(column->horizontalAlignment()); - column->setResizable(column->resizable()); - column->setVerticalAlignment(column->verticalAlignment()); - setCheckable(state().checkable); - setSortable(state().sortable); - _createModel(); - resizeColumns(); - gtk_tree_view_set_rules_hint(gtkTreeView, self().columns() >= 2); //two or more columns + checkbutton column +auto pListView::append(sListViewHeader header) -> void { } auto pListView::append(sListViewItem item) -> void { - gtk_list_store_append(gtkListStore, &item->self()->gtkIter); - - item->setChecked(item->checked()); - item->setSelected(item->selected()); - for(auto column : range(self().columns())) { - if(auto cell = item->cell(column)) { - if(auto self = cell->self()) { - self->setIcon(cell->state.icon); - self->setText(cell->state.text); - } - } - } } -auto pListView::checkAll() -> void { - for(auto& item : state().items) { - if(auto delegate = item->self()) delegate->setChecked(true); - } -} - -auto pListView::focused() -> bool { +auto pListView::focused() const -> bool { return GTK_WIDGET_HAS_FOCUS(gtkTreeView); } -auto pListView::remove(sListViewColumn column) -> void { - if(auto delegate = column->self()) { - gtk_tree_view_remove_column(gtkTreeView, delegate->gtkColumn); - delegate->gtkColumn = nullptr; - } - _createModel(); - gtk_tree_view_set_rules_hint(gtkTreeView, self().columns() >= 2); //two or more columns + checkbutton column +auto pListView::remove(sListViewHeader header) -> void { } auto pListView::remove(sListViewItem item) -> void { - lock(); - if(auto delegate = item->self()) { - gtk_list_store_remove(gtkListStore, &delegate->gtkIter); - _updateSelected(); - } - unlock(); } auto pListView::reset() -> void { - GList* list = gtk_tree_view_get_columns(gtkTreeView), *p = list; + GList* list = gtk_tree_view_get_columns(gtkTreeView); + GList* p = list; while(p && p->data) { gtk_tree_view_remove_column(gtkTreeView, (GtkTreeViewColumn*)p->data); p = p->next; @@ -125,41 +81,40 @@ auto pListView::reset() -> void { auto pListView::resizeColumns() -> void { lock(); - vector widths; - signed minimumWidth = 0; - signed expandable = 0; - for(auto column : range(state().columns)) { - signed width = _width(column); - widths.append(width); - minimumWidth += width; - if(state().columns[column]->expandable()) expandable++; - } + if(auto& header = state().header) { + vector widths; + signed minimumWidth = 0; + signed expandable = 0; + for(auto column : range(header->columnCount())) { + signed width = _width(column); + widths.append(width); + minimumWidth += width; + if(header->column(column).expandable()) expandable++; + } - signed maximumWidth = self().geometry().width() - 6; - if(auto scrollBar = gtk_scrolled_window_get_vscrollbar(gtkScrolledWindow)) { - if(gtk_widget_get_visible(scrollBar)) maximumWidth -= scrollBar->allocation.width; - } + signed maximumWidth = self().geometry().width() - 6; + if(auto scrollBar = gtk_scrolled_window_get_vscrollbar(gtkScrolledWindow)) { + if(gtk_widget_get_visible(scrollBar)) maximumWidth -= scrollBar->allocation.width; + } - signed expandWidth = 0; - if(expandable && maximumWidth > minimumWidth) { - expandWidth = (maximumWidth - minimumWidth) / expandable; - } + signed expandWidth = 0; + if(expandable && maximumWidth > minimumWidth) { + expandWidth = (maximumWidth - minimumWidth) / expandable; + } - for(auto column : range(state().columns)) { - if(auto self = state().columns[column]->self()) { - signed width = widths[column]; - if(self->state().expandable) width += expandWidth; - gtk_tree_view_column_set_fixed_width(self->gtkColumn, width); + for(auto column : range(header->columnCount())) { + if(auto self = header->state.columns[column]->self()) { + signed width = widths[column]; + if(self->state().expandable) width += expandWidth; + gtk_tree_view_column_set_fixed_width(self->gtkColumn, width); + } } } unlock(); } -auto pListView::selectAll() -> void { - for(auto& item : state().items) { - if(auto delegate = item->self()) delegate->setSelected(true); - } +auto pListView::setAlignment(Alignment alignment) -> void { } auto pListView::setBackgroundColor(Color color) -> void { @@ -171,10 +126,8 @@ auto pListView::setBatchable(bool batchable) -> void { gtk_tree_selection_set_mode(gtkTreeSelection, batchable ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE); } -auto pListView::setCheckable(bool checkable) -> void { - if(auto delegate = _column(0)) { - gtk_cell_renderer_set_visible(delegate->gtkCellToggle, checkable); - } +auto pListView::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 { @@ -182,8 +135,8 @@ auto pListView::setFocused() -> void { } auto pListView::setFont(const string& font) -> void { - for(auto& column : state().columns) { - if(auto delegate = column->self()) delegate->setFont(column->font(true)); + if(auto& header = state().header) { + if(auto self = header->self()) self->_setState(); } } @@ -192,39 +145,22 @@ auto pListView::setForegroundColor(Color color) -> void { gtk_widget_modify_text(gtkWidgetChild, GTK_STATE_NORMAL, color ? &gdkColor : nullptr); } -auto pListView::setGridVisible(bool visible) -> void { - gtk_tree_view_set_grid_lines(gtkTreeView, visible ? GTK_TREE_VIEW_GRID_LINES_BOTH : GTK_TREE_VIEW_GRID_LINES_NONE); -} - -auto pListView::setHeaderVisible(bool visible) -> void { - gtk_tree_view_set_headers_visible(gtkTreeView, visible); -} - -auto pListView::setSortable(bool sortable) -> void { - for(auto& column : state().columns) { - if(auto delegate = column->self()) { - gtk_tree_view_column_set_clickable(delegate->gtkColumn, sortable); +auto pListView::setGeometry(Geometry geometry) -> void { + pWidget::setGeometry(geometry); + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(column->state.expandable) return resizeColumns(); } } } -auto pListView::uncheckAll() -> void { - for(auto& item : state().items) { - if(auto delegate = item->self()) delegate->setChecked(false); - } -} - -auto pListView::unselectAll() -> void { - for(auto& item : state().items) { - if(auto delegate = item->self()) delegate->setSelected(false); - } -} - auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { - unsigned width = 8; //margin - if(state().checkable && _column == 0) width += 32; //checkbox + unsigned width = 8; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { + if(cell->state.checkable) { + width += 32; + } if(auto& icon = cell->state.icon) { width += icon.width() + 2; } @@ -236,19 +172,16 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { return width; } -auto pListView::_column(unsigned column) -> pListViewColumn* { - if(auto delegate = self().column(column)) return delegate->self(); - return nullptr; -} - auto pListView::_columnWidth(unsigned _column) -> unsigned { - unsigned width = 8; //margin - if(auto column = self().column(_column)) { - if(auto& icon = column->state.icon) { - width += icon.width() + 2; - } - if(auto& text = column->state.text) { - width += Font::size(column->font(true), text).width(); + unsigned width = 8; + if(auto& header = state().header) { + if(auto column = header->column(_column)) { + if(auto& icon = column->state.icon) { + width += icon.width() + 2; + } + if(auto& text = column->state.text) { + width += Font::size(column->font(true), text).width(); + } } } return width; @@ -260,12 +193,15 @@ auto pListView::_createModel() -> void { gtkTreeModel = nullptr; vector types; - unsigned position = 0; - for(auto column : state().columns) { - if(!column->self()->gtkColumn) continue; //column is being removed - if(position++ == 0) types.append(G_TYPE_BOOLEAN); - types.append(GDK_TYPE_PIXBUF); - types.append(G_TYPE_STRING); + if(auto& header = state().header) { + for(auto column : header->state.columns) { + if(auto self = column->self()) { + if(!self->gtkColumn) continue; //may not have been created yet; or recently destroyed + types.append(G_TYPE_BOOLEAN); + types.append(GDK_TYPE_PIXBUF); + types.append(G_TYPE_STRING); + } + } } if(!types) return; //no columns available @@ -278,15 +214,6 @@ auto pListView::_doActivate() -> void { if(!locked()) self().doActivate(); } -auto pListView::_doCellRendererToggleDataFunc(GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { - auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter); - auto row = decimal(path); - if(auto item = self().item(row)) { - gtk_cell_renderer_set_visible(renderer, state().checkable && item->state.checkable); - } - g_free(path); -} - auto pListView::_doChange() -> void { if(!locked()) _updateSelected(); } @@ -295,18 +222,70 @@ auto pListView::_doContext() -> void { if(!locked()) self().doContext(); } -auto pListView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* path, const char* text) -> void { - for(auto& column : state().columns) { - if(auto delegate = column->self()) { - if(gtkCellRendererText == GTK_CELL_RENDERER_TEXT(delegate->gtkCellText)) { - auto row = decimal(path); +auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { + auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter); + auto row = decimal(path); + g_free(path); + + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(auto p = column->self()) { + if(renderer != GTK_CELL_RENDERER(p->gtkCellToggle) + && renderer != GTK_CELL_RENDERER(p->gtkCellIcon) + && renderer != GTK_CELL_RENDERER(p->gtkCellText) + ) continue; if(auto item = self().item(row)) { if(auto cell = item->cell(column->offset())) { - if(string{text} != cell->state.text) { - cell->setText(text); - if(!locked()) self().doEdit(cell); + if(renderer == GTK_CELL_RENDERER(p->gtkCellToggle)) { + gtk_cell_renderer_set_visible(renderer, cell->state.checkable); + } else if(renderer == GTK_CELL_RENDERER(p->gtkCellText)) { + auto alignment = cell->alignment(true); + if(!alignment) alignment = {0.0, 0.5}; + //note: below line will center column header text; but causes strange glitches + //(specifically, windows fail to respond to the close button ... some kind of heap corruption inside GTK+) + //gtk_tree_view_column_set_alignment(gtkColumn, alignment.horizontal()); + gtk_cell_renderer_set_alignment(renderer, alignment.horizontal(), alignment.vertical()); + auto pangoAlignment = PANGO_ALIGN_CENTER; + if(alignment.horizontal() < 0.333) pangoAlignment = PANGO_ALIGN_LEFT; + if(alignment.horizontal() > 0.666) pangoAlignment = PANGO_ALIGN_RIGHT; + g_object_set(G_OBJECT(renderer), "alignment", pangoAlignment, nullptr); + auto font = pFont::create(cell->font(true)); + g_object_set(G_OBJECT(renderer), "font-desc", font, nullptr); + pango_font_description_free(font); + if(auto color = cell->foregroundColor(true)) { + auto gdkColor = CreateColor(color); + g_object_set(G_OBJECT(renderer), "foreground-gdk", &gdkColor, nullptr); + } else { + g_object_set(G_OBJECT(renderer), "foreground-set", false, nullptr); + } + } + if(auto color = cell->backgroundColor(true)) { + auto gdkColor = CreateColor(color); + g_object_set(G_OBJECT(renderer), "cell-background-gdk", &gdkColor, nullptr); + } else { + g_object_set(G_OBJECT(renderer), "cell-background-set", false, nullptr); + } + } + } + } + } + } +} + +auto pListView::_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()) { + if(gtkCellRendererText == GTK_CELL_RENDERER_TEXT(delegate->gtkCellText)) { + auto row = decimal(path); + if(auto item = self().item(row)) { + if(auto cell = item->cell(column->offset())) { + if(string{text} != cell->state.text) { + cell->setText(text); + if(!locked()) self().doEdit(cell); + } + return; } - return; } } } @@ -322,7 +301,7 @@ auto pListView::_doEvent(GdkEventButton* event) -> signed { //when clicking in empty space below the last list 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) { - self().unselectAll(); + for(auto& item : state().items) item->setSelected(false); self().doChange(); return true; } @@ -344,11 +323,13 @@ auto pListView::_doEvent(GdkEventButton* event) -> signed { } auto pListView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void { - for(auto& column : state().columns) { - if(auto delegate = column->self()) { - if(gtkTreeViewColumn == delegate->gtkColumn) { - if(!locked()) self().doSort(column); - return; + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(auto delegate = column->self()) { + if(gtkTreeViewColumn == delegate->gtkColumn) { + if(!locked()) self().doSort(column); + return; + } } } } @@ -363,12 +344,21 @@ auto pListView::_doMouseMove() -> signed { return false; } -auto pListView::_doToggle(const char* path) -> void { - if(auto item = self().item(decimal(path))) { - if(auto delegate = item->self()) { - item->state.checked = !item->state.checked; - delegate->setChecked(item->state.checked); - if(!locked()) self().doToggle(item); +auto pListView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const char* path) -> void { + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(auto delegate = column->self()) { + if(gtkCellRendererToggle == GTK_CELL_RENDERER_TOGGLE(delegate->gtkCellToggle)) { + auto row = decimal(path); + if(auto item = self().item(row)) { + if(auto cell = item->cell(column->offset())) { + cell->setChecked(!cell->checked()); + if(!locked()) self().doToggle(cell); + return; + } + } + } + } } } } @@ -411,7 +401,7 @@ auto pListView::_updateSelected() -> void { currentSelection = selected; for(auto& item : state().items) item->state.selected = false; for(auto& position : currentSelection) { - if(position >= self().items()) continue; + if(position >= self().itemCount()) continue; self().item(position)->state.selected = true; } @@ -419,16 +409,17 @@ auto pListView::_updateSelected() -> void { } auto pListView::_width(unsigned column) -> unsigned { - if(auto width = state().columns[column]->width()) return width; - unsigned width = 1; - if(!state().columns[column]->visible()) return width; - if(state().headerVisible) { - width = max(width, _columnWidth(column)); + if(auto& header = state().header) { + if(auto width = header->column(column).width()) return width; + unsigned width = 1; + if(!header->column(column).visible()) return width; + if(header->visible()) width = max(width, _columnWidth(column)); + for(auto row : range(state().items)) { + width = max(width, _cellWidth(row, column)); + } + return width; } - for(auto row : range(state().items)) { - width = max(width, _cellWidth(row, column)); - } - return width; + return 1; } } diff --git a/hiro/gtk/widget/list-view.hpp b/hiro/gtk/widget/list-view.hpp index 125c2db0..b59f9386 100644 --- a/hiro/gtk/widget/list-view.hpp +++ b/hiro/gtk/widget/list-view.hpp @@ -5,40 +5,34 @@ namespace hiro { struct pListView : pWidget { Declare(ListView, Widget) - auto append(sListViewColumn column) -> void; + auto append(sListViewHeader column) -> void; auto append(sListViewItem item) -> void; - auto checkAll() -> void; - auto focused() -> bool; - auto remove(sListViewColumn column) -> void; + auto focused() const -> bool override; + auto remove(sListViewHeader column) -> void; auto remove(sListViewItem item) -> void; auto reset() -> void; auto resizeColumns() -> void; - auto selectAll() -> void; + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setBatchable(bool batchable) -> void; - auto setCheckable(bool checkable) -> void; + auto setBordered(bool bordered) -> void; auto setFocused() -> void override; auto setFont(const string& font) -> void override; auto setForegroundColor(Color color) -> void; - auto setGridVisible(bool visible) -> void; - auto setHeaderVisible(bool visible) -> void; - auto setSortable(bool sortable) -> void; - auto uncheckAll() -> void; - auto unselectAll() -> void; + auto setGeometry(Geometry geometry) -> void override; auto _cellWidth(unsigned row, unsigned column) -> unsigned; - auto _column(unsigned column) -> pListViewColumn*; auto _columnWidth(unsigned column) -> unsigned; auto _createModel() -> void; auto _doActivate() -> void; - auto _doCellRendererToggleDataFunc(GtkCellRenderer* renderer, GtkTreeIter* iter) -> void; auto _doChange() -> void; auto _doContext() -> void; - auto _doEdit(GtkCellRendererText* renderer, const char* path, const char* text) -> void; + auto _doDataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void; + auto _doEdit(GtkCellRendererText* gtkCellRendererText, const char* path, const char* text) -> void; auto _doEvent(GdkEventButton* event) -> signed; auto _doHeaderActivate(GtkTreeViewColumn* column) -> void; auto _doMouseMove() -> signed; - auto _doToggle(const char* path) -> void; + auto _doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const char* path) -> void; auto _updateSelected() -> void; auto _width(unsigned column) -> unsigned; diff --git a/hiro/gtk/widget/tab-frame.cpp b/hiro/gtk/widget/tab-frame.cpp index a00a1064..ffc12a9d 100644 --- a/hiro/gtk/widget/tab-frame.cpp +++ b/hiro/gtk/widget/tab-frame.cpp @@ -125,9 +125,9 @@ auto pTabFrame::remove(sTabFrameItem item) -> void { //the new tab will be the one after this one unsigned displacement = 1; //... unless it's the last tab, in which case it's the one before it - if(item->offset() == self().items() - 1) displacement = -1; + if(item->offset() == self().itemCount() - 1) displacement = -1; //... unless there are no tabs left, in which case nothing is selected - if(self().items() > 1) { + if(self().itemCount() > 1) { setItemSelected(item->offset() + displacement); } } diff --git a/hiro/qt/action/action.cpp b/hiro/qt/action/action.cpp index e2358ab4..945679ee 100644 --- a/hiro/qt/action/action.cpp +++ b/hiro/qt/action/action.cpp @@ -1,6 +1,15 @@ -namespace phoenix { +#if defined(Hiro_Action) -void pAction::setEnabled(bool enabled) { +namespace hiro { + +auto pAction::construct() -> void { +} + +auto pAction::destruct() -> void { +} + +auto pAction::setEnabled(bool enabled) -> void { +/* if(dynamic_cast(&action)) { ((Menu&)action).p.qtMenu->setEnabled(enabled); } else if(dynamic_cast(&action)) { @@ -12,9 +21,11 @@ void pAction::setEnabled(bool enabled) { } else if(dynamic_cast(&action)) { ((RadioItem&)action).p.qtAction->setEnabled(enabled); } +*/ } -void pAction::setFont(string font) { +auto pAction::setFont(const string& font) -> void { +/* QFont qtFont = pFont::create(font); if(dynamic_cast(&action)) { @@ -28,9 +39,11 @@ void pAction::setFont(string font) { } else if(dynamic_cast(&action)) { ((RadioItem&)action).p.qtAction->setFont(qtFont); } +*/ } -void pAction::setVisible(bool visible) { +auto pAction::setVisible(bool visible) -> void { +/* if(dynamic_cast(&action)) { ((Menu&)action).p.qtMenu->menuAction()->setVisible(visible); } else if(dynamic_cast(&action)) { @@ -42,12 +55,33 @@ void pAction::setVisible(bool visible) { } else if(dynamic_cast(&action)) { ((RadioItem&)action).p.qtAction->setVisible(visible); } +*/ } -void pAction::constructor() { +auto pAction::_parentMenu() -> maybe { + if(auto parent = self().parentMenu()) { + if(auto self = parent->self()) return *self; + } + return nothing; } -void pAction::destructor() { +auto pAction::_parentMenuBar() -> maybe { + if(auto parent = self().parentMenuBar()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pAction::_parentPopupMenu() -> maybe { + if(auto parent = self().parentPopupMenu()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pAction::_setState() -> void { } } + +#endif diff --git a/hiro/qt/action/action.hpp b/hiro/qt/action/action.hpp new file mode 100644 index 00000000..8b9d302c --- /dev/null +++ b/hiro/qt/action/action.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_Action) + +namespace hiro { + +struct pAction : pObject { + Declare(Action, Object) + + auto setEnabled(bool enabled) -> void override; + auto setFont(const string& font) -> void override; + auto setVisible(bool visible) -> void override; + + auto _parentMenu() -> maybe; + auto _parentMenuBar() -> maybe; + auto _parentPopupMenu() -> maybe; + virtual auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/action/check-item.cpp b/hiro/qt/action/check-item.cpp deleted file mode 100644 index 0a4daa94..00000000 --- a/hiro/qt/action/check-item.cpp +++ /dev/null @@ -1,28 +0,0 @@ -namespace phoenix { - -void pCheckItem::setChecked(bool checked) { - qtAction->setChecked(checked); -} - -void pCheckItem::setText(string text) { - qtAction->setText(QString::fromUtf8(text)); -} - -void pCheckItem::constructor() { - qtAction = new QAction(0); - qtAction->setCheckable(true); - connect(qtAction, SIGNAL(triggered()), SLOT(onToggle())); -} - -void pCheckItem::destructor() { - if(action.state.menu) action.state.menu->remove(checkItem); - delete qtAction; - qtAction = nullptr; -} - -void pCheckItem::onToggle() { - checkItem.state.checked = qtAction->isChecked(); - if(checkItem.onToggle) checkItem.onToggle(); -} - -} diff --git a/hiro/qt/action/item.cpp b/hiro/qt/action/item.cpp deleted file mode 100644 index 2eeba6ea..00000000 --- a/hiro/qt/action/item.cpp +++ /dev/null @@ -1,26 +0,0 @@ -namespace phoenix { - -void pItem::setImage(const image& image) { - qtAction->setIcon(CreateIcon(image)); -} - -void pItem::setText(string text) { - qtAction->setText(QString::fromUtf8(text)); -} - -void pItem::constructor() { - qtAction = new QAction(0); - connect(qtAction, SIGNAL(triggered()), SLOT(onActivate())); -} - -void pItem::destructor() { - if(action.state.menu) action.state.menu->remove(item); - delete qtAction; - qtAction = nullptr; -} - -void pItem::onActivate() { - if(item.onActivate) item.onActivate(); -} - -} diff --git a/hiro/qt/action/menu-check-item.cpp b/hiro/qt/action/menu-check-item.cpp new file mode 100644 index 00000000..98a39d70 --- /dev/null +++ b/hiro/qt/action/menu-check-item.cpp @@ -0,0 +1,46 @@ +#if defined(Hiro_MenuCheckItem) + +namespace hiro { + +auto pMenuCheckItem::construct() -> void { + qtMenuCheckItem = new QtMenuCheckItem(*this); + qtMenuCheckItem->setCheckable(true); + qtMenuCheckItem->connect(qtMenuCheckItem, SIGNAL(triggered()), SLOT(onToggle())); + + if(auto parent = _parentMenu()) { + parent->qtMenu->addAction(qtMenuCheckItem); + } + + if(auto parent = _parentPopupMenu()) { + parent->qtPopupMenu->addAction(qtMenuCheckItem); + } + + _setState(); +} + +auto pMenuCheckItem::destruct() -> void { + delete qtMenuCheckItem; + qtMenuCheckItem = nullptr; +} + +auto pMenuCheckItem::setChecked(bool checked) -> void { + _setState(); +} + +auto pMenuCheckItem::setText(const string& text) -> void { + _setState(); +} + +auto pMenuCheckItem::_setState() -> void { + qtMenuCheckItem->setChecked(state().checked); + qtMenuCheckItem->setText(QString::fromUtf8(state().text)); +} + +auto QtMenuCheckItem::onToggle() -> void { + p.state().checked = isChecked(); + p.self().doToggle(); +} + +} + +#endif diff --git a/hiro/qt/action/menu-check-item.hpp b/hiro/qt/action/menu-check-item.hpp new file mode 100644 index 00000000..649dadbe --- /dev/null +++ b/hiro/qt/action/menu-check-item.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_MenuCheckItem) + +namespace hiro { + +struct pMenuCheckItem : pAction { + Declare(MenuCheckItem, Action) + + auto setChecked(bool checked) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void override; + + QtMenuCheckItem* qtMenuCheckItem = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/action/menu-item.cpp b/hiro/qt/action/menu-item.cpp new file mode 100644 index 00000000..18dc5cfd --- /dev/null +++ b/hiro/qt/action/menu-item.cpp @@ -0,0 +1,44 @@ +#if defined(Hiro_MenuItem) + +namespace hiro { + +auto pMenuItem::construct() -> void { + qtMenuItem = new QtMenuItem(*this); + qtMenuItem->connect(qtMenuItem, SIGNAL(triggered()), SLOT(onActivate())); + + if(auto parent = _parentMenu()) { + parent->qtMenu->addAction(qtMenuItem); + } + + if(auto parent = _parentPopupMenu()) { + parent->qtPopupMenu->addAction(qtMenuItem); + } + + _setState(); +} + +auto pMenuItem::destruct() -> void { + delete qtMenuItem; + qtMenuItem = nullptr; +} + +auto pMenuItem::setIcon(const image& icon) -> void { + _setState(); +} + +auto pMenuItem::setText(const string& text) -> void { + _setState(); +} + +auto pMenuItem::_setState() -> void { + qtMenuItem->setIcon(CreateIcon(state().icon)); + qtMenuItem->setText(state().text); +} + +auto QtMenuItem::onActivate() -> void { + p.self().doActivate(); +} + +} + +#endif diff --git a/hiro/qt/action/menu-item.hpp b/hiro/qt/action/menu-item.hpp new file mode 100644 index 00000000..35d815f7 --- /dev/null +++ b/hiro/qt/action/menu-item.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_MenuItem) + +namespace hiro { + +struct pMenuItem : pAction { + Declare(MenuItem, Action) + + auto setIcon(const image& icon) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void override; + + QtMenuItem* qtMenuItem = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/action/menu-radio-item.cpp b/hiro/qt/action/menu-radio-item.cpp new file mode 100644 index 00000000..a3cf8f16 --- /dev/null +++ b/hiro/qt/action/menu-radio-item.cpp @@ -0,0 +1,65 @@ +#if defined(Hiro_MenuRadioItem) + +namespace hiro { + +auto pMenuRadioItem::construct() -> void { + qtMenuRadioItem = new QtMenuRadioItem(*this); + qtActionGroup = new QActionGroup(nullptr); + qtMenuRadioItem->setCheckable(true); + qtMenuRadioItem->setActionGroup(qtActionGroup); + qtMenuRadioItem->setChecked(true); + qtMenuRadioItem->connect(qtMenuRadioItem, SIGNAL(triggered()), SLOT(onActivate())); + + if(auto parent = _parentMenu()) { + parent->qtMenu->addAction(qtMenuRadioItem); + } + + if(auto parent = _parentPopupMenu()) { + parent->qtPopupMenu->addAction(qtMenuRadioItem); + } + + _setState(); +} + +auto pMenuRadioItem::destruct() -> void { + delete qtMenuRadioItem; + delete qtActionGroup; + qtMenuRadioItem = nullptr; + qtActionGroup = nullptr; +} + +auto pMenuRadioItem::setChecked() -> void { + _setState(); +} + +auto pMenuRadioItem::setGroup(sGroup group) -> void { + _setState(); +} + +auto pMenuRadioItem::setText(const string& text) -> void { + _setState(); +} + +auto pMenuRadioItem::_setState() -> void { + if(auto group = state().group) { + if(auto object = group->object(0)) { + if(auto menuRadioItem = dynamic_cast(object.data())) { + if(auto self = menuRadioItem->self()) { + qtMenuRadioItem->setActionGroup(self->qtActionGroup); + } + } + } + } + qtMenuRadioItem->setChecked(state().checked); + qtMenuRadioItem->setText(QString::fromUtf8(state().text)); +} + +auto QtMenuRadioItem::onActivate() -> void { + if(p.state().checked) return; + p.state().checked = true; + p.self().doActivate(); +} + +} + +#endif diff --git a/hiro/qt/action/menu-radio-item.hpp b/hiro/qt/action/menu-radio-item.hpp new file mode 100644 index 00000000..58af8412 --- /dev/null +++ b/hiro/qt/action/menu-radio-item.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_MenuRadioItem) + +namespace hiro { + +struct pMenuRadioItem : pAction { + Declare(MenuRadioItem, Action) + + auto setChecked() -> void; + auto setGroup(sGroup group) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void override; + + QtMenuRadioItem* qtMenuRadioItem = nullptr; + QActionGroup* qtActionGroup = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/action/menu-separator.cpp b/hiro/qt/action/menu-separator.cpp new file mode 100644 index 00000000..099e9421 --- /dev/null +++ b/hiro/qt/action/menu-separator.cpp @@ -0,0 +1,25 @@ +#if defined(Hiro_MenuSeparator) + +namespace hiro { + +auto pMenuSeparator::construct() -> void { + qtMenuSeparator = new QAction(nullptr); + qtMenuSeparator->setSeparator(true); + + if(auto parent = _parentMenu()) { + parent->qtMenu->addAction(qtMenuSeparator); + } + + if(auto parent = _parentPopupMenu()) { + parent->qtPopupMenu->addAction(qtMenuSeparator); + } +} + +auto pMenuSeparator::destruct() -> void { + delete qtMenuSeparator; + qtMenuSeparator = nullptr; +} + +} + +#endif diff --git a/hiro/qt/action/menu-separator.hpp b/hiro/qt/action/menu-separator.hpp new file mode 100644 index 00000000..afcb1ef4 --- /dev/null +++ b/hiro/qt/action/menu-separator.hpp @@ -0,0 +1,13 @@ +#if defined(Hiro_MenuSeparator) + +namespace hiro { + +struct pMenuSeparator : pAction { + Declare(MenuSeparator, Action) + + QAction* qtMenuSeparator = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/action/menu.cpp b/hiro/qt/action/menu.cpp index 0b258fa3..17f0b345 100644 --- a/hiro/qt/action/menu.cpp +++ b/hiro/qt/action/menu.cpp @@ -1,56 +1,60 @@ -namespace phoenix { +#if defined(Hiro_Menu) -void pMenu::append(Action& action) { - if(dynamic_cast(&action)) { - qtMenu->addMenu(((Menu&)action).p.qtMenu); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((Separator&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((Item&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((CheckItem&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((RadioItem&)action).p.qtAction); - } -} +namespace hiro { -void pMenu::remove(Action& action) { - if(dynamic_cast(&action)) { - //QMenu::removeMenu() does not exist - qtMenu->clear(); - for(auto& action : menu.state.action) append(action); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((Separator&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((Item&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((CheckItem&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((CheckItem&)action).p.qtAction); - } -} - -void pMenu::setFont(string font) { - qtMenu->setFont(pFont::create(font)); - for(auto &item : menu.state.action) item.p.setFont(font); -} - -void pMenu::setImage(const image& image) { - qtMenu->setIcon(CreateIcon(image)); -} - -void pMenu::setText(string text) { - qtMenu->setTitle(QString::fromUtf8(text)); -} - -void pMenu::constructor() { +auto pMenu::construct() -> void { qtMenu = new QMenu; + + if(auto parent = _parentMenu()) { + parent->qtMenu->addMenu(qtMenu); + } + + if(auto parent = _parentMenuBar()) { + if(auto window = parent->_parent()) { + window->qtMenuBar->addMenu(qtMenu); + } + } + + if(auto parent = _parentPopupMenu()) { + parent->qtPopupMenu->addMenu(qtMenu); + } + + _setState(); } -void pMenu::destructor() { - if(action.state.menu) action.state.menu->remove(menu); +auto pMenu::destruct() -> void { delete qtMenu; qtMenu = nullptr; } +auto pMenu::append(sAction action) -> void { } + +auto pMenu::remove(sAction action) -> void { +} + +auto pMenu::setFont(const string& font) -> void { + _setState(); +} + +auto pMenu::setIcon(const image& icon) -> void { + _setState(); +} + +auto pMenu::setText(const string& text) -> void { + _setState(); +} + +auto pMenu::_setState() -> void { + qtMenu->setFont(pFont::create(self().font(true))); + qtMenu->setIcon(CreateIcon(state().icon)); + qtMenu->setTitle(QString::fromUtf8(state().text)); + + for(auto& action : state().actions) { + if(auto self = action->self()) self->setFont(action->font(true)); + } +} + +} + +#endif diff --git a/hiro/qt/action/menu.hpp b/hiro/qt/action/menu.hpp new file mode 100644 index 00000000..79efa66c --- /dev/null +++ b/hiro/qt/action/menu.hpp @@ -0,0 +1,21 @@ +#if defined(Hiro_Menu) + +namespace hiro { + +struct pMenu : public pAction { + Declare(Menu, Action) + + auto append(sAction action) -> void; + auto remove(sAction action) -> void; + auto setFont(const string& font) -> void override; + auto setIcon(const image& icon) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void override; + + QMenu* qtMenu = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/action/radio-item.cpp b/hiro/qt/action/radio-item.cpp deleted file mode 100644 index 0dc16084..00000000 --- a/hiro/qt/action/radio-item.cpp +++ /dev/null @@ -1,42 +0,0 @@ -namespace phoenix { - -void pRadioItem::setChecked() { - lock(); - for(auto& item : radioItem.state.group) { - bool checkState = item.p.qtAction == qtAction; - item.state.checked = checkState; - item.p.qtAction->setChecked(checkState); - } - unlock(); -} - -void pRadioItem::setGroup(const group& group) { -} - -void pRadioItem::setText(string text) { - qtAction->setText(QString::fromUtf8(text)); -} - -void pRadioItem::constructor() { - qtAction = new QAction(0); - qtGroup = new QActionGroup(0); - qtAction->setCheckable(true); - qtAction->setActionGroup(qtGroup); - qtAction->setChecked(true); - connect(qtAction, SIGNAL(triggered()), SLOT(onActivate())); -} - -void pRadioItem::destructor() { - if(action.state.menu) action.state.menu->remove(radioItem); - delete qtAction; - qtAction = nullptr; -} - -void pRadioItem::onActivate() { - if(!radioItem.state.checked) { - setChecked(); - if(!locked() && radioItem.onActivate) radioItem.onActivate(); - } -} - -} diff --git a/hiro/qt/action/separator.cpp b/hiro/qt/action/separator.cpp deleted file mode 100644 index b871bbae..00000000 --- a/hiro/qt/action/separator.cpp +++ /dev/null @@ -1,14 +0,0 @@ -namespace phoenix { - -void pSeparator::constructor() { - qtAction = new QAction(0); - qtAction->setSeparator(true); -} - -void pSeparator::destructor() { - if(action.state.menu) action.state.menu->remove(separator); - delete qtAction; - qtAction = nullptr; -} - -} diff --git a/hiro/qt/application.cpp b/hiro/qt/application.cpp index 8a723dc0..fc09378e 100644 --- a/hiro/qt/application.cpp +++ b/hiro/qt/application.cpp @@ -1,41 +1,44 @@ -namespace phoenix { +#if defined(Hiro_Application) + +namespace hiro { XlibDisplay* pApplication::display = nullptr; -void pApplication::run() { - if(Application::main) { - while(applicationState.quit == false) { +auto pApplication::run() -> void { + if(Application::state.onMain) { + while(!Application::state.quit) { + Application::doMain(); processEvents(); - Application::main(); } } else { QApplication::exec(); } } -bool pApplication::pendingEvents() { +auto pApplication::pendingEvents() -> bool { return QApplication::hasPendingEvents(); } -void pApplication::processEvents() { +auto pApplication::processEvents() -> void { while(pendingEvents()) QApplication::processEvents(); } -void pApplication::quit() { +auto pApplication::quit() -> void { QApplication::quit(); - //note: QApplication cannot be deleted; or libQtGui will crash - qtApplication = nullptr; + qtApplication = nullptr; //note: deleting QApplication will crash libQtGui } -void pApplication::syncX() { - for(unsigned n = 0; n < 8; n++) { +//this is sadly necessary for things like determining window frame geometry +//obviously, it is used as sparingly as possible +auto pApplication::syncX() -> void { + for(auto n : range(8)) { QApplication::syncX(); Application::processEvents(); usleep(2000); } } -void pApplication::initialize() { +auto pApplication::initialize() -> void { display = XOpenDisplay(0); settings = new Settings; @@ -43,7 +46,7 @@ void pApplication::initialize() { static int argc = 1; static char* argv[] = {new char[8], nullptr}; - strcpy(argv[0], "phoenix"); + strcpy(argv[0], "hiro"); char** argvp = argv; qtApplication = new QApplication(argc, argvp); @@ -52,3 +55,5 @@ void pApplication::initialize() { } } + +#endif diff --git a/hiro/qt/application.hpp b/hiro/qt/application.hpp new file mode 100644 index 00000000..3789df7b --- /dev/null +++ b/hiro/qt/application.hpp @@ -0,0 +1,21 @@ +#if defined(Hiro_Application) + +namespace hiro { + +struct pApplication { + static auto run() -> void; + static auto pendingEvents() -> bool; + static auto processEvents() -> void; + static auto quit() -> void; + + static auto initialize() -> void; + static auto syncX() -> void; + + static XlibDisplay* display; +}; + +static QApplication* qtApplication = nullptr; + +} + +#endif diff --git a/hiro/qt/browser-window.cpp b/hiro/qt/browser-window.cpp index 0b25cf6b..62329829 100644 --- a/hiro/qt/browser-window.cpp +++ b/hiro/qt/browser-window.cpp @@ -1,6 +1,9 @@ -namespace phoenix { +#if defined(Hiro_BrowserWindow) -string pBrowserWindow::directory(BrowserWindow::State& state) { +namespace hiro { + +auto pBrowserWindow::directory(BrowserWindow::State& state) -> string { +/* QString directory = QFileDialog::getExistingDirectory( state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : "Select Directory", @@ -9,9 +12,11 @@ string pBrowserWindow::directory(BrowserWindow::State& state) { string name = directory.toUtf8().constData(); if(name && name.endsWith("/") == false) name.append("/"); return name; +*/ } -string pBrowserWindow::open(BrowserWindow::State& state) { +auto pBrowserWindow::open(BrowserWindow::State& state) -> string { +/* string filters = state.filters.merge(";;"); //convert filter list from phoenix to Qt format, example: @@ -29,9 +34,11 @@ string pBrowserWindow::open(BrowserWindow::State& state) { QString::fromUtf8(state.path), QString::fromUtf8(filters) ); return filename.toUtf8().constData(); +*/ } -string pBrowserWindow::save(BrowserWindow::State& state) { +auto pBrowserWindow::save(BrowserWindow::State& state) -> string { +/* string filters = state.filters.merge(";;"); //convert filter list from phoenix to Qt format, example: @@ -49,6 +56,9 @@ string pBrowserWindow::save(BrowserWindow::State& state) { QString::fromUtf8(state.path), QString::fromUtf8(filters) ); return filename.toUtf8().constData(); +*/ } } + +#endif diff --git a/hiro/qt/browser-window.hpp b/hiro/qt/browser-window.hpp new file mode 100644 index 00000000..80e561b1 --- /dev/null +++ b/hiro/qt/browser-window.hpp @@ -0,0 +1,13 @@ +#if defined(Hiro_BrowserWindow) + +namespace hiro { + +struct pBrowserWindow { + static auto directory(BrowserWindow::State& state) -> string; + static auto open(BrowserWindow::State& state) -> string; + static auto save(BrowserWindow::State& state) -> string; +}; + +} + +#endif diff --git a/hiro/qt/desktop.cpp b/hiro/qt/desktop.cpp index 14106e58..8cc83628 100644 --- a/hiro/qt/desktop.cpp +++ b/hiro/qt/desktop.cpp @@ -1,13 +1,17 @@ -namespace phoenix { +#if defined(Hiro_Desktop) -Size pDesktop::size() { +namespace hiro { + +auto pDesktop::size() -> Size { QRect rect = QApplication::desktop()->screenGeometry(); return {rect.width(), rect.height()}; } -Geometry pDesktop::workspace() { +auto pDesktop::workspace() -> Geometry { QRect rect = QApplication::desktop()->availableGeometry(); return {rect.x(), rect.y(), rect.width(), rect.height()}; } } + +#endif diff --git a/hiro/qt/desktop.hpp b/hiro/qt/desktop.hpp new file mode 100644 index 00000000..2c179b61 --- /dev/null +++ b/hiro/qt/desktop.hpp @@ -0,0 +1,12 @@ +#if defined(Hiro_Desktop) + +namespace hiro { + +struct pDesktop { + static auto size() -> Size; + static auto workspace() -> Geometry; +}; + +} + +#endif diff --git a/hiro/qt/font.cpp b/hiro/qt/font.cpp index ab964054..fcdf26e5 100644 --- a/hiro/qt/font.cpp +++ b/hiro/qt/font.cpp @@ -1,28 +1,30 @@ -namespace phoenix { +#if defined(Hiro_Font) -string pFont::serif(unsigned size, string style) { +namespace hiro { + +auto pFont::serif(unsigned size, string style) -> string { if(size == 0) size = 8; if(style == "") style = "Normal"; return {"Serif, ", size, ", ", style}; } -string pFont::sans(unsigned size, string style) { +auto pFont::sans(unsigned size, string style) -> string { if(size == 0) size = 8; if(style == "") style = "Normal"; return {"Sans, ", size, ", ", style}; } -string pFont::monospace(unsigned size, string style) { +auto pFont::monospace(unsigned size, string style) -> string { if(size == 0) size = 8; if(style == "") style = "Normal"; return {"Liberation Mono, ", size, ", ", style}; } -Size pFont::size(string font, string text) { +auto pFont::size(string font, string text) -> Size { return pFont::size(pFont::create(font), text); } -QFont pFont::create(string description) { +auto pFont::create(string description) -> QFont { lstring part = description.split(",", 2L).strip(); string family = "Sans"; @@ -43,18 +45,20 @@ QFont pFont::create(string description) { return qtFont; } -Size pFont::size(const QFont& qtFont, string text) { +auto pFont::size(const QFont& qtFont, const string& text) -> Size { QFontMetrics metrics(qtFont); lstring lines; - lines.split("\n", text); + lines.split("\n", text ? text : " "); unsigned maxWidth = 0; for(auto& line : lines) { maxWidth = max(maxWidth, metrics.width(line)); } - return {maxWidth, metrics.height() * lines.size()}; + return Size().setWidth(maxWidth).setHeight(metrics.height() * lines.size()); } } + +#endif diff --git a/hiro/qt/font.hpp b/hiro/qt/font.hpp new file mode 100644 index 00000000..7928d775 --- /dev/null +++ b/hiro/qt/font.hpp @@ -0,0 +1,17 @@ +#if defined(Hiro_Font) + +namespace hiro { + +struct pFont { + static auto serif(unsigned size, string style) -> string; + static auto sans(unsigned size, string style) -> string; + static auto monospace(unsigned size, string style) -> string; + static auto size(string font, string text) -> Size; + + static auto create(string description) -> QFont; + static auto size(const QFont& qtFont, const string& text) -> Size; +}; + +} + +#endif diff --git a/hiro/qt/group.cpp b/hiro/qt/group.cpp new file mode 100644 index 00000000..cbf387ff --- /dev/null +++ b/hiro/qt/group.cpp @@ -0,0 +1,13 @@ +#if defined(Hiro_Group) + +namespace hiro { + +auto pGroup::construct() -> void { +} + +auto pGroup::destruct() -> void { +} + +} + +#endif diff --git a/hiro/qt/group.hpp b/hiro/qt/group.hpp new file mode 100644 index 00000000..a2ac6d72 --- /dev/null +++ b/hiro/qt/group.hpp @@ -0,0 +1,11 @@ +#if defined(Hiro_Group) + +namespace hiro { + +struct pGroup : pObject { + Declare(Group, Object) +}; + +} + +#endif diff --git a/hiro/qt/hotkey.cpp b/hiro/qt/hotkey.cpp new file mode 100644 index 00000000..608ba7bb --- /dev/null +++ b/hiro/qt/hotkey.cpp @@ -0,0 +1,13 @@ +#if defined(Hiro_Hotkey) + +namespace hiro { + +auto pHotkey::construct() -> void { +} + +auto pHotkey::destruct() -> void { +} + +} + +#endif diff --git a/hiro/qt/hotkey.hpp b/hiro/qt/hotkey.hpp new file mode 100644 index 00000000..b1caa7bc --- /dev/null +++ b/hiro/qt/hotkey.hpp @@ -0,0 +1,11 @@ +#if defined(Hiro_Hotkey) + +namespace hiro { + +struct pHotkey : pObject { + Declare(Hotkey, Object) +}; + +} + +#endif diff --git a/hiro/qt/keyboard.cpp b/hiro/qt/keyboard.cpp index 17821076..2dad0af7 100644 --- a/hiro/qt/keyboard.cpp +++ b/hiro/qt/keyboard.cpp @@ -1,149 +1,47 @@ -namespace phoenix { +#if defined(Hiro_Keyboard) -void pKeyboard::initialize() { - auto append = [](Keyboard::Scancode scancode, unsigned keysym) { - settings->keymap.insert(scancode, XKeysymToKeycode(pApplication::display, keysym)); - }; +namespace hiro { - append(Keyboard::Scancode::Escape, XK_Escape); - append(Keyboard::Scancode::F1, XK_F1); - append(Keyboard::Scancode::F2, XK_F2); - append(Keyboard::Scancode::F3, XK_F3); - append(Keyboard::Scancode::F4, XK_F4); - append(Keyboard::Scancode::F5, XK_F5); - append(Keyboard::Scancode::F6, XK_F6); - append(Keyboard::Scancode::F7, XK_F7); - append(Keyboard::Scancode::F8, XK_F8); - append(Keyboard::Scancode::F9, XK_F9); - append(Keyboard::Scancode::F10, XK_F10); - append(Keyboard::Scancode::F11, XK_F11); - append(Keyboard::Scancode::F12, XK_F12); - - append(Keyboard::Scancode::PrintScreen, XK_Print); - append(Keyboard::Scancode::ScrollLock, XK_Scroll_Lock); - append(Keyboard::Scancode::Pause, XK_Pause); - - append(Keyboard::Scancode::Insert, XK_Insert); - append(Keyboard::Scancode::Delete, XK_Delete); - append(Keyboard::Scancode::Home, XK_Home); - append(Keyboard::Scancode::End, XK_End); - append(Keyboard::Scancode::PageUp, XK_Prior); - append(Keyboard::Scancode::PageDown, XK_Next); - - append(Keyboard::Scancode::Up, XK_Up); - append(Keyboard::Scancode::Down, XK_Down); - append(Keyboard::Scancode::Left, XK_Left); - append(Keyboard::Scancode::Right, XK_Right); - - append(Keyboard::Scancode::Grave, XK_asciitilde); - append(Keyboard::Scancode::Number1, XK_1); - append(Keyboard::Scancode::Number2, XK_2); - append(Keyboard::Scancode::Number3, XK_3); - append(Keyboard::Scancode::Number4, XK_4); - append(Keyboard::Scancode::Number5, XK_5); - append(Keyboard::Scancode::Number6, XK_6); - append(Keyboard::Scancode::Number7, XK_7); - append(Keyboard::Scancode::Number8, XK_8); - append(Keyboard::Scancode::Number9, XK_9); - append(Keyboard::Scancode::Number0, XK_0); - append(Keyboard::Scancode::Minus, XK_minus); - append(Keyboard::Scancode::Equal, XK_equal); - append(Keyboard::Scancode::Backspace, XK_BackSpace); - - append(Keyboard::Scancode::BracketLeft, XK_bracketleft); - append(Keyboard::Scancode::BracketRight, XK_bracketright); - append(Keyboard::Scancode::Backslash, XK_backslash); - append(Keyboard::Scancode::Semicolon, XK_semicolon); - append(Keyboard::Scancode::Apostrophe, XK_apostrophe); - append(Keyboard::Scancode::Comma, XK_comma); - append(Keyboard::Scancode::Period, XK_period); - append(Keyboard::Scancode::Slash, XK_slash); - - append(Keyboard::Scancode::Tab, XK_Tab); - append(Keyboard::Scancode::CapsLock, XK_Caps_Lock); - append(Keyboard::Scancode::Return, XK_Return); - append(Keyboard::Scancode::ShiftLeft, XK_Shift_L); - append(Keyboard::Scancode::ShiftRight, XK_Shift_R); - append(Keyboard::Scancode::ControlLeft, XK_Control_L); - append(Keyboard::Scancode::ControlRight, XK_Control_R); - append(Keyboard::Scancode::SuperLeft, XK_Super_L); - append(Keyboard::Scancode::SuperRight, XK_Super_R); - append(Keyboard::Scancode::AltLeft, XK_Alt_L); - append(Keyboard::Scancode::AltRight, XK_Alt_R); - append(Keyboard::Scancode::Space, XK_space); - append(Keyboard::Scancode::Menu, XK_Menu); - - append(Keyboard::Scancode::A, XK_A); - append(Keyboard::Scancode::B, XK_B); - append(Keyboard::Scancode::C, XK_C); - append(Keyboard::Scancode::D, XK_D); - append(Keyboard::Scancode::E, XK_E); - append(Keyboard::Scancode::F, XK_F); - append(Keyboard::Scancode::G, XK_G); - append(Keyboard::Scancode::H, XK_H); - append(Keyboard::Scancode::I, XK_I); - append(Keyboard::Scancode::J, XK_J); - append(Keyboard::Scancode::K, XK_K); - append(Keyboard::Scancode::L, XK_L); - append(Keyboard::Scancode::M, XK_M); - append(Keyboard::Scancode::N, XK_N); - append(Keyboard::Scancode::O, XK_O); - append(Keyboard::Scancode::P, XK_P); - append(Keyboard::Scancode::Q, XK_Q); - append(Keyboard::Scancode::R, XK_R); - append(Keyboard::Scancode::S, XK_S); - append(Keyboard::Scancode::T, XK_T); - append(Keyboard::Scancode::U, XK_U); - append(Keyboard::Scancode::V, XK_V); - append(Keyboard::Scancode::W, XK_W); - append(Keyboard::Scancode::X, XK_X); - append(Keyboard::Scancode::Y, XK_Y); - append(Keyboard::Scancode::Z, XK_Z); - - append(Keyboard::Scancode::NumLock, XK_Num_Lock); - append(Keyboard::Scancode::Divide, XK_KP_Divide); - append(Keyboard::Scancode::Multiply, XK_KP_Multiply); - append(Keyboard::Scancode::Subtract, XK_KP_Subtract); - append(Keyboard::Scancode::Add, XK_KP_Add); - append(Keyboard::Scancode::Enter, XK_KP_Enter); - append(Keyboard::Scancode::Point, XK_KP_Decimal); - - append(Keyboard::Scancode::Keypad1, XK_KP_1); - append(Keyboard::Scancode::Keypad2, XK_KP_2); - append(Keyboard::Scancode::Keypad3, XK_KP_3); - append(Keyboard::Scancode::Keypad4, XK_KP_4); - append(Keyboard::Scancode::Keypad5, XK_KP_5); - append(Keyboard::Scancode::Keypad6, XK_KP_6); - append(Keyboard::Scancode::Keypad7, XK_KP_7); - append(Keyboard::Scancode::Keypad8, XK_KP_8); - append(Keyboard::Scancode::Keypad9, XK_KP_9); - append(Keyboard::Scancode::Keypad0, XK_KP_0); -} - -bool pKeyboard::pressed(Keyboard::Scancode scancode) { +auto pKeyboard::poll() -> vector { + vector result; char state[256]; XQueryKeymap(pApplication::display, state); - if(auto result = settings->keymap.find(scancode)) { - unsigned id = result(); - return state[id >> 3] & (1 << (id & 7)); + for(auto& code : settings->keycodes) { + result.append(_pressed(state, code)); } + return result; +} + +auto pKeyboard::pressed(unsigned code) -> bool { + char state[256]; + XQueryKeymap(pApplication::display, state); + return _pressed(state, code); +} + +auto pKeyboard::_pressed(const char* state, uint16_t code) -> bool { + uint8_t lo = code >> 0; + uint8_t hi = code >> 8; + + if(lo && state[lo >> 3] & (1 << (lo & 7))) return true; + if(hi && state[hi >> 3] & (1 << (hi & 7))) return true; + return false; } -vector pKeyboard::state() { - vector output; - output.resize((unsigned)Keyboard::Scancode::Limit); - for(auto& n : output) n = false; +auto pKeyboard::initialize() -> void { + auto append = [](unsigned lo, unsigned hi = 0) { + lo = lo ? (uint8_t)XKeysymToKeycode(pApplication::display, lo) : 0; + hi = hi ? (uint8_t)XKeysymToKeycode(pApplication::display, hi) : 0; + settings->keycodes.append(lo << 0 | hi << 8); + }; - char state[256]; - XQueryKeymap(pApplication::display, state); - for(auto node : settings->keymap) { - if(state[node.value >> 3] & (1 << (node.value & 7))) { - output[(unsigned)node.key] = true; - } + #define map(name, ...) if(key == name) { append(__VA_ARGS__); continue; } + for(auto& key : Keyboard::keys) { + #include } - - return output; + #undef map } } + +#endif diff --git a/hiro/qt/keyboard.hpp b/hiro/qt/keyboard.hpp new file mode 100644 index 00000000..74fc69e4 --- /dev/null +++ b/hiro/qt/keyboard.hpp @@ -0,0 +1,16 @@ +#if defined(Hiro_Keyboard) + +namespace hiro { + +struct pKeyboard { + static auto poll() -> vector; + static auto pressed(unsigned code) -> bool; + + static auto _pressed(const char* state, uint16_t code) -> bool; + + static auto initialize() -> void; +}; + +} + +#endif diff --git a/hiro/qt/layout.cpp b/hiro/qt/layout.cpp new file mode 100644 index 00000000..d8b998a5 --- /dev/null +++ b/hiro/qt/layout.cpp @@ -0,0 +1,19 @@ +#if defined(Hiro_Layout) + +namespace hiro { + +auto pLayout::construct() -> void { +} + +auto pLayout::destruct() -> void { +} + +auto pLayout::setVisible(bool visible) -> void { + for(auto& sizable : state().sizables) { + if(auto self = sizable->self()) self->setVisible(sizable->visible(true)); + } +} + +} + +#endif diff --git a/hiro/qt/layout.hpp b/hiro/qt/layout.hpp new file mode 100644 index 00000000..ec8345b1 --- /dev/null +++ b/hiro/qt/layout.hpp @@ -0,0 +1,13 @@ +#if defined(Hiro_Layout) + +namespace hiro { + +struct pLayout : pSizable { + Declare(Layout, Sizable) + + auto setVisible(bool visible) -> void override; +}; + +} + +#endif diff --git a/hiro/qt/menu-bar.cpp b/hiro/qt/menu-bar.cpp new file mode 100644 index 00000000..979ff305 --- /dev/null +++ b/hiro/qt/menu-bar.cpp @@ -0,0 +1,46 @@ +#if defined(Hiro_MenuBar) + +namespace hiro { + +auto pMenuBar::construct() -> void { + _setState(); +} + +auto pMenuBar::destruct() -> void { +} + +auto pMenuBar::append(sMenu menu) -> void { +} + +auto pMenuBar::remove(sMenu menu) -> void { +} + +auto pMenuBar::setEnabled(bool enabled) -> void { + _setState(); +} + +auto pMenuBar::setFont(const string& font) -> void { + _setState(); +} + +auto pMenuBar::setVisible(bool visible) -> void { + _setState(); +} + +auto pMenuBar::_parent() -> maybe { + if(auto parent = self().parentWindow()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pMenuBar::_setState() -> void { + if(auto parent = _parent()) { + parent->qtMenuBar->setFont(pFont::create(self().font(true))); + parent->qtMenuBar->setVisible(self().visible()); + } +} + +} + +#endif diff --git a/hiro/qt/menu-bar.hpp b/hiro/qt/menu-bar.hpp new file mode 100644 index 00000000..ddf8bf05 --- /dev/null +++ b/hiro/qt/menu-bar.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_MenuBar) + +namespace hiro { + +struct pMenuBar : pObject { + Declare(MenuBar, Object) + + auto append(sMenu menu) -> void; + auto remove(sMenu menu) -> void; + auto setEnabled(bool enabled) -> void override; + auto setFont(const string& font) -> void override; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/message-window.cpp b/hiro/qt/message-window.cpp index c4ca6da3..f214b8ad 100644 --- a/hiro/qt/message-window.cpp +++ b/hiro/qt/message-window.cpp @@ -1,6 +1,8 @@ -namespace phoenix { +#if defined(Hiro_MessageWindow) -static QMessageBox::StandardButtons MessageWindow_buttons(MessageWindow::Buttons buttons) { +namespace hiro { + +static auto MessageWindow_buttons(MessageWindow::Buttons buttons) -> QMessageBox::StandardButtons { QMessageBox::StandardButtons standardButtons = QMessageBox::NoButton; if(buttons == MessageWindow::Buttons::Ok) standardButtons = QMessageBox::Ok; if(buttons == MessageWindow::Buttons::OkCancel) standardButtons = QMessageBox::Ok | QMessageBox::Cancel; @@ -9,7 +11,7 @@ static QMessageBox::StandardButtons MessageWindow_buttons(MessageWindow::Buttons return standardButtons; } -static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons buttons, QMessageBox::StandardButton response) { +static auto MessageWindow_response(MessageWindow::Buttons buttons, QMessageBox::StandardButton response) -> MessageWindow::Response { if(response == QMessageBox::Ok) return MessageWindow::Response::Ok; if(response == QMessageBox::Cancel) return MessageWindow::Response::Cancel; if(response == QMessageBox::Yes) return MessageWindow::Response::Yes; @@ -24,32 +26,34 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but throw; } -MessageWindow::Response pMessageWindow::error(MessageWindow::State& state) { - return MessageWindow_response( - state.buttons, QMessageBox::critical(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", - QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) - ); +auto pMessageWindow::error(MessageWindow::State& state) -> MessageWindow::Response { +// return MessageWindow_response( +// state.buttons, QMessageBox::critical(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", +// QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) +// ); } -MessageWindow::Response pMessageWindow::information(MessageWindow::State& state) { - return MessageWindow_response( - state.buttons, QMessageBox::information(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", - QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) - ); +auto pMessageWindow::information(MessageWindow::State& state) -> MessageWindow::Response { +// return MessageWindow_response( +// state.buttons, QMessageBox::information(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", +// QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) +// ); } -MessageWindow::Response pMessageWindow::question(MessageWindow::State& state) { - return MessageWindow_response( - state.buttons, QMessageBox::question(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", - QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) - ); +auto pMessageWindow::question(MessageWindow::State& state) -> MessageWindow::Response { +// return MessageWindow_response( +// state.buttons, QMessageBox::question(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", +// QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) +// ); } -MessageWindow::Response pMessageWindow::warning(MessageWindow::State& state) { - return MessageWindow_response( - state.buttons, QMessageBox::warning(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", - QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) - ); +auto pMessageWindow::warning(MessageWindow::State& state) -> MessageWindow::Response { +// return MessageWindow_response( +// state.buttons, QMessageBox::warning(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ", +// QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons)) +// ); } } + +#endif diff --git a/hiro/qt/message-window.hpp b/hiro/qt/message-window.hpp new file mode 100644 index 00000000..b8b26af5 --- /dev/null +++ b/hiro/qt/message-window.hpp @@ -0,0 +1,14 @@ +#if defined(Hiro_MessageWindow) + +namespace hiro { + +struct pMessageWindow { + static auto error(MessageWindow::State& state) -> MessageWindow::Response; + static auto information(MessageWindow::State& state) -> MessageWindow::Response; + static auto question(MessageWindow::State& state) -> MessageWindow::Response; + static auto warning(MessageWindow::State& state) -> MessageWindow::Response; +}; + +} + +#endif diff --git a/hiro/qt/monitor.cpp b/hiro/qt/monitor.cpp index 410b748a..a2774187 100644 --- a/hiro/qt/monitor.cpp +++ b/hiro/qt/monitor.cpp @@ -1,16 +1,20 @@ -namespace phoenix { +#if defined(Hiro_Monitor) -unsigned pMonitor::count() { +namespace hiro { + +auto pMonitor::count() -> unsigned { return QApplication::desktop()->screenCount(); } -Geometry pMonitor::geometry(unsigned monitor) { +auto pMonitor::geometry(unsigned monitor) -> Geometry { QRect rectangle = QApplication::desktop()->screenGeometry(monitor); return {rectangle.x(), rectangle.y(), rectangle.width(), rectangle.height()}; } -unsigned pMonitor::primary() { +auto pMonitor::primary() -> unsigned { return QApplication::desktop()->primaryScreen(); } } + +#endif diff --git a/hiro/qt/monitor.hpp b/hiro/qt/monitor.hpp new file mode 100644 index 00000000..2ec76265 --- /dev/null +++ b/hiro/qt/monitor.hpp @@ -0,0 +1,13 @@ +#if defined(Hiro_Monitor) + +namespace hiro { + +struct pMonitor { + static auto count() -> unsigned; + static auto geometry(unsigned monitor) -> Geometry; + static auto primary() -> unsigned; +}; + +} + +#endif diff --git a/hiro/qt/mouse.cpp b/hiro/qt/mouse.cpp index 169b5111..53cd8252 100644 --- a/hiro/qt/mouse.cpp +++ b/hiro/qt/mouse.cpp @@ -1,11 +1,13 @@ -namespace phoenix { +#if defined(Hiro_Mouse) -Position pMouse::position() { +namespace hiro { + +auto pMouse::position() -> Position { QPoint point = QCursor::pos(); return {point.x(), point.y()}; } -bool pMouse::pressed(Mouse::Button button) { +auto pMouse::pressed(Mouse::Button button) -> bool { Qt::MouseButtons buttons = QApplication::mouseButtons(); switch(button) { case Mouse::Button::Left: return buttons & Qt::LeftButton; @@ -16,3 +18,5 @@ bool pMouse::pressed(Mouse::Button button) { } } + +#endif diff --git a/hiro/qt/mouse.hpp b/hiro/qt/mouse.hpp new file mode 100644 index 00000000..72a56058 --- /dev/null +++ b/hiro/qt/mouse.hpp @@ -0,0 +1,12 @@ +#if defined(Hiro_Mouse) + +namespace hiro { + +struct pMouse { + static auto position() -> Position; + static auto pressed(Mouse::Button button) -> bool; +}; + +} + +#endif diff --git a/hiro/qt/object.cpp b/hiro/qt/object.cpp new file mode 100644 index 00000000..fae97d8c --- /dev/null +++ b/hiro/qt/object.cpp @@ -0,0 +1,35 @@ +#if defined(Hiro_Object) + +namespace hiro { + +auto pObject::construct() -> void { +} + +auto pObject::destruct() -> void { +} + +auto pObject::focused() const -> bool { + return false; +} + +auto pObject::remove() -> void { +} + +auto pObject::reset() -> void { +} + +auto pObject::setEnabled(bool enabled) -> void { +} + +auto pObject::setFocused() -> void { +} + +auto pObject::setFont(const string& font) -> void { +} + +auto pObject::setVisible(bool visible) -> void { +} + +} + +#endif diff --git a/hiro/qt/object.hpp b/hiro/qt/object.hpp new file mode 100644 index 00000000..5e198d81 --- /dev/null +++ b/hiro/qt/object.hpp @@ -0,0 +1,31 @@ +#if defined(Hiro_Object) + +namespace hiro { + +struct pObject { + pObject(mObject& reference) : reference(reference) {} + virtual ~pObject() {} + auto self() const -> mObject& { return (mObject&)reference; } + auto state() const -> mObject::State& { return self().state; } + virtual auto construct() -> void; + virtual auto destruct() -> void; + + virtual auto focused() const -> bool; + virtual auto remove() -> void; + virtual auto reset() -> void; + virtual auto setEnabled(bool enabled) -> void; + virtual auto setFocused() -> void; + virtual auto setFont(const string& font) -> void; + virtual auto setVisible(bool visible) -> void; + + auto locked() const -> bool { return locks != 0; } + auto lock() -> void { locks++; } + auto unlock() -> void { locks--; } + + mObject& reference; + signed locks = 0; +}; + +} + +#endif diff --git a/hiro/qt/platform.cpp b/hiro/qt/platform.cpp index 849bd5b4..aac1de03 100644 --- a/hiro/qt/platform.cpp +++ b/hiro/qt/platform.cpp @@ -1,26 +1,37 @@ -#include "platform.moc.hpp" -#include "platform.moc" +#include "qt.hpp" +#include "qt.moc" +#include "platform.hpp" #include "utility.cpp" #include "settings.cpp" +#include "font.cpp" #include "desktop.cpp" #include "monitor.cpp" #include "keyboard.cpp" #include "mouse.cpp" #include "browser-window.cpp" #include "message-window.cpp" -#include "font.cpp" + +#include "object.cpp" +#include "group.cpp" + +#include "hotkey.cpp" #include "timer.cpp" #include "window.cpp" +#include "status-bar.cpp" +#include "menu-bar.cpp" #include "popup-menu.cpp" #include "action/action.cpp" #include "action/menu.cpp" -#include "action/separator.cpp" -#include "action/item.cpp" -#include "action/check-item.cpp" -#include "action/radio-item.cpp" +#include "action/menu-separator.cpp" +#include "action/menu-item.cpp" +#include "action/menu-check-item.cpp" +#include "action/menu-radio-item.cpp" + +#include "sizable.cpp" +#include "layout.cpp" #include "widget/widget.cpp" #include "widget/button.cpp" @@ -28,6 +39,7 @@ #include "widget/check-button.cpp" #include "widget/check-label.cpp" #include "widget/combo-button.cpp" +#include "widget/combo-button-item.cpp" #include "widget/console.cpp" #include "widget/frame.cpp" #include "widget/hex-edit.cpp" @@ -37,10 +49,15 @@ #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/text-edit.cpp" #include "widget/vertical-scroller.cpp" #include "widget/vertical-slider.cpp" diff --git a/hiro/qt/platform.hpp b/hiro/qt/platform.hpp new file mode 100644 index 00000000..82c0226a --- /dev/null +++ b/hiro/qt/platform.hpp @@ -0,0 +1,137 @@ +#include "settings.hpp" + +#define Declare(Name, Base) \ + p##Name(m##Name& reference) : p##Base(reference) {} \ + auto self() const -> m##Name& { return (m##Name&)reference; } \ + auto state() const -> m##Name::State& { return self().state; } \ + auto construct() -> void override; \ + auto destruct() -> void override; \ + +#include "application.hpp" +#include "font.hpp" +#include "desktop.hpp" +#include "monitor.hpp" +#include "keyboard.hpp" +#include "mouse.hpp" +#include "browser-window.hpp" +#include "message-window.hpp" + +#include "object.hpp" +#include "group.hpp" + +#include "hotkey.hpp" +#include "timer.hpp" +#include "window.hpp" +#include "status-bar.hpp" +#include "menu-bar.hpp" +#include "popup-menu.hpp" + +#include "action/action.hpp" +#include "action/menu.hpp" +#include "action/menu-separator.hpp" +#include "action/menu-item.hpp" +#include "action/menu-check-item.hpp" +#include "action/menu-radio-item.hpp" + +#include "sizable.hpp" +#include "layout.hpp" + +#include "widget/widget.hpp" +#include "widget/button.hpp" +#include "widget/canvas.hpp" +#include "widget/check-button.hpp" +#include "widget/check-label.hpp" +#include "widget/combo-button.hpp" +#include "widget/combo-button-item.hpp" +#include "widget/frame.hpp" +#include "widget/hex-edit.hpp" +#include "widget/horizontal-scroller.hpp" +#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/text-edit.hpp" +#include "widget/vertical-scroller.hpp" +#include "widget/vertical-slider.hpp" +#include "widget/viewport.hpp" + +namespace hiro { + +#if defined(Hiro_Console) +struct pConsole : public QObject, public pWidget { + Q_OBJECT + +public: + Console& console; + struct QtConsole : public QTextEdit { + pConsole& self; + void keyPressEvent(QKeyEvent*); + void keyPressEventAcknowledge(QKeyEvent*); + QtConsole(pConsole& self) : self(self) {} + }; + QtConsole* qtConsole; + + void print(string text); + void reset(); + void setBackgroundColor(Color color); + void setForegroundColor(Color color); + void setPrompt(string prompt); + + pConsole(Console& console) : pWidget(console), console(console) {} + void constructor(); + void destructor(); + void orphan(); + void keyPressEvent(QKeyEvent*); +}; +#endif + +#if defined(Hiro_IconView) +struct pIconView : public QObject, public pWidget { + Q_OBJECT + +public: + IconView& iconView; + struct QtListWidget : public QListWidget { + void resizeEvent(QResizeEvent*); + }; + QtListWidget* qtIconView; + + void append(); + void remove(unsigned selection); + void reset(); + void setBackgroundColor(Color color); + void setFlow(Orientation flow); + void setForegroundColor(Color color); + void setImage(unsigned selection, const image& image); + void setOrientation(Orientation orientation); + void setSelected(unsigned selection, bool selected); + void setSelected(const vector& selections); + void setSelectedAll(); + void setSelectedNone(); + void setSingleSelection(bool singleSelection); + void setText(unsigned selection, const string& text); + + pIconView(IconView& iconView) : pWidget(iconView), iconView(iconView) {} + void constructor(); + void destructor(); + void orphan(); + +public slots: + void onActivate(); + void onChange(); + void onContext(); +}; +#endif + +#undef Declare + +} diff --git a/hiro/qt/platform.moc b/hiro/qt/platform.moc deleted file mode 100644 index 7ff83e9b..00000000 --- a/hiro/qt/platform.moc +++ /dev/null @@ -1,1816 +0,0 @@ -/**************************************************************************** -** Meta object code from reading C++ file 'platform.moc.hpp' -** -** Created by: The Qt Meta Object Compiler version 63 (Qt 4.8.5) -** -** WARNING! All changes made in this file will be lost! -*****************************************************************************/ - -#if !defined(Q_MOC_OUTPUT_REVISION) -#error "The header file 'platform.moc.hpp' doesn't include ." -#elif Q_MOC_OUTPUT_REVISION != 63 -#error "This file was generated using the moc from 4.8.5. It" -#error "cannot be used with the include files from this version of Qt." -#error "(The moc has changed too much.)" -#endif - -QT_BEGIN_MOC_NAMESPACE -static const uint qt_meta_data_phoenix__pTimer[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 16, 29, 29, 29, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pTimer[] = { - "phoenix::pTimer\0onActivate()\0\0" -}; - -void phoenix::pTimer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pTimer *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pTimer::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pTimer::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTimer, - qt_meta_data_phoenix__pTimer, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pTimer::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pTimer::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pTimer::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pTimer)) - return static_cast(const_cast< pTimer*>(this)); - if (!strcmp(_clname, "pObject")) - return static_cast< pObject*>(const_cast< pTimer*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pTimer::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pWindow[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 0, 0, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pWindow[] = { - "phoenix::pWindow\0" -}; - -void phoenix::pWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - Q_UNUSED(_o); - Q_UNUSED(_id); - Q_UNUSED(_c); - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pWindow::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pWindow::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pWindow, - qt_meta_data_phoenix__pWindow, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pWindow::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pWindow::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pWindow::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pWindow)) - return static_cast(const_cast< pWindow*>(this)); - if (!strcmp(_clname, "pObject")) - return static_cast< pObject*>(const_cast< pWindow*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - return _id; -} -static const uint qt_meta_data_phoenix__pItem[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 15, 28, 28, 28, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pItem[] = { - "phoenix::pItem\0onActivate()\0\0" -}; - -void phoenix::pItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pItem *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pItem::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pItem::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pItem, - qt_meta_data_phoenix__pItem, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pItem::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pItem::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pItem::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pItem)) - return static_cast(const_cast< pItem*>(this)); - if (!strcmp(_clname, "pAction")) - return static_cast< pAction*>(const_cast< pItem*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pCheckItem[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 20, 31, 31, 31, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pCheckItem[] = { - "phoenix::pCheckItem\0onToggle()\0\0" -}; - -void phoenix::pCheckItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pCheckItem *_t = static_cast(_o); - switch (_id) { - case 0: _t->onToggle(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pCheckItem::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pCheckItem::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckItem, - qt_meta_data_phoenix__pCheckItem, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pCheckItem::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pCheckItem::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pCheckItem::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pCheckItem)) - return static_cast(const_cast< pCheckItem*>(this)); - if (!strcmp(_clname, "pAction")) - return static_cast< pAction*>(const_cast< pCheckItem*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pCheckItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pRadioItem[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 20, 33, 33, 33, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pRadioItem[] = { - "phoenix::pRadioItem\0onActivate()\0\0" -}; - -void phoenix::pRadioItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pRadioItem *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pRadioItem::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pRadioItem::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioItem, - qt_meta_data_phoenix__pRadioItem, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pRadioItem::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pRadioItem::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pRadioItem::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pRadioItem)) - return static_cast(const_cast< pRadioItem*>(this)); - if (!strcmp(_clname, "pAction")) - return static_cast< pAction*>(const_cast< pRadioItem*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pRadioItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pButton[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 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, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pButton[] = { - "phoenix::pButton\0onActivate()\0\0" -}; - -void phoenix::pButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pButton *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pButton::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pButton::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pButton, - qt_meta_data_phoenix__pButton, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pButton::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pButton::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pButton::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pButton)) - return static_cast(const_cast< pButton*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pButton*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pCanvas[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 0, 0, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pCanvas[] = { - "phoenix::pCanvas\0" -}; - -void phoenix::pCanvas::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - Q_UNUSED(_o); - Q_UNUSED(_id); - Q_UNUSED(_c); - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pCanvas::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pCanvas::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCanvas, - qt_meta_data_phoenix__pCanvas, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pCanvas::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pCanvas::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pCanvas::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pCanvas)) - return static_cast(const_cast< pCanvas*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pCanvas*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pCanvas::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - return _id; -} -static const uint qt_meta_data_phoenix__pCheckButton[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 22, 37, 45, 45, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pCheckButton[] = { - "phoenix::pCheckButton\0onToggle(bool)\0" - "checked\0\0" -}; - -void phoenix::pCheckButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pCheckButton *_t = static_cast(_o); - switch (_id) { - case 0: _t->onToggle((*reinterpret_cast< bool(*)>(_a[1]))); break; - default: ; - } - } -} - -const QMetaObjectExtraData phoenix::pCheckButton::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pCheckButton::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckButton, - qt_meta_data_phoenix__pCheckButton, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pCheckButton::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pCheckButton::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pCheckButton::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pCheckButton)) - return static_cast(const_cast< pCheckButton*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pCheckButton*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pCheckLabel[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 21, 32, 32, 32, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pCheckLabel[] = { - "phoenix::pCheckLabel\0onToggle()\0\0" -}; - -void phoenix::pCheckLabel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pCheckLabel *_t = static_cast(_o); - switch (_id) { - case 0: _t->onToggle(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pCheckLabel::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pCheckLabel::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckLabel, - qt_meta_data_phoenix__pCheckLabel, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pCheckLabel::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pCheckLabel::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pCheckLabel::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pCheckLabel)) - return static_cast(const_cast< pCheckLabel*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pCheckLabel*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pCheckLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pComboButton[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 22, 33, 33, 33, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pComboButton[] = { - "phoenix::pComboButton\0onChange()\0\0" -}; - -void phoenix::pComboButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pComboButton *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pComboButton::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pComboButton::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pComboButton, - qt_meta_data_phoenix__pComboButton, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pComboButton::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pComboButton::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pComboButton::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pComboButton)) - return static_cast(const_cast< pComboButton*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pComboButton*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pComboButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pConsole[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 0, 0, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pConsole[] = { - "phoenix::pConsole\0" -}; - -void phoenix::pConsole::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - Q_UNUSED(_o); - Q_UNUSED(_id); - Q_UNUSED(_c); - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pConsole::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pConsole::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pConsole, - qt_meta_data_phoenix__pConsole, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pConsole::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pConsole::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pConsole::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pConsole)) - return static_cast(const_cast< pConsole*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pConsole*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pConsole::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - return _id; -} -static const uint qt_meta_data_phoenix__pFrame[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 0, 0, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pFrame[] = { - "phoenix::pFrame\0" -}; - -void phoenix::pFrame::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - Q_UNUSED(_o); - Q_UNUSED(_id); - Q_UNUSED(_c); - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pFrame::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pFrame::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pFrame, - qt_meta_data_phoenix__pFrame, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pFrame::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pFrame::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pFrame::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pFrame)) - return static_cast(const_cast< pFrame*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pFrame*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - return _id; -} -static const uint qt_meta_data_phoenix__pHexEdit[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 18, 29, 29, 29, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pHexEdit[] = { - "phoenix::pHexEdit\0onScroll()\0\0" -}; - -void phoenix::pHexEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pHexEdit *_t = static_cast(_o); - switch (_id) { - case 0: _t->onScroll(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pHexEdit::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pHexEdit::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHexEdit, - qt_meta_data_phoenix__pHexEdit, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pHexEdit::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pHexEdit::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pHexEdit::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pHexEdit)) - return static_cast(const_cast< pHexEdit*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pHexEdit*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pHorizontalScroller[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 29, 40, 40, 40, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pHorizontalScroller[] = { - "phoenix::pHorizontalScroller\0onChange()\0" - "\0" -}; - -void phoenix::pHorizontalScroller::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pHorizontalScroller *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pHorizontalScroller::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pHorizontalScroller::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHorizontalScroller, - qt_meta_data_phoenix__pHorizontalScroller, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pHorizontalScroller::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pHorizontalScroller::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pHorizontalScroller::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pHorizontalScroller)) - return static_cast(const_cast< pHorizontalScroller*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pHorizontalScroller*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pHorizontalScroller::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pHorizontalSlider[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 27, 38, 38, 38, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pHorizontalSlider[] = { - "phoenix::pHorizontalSlider\0onChange()\0" - "\0" -}; - -void phoenix::pHorizontalSlider::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pHorizontalSlider *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pHorizontalSlider::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pHorizontalSlider::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHorizontalSlider, - qt_meta_data_phoenix__pHorizontalSlider, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pHorizontalSlider::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pHorizontalSlider::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pHorizontalSlider::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pHorizontalSlider)) - return static_cast(const_cast< pHorizontalSlider*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pHorizontalSlider*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pHorizontalSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pIconView[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 3, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 19, 32, 32, 32, 0x0a, - 33, 32, 32, 32, 0x0a, - 44, 32, 32, 32, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pIconView[] = { - "phoenix::pIconView\0onActivate()\0\0" - "onChange()\0onContext()\0" -}; - -void phoenix::pIconView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pIconView *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - case 1: _t->onChange(); break; - case 2: _t->onContext(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pIconView::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pIconView::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pIconView, - qt_meta_data_phoenix__pIconView, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pIconView::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pIconView::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pIconView::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pIconView)) - return static_cast(const_cast< pIconView*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pIconView*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pIconView::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 3) - qt_static_metacall(this, _c, _id, _a); - _id -= 3; - } - return _id; -} -static const uint qt_meta_data_phoenix__pLineEdit[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 2, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 19, 32, 32, 32, 0x0a, - 33, 32, 32, 32, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pLineEdit[] = { - "phoenix::pLineEdit\0onActivate()\0\0" - "onChange()\0" -}; - -void phoenix::pLineEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pLineEdit *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - case 1: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pLineEdit::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pLineEdit::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pLineEdit, - qt_meta_data_phoenix__pLineEdit, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pLineEdit::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pLineEdit::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pLineEdit::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pLineEdit)) - return static_cast(const_cast< pLineEdit*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pLineEdit*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 2) - qt_static_metacall(this, _c, _id, _a); - _id -= 2; - } - return _id; -} -static const uint qt_meta_data_phoenix__pListView[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 6, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 19, 32, 32, 32, 0x0a, - 33, 32, 32, 32, 0x0a, - 44, 32, 32, 32, 0x0a, - 56, 68, 32, 32, 0x0a, - 75, 102, 32, 32, 0x0a, - 107, 141, 161, 32, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pListView[] = { - "phoenix::pListView\0onActivate()\0\0" - "onChange()\0onContext()\0onSort(int)\0" - "column\0onToggle(QTreeWidgetItem*)\0" - "item\0calculateAlignment(double,double)\0" - "horizontal,vertical\0int\0" -}; - -void phoenix::pListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pListView *_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]))); break; - case 5: { int _r = _t->calculateAlignment((*reinterpret_cast< double(*)>(_a[1])),(*reinterpret_cast< double(*)>(_a[2]))); - if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; } break; - default: ; - } - } -} - -const QMetaObjectExtraData phoenix::pListView::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pListView::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pListView, - qt_meta_data_phoenix__pListView, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pListView::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pListView::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pListView::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pListView)) - return static_cast(const_cast< pListView*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pListView*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 6) - qt_static_metacall(this, _c, _id, _a); - _id -= 6; - } - return _id; -} -static const uint qt_meta_data_phoenix__pRadioLabel[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 21, 34, 34, 34, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pRadioLabel[] = { - "phoenix::pRadioLabel\0onActivate()\0\0" -}; - -void phoenix::pRadioLabel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pRadioLabel *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pRadioLabel::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pRadioLabel::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioLabel, - qt_meta_data_phoenix__pRadioLabel, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pRadioLabel::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pRadioLabel::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pRadioLabel::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pRadioLabel)) - return static_cast(const_cast< pRadioLabel*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pRadioLabel*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pRadioLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pRadioButton[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 22, 35, 35, 35, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pRadioButton[] = { - "phoenix::pRadioButton\0onActivate()\0\0" -}; - -void phoenix::pRadioButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pRadioButton *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pRadioButton::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pRadioButton::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioButton, - qt_meta_data_phoenix__pRadioButton, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pRadioButton::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pRadioButton::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pRadioButton::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pRadioButton)) - return static_cast(const_cast< pRadioButton*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pRadioButton*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pRadioButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pTabFrame[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 19, 33, 43, 43, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pTabFrame[] = { - "phoenix::pTabFrame\0onChange(int)\0" - "selection\0\0" -}; - -void phoenix::pTabFrame::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pTabFrame *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange((*reinterpret_cast< int(*)>(_a[1]))); break; - default: ; - } - } -} - -const QMetaObjectExtraData phoenix::pTabFrame::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pTabFrame::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTabFrame, - qt_meta_data_phoenix__pTabFrame, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pTabFrame::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pTabFrame::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pTabFrame::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pTabFrame)) - return static_cast(const_cast< pTabFrame*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pTabFrame*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pTabFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pTextEdit[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 19, 30, 30, 30, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pTextEdit[] = { - "phoenix::pTextEdit\0onChange()\0\0" -}; - -void phoenix::pTextEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pTextEdit *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pTextEdit::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pTextEdit::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTextEdit, - qt_meta_data_phoenix__pTextEdit, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pTextEdit::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pTextEdit::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pTextEdit::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pTextEdit)) - return static_cast(const_cast< pTextEdit*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pTextEdit*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pVerticalScroller[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 27, 38, 38, 38, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pVerticalScroller[] = { - "phoenix::pVerticalScroller\0onChange()\0" - "\0" -}; - -void phoenix::pVerticalScroller::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pVerticalScroller *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pVerticalScroller::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pVerticalScroller::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pVerticalScroller, - qt_meta_data_phoenix__pVerticalScroller, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pVerticalScroller::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pVerticalScroller::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pVerticalScroller::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pVerticalScroller)) - return static_cast(const_cast< pVerticalScroller*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pVerticalScroller*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pVerticalScroller::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -static const uint qt_meta_data_phoenix__pVerticalSlider[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 1, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 25, 36, 36, 36, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_phoenix__pVerticalSlider[] = { - "phoenix::pVerticalSlider\0onChange()\0" - "\0" -}; - -void phoenix::pVerticalSlider::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - pVerticalSlider *_t = static_cast(_o); - switch (_id) { - case 0: _t->onChange(); break; - default: ; - } - } - Q_UNUSED(_a); -} - -const QMetaObjectExtraData phoenix::pVerticalSlider::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject phoenix::pVerticalSlider::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pVerticalSlider, - qt_meta_data_phoenix__pVerticalSlider, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &phoenix::pVerticalSlider::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *phoenix::pVerticalSlider::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *phoenix::pVerticalSlider::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_phoenix__pVerticalSlider)) - return static_cast(const_cast< pVerticalSlider*>(this)); - if (!strcmp(_clname, "pWidget")) - return static_cast< pWidget*>(const_cast< pVerticalSlider*>(this)); - return QObject::qt_metacast(_clname); -} - -int phoenix::pVerticalSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 1) - qt_static_metacall(this, _c, _id, _a); - _id -= 1; - } - return _id; -} -QT_END_MOC_NAMESPACE diff --git a/hiro/qt/platform.moc.hpp b/hiro/qt/platform.moc.hpp deleted file mode 100644 index ac1b96b7..00000000 --- a/hiro/qt/platform.moc.hpp +++ /dev/null @@ -1,876 +0,0 @@ -namespace phoenix { - -struct pApplication { - static XlibDisplay* display; - - static void run(); - static bool pendingEvents(); - static void processEvents(); - static void quit(); - - static void initialize(); - static void syncX(); -}; - -static QApplication* qtApplication = nullptr; - -struct Settings : Configuration::Document { - bimap keymap; - - struct Geometry : Configuration::Node { - unsigned frameX; - unsigned frameY; - unsigned frameWidth; - unsigned frameHeight; - unsigned menuHeight; - unsigned statusHeight; - } geometry; - - void load(); - void save(); - Settings(); -}; - -struct pWindow; -struct pMenu; -struct pLayout; -struct pWidget; - -struct pFont { - static string serif(unsigned size, string style); - static string sans(unsigned size, string style); - static string monospace(unsigned size, string style); - static Size size(string font, string text); - - static QFont create(string description); - static Size size(const QFont& qtFont, string text); -}; - -struct pDesktop { - static Size size(); - static Geometry workspace(); -}; - -struct pMonitor { - static unsigned count(); - static Geometry geometry(unsigned monitor); - static unsigned primary(); -}; - -struct pKeyboard { - static bool pressed(Keyboard::Scancode scancode); - static vector state(); - - static void initialize(); -}; - -struct pMouse { - static Position position(); - static bool pressed(Mouse::Button button); -}; - -struct pBrowserWindow { - static string directory(BrowserWindow::State& state); - static string open(BrowserWindow::State& state); - static string save(BrowserWindow::State& state); -}; - -struct pMessageWindow { - static MessageWindow::Response error(MessageWindow::State& state); - static MessageWindow::Response information(MessageWindow::State& state); - static MessageWindow::Response question(MessageWindow::State& state); - static MessageWindow::Response warning(MessageWindow::State& state); -}; - -struct pObject { - Object& object; - signed locks = 0; - - bool locked() const { return locks != 0; } - void lock() { locks++; } - void unlock() { locks--; } - - pObject(Object& object) : object(object) {} - virtual ~pObject() {} - void constructor() {} - void destructor() {} -}; - -struct pTimer : public QObject, public pObject { - Q_OBJECT - -public: - Timer& timer; - QTimer* qtTimer; - - void setEnabled(bool enabled); - void setInterval(unsigned interval); - - pTimer(Timer& timer) : pObject(timer), timer(timer) {} - void constructor(); - void destructor(); - -public slots: - void onActivate(); -}; - -struct pWindow : public QObject, public pObject { - Q_OBJECT - -public: - Window& window; - struct QtWindow : public QWidget { - pWindow& self; - void closeEvent(QCloseEvent*); - void dragEnterEvent(QDragEnterEvent*); - void dropEvent(QDropEvent*); - void keyPressEvent(QKeyEvent*); - void keyReleaseEvent(QKeyEvent*); - void moveEvent(QMoveEvent*); - void resizeEvent(QResizeEvent*); - QSize sizeHint() const; - QtWindow(pWindow& self) : self(self) {} - }; - QtWindow* qtWindow; - QVBoxLayout* qtLayout; - QMenuBar* qtMenu; - QStatusBar* qtStatus; - QWidget* qtContainer; - - void append(Layout& layout); - void append(Menu& menu); - void append(Widget& widget); - Geometry frameMargin(); - bool focused(); - void remove(Layout& layout); - void remove(Menu& menu); - void remove(Widget& widget); - void setBackgroundColor(Color color); - void setDroppable(bool droppable); - void setFocused(); - void setFullScreen(bool fullScreen); - void setGeometry(Geometry geometry); - void setMenuFont(string font); - void setMenuVisible(bool visible); - void setModal(bool modal); - void setResizable(bool resizable); - void setStatusFont(string font); - void setStatusText(string text); - void setStatusVisible(bool visible); - void setTitle(string text); - void setVisible(bool visible); - void setWidgetFont(string font); - - pWindow(Window& window) : pObject(window), window(window) {} - void constructor(); - void destructor(); - void updateFrameGeometry(); -}; - -struct pPopupMenu : public pObject { - PopupMenu& popupMenu; - QMenu* qtMenu; - - void append(Action& action); - void remove(Action& action); - void setVisible(); - - pPopupMenu(PopupMenu& popupMenu) : pObject(popupMenu), popupMenu(popupMenu) {} - void constructor(); - void destructor(); -}; - -struct pAction : public pObject { - Action& action; - - void setEnabled(bool enabled); - void setFont(string font); - void setVisible(bool visible); - - pAction(Action& action) : pObject(action), action(action) {} - void constructor(); - void destructor(); -}; - -struct pMenu : public pAction { - Menu& menu; - QMenu* qtMenu; - - void append(Action& action); - void remove(Action& action); - void setFont(string font); - void setImage(const image& image); - void setText(string text); - - pMenu(Menu& menu) : pAction(menu), menu(menu) {} - void constructor(); - void destructor(); -}; - -struct pSeparator : public pAction { - Separator& separator; - QAction* qtAction; - - pSeparator(Separator& separator) : pAction(separator), separator(separator) {} - void constructor(); - void destructor(); -}; - -struct pItem : public QObject, public pAction { - Q_OBJECT - -public: - Item& item; - QAction* qtAction; - - void setImage(const image& image); - void setText(string text); - - pItem(Item& item) : pAction(item), item(item) {} - void constructor(); - void destructor(); - -public slots: - void onActivate(); -}; - -struct pCheckItem : public QObject, public pAction { - Q_OBJECT - -public: - CheckItem& checkItem; - QAction* qtAction; - - void setChecked(bool checked); - void setText(string text); - - pCheckItem(CheckItem& checkItem) : pAction(checkItem), checkItem(checkItem) {} - void constructor(); - void destructor(); - -public slots: - void onToggle(); -}; - -struct pRadioItem : public QObject, public pAction { - Q_OBJECT - -public: - RadioItem& radioItem; - QAction* qtAction; - QActionGroup* qtGroup; - - void setChecked(); - void setGroup(const group& group); - void setText(string text); - - pRadioItem(RadioItem& radioItem) : pAction(radioItem), radioItem(radioItem) {} - void constructor(); - void destructor(); - -public slots: - void onActivate(); -}; - -struct pSizable : public pObject { - Sizable& sizable; - - virtual Position displacement() { return {0, 0}; } - - pSizable(Sizable& sizable) : pObject(sizable), sizable(sizable) {} - - void constructor() {} - void destructor() {} -}; - -struct pLayout : public pSizable { - Layout& layout; - - pLayout(Layout& layout) : pSizable(layout), layout(layout) {} - - void constructor() {} - void destructor() {} -}; - -struct pWidget : public pSizable { - Widget& widget; - QWidget* qtWidget; - - virtual QWidget* container(Widget& widget); - bool focused(); - virtual Size minimumSize(); - virtual void setEnabled(bool enabled); - void setFocused(); - void setFont(string font); - virtual void setGeometry(Geometry geometry); - virtual void setVisible(bool visible); - - pWidget(Widget& widget) : pSizable(widget), widget(widget) {} - void constructor(); - void synchronizeState(); - void destructor(); - virtual void orphan(); -}; - -struct pButton : public QObject, public pWidget { - Q_OBJECT - -public: - Button& button; - QToolButton* qtButton; - - Size minimumSize(); - void setBordered(bool bordered); - void setImage(const image& image, Orientation orientation); - void setText(string text); - - pButton(Button& button) : pWidget(button), button(button) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onActivate(); -}; - -struct pCanvas : public QObject, public pWidget { - Q_OBJECT - -public: - Canvas& canvas; - QImage* surface = nullptr; - unsigned surfaceWidth = 0; - unsigned surfaceHeight = 0; - struct QtCanvas : public QWidget { - pCanvas& self; - void dragEnterEvent(QDragEnterEvent*); - void dropEvent(QDropEvent*); - void leaveEvent(QEvent*); - void mouseMoveEvent(QMouseEvent*); - void mousePressEvent(QMouseEvent*); - void mouseReleaseEvent(QMouseEvent*); - void paintEvent(QPaintEvent*); - QtCanvas(pCanvas& self); - }; - QtCanvas* qtCanvas; - - void setDroppable(bool droppable); - void setGeometry(Geometry geometry); - void setMode(Canvas::Mode mode); - void setSize(Size size); - - pCanvas(Canvas& canvas) : pWidget(canvas), canvas(canvas) {} - void constructor(); - void destructor(); - void orphan(); - void rasterize(); - void release(); - -public slots: -}; - -struct pCheckButton : public QObject, public pWidget { - Q_OBJECT - -public: - CheckButton& checkButton; - QToolButton* qtCheckButton; - - Size minimumSize(); - void setChecked(bool checked); - void setImage(const image& image, Orientation orientation); - void setText(string text); - - pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onToggle(bool checked); -}; - -struct pCheckLabel : public QObject, public pWidget { - Q_OBJECT - -public: - CheckLabel& checkLabel; - QCheckBox* qtCheckLabel; - - Size minimumSize(); - void setChecked(bool checked); - void setText(string text); - - pCheckLabel(CheckLabel& checkLabel) : pWidget(checkLabel), checkLabel(checkLabel) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onToggle(); -}; - -struct pComboButton : public QObject, public pWidget { - Q_OBJECT - -public: - ComboButton& comboButton; - QComboBox* qtComboButton; - - void append(); - Size minimumSize(); - void remove(unsigned selection); - void reset(); - void setSelected(unsigned selection); - void setText(unsigned selection, string text); - - pComboButton(ComboButton& comboButton) : pWidget(comboButton), comboButton(comboButton) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onChange(); -}; - -struct pConsole : public QObject, public pWidget { - Q_OBJECT - -public: - Console& console; - struct QtConsole : public QTextEdit { - pConsole& self; - void keyPressEvent(QKeyEvent*); - void keyPressEventAcknowledge(QKeyEvent*); - QtConsole(pConsole& self) : self(self) {} - }; - QtConsole* qtConsole; - - void print(string text); - void reset(); - void setBackgroundColor(Color color); - void setForegroundColor(Color color); - void setPrompt(string prompt); - - pConsole(Console& console) : pWidget(console), console(console) {} - void constructor(); - void destructor(); - void orphan(); - void keyPressEvent(QKeyEvent*); -}; - -struct pFrame : public QObject, public pWidget { - Q_OBJECT - -public: - Frame& frame; - QGroupBox* qtFrame; - - void setEnabled(bool enabled); - void setGeometry(Geometry geometry); - void setText(string text); - void setVisible(bool visible); - - pFrame(Frame& frame) : pWidget(frame), frame(frame) {} - void constructor(); - void destructor(); - void orphan(); -}; - -struct pHexEdit : public QObject, public pWidget { - Q_OBJECT - -public: - HexEdit& hexEdit; - struct QtHexEdit : public QTextEdit { - pHexEdit& self; - void keyPressEvent(QKeyEvent*); - void keyPressEventAcknowledge(QKeyEvent*); - void wheelEvent(QWheelEvent*); - QtHexEdit(pHexEdit& self) : self(self) {} - }; - struct QtHexEditScrollBar : public QScrollBar { - pHexEdit& self; - bool event(QEvent*); - QtHexEditScrollBar(pHexEdit& self) : QScrollBar(Qt::Vertical), self(self) {} - }; - QtHexEdit* qtHexEdit; - QHBoxLayout* qtLayout; - QtHexEditScrollBar* qtScroll; - - void setBackgroundColor(Color color); - void setColumns(unsigned columns); - void setForegroundColor(Color color); - void setLength(unsigned length); - void setOffset(unsigned offset); - void setRows(unsigned rows); - void update(); - - pHexEdit(HexEdit& hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {} - void constructor(); - void destructor(); - void orphan(); - void keyPressEvent(QKeyEvent*); - signed rows(); - signed rowsScrollable(); - void scrollTo(signed position); - -public slots: - void onScroll(); -}; - -struct pHorizontalScroller : public QObject, public pWidget { - Q_OBJECT - -public: - HorizontalScroller& horizontalScroller; - QScrollBar* qtScroller; - - Size minimumSize(); - void setLength(unsigned length); - void setPosition(unsigned position); - - pHorizontalScroller(HorizontalScroller& horizontalScroller) : pWidget(horizontalScroller), horizontalScroller(horizontalScroller) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onChange(); -}; - -struct pHorizontalSlider : public QObject, public pWidget { - Q_OBJECT - -public: - HorizontalSlider& horizontalSlider; - QSlider* qtSlider; - - Size minimumSize(); - void setLength(unsigned length); - void setPosition(unsigned position); - - pHorizontalSlider(HorizontalSlider& horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onChange(); -}; - -struct pIconView : public QObject, public pWidget { - Q_OBJECT - -public: - IconView& iconView; - struct QtListWidget : public QListWidget { - void resizeEvent(QResizeEvent*); - }; - QtListWidget* qtIconView; - - void append(); - void remove(unsigned selection); - void reset(); - void setBackgroundColor(Color color); - void setFlow(Orientation flow); - void setForegroundColor(Color color); - void setImage(unsigned selection, const image& image); - void setOrientation(Orientation orientation); - void setSelected(unsigned selection, bool selected); - void setSelected(const vector& selections); - void setSelectedAll(); - void setSelectedNone(); - void setSingleSelection(bool singleSelection); - void setText(unsigned selection, const string& text); - - pIconView(IconView& iconView) : pWidget(iconView), iconView(iconView) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onActivate(); - void onChange(); - void onContext(); -}; - -struct pLabel : public pWidget { - Label& label; - QLabel* qtLabel; - - Size minimumSize(); - void setText(string text); - - pLabel(Label& label) : pWidget(label), label(label) {} - void constructor(); - void destructor(); - void orphan(); -}; - -struct pLineEdit : public QObject, public pWidget { - Q_OBJECT - -public: - LineEdit& lineEdit; - QLineEdit* qtLineEdit; - - Size minimumSize(); - void setBackgroundColor(Color color); - void setEditable(bool editable); - void setForegroundColor(Color color); - void setText(string text); - string text(); - - pLineEdit(LineEdit& lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onActivate(); - void onChange(); -}; - -struct pListView : public QObject, public pWidget { - Q_OBJECT - -public: - ListView& listView; - struct QtTreeWidget : public QTreeWidget { - pListView& self; - void mousePressEvent(QMouseEvent*); - QtTreeWidget(pListView& self); - }; - struct QtTreeWidgetDelegate : public QStyledItemDelegate { - pListView& self; - void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; - QtTreeWidgetDelegate(pListView& self); - }; - QtTreeWidget* qtListView; - QtTreeWidgetDelegate* qtListViewDelegate; - - void appendColumn(); - void appendItem(); - void removeColumn(unsigned position); - void removeItem(unsigned position); - void reset(); - void resizeColumns(); - void setActiveColumn(unsigned column); - void setBackgroundColor(Color color); - void setCheckable(bool checkable); - void setChecked(unsigned position, bool checked); - void setChecked(const vector& selections); - void setCheckedAll(); - void setCheckedNone(); - void setColumnBackgroundColor(unsigned position, maybe color); - void setColumnEditable(unsigned position, bool editable); - void setColumnFont(unsigned position, maybe font); - void setColumnForegroundColor(unsigned position, maybe color); - void setColumnHorizontalAlignment(unsigned position, double alignment); - void setColumnResizable(unsigned position, bool resizable); - void setColumnSortable(unsigned position, bool sortable); - void setColumnText(unsigned position, const string& text); - void setColumnVerticalAlignment(unsigned position, double alignment); - void setColumnVisible(unsigned position, bool visible); - void setColumnWidth(unsigned position, signed width); - void setForegroundColor(Color color); - void setGridVisible(bool visible); - void setHeaderVisible(bool visible); - void setImage(unsigned row, unsigned column, const image& image); - void setSelected(unsigned position, bool selected); - void setSelected(const vector& selections); - void setSelectedAll(); - void setSelectedNone(); - void setSingleSelection(bool singleSelection); - void setText(unsigned row, unsigned column, string text); - - pListView(ListView& listView) : pWidget(listView), listView(listView) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onActivate(); - void onChange(); - void onContext(); - void onSort(int column); - void onToggle(QTreeWidgetItem* item); - int calculateAlignment(double horizontal, double vertical); -}; - -struct pProgressBar : public pWidget { - ProgressBar& progressBar; - QProgressBar* qtProgressBar; - - Size minimumSize(); - void setPosition(unsigned position); - - pProgressBar(ProgressBar& progressBar) : pWidget(progressBar), progressBar(progressBar) {} - void constructor(); - void destructor(); - void orphan(); -}; - -struct pRadioLabel : public QObject, public pWidget { - Q_OBJECT - -public: - RadioLabel& radioLabel; - QRadioButton* qtRadioLabel; - - bool checked(); - Size minimumSize(); - void setChecked(); - void setGroup(const group& group); - void setText(string text); - - pRadioLabel(RadioLabel& radioLabel) : pWidget(radioLabel), radioLabel(radioLabel) {} - pRadioLabel& parent(); - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onActivate(); -}; - -struct pRadioButton : public QObject, public pWidget { - Q_OBJECT - -public: - RadioButton& radioButton; - QToolButton* qtRadioButton; - - Size minimumSize(); - void setChecked(); - void setGroup(const group& group); - void setImage(const image& image, Orientation orientation); - void setText(string text); - - pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {} - pRadioButton& parent(); - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onActivate(); -}; - -struct pTabFrame : public QObject, public pWidget { - Q_OBJECT - -public: - TabFrame& tabFrame; - QTabWidget* qtTabFrame; - - void append(); - QWidget* container(Widget& widget); - Position displacement(); - void remove(unsigned selection); - void setEnabled(bool enabled); - void setGeometry(Geometry geometry); - void setImage(unsigned selection, const image& image); - void setSelected(unsigned selection); - void setText(unsigned selection, string text); - void setVisible(bool visible); - - pTabFrame(TabFrame& tabFrame) : pWidget(tabFrame), tabFrame(tabFrame) {} - void constructor(); - void destructor(); - void orphan(); - void synchronizeLayout(); - -public slots: - void onChange(int selection); -}; - -struct pTextEdit : public QObject, public pWidget { - Q_OBJECT - -public: - TextEdit& textEdit; - QTextEdit* qtTextEdit; - - void setBackgroundColor(Color color); - void setCursorPosition(unsigned position); - void setEditable(bool editable); - void setForegroundColor(Color color); - void setText(string text); - void setWordWrap(bool wordWrap); - string text(); - - pTextEdit(TextEdit& textEdit) : pWidget(textEdit), textEdit(textEdit) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onChange(); -}; - -struct pVerticalScroller : public QObject, public pWidget { - Q_OBJECT - -public: - VerticalScroller& verticalScroller; - QScrollBar* qtScroller; - - Size minimumSize(); - void setLength(unsigned length); - void setPosition(unsigned position); - - pVerticalScroller(VerticalScroller& verticalScroller) : pWidget(verticalScroller), verticalScroller(verticalScroller) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onChange(); -}; - -struct pVerticalSlider : public QObject, public pWidget { - Q_OBJECT - -public: - VerticalSlider& verticalSlider; - QSlider* qtSlider; - - Size minimumSize(); - void setLength(unsigned length); - void setPosition(unsigned position); - - pVerticalSlider(VerticalSlider& verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {} - void constructor(); - void destructor(); - void orphan(); - -public slots: - void onChange(); -}; - -struct pViewport : public pWidget { - Viewport& viewport; - struct QtViewport : public QWidget { - pViewport& self; - void dragEnterEvent(QDragEnterEvent*); - void dropEvent(QDropEvent*); - void leaveEvent(QEvent*); - void mouseMoveEvent(QMouseEvent*); - void mousePressEvent(QMouseEvent*); - void mouseReleaseEvent(QMouseEvent*); - QtViewport(pViewport& self); - }; - QtViewport* qtViewport; - - uintptr_t handle(); - void setDroppable(bool droppable); - - pViewport(Viewport& viewport) : pWidget(viewport), viewport(viewport) {} - void constructor(); - void destructor(); - void orphan(); -}; - -} diff --git a/hiro/qt/popup-menu.cpp b/hiro/qt/popup-menu.cpp index 789765c6..cc74a027 100644 --- a/hiro/qt/popup-menu.cpp +++ b/hiro/qt/popup-menu.cpp @@ -1,46 +1,40 @@ -namespace phoenix { +#if defined(Hiro_PopupMenu) -void pPopupMenu::append(Action& action) { - if(dynamic_cast(&action)) { - qtMenu->addMenu(((Menu&)action).p.qtMenu); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((Separator&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((Item&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((CheckItem&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->addAction(((RadioItem&)action).p.qtAction); +namespace hiro { + +auto pPopupMenu::construct() -> void { + qtPopupMenu = new QMenu; + _setState(); +} + +auto pPopupMenu::destruct() -> void { + delete qtPopupMenu; + qtPopupMenu = nullptr; +} + +auto pPopupMenu::append(sAction action) -> void { + _setState(); +} + +auto pPopupMenu::remove(sAction action) -> void { + _setState(); +} + +auto pPopupMenu::setFont(const string& font) -> void { + _setState(); +} + +auto pPopupMenu::setVisible(bool visible) -> void { + if(visible) qtPopupMenu->popup(QCursor::pos()); +} + +auto pPopupMenu::_setState() -> void { + qtPopupMenu->setFont(pFont::create(self().font(true))); + for(auto& action : state().actions) { + if(auto self = action->self()) self->_setState(); } } -void pPopupMenu::remove(Action& action) { - if(dynamic_cast(&action)) { - //QMenu::removeMenu() does not exist - qtMenu->clear(); - for(auto& action : popupMenu.state.action) append(action); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((Separator&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((Item&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((CheckItem&)action).p.qtAction); - } else if(dynamic_cast(&action)) { - qtMenu->removeAction(((RadioItem&)action).p.qtAction); - } } -void pPopupMenu::setVisible() { - qtMenu->popup(QCursor::pos()); -} - -void pPopupMenu::constructor() { - qtMenu = new QMenu; -} - -void pPopupMenu::destructor() { - delete qtMenu; - qtMenu = nullptr; -} - -} +#endif diff --git a/hiro/qt/popup-menu.hpp b/hiro/qt/popup-menu.hpp new file mode 100644 index 00000000..04bf4d76 --- /dev/null +++ b/hiro/qt/popup-menu.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_PopupMenu) + +namespace hiro { + +struct pPopupMenu : pObject { + Declare(PopupMenu, Object) + + auto append(sAction action) -> void; + auto remove(sAction action) -> void; + auto setFont(const string& font) -> void override; + auto setVisible(bool visible) -> void override; + + auto _setState() -> void; + + QMenu* qtPopupMenu = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/qt.hpp b/hiro/qt/qt.hpp new file mode 100644 index 00000000..b5263547 --- /dev/null +++ b/hiro/qt/qt.hpp @@ -0,0 +1,303 @@ +/* + Qt requires moc in order to bind callbacks, which causes many complications. + + First, moc is not C++11-aware. Thus, all of the "public slots:" functions must + be declared using C++98 syntax. + + Second, multiple inheritance with QObject (eg pWindow : QObject, pObject) + seems to cause heap corruption. As such, we need to have separate classes for + inheriting from QObject, which are defined in this file. + + Third, moc preprocessor output is required for every Q_OBJECT class. So to + avoid needing to generate several .moc files, all QObject classes are placed + inside this one file instead. +*/ + +#if !defined(HIRO_QT) + #include "../components.hpp" +#endif + +namespace hiro { + +#if defined(Hiro_Timer) +struct QtTimer : public QTimer { + Q_OBJECT +public: + QtTimer(pTimer& p) : p(p) {} + pTimer& p; +public slots: + void onActivate(); +}; +#endif + +#if defined(Hiro_Window) +struct QtWindow : public QWidget { + QtWindow(pWindow& p) : p(p) {} + auto closeEvent(QCloseEvent*) -> void; + auto dragEnterEvent(QDragEnterEvent*) -> void; + auto dropEvent(QDropEvent*) -> void; + auto keyPressEvent(QKeyEvent*) -> void; + auto keyReleaseEvent(QKeyEvent*) -> void; + auto moveEvent(QMoveEvent*) -> void; + auto resizeEvent(QResizeEvent*) -> void; + auto sizeHint() const -> QSize; + pWindow& p; +}; +#endif + +#if defined(Hiro_MenuItem) +struct QtMenuItem : public QAction { + Q_OBJECT +public: + QtMenuItem(pMenuItem& p) : QAction(nullptr), p(p) {} + pMenuItem& p; +public slots: + void onActivate(); +}; +#endif + +#if defined(Hiro_MenuCheckItem) +struct QtMenuCheckItem : public QAction { + Q_OBJECT +public: + QtMenuCheckItem(pMenuCheckItem& p) : QAction(nullptr), p(p) {} + pMenuCheckItem& p; +public slots: + void onToggle(); +}; +#endif + +#if defined(Hiro_MenuRadioItem) +struct QtMenuRadioItem : public QAction { + Q_OBJECT +public: + QtMenuRadioItem(pMenuRadioItem& p) : QAction(nullptr), p(p) {} + pMenuRadioItem& p; +public slots: + void onActivate(); +}; +#endif + +#if defined(Hiro_Button) +struct QtButton : public QToolButton { + Q_OBJECT +public: + QtButton(pButton& p) : p(p) {} + pButton& p; +public slots: + void onActivate(); +}; +#endif + +#if defined(Hiro_Canvas) +struct QtCanvas : public QWidget { + Q_OBJECT +public: + QtCanvas(pCanvas& p) : p(p) {} + auto dragEnterEvent(QDragEnterEvent*) -> void; + auto dropEvent(QDropEvent*) -> void; + auto leaveEvent(QEvent*) -> void; + auto mouseMoveEvent(QMouseEvent*) -> void; + auto mousePressEvent(QMouseEvent*) -> void; + auto mouseReleaseEvent(QMouseEvent*) -> void; + auto paintEvent(QPaintEvent*) -> void; + pCanvas& p; +}; +#endif + +#if defined(Hiro_CheckButton) +struct QtCheckButton : public QToolButton { + Q_OBJECT +public: + QtCheckButton(pCheckButton& p) : p(p) {} + pCheckButton& p; +public slots: + void onToggle(bool checked); +}; +#endif + +#if defined(Hiro_CheckLabel) +struct QtCheckLabel : public QCheckBox { + Q_OBJECT +public: + QtCheckLabel(pCheckLabel& p) : p(p) {} + pCheckLabel& p; +public slots: + void onToggle(); +}; +#endif + +#if defined(Hiro_ComboButton) +struct QtComboButton : public QComboBox { + Q_OBJECT +public: + QtComboButton(pComboButton& p) : p(p) {} + pComboButton& p; +public slots: + void onChange(); +}; +#endif + +#if defined(Hiro_HexEdit) +struct QtHexEdit : public QTextEdit { + Q_OBJECT +public: + QtHexEdit(pHexEdit& p) : p(p) {} + auto keyPressEvent(QKeyEvent*) -> void; + auto keyPressEventAcknowledge(QKeyEvent*) -> void; + auto wheelEvent(QWheelEvent*) -> void; + pHexEdit& p; +}; + +struct QtHexEditScrollBar : public QScrollBar { + Q_OBJECT +public: + QtHexEditScrollBar(pHexEdit& p) : p(p) {} + auto event(QEvent*) -> bool; + pHexEdit& p; +public slots: + void onScroll(); +}; +#endif + +#if defined(Hiro_HorizontalScroller) +struct QtHorizontalScroller : public QScrollBar { + Q_OBJECT +public: + QtHorizontalScroller(pHorizontalScroller& p) : QScrollBar(Qt::Horizontal), p(p) {} + pHorizontalScroller& p; +public slots: + void onChange(); +}; +#endif + +#if defined(Hiro_HorizontalSlider) +struct QtHorizontalSlider : public QSlider { + Q_OBJECT +public: + QtHorizontalSlider(pHorizontalSlider& p) : QSlider(Qt::Horizontal), p(p) {} + pHorizontalSlider& p; +public slots: + void onChange(); +}; +#endif + +#if defined(Hiro_LineEdit) +struct QtLineEdit : public QLineEdit { + Q_OBJECT +public: + QtLineEdit(pLineEdit& p) : p(p) {} + pLineEdit& p; +public slots: + void onActivate(); + void onChange(); +}; +#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); +}; + +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 +public: + QtRadioLabel(pRadioLabel& p) : p(p) {} + pRadioLabel& p; +public slots: + void onActivate(); +}; +#endif + +#if defined(Hiro_RadioButton) +struct QtRadioButton : public QToolButton { + Q_OBJECT +public: + QtRadioButton(pRadioButton& p) : p(p) {} + pRadioButton& p; +public slots: + void onActivate(); +}; +#endif + +#if defined(Hiro_TabFrame) +struct QtTabFrame : public QTabWidget { + Q_OBJECT +public: + QtTabFrame(pTabFrame& p) : p(p) {} + pTabFrame& p; + auto showEvent(QShowEvent*) -> void override; +public slots: + void onChange(int selection); +}; +#endif + +#if defined(Hiro_TextEdit) +struct QtTextEdit : public QTextEdit { + Q_OBJECT +public: + QtTextEdit(pTextEdit& p) : p(p) {} + pTextEdit& p; +public slots: + void onChange(); +}; +#endif + +#if defined(Hiro_VerticalScroller) +struct QtVerticalScroller : public QScrollBar { + Q_OBJECT +public: + QtVerticalScroller(pVerticalScroller& p) : QScrollBar(Qt::Vertical), p(p) {} + pVerticalScroller& p; +public slots: + void onChange(); +}; +#endif + +#if defined(Hiro_VerticalSlider) +struct QtVerticalSlider : public QSlider { + Q_OBJECT +public: + QtVerticalSlider(pVerticalSlider& p) : QSlider(Qt::Vertical), p(p) {} + pVerticalSlider& p; +public slots: + void onChange(); +}; +#endif + +#if defined(Hiro_Viewport) +struct QtViewport : public QWidget { + Q_OBJECT +public: + QtViewport(pViewport& p) : p(p) {} + auto dragEnterEvent(QDragEnterEvent*) -> void; + auto dropEvent(QDropEvent*) -> void; + auto leaveEvent(QEvent*) -> void; + auto mouseMoveEvent(QMouseEvent*) -> void; + auto mousePressEvent(QMouseEvent*) -> void; + auto mouseReleaseEvent(QMouseEvent*) -> void; + pViewport& p; +}; +#endif + +} diff --git a/hiro/qt/qt.moc b/hiro/qt/qt.moc new file mode 100644 index 00000000..c0b4ce98 --- /dev/null +++ b/hiro/qt/qt.moc @@ -0,0 +1,1624 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'qt.hpp' +** +** Created by: The Qt Meta Object Compiler version 63 (Qt 4.8.6) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'qt.hpp' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 63 +#error "This file was generated using the moc from 4.8.6. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +static const uint qt_meta_data_hiro__QtTimer[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 14, 27, 27, 27, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtTimer[] = { + "hiro::QtTimer\0onActivate()\0\0" +}; + +void hiro::QtTimer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtTimer *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtTimer::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtTimer::staticMetaObject = { + { &QTimer::staticMetaObject, qt_meta_stringdata_hiro__QtTimer, + qt_meta_data_hiro__QtTimer, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtTimer::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtTimer::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtTimer::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtTimer)) + return static_cast(const_cast< QtTimer*>(this)); + return QTimer::qt_metacast(_clname); +} + +int hiro::QtTimer::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QTimer::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtMenuItem[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 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, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtMenuItem[] = { + "hiro::QtMenuItem\0onActivate()\0\0" +}; + +void hiro::QtMenuItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtMenuItem *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtMenuItem::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtMenuItem::staticMetaObject = { + { &QAction::staticMetaObject, qt_meta_stringdata_hiro__QtMenuItem, + qt_meta_data_hiro__QtMenuItem, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtMenuItem::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtMenuItem::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtMenuItem::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtMenuItem)) + return static_cast(const_cast< QtMenuItem*>(this)); + return QAction::qt_metacast(_clname); +} + +int hiro::QtMenuItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QAction::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtMenuCheckItem[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 22, 33, 33, 33, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtMenuCheckItem[] = { + "hiro::QtMenuCheckItem\0onToggle()\0\0" +}; + +void hiro::QtMenuCheckItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtMenuCheckItem *_t = static_cast(_o); + switch (_id) { + case 0: _t->onToggle(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtMenuCheckItem::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtMenuCheckItem::staticMetaObject = { + { &QAction::staticMetaObject, qt_meta_stringdata_hiro__QtMenuCheckItem, + qt_meta_data_hiro__QtMenuCheckItem, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtMenuCheckItem::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtMenuCheckItem::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtMenuCheckItem::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtMenuCheckItem)) + return static_cast(const_cast< QtMenuCheckItem*>(this)); + return QAction::qt_metacast(_clname); +} + +int hiro::QtMenuCheckItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QAction::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtMenuRadioItem[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 22, 35, 35, 35, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtMenuRadioItem[] = { + "hiro::QtMenuRadioItem\0onActivate()\0\0" +}; + +void hiro::QtMenuRadioItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtMenuRadioItem *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtMenuRadioItem::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtMenuRadioItem::staticMetaObject = { + { &QAction::staticMetaObject, qt_meta_stringdata_hiro__QtMenuRadioItem, + qt_meta_data_hiro__QtMenuRadioItem, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtMenuRadioItem::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtMenuRadioItem::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtMenuRadioItem::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtMenuRadioItem)) + return static_cast(const_cast< QtMenuRadioItem*>(this)); + return QAction::qt_metacast(_clname); +} + +int hiro::QtMenuRadioItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QAction::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtButton[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 15, 28, 28, 28, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtButton[] = { + "hiro::QtButton\0onActivate()\0\0" +}; + +void hiro::QtButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtButton *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtButton::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtButton::staticMetaObject = { + { &QToolButton::staticMetaObject, qt_meta_stringdata_hiro__QtButton, + qt_meta_data_hiro__QtButton, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtButton::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtButton::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtButton::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtButton)) + return static_cast(const_cast< QtButton*>(this)); + return QToolButton::qt_metacast(_clname); +} + +int hiro::QtButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QToolButton::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtCanvas[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 0, 0, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtCanvas[] = { + "hiro::QtCanvas\0" +}; + +void hiro::QtCanvas::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + Q_UNUSED(_o); + Q_UNUSED(_id); + Q_UNUSED(_c); + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtCanvas::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtCanvas::staticMetaObject = { + { &QWidget::staticMetaObject, qt_meta_stringdata_hiro__QtCanvas, + qt_meta_data_hiro__QtCanvas, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtCanvas::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtCanvas::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtCanvas::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtCanvas)) + return static_cast(const_cast< QtCanvas*>(this)); + return QWidget::qt_metacast(_clname); +} + +int hiro::QtCanvas::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + return _id; +} +static const uint qt_meta_data_hiro__QtCheckButton[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 20, 35, 43, 43, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtCheckButton[] = { + "hiro::QtCheckButton\0onToggle(bool)\0" + "checked\0\0" +}; + +void hiro::QtCheckButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtCheckButton *_t = static_cast(_o); + switch (_id) { + case 0: _t->onToggle((*reinterpret_cast< bool(*)>(_a[1]))); break; + default: ; + } + } +} + +const QMetaObjectExtraData hiro::QtCheckButton::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtCheckButton::staticMetaObject = { + { &QToolButton::staticMetaObject, qt_meta_stringdata_hiro__QtCheckButton, + qt_meta_data_hiro__QtCheckButton, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtCheckButton::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtCheckButton::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtCheckButton::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtCheckButton)) + return static_cast(const_cast< QtCheckButton*>(this)); + return QToolButton::qt_metacast(_clname); +} + +int hiro::QtCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QToolButton::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtCheckLabel[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 19, 30, 30, 30, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtCheckLabel[] = { + "hiro::QtCheckLabel\0onToggle()\0\0" +}; + +void hiro::QtCheckLabel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtCheckLabel *_t = static_cast(_o); + switch (_id) { + case 0: _t->onToggle(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtCheckLabel::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtCheckLabel::staticMetaObject = { + { &QCheckBox::staticMetaObject, qt_meta_stringdata_hiro__QtCheckLabel, + qt_meta_data_hiro__QtCheckLabel, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtCheckLabel::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtCheckLabel::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtCheckLabel::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtCheckLabel)) + return static_cast(const_cast< QtCheckLabel*>(this)); + return QCheckBox::qt_metacast(_clname); +} + +int hiro::QtCheckLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QCheckBox::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtComboButton[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 20, 31, 31, 31, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtComboButton[] = { + "hiro::QtComboButton\0onChange()\0\0" +}; + +void hiro::QtComboButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtComboButton *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtComboButton::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtComboButton::staticMetaObject = { + { &QComboBox::staticMetaObject, qt_meta_stringdata_hiro__QtComboButton, + qt_meta_data_hiro__QtComboButton, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtComboButton::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtComboButton::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtComboButton::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtComboButton)) + return static_cast(const_cast< QtComboButton*>(this)); + return QComboBox::qt_metacast(_clname); +} + +int hiro::QtComboButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QComboBox::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtHexEdit[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 0, 0, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtHexEdit[] = { + "hiro::QtHexEdit\0" +}; + +void hiro::QtHexEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + Q_UNUSED(_o); + Q_UNUSED(_id); + Q_UNUSED(_c); + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtHexEdit::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtHexEdit::staticMetaObject = { + { &QTextEdit::staticMetaObject, qt_meta_stringdata_hiro__QtHexEdit, + qt_meta_data_hiro__QtHexEdit, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtHexEdit::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtHexEdit::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtHexEdit::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtHexEdit)) + return static_cast(const_cast< QtHexEdit*>(this)); + return QTextEdit::qt_metacast(_clname); +} + +int hiro::QtHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QTextEdit::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + return _id; +} +static const uint qt_meta_data_hiro__QtHexEditScrollBar[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 25, 36, 36, 36, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtHexEditScrollBar[] = { + "hiro::QtHexEditScrollBar\0onScroll()\0" + "\0" +}; + +void hiro::QtHexEditScrollBar::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtHexEditScrollBar *_t = static_cast(_o); + switch (_id) { + case 0: _t->onScroll(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtHexEditScrollBar::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtHexEditScrollBar::staticMetaObject = { + { &QScrollBar::staticMetaObject, qt_meta_stringdata_hiro__QtHexEditScrollBar, + qt_meta_data_hiro__QtHexEditScrollBar, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtHexEditScrollBar::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtHexEditScrollBar::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtHexEditScrollBar::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtHexEditScrollBar)) + return static_cast(const_cast< QtHexEditScrollBar*>(this)); + return QScrollBar::qt_metacast(_clname); +} + +int hiro::QtHexEditScrollBar::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QScrollBar::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtHorizontalScroller[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 27, 38, 38, 38, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtHorizontalScroller[] = { + "hiro::QtHorizontalScroller\0onChange()\0" + "\0" +}; + +void hiro::QtHorizontalScroller::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtHorizontalScroller *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtHorizontalScroller::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtHorizontalScroller::staticMetaObject = { + { &QScrollBar::staticMetaObject, qt_meta_stringdata_hiro__QtHorizontalScroller, + qt_meta_data_hiro__QtHorizontalScroller, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtHorizontalScroller::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtHorizontalScroller::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtHorizontalScroller::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtHorizontalScroller)) + return static_cast(const_cast< QtHorizontalScroller*>(this)); + return QScrollBar::qt_metacast(_clname); +} + +int hiro::QtHorizontalScroller::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QScrollBar::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtHorizontalSlider[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 25, 36, 36, 36, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtHorizontalSlider[] = { + "hiro::QtHorizontalSlider\0onChange()\0" + "\0" +}; + +void hiro::QtHorizontalSlider::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtHorizontalSlider *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtHorizontalSlider::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtHorizontalSlider::staticMetaObject = { + { &QSlider::staticMetaObject, qt_meta_stringdata_hiro__QtHorizontalSlider, + qt_meta_data_hiro__QtHorizontalSlider, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtHorizontalSlider::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtHorizontalSlider::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtHorizontalSlider::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtHorizontalSlider)) + return static_cast(const_cast< QtHorizontalSlider*>(this)); + return QSlider::qt_metacast(_clname); +} + +int hiro::QtHorizontalSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QSlider::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtLineEdit[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 2, 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, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtLineEdit[] = { + "hiro::QtLineEdit\0onActivate()\0\0" + "onChange()\0" +}; + +void hiro::QtLineEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtLineEdit *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + case 1: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtLineEdit::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtLineEdit::staticMetaObject = { + { &QLineEdit::staticMetaObject, qt_meta_stringdata_hiro__QtLineEdit, + qt_meta_data_hiro__QtLineEdit, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtLineEdit::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtLineEdit::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtLineEdit::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtLineEdit)) + return static_cast(const_cast< QtLineEdit*>(this)); + return QLineEdit::qt_metacast(_clname); +} + +int hiro::QtLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QLineEdit::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 2) + qt_static_metacall(this, _c, _id, _a); + _id -= 2; + } + 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, 100, 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*)\0" + "item\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]))); 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: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 19, 32, 32, 32, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtRadioLabel[] = { + "hiro::QtRadioLabel\0onActivate()\0\0" +}; + +void hiro::QtRadioLabel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtRadioLabel *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtRadioLabel::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtRadioLabel::staticMetaObject = { + { &QRadioButton::staticMetaObject, qt_meta_stringdata_hiro__QtRadioLabel, + qt_meta_data_hiro__QtRadioLabel, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtRadioLabel::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtRadioLabel::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtRadioLabel::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtRadioLabel)) + return static_cast(const_cast< QtRadioLabel*>(this)); + return QRadioButton::qt_metacast(_clname); +} + +int hiro::QtRadioLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QRadioButton::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtRadioButton[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 20, 33, 33, 33, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtRadioButton[] = { + "hiro::QtRadioButton\0onActivate()\0\0" +}; + +void hiro::QtRadioButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtRadioButton *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtRadioButton::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtRadioButton::staticMetaObject = { + { &QToolButton::staticMetaObject, qt_meta_stringdata_hiro__QtRadioButton, + qt_meta_data_hiro__QtRadioButton, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtRadioButton::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtRadioButton::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtRadioButton::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtRadioButton)) + return static_cast(const_cast< QtRadioButton*>(this)); + return QToolButton::qt_metacast(_clname); +} + +int hiro::QtRadioButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QToolButton::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtTabFrame[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 17, 31, 41, 41, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtTabFrame[] = { + "hiro::QtTabFrame\0onChange(int)\0selection\0" + "\0" +}; + +void hiro::QtTabFrame::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtTabFrame *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange((*reinterpret_cast< int(*)>(_a[1]))); break; + default: ; + } + } +} + +const QMetaObjectExtraData hiro::QtTabFrame::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtTabFrame::staticMetaObject = { + { &QTabWidget::staticMetaObject, qt_meta_stringdata_hiro__QtTabFrame, + qt_meta_data_hiro__QtTabFrame, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtTabFrame::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtTabFrame::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtTabFrame::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtTabFrame)) + return static_cast(const_cast< QtTabFrame*>(this)); + return QTabWidget::qt_metacast(_clname); +} + +int hiro::QtTabFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QTabWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtTextEdit[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 17, 28, 28, 28, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtTextEdit[] = { + "hiro::QtTextEdit\0onChange()\0\0" +}; + +void hiro::QtTextEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtTextEdit *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtTextEdit::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtTextEdit::staticMetaObject = { + { &QTextEdit::staticMetaObject, qt_meta_stringdata_hiro__QtTextEdit, + qt_meta_data_hiro__QtTextEdit, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtTextEdit::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtTextEdit::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtTextEdit::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtTextEdit)) + return static_cast(const_cast< QtTextEdit*>(this)); + return QTextEdit::qt_metacast(_clname); +} + +int hiro::QtTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QTextEdit::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtVerticalScroller[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 25, 36, 36, 36, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtVerticalScroller[] = { + "hiro::QtVerticalScroller\0onChange()\0" + "\0" +}; + +void hiro::QtVerticalScroller::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtVerticalScroller *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtVerticalScroller::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtVerticalScroller::staticMetaObject = { + { &QScrollBar::staticMetaObject, qt_meta_stringdata_hiro__QtVerticalScroller, + qt_meta_data_hiro__QtVerticalScroller, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtVerticalScroller::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtVerticalScroller::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtVerticalScroller::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtVerticalScroller)) + return static_cast(const_cast< QtVerticalScroller*>(this)); + return QScrollBar::qt_metacast(_clname); +} + +int hiro::QtVerticalScroller::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QScrollBar::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtVerticalSlider[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 23, 34, 34, 34, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtVerticalSlider[] = { + "hiro::QtVerticalSlider\0onChange()\0\0" +}; + +void hiro::QtVerticalSlider::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtVerticalSlider *_t = static_cast(_o); + switch (_id) { + case 0: _t->onChange(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtVerticalSlider::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtVerticalSlider::staticMetaObject = { + { &QSlider::staticMetaObject, qt_meta_stringdata_hiro__QtVerticalSlider, + qt_meta_data_hiro__QtVerticalSlider, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtVerticalSlider::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtVerticalSlider::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtVerticalSlider::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtVerticalSlider)) + return static_cast(const_cast< QtVerticalSlider*>(this)); + return QSlider::qt_metacast(_clname); +} + +int hiro::QtVerticalSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QSlider::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } + return _id; +} +static const uint qt_meta_data_hiro__QtViewport[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 0, 0, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtViewport[] = { + "hiro::QtViewport\0" +}; + +void hiro::QtViewport::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + Q_UNUSED(_o); + Q_UNUSED(_id); + Q_UNUSED(_c); + Q_UNUSED(_a); +} + +const QMetaObjectExtraData hiro::QtViewport::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtViewport::staticMetaObject = { + { &QWidget::staticMetaObject, qt_meta_stringdata_hiro__QtViewport, + qt_meta_data_hiro__QtViewport, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtViewport::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtViewport::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtViewport::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtViewport)) + return static_cast(const_cast< QtViewport*>(this)); + return QWidget::qt_metacast(_clname); +} + +int hiro::QtViewport::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + return _id; +} +QT_END_MOC_NAMESPACE diff --git a/hiro/qt/settings.cpp b/hiro/qt/settings.cpp index 11ad54ac..cbf2d56e 100644 --- a/hiro/qt/settings.cpp +++ b/hiro/qt/settings.cpp @@ -1,17 +1,6 @@ -namespace phoenix { +namespace hiro { -static Settings *settings = nullptr; - -void Settings::load() { - string path = {userpath(), ".config/phoenix/"}; - Configuration::Document::load({path, "qt.bml"}); -} - -void Settings::save() { - string path = {userpath(), ".config/phoenix/"}; - directory::create(path, 0755); - Configuration::Document::save({path, "qt.bml"}); -} +static Settings* settings = nullptr; Settings::Settings() { geometry.append(geometry.frameX = 4, "FrameX"); @@ -23,4 +12,15 @@ Settings::Settings() { append(geometry, "Geometry"); } +auto Settings::load() -> void { + string path{configpath(), "hiro/"}; + Configuration::Document::load({path, "qt.bml"}); +} + +auto Settings::save() -> void { + string path{configpath(), "hiro/"}; + directory::create(path, 0755); + Configuration::Document::save({path, "qt.bml"}); +} + } diff --git a/hiro/qt/settings.hpp b/hiro/qt/settings.hpp new file mode 100644 index 00000000..c74657f1 --- /dev/null +++ b/hiro/qt/settings.hpp @@ -0,0 +1,20 @@ +namespace hiro { + +struct Settings : Configuration::Document { + vector keycodes; + + struct Geometry : Configuration::Node { + signed frameX; + signed frameY; + signed frameWidth; + signed frameHeight; + signed menuHeight; + signed statusHeight; + } geometry; + + Settings(); + auto load() -> void; + auto save() -> void; +}; + +} diff --git a/hiro/qt/sizable.cpp b/hiro/qt/sizable.cpp new file mode 100644 index 00000000..4e793ab3 --- /dev/null +++ b/hiro/qt/sizable.cpp @@ -0,0 +1,20 @@ +#if defined(Hiro_Sizable) + +namespace hiro { + +auto pSizable::construct() -> void { +} + +auto pSizable::destruct() -> void { +} + +auto pSizable::minimumSize() const -> Size { + return {0, 0}; +} + +auto pSizable::setGeometry(Geometry geometry) -> void { +} + +} + +#endif diff --git a/hiro/qt/sizable.hpp b/hiro/qt/sizable.hpp new file mode 100644 index 00000000..5270283f --- /dev/null +++ b/hiro/qt/sizable.hpp @@ -0,0 +1,14 @@ +#if defined(Hiro_Sizable) + +namespace hiro { + +struct pSizable : pObject { + Declare(Sizable, Object) + + virtual auto minimumSize() const -> Size; + virtual auto setGeometry(Geometry geometry) -> void; +}; + +} + +#endif diff --git a/hiro/qt/status-bar.cpp b/hiro/qt/status-bar.cpp new file mode 100644 index 00000000..bf8e3faf --- /dev/null +++ b/hiro/qt/status-bar.cpp @@ -0,0 +1,45 @@ +#if defined(Hiro_StatusBar) + +namespace hiro { + +auto pStatusBar::construct() -> void { + _setState(); +} + +auto pStatusBar::destruct() -> void { +} + +auto pStatusBar::setEnabled(bool enabled) -> void { + _setState(); +} + +auto pStatusBar::setFont(const string& font) -> void { + _setState(); +} + +auto pStatusBar::setText(const string& text) -> void { + _setState(); +} + +auto pStatusBar::setVisible(bool visible) -> void { + _setState(); +} + +auto pStatusBar::_parent() -> maybe { + if(auto parent = self().parentWindow()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pStatusBar::_setState() -> void { + if(auto parent = _parent()) { + parent->qtStatusBar->setFont(pFont::create(self().font(true))); + parent->qtStatusBar->showMessage(QString::fromUtf8(state().text), 0); + parent->qtStatusBar->setVisible(self().visible()); + } +} + +} + +#endif diff --git a/hiro/qt/status-bar.hpp b/hiro/qt/status-bar.hpp new file mode 100644 index 00000000..7d0f9bec --- /dev/null +++ b/hiro/qt/status-bar.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_StatusBar) + +namespace hiro { + +struct pStatusBar : pObject { + Declare(StatusBar, Object) + + auto setEnabled(bool enabled) -> void override; + auto setFont(const string& font) -> void override; + auto setText(const string& text) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/timer.cpp b/hiro/qt/timer.cpp index 6ed9a3b8..13a67615 100644 --- a/hiro/qt/timer.cpp +++ b/hiro/qt/timer.cpp @@ -1,6 +1,18 @@ -namespace phoenix { +#if defined(Hiro_Timer) -void pTimer::setEnabled(bool enabled) { +namespace hiro { + +auto pTimer::construct() -> void { + qtTimer = new QtTimer(*this); + qtTimer->setInterval(0); + qtTimer->connect(qtTimer, SIGNAL(timeout()), SLOT(onActivate())); +} + +auto pTimer::destruct() -> void { + delete qtTimer; +} + +auto pTimer::setEnabled(bool enabled) -> void { if(enabled) { qtTimer->start(); } else { @@ -8,22 +20,14 @@ void pTimer::setEnabled(bool enabled) { } } -void pTimer::setInterval(unsigned interval) { +auto pTimer::setInterval(unsigned interval) -> void { qtTimer->setInterval(interval); } -void pTimer::constructor() { - qtTimer = new QTimer; - qtTimer->setInterval(0); - connect(qtTimer, SIGNAL(timeout()), SLOT(onActivate())); -} - -void pTimer::destructor() { - delete qtTimer; -} - -void pTimer::onActivate() { - if(timer.onActivate) timer.onActivate(); +auto QtTimer::onActivate() -> void { + p.self().doActivate(); } } + +#endif diff --git a/hiro/qt/timer.hpp b/hiro/qt/timer.hpp new file mode 100644 index 00000000..a3fb8f54 --- /dev/null +++ b/hiro/qt/timer.hpp @@ -0,0 +1,16 @@ +#if defined(Hiro_Timer) + +namespace hiro { + +struct pTimer : pObject { + Declare(Timer, Object) + + auto setEnabled(bool enabled) -> void override; + auto setInterval(unsigned interval) -> void; + + QtTimer* qtTimer = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/utility.cpp b/hiro/qt/utility.cpp index 4a175807..86eeeef1 100644 --- a/hiro/qt/utility.cpp +++ b/hiro/qt/utility.cpp @@ -1,22 +1,37 @@ -namespace phoenix { +namespace hiro { -static QIcon CreateIcon(const nall::image& image, bool scale = false) { - if(image.empty()) return QIcon(); - nall::image qtBuffer = image; - qtBuffer.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0); +static auto CalculateAlignment(Alignment alignment) -> signed { + signed result = 0; + if(alignment.horizontal() < 0.333) result |= Qt::AlignLeft; + else if(alignment.horizontal() > 0.666) result |= Qt::AlignRight; + else result |= Qt::AlignCenter; + if(alignment.vertical() < 0.333) result |= Qt::AlignTop; + else if(alignment.vertical() > 0.666) result |= Qt::AlignBottom; + else result |= Qt::AlignVCenter; + return result; +} + +static auto CreateBrush(Color color) -> QBrush { + return color ? QColor(color.red(), color.green(), color.blue()) : QBrush(); +} + +static auto CreateIcon(const nall::image& icon, bool scale = false) -> QIcon { + if(!icon) return QIcon(); + auto qtBuffer = icon; + qtBuffer.transform(); if(scale) qtBuffer.scale(16, 16, Interpolation::Linear); - QImage qtImage(qtBuffer.data, qtBuffer.width, qtBuffer.height, QImage::Format_ARGB32); + QImage qtImage(qtBuffer.data(), qtBuffer.width(), qtBuffer.height(), QImage::Format_ARGB32); return QIcon(QPixmap::fromImage(qtImage)); } -static lstring DropPaths(QDropEvent* event) { +static auto DropPaths(QDropEvent* event) -> lstring { QList urls = event->mimeData()->urls(); if(urls.size() == 0) return {}; lstring paths; - for(unsigned n = 0; n < urls.size(); n++) { - string path = urls[n].path().toUtf8().constData(); - if(path.empty()) continue; + for(auto n : range(urls.size())) { + string path{urls[n].path().toUtf8().constData()}; + if(!path) continue; if(directory::exists(path) && !path.endsWith("/")) path.append("/"); paths.append(path); } @@ -24,7 +39,8 @@ static lstring DropPaths(QDropEvent* event) { return paths; } -static Position GetDisplacement(Sizable* sizable) { +/* +static auto GetDisplacement(Sizable* sizable) -> Position { Position position; while(sizable->state.parent) { Position displacement = sizable->state.parent->p.displacement(); @@ -34,24 +50,30 @@ static Position GetDisplacement(Sizable* sizable) { } return position; } +*/ -static Layout* GetParentWidgetLayout(Sizable* sizable) { +/* +static auto GetParentWidgetLayout(Sizable* sizable) -> Layout* { while(sizable) { if(sizable->state.parent && dynamic_cast(sizable->state.parent)) return (Layout*)sizable; sizable = sizable->state.parent; } return nullptr; } +*/ -static Widget* GetParentWidget(Sizable* sizable) { +/* +static auto GetParentWidget(Sizable* sizable) -> Widget* { while(sizable) { if(sizable->state.parent && dynamic_cast(sizable->state.parent)) return (Widget*)sizable->state.parent; sizable = sizable->state.parent; } return nullptr; } +*/ -static Keyboard::Keycode Keysym(int keysym) { +/* +static auto Keysym(int keysym) -> Keyboard::Keycode { switch(keysym) { case XK_Escape: return Keyboard::Keycode::Escape; case XK_F1: return Keyboard::Keycode::F1; @@ -233,5 +255,6 @@ static Keyboard::Keycode Keysym(int keysym) { } return Keyboard::Keycode::None; } +*/ } diff --git a/hiro/qt/widget/button.cpp b/hiro/qt/widget/button.cpp index 083e5272..e0593c04 100644 --- a/hiro/qt/widget/button.cpp +++ b/hiro/qt/widget/button.cpp @@ -1,62 +1,66 @@ -namespace phoenix { +#if defined(Hiro_Button) -Size pButton::minimumSize() { - Size size = pFont::size(qtWidget->font(), button.state.text); +namespace hiro { - if(button.state.orientation == Orientation::Horizontal) { - size.width += button.state.image.width; - size.height = max(button.state.image.height, size.height); - } +auto pButton::construct() -> void { + qtWidget = qtButton = new QtButton(*this); + qtButton->setToolButtonStyle(Qt::ToolButtonTextOnly); + qtButton->connect(qtButton, SIGNAL(released()), SLOT(onActivate())); - if(button.state.orientation == Orientation::Vertical) { - size.width = max(button.state.image.width, size.width); - size.height += button.state.image.height; - } + setBordered(state().bordered); + setIcon(state().icon); + setOrientation(state().orientation); + setText(state().text); - return {size.width + (button.state.text ? 20 : 12), size.height + 12}; + pWidget::construct(); } -void pButton::setBordered(bool bordered) { - qtButton->setAutoRaise(bordered == false); +auto pButton::destruct() -> void { + delete qtButton; + qtWidget = qtButton = nullptr; } -void pButton::setImage(const image& image, Orientation orientation) { - qtButton->setIconSize(QSize(image.width, image.height)); - qtButton->setIcon(CreateIcon(image)); +auto pButton::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + + if(state().orientation == Orientation::Horizontal) { + size.setWidth(size.width() + state().icon.width()); + size.setHeight(max(state().icon.height(), size.height())); + } + + if(state().orientation == Orientation::Vertical) { + size.setWidth(max(state().icon.width(), size.width())); + size.setHeight(size.height() + state().icon.height()); + } + + return {size.width() + (state().text ? 20 : 12), size.height() + 12}; +} + +auto pButton::setBordered(bool bordered) -> void { + qtButton->setAutoRaise(!bordered); +} + +auto pButton::setIcon(const image& icon) -> void { + qtButton->setIconSize(QSize(icon.width(), icon.height())); + qtButton->setIcon(CreateIcon(icon)); qtButton->setStyleSheet("text-align: top;"); +} + +auto pButton::setOrientation(Orientation orientation) -> void { switch(orientation) { case Orientation::Horizontal: qtButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break; case Orientation::Vertical: qtButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); break; } } -void pButton::setText(string text) { +auto pButton::setText(const string& text) -> void { qtButton->setText(QString::fromUtf8(text)); } -void pButton::constructor() { - qtWidget = qtButton = new QToolButton; - qtButton->setToolButtonStyle(Qt::ToolButtonTextOnly); - connect(qtButton, SIGNAL(released()), SLOT(onActivate())); - - pWidget::synchronizeState(); - setBordered(button.state.bordered); - setImage(button.state.image, button.state.orientation); - setText(button.state.text); -} - -void pButton::destructor() { - delete qtButton; - qtWidget = qtButton = nullptr; -} - -void pButton::orphan() { - destructor(); - constructor(); -} - -void pButton::onActivate() { - if(button.onActivate) button.onActivate(); +auto QtButton::onActivate() -> void { + p.self().doActivate(); } } + +#endif diff --git a/hiro/qt/widget/button.hpp b/hiro/qt/widget/button.hpp new file mode 100644 index 00000000..2cc25b0d --- /dev/null +++ b/hiro/qt/widget/button.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_Button) + +namespace hiro { + +struct pButton : pWidget { + Declare(Button, Widget) + + auto minimumSize() const -> Size override; + auto setBordered(bool bordered) -> void; + auto setIcon(const image& icon) -> void; + auto setOrientation(Orientation orientation) -> void; + auto setText(const string& text) -> void; + + QtButton* qtButton = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/canvas.cpp b/hiro/qt/widget/canvas.cpp index 648fc030..37181a1b 100644 --- a/hiro/qt/widget/canvas.cpp +++ b/hiro/qt/widget/canvas.cpp @@ -1,155 +1,180 @@ -namespace phoenix { +#if defined(Hiro_Canvas) -void pCanvas::setDroppable(bool droppable) { - qtCanvas->setAcceptDrops(droppable); -} +namespace hiro { -void pCanvas::setGeometry(Geometry geometry) { - if(canvas.state.width == 0 || canvas.state.height == 0) rasterize(); - unsigned width = canvas.state.width; - unsigned height = canvas.state.height; - if(width == 0) width = widget.state.geometry.width; - if(height == 0) height = widget.state.geometry.height; - - if(width < geometry.width) { - geometry.x += (geometry.width - width) / 2; - geometry.width = width; - } - - if(height < geometry.height) { - geometry.y += (geometry.height - height) / 2; - geometry.height = height; - } - - pWidget::setGeometry(geometry); -} - -void pCanvas::setMode(Canvas::Mode mode) { - rasterize(); - qtCanvas->update(); -} - -void pCanvas::setSize(Size size) { - rasterize(); - qtCanvas->update(); -} - -void pCanvas::constructor() { +auto pCanvas::construct() -> void { qtWidget = qtCanvas = new QtCanvas(*this); qtCanvas->setMouseTracking(true); - pWidget::synchronizeState(); - rasterize(), qtCanvas->update(); + pWidget::construct(); + _rasterize(); + qtCanvas->update(); } -void pCanvas::destructor() { - release(); +auto pCanvas::destruct() -> void { + _release(); delete qtCanvas; qtWidget = qtCanvas = nullptr; } -void pCanvas::orphan() { - destructor(); - constructor(); +auto pCanvas::minimumSize() const -> Size { + return {max(0, state().size.width()), max(0, state().size.height())}; } -void pCanvas::rasterize() { - unsigned width = canvas.state.width; - unsigned height = canvas.state.height; - if(width == 0) width = widget.state.geometry.width; - if(height == 0) height = widget.state.geometry.height; +auto pCanvas::setColor(Color color) -> void { + mode = Mode::Color; + update(); +} - if(canvas.state.mode != Canvas::Mode::Color) { - if(width != surfaceWidth || height != surfaceHeight) release(); - if(!surface) surface = new QImage(width, height, QImage::Format_ARGB32); +auto pCanvas::setData(Size size) -> void { + mode = Mode::Data; + update(); +} + +auto pCanvas::setDroppable(bool droppable) -> void { + qtCanvas->setAcceptDrops(droppable); +} + +auto pCanvas::setGeometry(Geometry geometry) -> void { + update(); + pWidget::setGeometry(geometry); +} + +auto pCanvas::setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> void { + mode = Mode::Gradient; + update(); +} + +auto pCanvas::setIcon(const image& icon) -> void { + mode = Mode::Icon; + update(); +} + +auto pCanvas::update() -> void { + _rasterize(); + qtCanvas->update(); +} + +auto pCanvas::_rasterize() -> void { + signed width = 0; + signed height = 0; + + if(mode == Mode::Color || mode == Mode::Gradient) { + width = pSizable::state().geometry.width(); + height = pSizable::state().geometry.height(); + } else { + width = state().size.width(); + height = state().size.height(); } - if(canvas.state.mode == Canvas::Mode::Gradient) { - nall::image image; - image.allocate(width, height); - image.gradient( - canvas.state.gradient[0].argb(), canvas.state.gradient[1].argb(), canvas.state.gradient[2].argb(), canvas.state.gradient[3].argb() + if(width <= 0 || height <= 0) return; + + if(width != qtImageWidth || height != qtImageHeight) _release(); + qtImageWidth = width; + qtImageHeight = height; + + if(!qtImage) qtImage = new QImage(width, height, QImage::Format_ARGB32); + auto buffer = (uint32_t*)qtImage->bits(); + + if(mode == Mode::Color) { + uint32_t color = state().color.value(); + for(auto n : range(width * height)) buffer[n] = color; + } + + if(mode == Mode::Gradient) { + image fill; + fill.allocate(width, height); + fill.gradient( + state().gradient[0].value(), state().gradient[1].value(), state().gradient[2].value(), state().gradient[3].value() ); - memcpy(surface->bits(), image.data, image.size); + memory::copy(buffer, fill.data(), fill.size()); } - if(canvas.state.mode == Canvas::Mode::Image) { - nall::image image = canvas.state.image; - image.scale(width, height); - image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0); - memcpy(surface->bits(), image.data, image.size); + if(mode == Mode::Icon) { + auto icon = state().icon; + icon.scale(width, height); + icon.transform(); + memory::copy(buffer, icon.data(), icon.size()); } - if(canvas.state.mode == Canvas::Mode::Data) { - if(width == canvas.state.width && height == canvas.state.height) { - memcpy(surface->bits(), canvas.state.data, width * height * sizeof(uint32_t)); - } else { - memset(surface->bits(), 0x00, width * height * sizeof(uint32_t)); - } + if(mode == Mode::Data) { + memory::copy(buffer, state().data.data(), state().data.size() * sizeof(uint32_t)); } - - surfaceWidth = width; - surfaceHeight = height; } -void pCanvas::release() { - if(surface == nullptr) return; - delete surface; - surface = nullptr; - surfaceWidth = 0; - surfaceHeight = 0; +auto pCanvas::_release() -> void { + if(qtImage) { + delete qtImage; + qtImage = nullptr; + } + qtImageWidth = 0; + qtImageHeight = 0; } -void pCanvas::QtCanvas::dragEnterEvent(QDragEnterEvent* event) { +auto QtCanvas::dragEnterEvent(QDragEnterEvent* event) -> void { if(event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } -void pCanvas::QtCanvas::dropEvent(QDropEvent* event) { - lstring paths = DropPaths(event); - if(paths.empty()) return; - if(self.canvas.onDrop) self.canvas.onDrop(paths); +auto QtCanvas::dropEvent(QDropEvent* event) -> void { + if(auto paths = DropPaths(event)) p.self().doDrop(paths); } -void pCanvas::QtCanvas::leaveEvent(QEvent* event) { - if(self.canvas.onMouseLeave) self.canvas.onMouseLeave(); +auto QtCanvas::leaveEvent(QEvent* event) -> void { + p.self().doMouseLeave(); } -void pCanvas::QtCanvas::mouseMoveEvent(QMouseEvent* event) { - if(self.canvas.onMouseMove) self.canvas.onMouseMove({event->pos().x(), event->pos().y()}); +auto QtCanvas::mouseMoveEvent(QMouseEvent* event) -> void { + p.self().doMouseMove({event->pos().x(), event->pos().y()}); } -void pCanvas::QtCanvas::mousePressEvent(QMouseEvent* event) { - if(!self.canvas.onMousePress) return; +auto QtCanvas::mousePressEvent(QMouseEvent* event) -> void { switch(event->button()) { - case Qt::LeftButton: self.canvas.onMousePress(Mouse::Button::Left); break; - case Qt::MidButton: self.canvas.onMousePress(Mouse::Button::Middle); break; - case Qt::RightButton: self.canvas.onMousePress(Mouse::Button::Right); break; + case Qt::LeftButton: p.self().doMousePress(Mouse::Button::Left); break; + case Qt::MidButton: p.self().doMousePress(Mouse::Button::Middle); break; + case Qt::RightButton: p.self().doMousePress(Mouse::Button::Right); break; } } -void pCanvas::QtCanvas::mouseReleaseEvent(QMouseEvent* event) { - if(!self.canvas.onMouseRelease) return; +auto QtCanvas::mouseReleaseEvent(QMouseEvent* event) -> void { switch(event->button()) { - case Qt::LeftButton: self.canvas.onMouseRelease(Mouse::Button::Left); break; - case Qt::MidButton: self.canvas.onMouseRelease(Mouse::Button::Middle); break; - case Qt::RightButton: self.canvas.onMouseRelease(Mouse::Button::Right); break; + case Qt::LeftButton: p.self().doMouseRelease(Mouse::Button::Left); break; + case Qt::MidButton: p.self().doMouseRelease(Mouse::Button::Middle); break; + case Qt::RightButton: p.self().doMouseRelease(Mouse::Button::Right); break; } } -void pCanvas::QtCanvas::paintEvent(QPaintEvent* event) { - Canvas& canvas = self.canvas; - QPainter painter(self.qtCanvas); +auto QtCanvas::paintEvent(QPaintEvent* event) -> void { + if(!p.qtImage) return; - if(canvas.state.mode == Canvas::Mode::Color) { - painter.fillRect(event->rect(), QBrush(QColor(canvas.state.color.red, canvas.state.color.green, canvas.state.color.blue, canvas.state.color.alpha))); + signed sx = 0, sy = 0, dx = 0, dy = 0; + signed width = p.qtImageWidth; + signed height = p.qtImageHeight; + auto geometry = p.pSizable::state().geometry; + + if(width <= geometry.width()) { + sx = 0; + dx = (geometry.width() - width) / 2; } else { - painter.drawImage(0, 0, *self.surface); + sx = (width - geometry.width()) / 2; + dx = 0; + width = geometry.width(); } -} -pCanvas::QtCanvas::QtCanvas(pCanvas& self) : self(self) { + if(height <= geometry.height()) { + sy = 0; + dy = (geometry.height() - height) / 2; + } else { + sy = (height - geometry.height()) / 2; + dy = 0; + height = geometry.height(); + } + + QPainter painter(p.qtCanvas); + painter.drawImage(dx, dy, *p.qtImage, sx, sy, width, height); } } + +#endif diff --git a/hiro/qt/widget/canvas.hpp b/hiro/qt/widget/canvas.hpp new file mode 100644 index 00000000..91682f43 --- /dev/null +++ b/hiro/qt/widget/canvas.hpp @@ -0,0 +1,31 @@ +#if defined(Hiro_Canvas) + +namespace hiro { + +struct pCanvas : pWidget { + Declare(Canvas, Widget) + + auto minimumSize() const -> Size; + auto setColor(Color color) -> void; + auto setData(Size size) -> void; + auto setDroppable(bool droppable) -> void; + auto setGeometry(Geometry geometry) -> void; + auto setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> void; + auto setIcon(const image& icon) -> void; + auto update() -> void; + + enum class Mode : unsigned { Color, Data, Gradient, Icon }; + + auto _rasterize() -> void; + auto _release() -> void; + + QtCanvas* qtCanvas = nullptr; + QImage* qtImage = nullptr; + unsigned qtImageWidth = 0; + unsigned qtImageHeight = 0; + Mode mode = Mode::Color; +}; + +} + +#endif diff --git a/hiro/qt/widget/check-button.cpp b/hiro/qt/widget/check-button.cpp index 6248ab51..4e71ef8b 100644 --- a/hiro/qt/widget/check-button.cpp +++ b/hiro/qt/widget/check-button.cpp @@ -1,63 +1,78 @@ -namespace phoenix { +#if defined(Hiro_CheckButton) -Size pCheckButton::minimumSize() { - Size size = pFont::size(qtWidget->font(), checkButton.state.text); +namespace hiro { - if(checkButton.state.orientation == Orientation::Horizontal) { - size.width += checkButton.state.image.width; - size.height = max(checkButton.state.image.height, size.height); - } +auto pCheckButton::construct() -> void { + qtWidget = qtCheckButton = new QtCheckButton(*this); + qtCheckButton->setCheckable(true); + qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextOnly); + qtCheckButton->connect(qtCheckButton, SIGNAL(toggled(bool)), SLOT(onToggle(bool))); - if(checkButton.state.orientation == Orientation::Vertical) { - size.width = max(checkButton.state.image.width, size.width); - size.height += checkButton.state.image.height; - } - - return {size.width + 20, size.height + 12}; + pWidget::construct(); + _setState(); } -void pCheckButton::setChecked(bool checked) { +auto pCheckButton::destruct() -> void { + delete qtCheckButton; + qtCheckButton = nullptr; +} + +auto pCheckButton::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + + if(state().orientation == Orientation::Horizontal) { + size.setWidth(size.width() + state().icon.width()); + size.setHeight(max(state().icon.height(), size.height())); + } + + if(state().orientation == Orientation::Vertical) { + size.setWidth(max(state().icon.width(), size.width())); + size.setHeight(size.height() + state().icon.height()); + } + + return {size.width() + 20, size.height() + 12}; +} + +auto pCheckButton::setBordered(bool bordered) -> void { + _setState(); +} + +auto pCheckButton::setChecked(bool checked) -> void { + _setState(); +} + +auto pCheckButton::setIcon(const image& icon) -> void { + _setState(); +} + +auto pCheckButton::setOrientation(Orientation orientation) -> void { + _setState(); +} + +auto pCheckButton::setText(const string& text) -> void { + _setState(); +} + +auto pCheckButton::_setState() -> void { lock(); - qtCheckButton->setChecked(checked); - unlock(); -} - -void pCheckButton::setImage(const image& image, Orientation orientation) { - qtCheckButton->setIconSize(QSize(image.width, image.height)); - qtCheckButton->setIcon(CreateIcon(image)); + qtCheckButton->setAutoRaise(!state().bordered); + qtCheckButton->setChecked(state().checked); + qtCheckButton->setIconSize(QSize(state().icon.width(), state().icon.height())); + qtCheckButton->setIcon(CreateIcon(state().icon)); qtCheckButton->setStyleSheet("text-align: top;"); - switch(orientation) { + switch(state().orientation) { case Orientation::Horizontal: qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break; case Orientation::Vertical: qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); break; } + qtCheckButton->setText(QString::fromUtf8(state().text)); + unlock(); } -void pCheckButton::setText(string text) { - qtCheckButton->setText(QString::fromUtf8(text)); -} - -void pCheckButton::constructor() { - qtWidget = qtCheckButton = new QToolButton; - qtCheckButton->setCheckable(true); - qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextOnly); - connect(qtCheckButton, SIGNAL(toggled(bool)), SLOT(onToggle(bool))); - - pWidget::synchronizeState(); - setChecked(checkButton.state.checked); - setText(checkButton.state.text); -} - -void pCheckButton::destructor() { -} - -void pCheckButton::orphan() { - destructor(); - constructor(); -} - -void pCheckButton::onToggle(bool checked) { - checkButton.state.checked = checked; - if(!locked() && checkButton.onToggle) checkButton.onToggle(); +auto QtCheckButton::onToggle(bool checked) -> void { + p.state().checked = checked; + if(!p.locked()) p.self().doToggle(); } } + +#endif diff --git a/hiro/qt/widget/check-button.hpp b/hiro/qt/widget/check-button.hpp new file mode 100644 index 00000000..092c8024 --- /dev/null +++ b/hiro/qt/widget/check-button.hpp @@ -0,0 +1,22 @@ +#if defined(Hiro_CheckButton) + +namespace hiro { + +struct pCheckButton : pWidget { + Declare(CheckButton, Widget) + + auto minimumSize() const -> Size override; + auto setBordered(bool bordered) -> void; + auto setChecked(bool checked) -> void; + auto setIcon(const image& icon) -> void; + auto setOrientation(Orientation orientation) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void; + + QtCheckButton* qtCheckButton = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/check-label.cpp b/hiro/qt/widget/check-label.cpp index b3246fa4..d5b9de23 100644 --- a/hiro/qt/widget/check-label.cpp +++ b/hiro/qt/widget/check-label.cpp @@ -1,42 +1,45 @@ -namespace phoenix { +#if defined(Hiro_CheckLabel) -Size pCheckLabel::minimumSize() { - Size size = pFont::size(qtWidget->font(), checkLabel.state.text); - return {size.width + 26, size.height + 6}; +namespace hiro { + +auto pCheckLabel::construct() -> void { + qtWidget = qtCheckLabel = new QtCheckLabel(*this); + qtCheckLabel->connect(qtCheckLabel, SIGNAL(stateChanged(int)), SLOT(onToggle())); + + pWidget::construct(); + _setState(); } -void pCheckLabel::setChecked(bool checked) { - lock(); - qtCheckLabel->setChecked(checked); - unlock(); -} - -void pCheckLabel::setText(string text) { - qtCheckLabel->setText(QString::fromUtf8(text)); -} - -void pCheckLabel::constructor() { - qtWidget = qtCheckLabel = new QCheckBox; - connect(qtCheckLabel, SIGNAL(stateChanged(int)), SLOT(onToggle())); - - pWidget::synchronizeState(); - setChecked(checkLabel.state.checked); - setText(checkLabel.state.text); -} - -void pCheckLabel::destructor() { +auto pCheckLabel::destruct() -> void { delete qtCheckLabel; qtWidget = qtCheckLabel = nullptr; } -void pCheckLabel::orphan() { - destructor(); - constructor(); +auto pCheckLabel::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + return {size.width() + 26, size.height() + 6}; } -void pCheckLabel::onToggle() { - checkLabel.state.checked = qtCheckLabel->isChecked(); - if(!locked() && checkLabel.onToggle) checkLabel.onToggle(); +auto pCheckLabel::setChecked(bool checked) -> void { + _setState(); +} + +auto pCheckLabel::setText(const string& text) -> void { + _setState(); +} + +auto pCheckLabel::_setState() -> void { + lock(); + qtCheckLabel->setChecked(state().checked); + qtCheckLabel->setText(QString::fromUtf8(state().text)); + unlock(); +} + +auto QtCheckLabel::onToggle() -> void { + p.state().checked = p.qtCheckLabel->isChecked(); + if(!p.locked()) p.self().doToggle(); } } + +#endif diff --git a/hiro/qt/widget/check-label.hpp b/hiro/qt/widget/check-label.hpp new file mode 100644 index 00000000..7bd53abd --- /dev/null +++ b/hiro/qt/widget/check-label.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_CheckLabel) + +namespace hiro { + +struct pCheckLabel : pWidget { + Declare(CheckLabel, Widget) + + auto minimumSize() const -> Size override; + auto setChecked(bool checked) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void; + + QtCheckLabel* qtCheckLabel = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/combo-button-item.cpp b/hiro/qt/widget/combo-button-item.cpp new file mode 100644 index 00000000..6bc1d067 --- /dev/null +++ b/hiro/qt/widget/combo-button-item.cpp @@ -0,0 +1,49 @@ +#if defined(Hiro_ComboButton) + +namespace hiro { + +auto pComboButtonItem::construct() -> void { + if(auto parent = _parent()) { + parent->qtComboButton->addItem(""); + _setState(); + } +} + +auto pComboButtonItem::destruct() -> void { + if(auto parent = _parent()) { + parent->lock(); + parent->qtComboButton->removeItem(self().offset()); + parent->unlock(); + } +} + +auto pComboButtonItem::setIcon(const image& icon) -> void { + _setState(); +} + +auto pComboButtonItem::setSelected() -> void { + _setState(); +} + +auto pComboButtonItem::setText(const string& text) -> void { + _setState(); +} + +auto pComboButtonItem::_parent() -> maybe { + if(auto parent = self().parentComboButton()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pComboButtonItem::_setState() -> void { + if(auto parent = _parent()) { + parent->qtComboButton->setItemIcon(self().offset(), CreateIcon(state().icon)); + if(state().selected) parent->qtComboButton->setCurrentIndex(self().offset()); + parent->qtComboButton->setItemText(self().offset(), QString::fromUtf8(state().text)); + } +} + +} + +#endif diff --git a/hiro/qt/widget/combo-button-item.hpp b/hiro/qt/widget/combo-button-item.hpp new file mode 100644 index 00000000..11e65a4e --- /dev/null +++ b/hiro/qt/widget/combo-button-item.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_ComboButton) + +namespace hiro { + +struct pComboButtonItem : pObject { + Declare(ComboButtonItem, Object) + + auto setIcon(const image& icon) -> void; + auto setSelected() -> void; + auto setText(const string& text) -> void; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/widget/combo-button.cpp b/hiro/qt/widget/combo-button.cpp index 4e7250c7..02a2b89e 100644 --- a/hiro/qt/widget/combo-button.cpp +++ b/hiro/qt/widget/combo-button.cpp @@ -1,67 +1,44 @@ -namespace phoenix { +#if defined(Hiro_ComboButton) -void pComboButton::append() { - lock(); - qtComboButton->addItem(""); - unlock(); +namespace hiro { + +auto pComboButton::construct() -> void { + qtWidget = qtComboButton = new QtComboButton(*this); + qtComboButton->connect(qtComboButton, SIGNAL(currentIndexChanged(int)), SLOT(onChange())); + + pWidget::construct(); } -Size pComboButton::minimumSize() { - unsigned maximumWidth = 0; - for(auto& text : comboButton.state.text) maximumWidth = max(maximumWidth, pFont::size(qtWidget->font(), text).width); - Size size = pFont::size(qtWidget->font(), " "); - return {maximumWidth + 32, size.height + 12}; +auto pComboButton::destruct() -> void { + delete qtComboButton; + qtWidget = qtComboButton = nullptr; } -void pComboButton::remove(unsigned selection) { - lock(); - qtComboButton->removeItem(selection); - if(selection == comboButton.state.selection) comboButton[0].setSelected(); - unlock(); +auto pComboButton::append(sComboButtonItem item) -> void { } -void pComboButton::reset() { +auto pComboButton::minimumSize() const -> Size { + signed maximumWidth = 0; + for(auto& item : state().items) { + maximumWidth = max(maximumWidth, pFont::size(qtWidget->font(), item->state.text).width()); + } + auto size = pFont::size(qtWidget->font(), " "); + return {maximumWidth + 32, size.height() + 12}; +} + +auto pComboButton::remove(sComboButtonItem item) -> void { +} + +auto pComboButton::reset() -> void { lock(); while(qtComboButton->count()) qtComboButton->removeItem(0); unlock(); } -void pComboButton::setSelected(unsigned selection) { - lock(); - qtComboButton->setCurrentIndex(selection); - unlock(); -} - -void pComboButton::setText(unsigned selection, string text) { - qtComboButton->setItemText(selection, text); -} - -void pComboButton::constructor() { - qtWidget = qtComboButton = new QComboBox; - connect(qtComboButton, SIGNAL(currentIndexChanged(int)), SLOT(onChange())); - - pWidget::synchronizeState(); - unsigned selection = comboButton.state.selection; - for(unsigned n = 0; n < comboButton.count(); n++) { - append(); - setText(n, comboButton.state.text[n]); - } - comboButton[selection].setSelected(); -} - -void pComboButton::destructor() { - delete qtComboButton; - qtWidget = qtComboButton = nullptr; -} - -void pComboButton::orphan() { - destructor(); - constructor(); -} - -void pComboButton::onChange() { - comboButton.state.selection = qtComboButton->currentIndex(); - if(!locked() && comboButton.onChange) comboButton.onChange(); +auto QtComboButton::onChange() -> void { + if(!p.locked()) p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/combo-button.hpp b/hiro/qt/widget/combo-button.hpp new file mode 100644 index 00000000..e1cb035d --- /dev/null +++ b/hiro/qt/widget/combo-button.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_ComboButton) + +namespace hiro { + +struct pComboButton : pWidget { + Declare(ComboButton, Widget) + + auto append(sComboButtonItem item) -> void; + auto minimumSize() const -> Size override; + auto remove(sComboButtonItem item) -> void; + auto reset() -> void; + + QtComboButton* qtComboButton = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/console.cpp b/hiro/qt/widget/console.cpp index 5173a126..cbce9519 100644 --- a/hiro/qt/widget/console.cpp +++ b/hiro/qt/widget/console.cpp @@ -1,4 +1,6 @@ -namespace phoenix { +#if defined(Hiro_Console) + +namespace hiro { void pConsole::print(string text) { } @@ -50,3 +52,5 @@ void pConsole::QtConsole::keyPressEventAcknowledge(QKeyEvent* event) { } } + +#endif diff --git a/hiro/qt/widget/frame.cpp b/hiro/qt/widget/frame.cpp index 77edb5a9..8fb42335 100644 --- a/hiro/qt/widget/frame.cpp +++ b/hiro/qt/widget/frame.cpp @@ -1,30 +1,8 @@ -namespace phoenix { +#if defined(Hiro_Frame) -void pFrame::setEnabled(bool enabled) { - if(frame.state.layout) frame.state.layout->setEnabled(frame.state.layout->enabled()); - pWidget::setEnabled(enabled); -} +namespace hiro { -void pFrame::setGeometry(Geometry geometry) { - pWidget::setGeometry(geometry); - if(frame.state.layout == nullptr) return; - Size size = pFont::size(widget.state.font, frame.state.text); - if(frame.state.text.empty()) size.height = 8; - geometry.x += 1, geometry.width -= 2; - geometry.y += size.height, geometry.height -= size.height + 1; - frame.state.layout->setGeometry(geometry); -} - -void pFrame::setText(string text) { - qtFrame->setTitle(QString::fromUtf8(text)); -} - -void pFrame::setVisible(bool visible) { - if(frame.state.layout) frame.state.layout->setVisible(frame.state.layout->visible()); - pWidget::setVisible(visible); -} - -void pFrame::constructor() { +auto pFrame::construct() -> void { qtWidget = qtFrame = new QGroupBox; if(QApplication::style()->objectName() == "gtk+") { //QGtkStyle (gtk+) theme disrespects font weight and omits the border, even if native GTK+ theme does not @@ -35,18 +13,46 @@ void pFrame::constructor() { ); } - pWidget::synchronizeState(); - setText(frame.state.text); + pWidget::construct(); + _setState(); } -void pFrame::destructor() { +auto pFrame::destruct() -> void { delete qtFrame; qtWidget = qtFrame = nullptr; } -void pFrame::orphan() { - destructor(); - constructor(); +auto pFrame::setEnabled(bool enabled) -> void { + if(auto layout = state().layout) layout->setEnabled(layout->enabled(true)); + pWidget::setEnabled(enabled); +} + +auto pFrame::setGeometry(Geometry geometry) -> void { + pWidget::setGeometry(geometry); + if(auto layout = state().layout) { + auto size = pFont::size(qtFrame->font(), state().text); + if(!state().text) size.setHeight(8); + layout->setGeometry({ + 4, size.height(), + geometry.width() - 8, + geometry.height() - size.height() - 4 + }); + } +} + +auto pFrame::setText(const string& text) -> void { + _setState(); +} + +auto pFrame::setVisible(bool visible) -> void { + if(auto layout = state().layout) layout->setVisible(layout->visible(true)); + pWidget::setVisible(visible); +} + +auto pFrame::_setState() -> void { + qtFrame->setTitle(QString::fromUtf8(state().text)); } } + +#endif diff --git a/hiro/qt/widget/frame.hpp b/hiro/qt/widget/frame.hpp new file mode 100644 index 00000000..6faf26cd --- /dev/null +++ b/hiro/qt/widget/frame.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_Frame) + +namespace hiro { + +struct pFrame : pWidget { + Declare(Frame, Widget) + + auto setEnabled(bool enabled) -> void override; + auto setGeometry(Geometry geometry) -> void override; + auto setText(const string& text) -> void; + auto setVisible(bool visible) -> void override; + + auto _setState() -> void; + + QGroupBox* qtFrame = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/hex-edit.cpp b/hiro/qt/widget/hex-edit.cpp index 4a465886..a410a696 100644 --- a/hiro/qt/widget/hex-edit.cpp +++ b/hiro/qt/widget/hex-edit.cpp @@ -1,83 +1,8 @@ -namespace phoenix { +#if defined(Hiro_HexEdit) -void pHexEdit::setBackgroundColor(Color color) { - QPalette palette = qtHexEdit->palette(); - palette.setColor(QPalette::Base, QColor(color.red, color.green, color.blue)); - qtHexEdit->setPalette(palette); - qtHexEdit->setAutoFillBackground(true); -} +namespace hiro { -void pHexEdit::setColumns(unsigned columns) { - update(); -} - -void pHexEdit::setForegroundColor(Color color) { - QPalette palette = qtHexEdit->palette(); - palette.setColor(QPalette::Text, QColor(color.red, color.green, color.blue)); - qtHexEdit->setPalette(palette); -} - -void pHexEdit::setLength(unsigned length) { - //add one if last row is not equal to column length (eg only part of the row is present) - bool indivisible = hexEdit.state.columns == 0 || (hexEdit.state.length % hexEdit.state.columns) != 0; - qtScroll->setRange(0, hexEdit.state.length / hexEdit.state.columns + indivisible - hexEdit.state.rows); - update(); -} - -void pHexEdit::setOffset(unsigned offset) { - lock(); - qtScroll->setSliderPosition(hexEdit.state.offset / hexEdit.state.columns); - unlock(); - update(); -} - -void pHexEdit::setRows(unsigned rows) { - qtScroll->setPageStep(hexEdit.state.rows); - update(); -} - -void pHexEdit::update() { - if(!hexEdit.onRead) { - qtHexEdit->setPlainText(""); - return; - } - - unsigned cursorPosition = qtHexEdit->textCursor().position(); - - string output; - unsigned offset = hexEdit.state.offset; - for(unsigned row = 0; row < hexEdit.state.rows; row++) { - output.append(hex<8>(offset)); - output.append(" "); - - string hexdata; - string ansidata = " "; - - for(unsigned column = 0; column < hexEdit.state.columns; column++) { - if(offset < hexEdit.state.length) { - uint8_t data = hexEdit.onRead(offset++); - hexdata.append(hex<2>(data)); - hexdata.append(" "); - ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.'); - } else { - hexdata.append(" "); - ansidata.append(" "); - } - } - - output.append(hexdata); - output.append(ansidata); - if(offset >= hexEdit.state.length) break; - if(row != hexEdit.state.rows - 1) output.append("\n"); - } - - qtHexEdit->setPlainText(QString::fromUtf8(output)); - QTextCursor cursor = qtHexEdit->textCursor(); - cursor.setPosition(cursorPosition); - qtHexEdit->setTextCursor(cursor); -} - -void pHexEdit::constructor() { +auto pHexEdit::construct() -> void { qtWidget = qtHexEdit = new QtHexEdit(*this); qtHexEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -90,36 +15,92 @@ void pHexEdit::constructor() { qtLayout->setSpacing(0); qtHexEdit->setLayout(qtLayout); - qtScroll = new QtHexEditScrollBar(*this); - qtScroll->setSingleStep(1); - qtLayout->addWidget(qtScroll); + qtScrollBar = new QtHexEditScrollBar(*this); + qtScrollBar->setSingleStep(1); + qtLayout->addWidget(qtScrollBar); - connect(qtScroll, SIGNAL(actionTriggered(int)), SLOT(onScroll())); + qtScrollBar->connect(qtScrollBar, SIGNAL(actionTriggered(int)), SLOT(onScroll())); - pWidget::synchronizeState(); - setColumns(hexEdit.state.columns); - setRows(hexEdit.state.rows); - setLength(hexEdit.state.length); - setOffset(hexEdit.state.offset); - update(); + pWidget::construct(); + _setState(); } -void pHexEdit::destructor() { - delete qtScroll; +auto pHexEdit::destruct() -> void { + delete qtScrollBar; delete qtLayout; delete qtHexEdit; qtWidget = qtHexEdit = nullptr; qtLayout = nullptr; - qtScroll = nullptr; + qtScrollBar = nullptr; } -void pHexEdit::orphan() { - destructor(); - constructor(); +auto pHexEdit::setAddress(unsigned address) -> void { + _setState(); } -void pHexEdit::keyPressEvent(QKeyEvent* event) { - if(!hexEdit.onRead) return; +auto pHexEdit::setBackgroundColor(Color color) -> void { + _setState(); +} + +auto pHexEdit::setColumns(unsigned columns) -> void { + _setState(); +} + +auto pHexEdit::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pHexEdit::setLength(unsigned length) -> void { + _setState(); +} + +auto pHexEdit::setRows(unsigned rows) -> void { + _setState(); +} + +auto pHexEdit::update() -> void { + if(!state().onRead) { + qtHexEdit->setPlainText(""); + return; + } + + unsigned cursorPosition = qtHexEdit->textCursor().position(); + + string output; + unsigned address = state().address; + for(unsigned row = 0; row < state().rows; row++) { + output.append(hex(address, 8L)); + output.append(" "); + + string hexdata; + string ansidata = " "; + + for(unsigned column = 0; column < state().columns; column++) { + if(address < state().length) { + uint8_t data = self().doRead(address++); + hexdata.append(hex(data, 2L)); + hexdata.append(" "); + ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.'); + } else { + hexdata.append(" "); + ansidata.append(" "); + } + } + + output.append(hexdata); + output.append(ansidata); + if(address >= state().length) break; + if(row != state().rows - 1) output.append("\n"); + } + + qtHexEdit->setPlainText(QString::fromUtf8(output)); + QTextCursor cursor = qtHexEdit->textCursor(); + cursor.setPosition(cursorPosition); + qtHexEdit->setTextCursor(cursor); +} + +auto pHexEdit::_keyPressEvent(QKeyEvent* event) -> void { + if(!state().onRead) return; //allow Ctrl+C (copy) if(event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier) { @@ -131,7 +112,7 @@ void pHexEdit::keyPressEvent(QKeyEvent* event) { if(event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) return; QTextCursor cursor = qtHexEdit->textCursor(); - signed lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 1; + signed lineWidth = 10 + (state().columns * 3) + 1 + state().columns + 1; signed cursorY = cursor.position() / lineWidth; signed cursorX = cursor.position() % lineWidth; @@ -168,27 +149,27 @@ void pHexEdit::keyPressEvent(QKeyEvent* event) { cursor.setPosition(cursor.position() - lineWidth); qtHexEdit->setTextCursor(cursor); } else { - scrollTo(qtScroll->sliderPosition() - 1); + _scrollTo(qtScrollBar->sliderPosition() - 1); } return; case Qt::Key_Down: - if(cursorY >= rows() - 1) { + if(cursorY >= _rows() - 1) { //cannot scroll down further - } else if(cursorY < hexEdit.state.rows - 1) { + } else if(cursorY < state().rows - 1) { cursor.setPosition(cursor.position() + lineWidth); qtHexEdit->setTextCursor(cursor); } else { - scrollTo(qtScroll->sliderPosition() + 1); + _scrollTo(qtScrollBar->sliderPosition() + 1); } return; case Qt::Key_PageUp: - scrollTo(qtScroll->sliderPosition() - hexEdit.state.rows); + _scrollTo(qtScrollBar->sliderPosition() - state().rows); return; case Qt::Key_PageDown: - scrollTo(qtScroll->sliderPosition() + hexEdit.state.rows); + _scrollTo(qtScrollBar->sliderPosition() + state().rows); return; case Qt::Key_0: nibble = 0; break; @@ -216,12 +197,12 @@ void pHexEdit::keyPressEvent(QKeyEvent* event) { //not on a space bool cursorNibble = (cursorX % 3) == 1; //0 = high, 1 = low cursorX /= 3; - if(cursorX < hexEdit.state.columns) { + if(cursorX < state().columns) { //not in ANSI region - unsigned offset = hexEdit.state.offset + (cursorY * hexEdit.state.columns + cursorX); + unsigned address = state().address + (cursorY * state().columns + cursorX); - if(offset >= hexEdit.state.length) return; //do not edit past end of file - uint8_t data = hexEdit.onRead(offset); + if(address >= state().length) return; //do not edit past end of file + uint8_t data = self().doRead(address); //write modified value if(cursorNibble == 1) { @@ -229,11 +210,11 @@ void pHexEdit::keyPressEvent(QKeyEvent* event) { } else { data = (data & 0x0f) | (nibble << 4); } - if(hexEdit.onWrite) hexEdit.onWrite(offset, data); + self().doWrite(address, data); //auto-advance cursor to next nibble/byte unsigned step = 1; - if(cursorNibble && cursorX != hexEdit.state.columns - 1) step = 2; + if(cursorNibble && cursorX != state().columns - 1) step = 2; cursor.setPosition(cursor.position() + step); qtHexEdit->setTextCursor(cursor); @@ -245,54 +226,82 @@ void pHexEdit::keyPressEvent(QKeyEvent* event) { } //number of actual rows -signed pHexEdit::rows() { - return (max(1u, hexEdit.state.length) + hexEdit.state.columns - 1) / hexEdit.state.columns; +auto pHexEdit::_rows() -> signed { + return (max(1u, state().length) + state().columns - 1) / state().columns; } //number of scrollable row positions -signed pHexEdit::rowsScrollable() { - return max(0u, rows() - hexEdit.state.rows); +auto pHexEdit::_rowsScrollable() -> signed { + return max(0u, _rows() - state().rows); } -void pHexEdit::scrollTo(signed position) { - if(position > rowsScrollable()) position = rowsScrollable(); +auto pHexEdit::_scrollTo(signed position) -> void { + if(position > _rowsScrollable()) position = _rowsScrollable(); if(position < 0) position = 0; - qtScroll->setSliderPosition(position); + qtScrollBar->setSliderPosition(position); } -void pHexEdit::onScroll() { - if(locked()) return; - unsigned offset = qtScroll->sliderPosition(); - hexEdit.state.offset = offset * hexEdit.state.columns; +auto pHexEdit::_setState() -> void { + lock(); + if(auto color = state().backgroundColor) { + QPalette palette = qtHexEdit->palette(); + palette.setColor(QPalette::Base, QColor(color.red(), color.green(), color.blue())); + qtHexEdit->setPalette(palette); + qtHexEdit->setAutoFillBackground(true); + } else { + //todo + } + if(auto color = state().foregroundColor) { + QPalette palette = qtHexEdit->palette(); + palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue())); + qtHexEdit->setPalette(palette); + } else { + //todo + } + //add one if last row is not equal to column length (eg only part of the row is present) + bool indivisible = state().columns == 0 || (state().length % state().columns) != 0; + qtScrollBar->setRange(0, state().length / state().columns + indivisible - state().rows); + qtScrollBar->setSliderPosition(state().address / state().columns); + qtScrollBar->setPageStep(state().rows); update(); + unlock(); } -void pHexEdit::QtHexEdit::keyPressEvent(QKeyEvent* event) { - self.keyPressEvent(event); +auto QtHexEdit::keyPressEvent(QKeyEvent* event) -> void { + p._keyPressEvent(event); } -void pHexEdit::QtHexEdit::keyPressEventAcknowledge(QKeyEvent* event) { +auto QtHexEdit::keyPressEventAcknowledge(QKeyEvent* event) -> void { QTextEdit::keyPressEvent(event); } -void pHexEdit::QtHexEdit::wheelEvent(QWheelEvent* event) { +auto QtHexEdit::wheelEvent(QWheelEvent* event) -> void { if(event->orientation() == Qt::Vertical) { signed offset = event->delta() < 0 ? +1 : -1; - self.scrollTo(self.qtScroll->sliderPosition() + offset); + p._scrollTo(p.qtScrollBar->sliderPosition() + offset); event->accept(); } } -bool pHexEdit::QtHexEditScrollBar::event(QEvent* event) { +auto QtHexEditScrollBar::event(QEvent* event) -> bool { if(event->type() == QEvent::Wheel) { - QWheelEvent* wheelEvent = (QWheelEvent*)event; + auto wheelEvent = (QWheelEvent*)event; if(wheelEvent->orientation() == Qt::Vertical) { signed offset = wheelEvent->delta() < 0 ? +1 : -1; - self.scrollTo(sliderPosition() + offset); + p._scrollTo(sliderPosition() + offset); return true; } } return QScrollBar::event(event); } +auto QtHexEditScrollBar::onScroll() -> void { + if(p.locked()) return; + unsigned address = sliderPosition(); + p.state().address = address * p.state().columns; + p.update(); } + +} + +#endif diff --git a/hiro/qt/widget/hex-edit.hpp b/hiro/qt/widget/hex-edit.hpp new file mode 100644 index 00000000..3718a840 --- /dev/null +++ b/hiro/qt/widget/hex-edit.hpp @@ -0,0 +1,29 @@ +#if defined(Hiro_HexEdit) + +namespace hiro { + +struct pHexEdit : pWidget { + Declare(HexEdit, Widget) + + auto setAddress(unsigned address) -> void; + auto setBackgroundColor(Color color) -> void; + auto setColumns(unsigned columns) -> void; + auto setForegroundColor(Color color) -> void; + auto setLength(unsigned length) -> void; + auto setRows(unsigned rows) -> void; + auto update() -> void; + + auto _keyPressEvent(QKeyEvent*) -> void; + auto _rows() -> signed; + auto _rowsScrollable() -> signed; + auto _scrollTo(signed position) -> void; + auto _setState() -> void; + + QtHexEdit* qtHexEdit = nullptr; + QHBoxLayout* qtLayout = nullptr; + QtHexEditScrollBar* qtScrollBar = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/horizontal-scroller.cpp b/hiro/qt/widget/horizontal-scroller.cpp index 5ff5866e..9fb45d46 100644 --- a/hiro/qt/widget/horizontal-scroller.cpp +++ b/hiro/qt/widget/horizontal-scroller.cpp @@ -1,43 +1,46 @@ -namespace phoenix { +#if defined(Hiro_HorizontalScroller) -Size pHorizontalScroller::minimumSize() { +namespace hiro { + +auto pHorizontalScroller::construct() -> void { + qtWidget = qtHorizontalScroller = new QtHorizontalScroller(*this); + qtHorizontalScroller->setRange(0, 100); + qtHorizontalScroller->setPageStep(101 >> 3); + qtHorizontalScroller->connect(qtHorizontalScroller, SIGNAL(valueChanged(int)), SLOT(onChange())); + + pWidget::construct(); + _setState(); +} + +auto pHorizontalScroller::destruct() -> void { + delete qtHorizontalScroller; + qtWidget = qtHorizontalScroller = nullptr; +} + +auto pHorizontalScroller::minimumSize() const -> Size { return {0, 15}; } -void pHorizontalScroller::setLength(unsigned length) { - length += length == 0; - qtScroller->setRange(0, length - 1); - qtScroller->setPageStep(length >> 3); +auto pHorizontalScroller::setLength(unsigned length) -> void { + _setState(); } -void pHorizontalScroller::setPosition(unsigned position) { - qtScroller->setValue(position); +auto pHorizontalScroller::setPosition(unsigned position) -> void { + _setState(); } -void pHorizontalScroller::constructor() { - qtWidget = qtScroller = new QScrollBar(Qt::Horizontal); - qtScroller->setRange(0, 100); - qtScroller->setPageStep(101 >> 3); - connect(qtScroller, SIGNAL(valueChanged(int)), SLOT(onChange())); - - pWidget::synchronizeState(); - setLength(horizontalScroller.state.length); - setPosition(horizontalScroller.state.position); +auto pHorizontalScroller::_setState() -> void { + signed length = state().length + (state().length == 0); + qtHorizontalScroller->setRange(0, length - 1); + qtHorizontalScroller->setPageStep(length >> 3); + qtHorizontalScroller->setValue(state().position); } -void pHorizontalScroller::destructor() { - delete qtScroller; - qtWidget = qtScroller = nullptr; -} - -void pHorizontalScroller::orphan() { - destructor(); - constructor(); -} - -void pHorizontalScroller::onChange() { - horizontalScroller.state.position = qtScroller->value(); - if(horizontalScroller.onChange) horizontalScroller.onChange(); +auto QtHorizontalScroller::onChange() -> void { + p.state().position = value(); + p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/horizontal-scroller.hpp b/hiro/qt/widget/horizontal-scroller.hpp new file mode 100644 index 00000000..e0eed4f8 --- /dev/null +++ b/hiro/qt/widget/horizontal-scroller.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_HorizontalScroller) + +namespace hiro { + +struct pHorizontalScroller : pWidget { + Declare(HorizontalScroller, Widget) + + auto minimumSize() const -> Size override; + auto setLength(unsigned length) -> void; + auto setPosition(unsigned position) -> void; + + auto _setState() -> void; + + QtHorizontalScroller* qtHorizontalScroller = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/horizontal-slider.cpp b/hiro/qt/widget/horizontal-slider.cpp index 5cfbdb9e..672a0423 100644 --- a/hiro/qt/widget/horizontal-slider.cpp +++ b/hiro/qt/widget/horizontal-slider.cpp @@ -1,43 +1,46 @@ -namespace phoenix { +#if defined(Hiro_HorizontalSlider) -Size pHorizontalSlider::minimumSize() { +namespace hiro { + +auto pHorizontalSlider::minimumSize() const -> Size { return {0, 20}; } -void pHorizontalSlider::setLength(unsigned length) { - length += length == 0; - qtSlider->setRange(0, length - 1); - qtSlider->setPageStep(length >> 3); +auto pHorizontalSlider::setLength(unsigned length) -> void { + _setState(); } -void pHorizontalSlider::setPosition(unsigned position) { - qtSlider->setValue(position); +auto pHorizontalSlider::setPosition(unsigned position) -> void { + _setState(); } -void pHorizontalSlider::constructor() { - qtWidget = qtSlider = new QSlider(Qt::Horizontal); - qtSlider->setRange(0, 100); - qtSlider->setPageStep(101 >> 3); - connect(qtSlider, SIGNAL(valueChanged(int)), SLOT(onChange())); +auto pHorizontalSlider::construct() -> void { + qtWidget = qtHorizontalSlider = new QtHorizontalSlider(*this); + qtHorizontalSlider->setRange(0, 100); + qtHorizontalSlider->setPageStep(101 >> 3); + qtHorizontalSlider->connect(qtHorizontalSlider, SIGNAL(valueChanged(int)), SLOT(onChange())); - pWidget::synchronizeState(); - setLength(horizontalSlider.state.length); - setPosition(horizontalSlider.state.position); + pWidget::construct(); + _setState(); } -void pHorizontalSlider::destructor() { - delete qtSlider; - qtWidget = qtSlider = nullptr; +auto pHorizontalSlider::destruct() -> void { + delete qtHorizontalSlider; + qtWidget = qtHorizontalSlider = nullptr; } -void pHorizontalSlider::orphan() { - destructor(); - constructor(); +auto pHorizontalSlider::_setState() -> void { + signed length = state().length + (state().length == 0); + qtHorizontalSlider->setRange(0, length - 1); + qtHorizontalSlider->setPageStep(length >> 3); + qtHorizontalSlider->setValue(state().position); } -void pHorizontalSlider::onChange() { - horizontalSlider.state.position = qtSlider->value(); - if(horizontalSlider.onChange) horizontalSlider.onChange(); +auto QtHorizontalSlider::onChange() -> void { + p.state().position = value(); + p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/horizontal-slider.hpp b/hiro/qt/widget/horizontal-slider.hpp new file mode 100644 index 00000000..e1dea2f8 --- /dev/null +++ b/hiro/qt/widget/horizontal-slider.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_HorizontalSlider) + +namespace hiro { + +struct pHorizontalSlider : pWidget { + Declare(HorizontalSlider, Widget) + + auto minimumSize() const -> Size; + auto setLength(unsigned length) -> void; + auto setPosition(unsigned position) -> void; + + auto _setState() -> void; + + QtHorizontalSlider* qtHorizontalSlider = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/icon-view.cpp b/hiro/qt/widget/icon-view.cpp index d829cd0d..773669a0 100644 --- a/hiro/qt/widget/icon-view.cpp +++ b/hiro/qt/widget/icon-view.cpp @@ -1,4 +1,6 @@ -namespace phoenix { +#if defined(Hiro_IconView) + +namespace hiro { void pIconView::append() { lock(); @@ -146,3 +148,5 @@ void pIconView::QtListWidget::resizeEvent(QResizeEvent* event) { } } + +#endif diff --git a/hiro/qt/widget/label.cpp b/hiro/qt/widget/label.cpp index e41a968d..efc52aee 100644 --- a/hiro/qt/widget/label.cpp +++ b/hiro/qt/widget/label.cpp @@ -1,29 +1,35 @@ -namespace phoenix { +#if defined(Hiro_Label) -Size pLabel::minimumSize() { - Size size = pFont::size(qtWidget->font(), label.state.text); - return {size.width, size.height}; -} +namespace hiro { -void pLabel::setText(string text) { - qtLabel->setText(QString::fromUtf8(text)); -} - -void pLabel::constructor() { +auto pLabel::construct() -> void { qtWidget = qtLabel = new QLabel; - pWidget::synchronizeState(); - setText(label.state.text); + setAlignment(state().alignment); + setText(state().text); + + pWidget::construct(); } -void pLabel::destructor() { +auto pLabel::destruct() -> void { delete qtLabel; qtWidget = qtLabel = nullptr; } -void pLabel::orphan() { - destructor(); - constructor(); +auto pLabel::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + return {size.width(), size.height()}; +} + +auto pLabel::setAlignment(Alignment alignment) -> void { + if(!alignment) alignment = {0.0, 0.5}; + qtLabel->setAlignment((Qt::Alignment)CalculateAlignment(alignment)); +} + +auto pLabel::setText(const string& text) -> void { + qtLabel->setText(QString::fromUtf8(text)); } } + +#endif diff --git a/hiro/qt/widget/label.hpp b/hiro/qt/widget/label.hpp new file mode 100644 index 00000000..7cd36560 --- /dev/null +++ b/hiro/qt/widget/label.hpp @@ -0,0 +1,17 @@ +#if defined(Hiro_Label) + +namespace hiro { + +struct pLabel : pWidget { + Declare(Label, Widget) + + auto minimumSize() const -> Size override; + auto setAlignment(Alignment alignment) -> void; + auto setText(const string& text) -> void; + + QLabel* qtLabel = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/line-edit.cpp b/hiro/qt/widget/line-edit.cpp index ab537608..55a01b06 100644 --- a/hiro/qt/widget/line-edit.cpp +++ b/hiro/qt/widget/line-edit.cpp @@ -1,62 +1,71 @@ -namespace phoenix { +#if defined(Hiro_LineEdit) -Size pLineEdit::minimumSize() { - Size size = pFont::size(qtWidget->font(), lineEdit.state.text); - return {size.width + 12, size.height + 12}; +namespace hiro { + +auto pLineEdit::construct() -> void { + qtWidget = qtLineEdit = new QtLineEdit(*this); + qtLineEdit->connect(qtLineEdit, SIGNAL(returnPressed()), SLOT(onActivate())); + qtLineEdit->connect(qtLineEdit, SIGNAL(textEdited(const QString&)), SLOT(onChange())); + + pWidget::construct(); + _setState(); } -void pLineEdit::setBackgroundColor(Color color) { - QPalette palette = qtLineEdit->palette(); - palette.setColor(QPalette::Base, QColor(color.red, color.green, color.blue)); - qtLineEdit->setPalette(palette); - qtLineEdit->setAutoFillBackground(true); -} - -void pLineEdit::setEditable(bool editable) { - qtLineEdit->setReadOnly(!editable); -} - -void pLineEdit::setForegroundColor(Color color) { - QPalette palette = qtLineEdit->palette(); - palette.setColor(QPalette::Text, QColor(color.red, color.green, color.blue)); - qtLineEdit->setPalette(palette); -} - -void pLineEdit::setText(string text) { - qtLineEdit->setText(QString::fromUtf8(text)); -} - -string pLineEdit::text() { - return qtLineEdit->text().toUtf8().constData(); -} - -void pLineEdit::constructor() { - qtWidget = qtLineEdit = new QLineEdit; - connect(qtLineEdit, SIGNAL(returnPressed()), SLOT(onActivate())); - connect(qtLineEdit, SIGNAL(textEdited(const QString&)), SLOT(onChange())); - - pWidget::synchronizeState(); - setEditable(lineEdit.state.editable); - setText(lineEdit.state.text); -} - -void pLineEdit::destructor() { +auto pLineEdit::destruct() -> void { delete qtLineEdit; qtWidget = qtLineEdit = nullptr; } -void pLineEdit::orphan() { - destructor(); - constructor(); +auto pLineEdit::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + return {size.width() + 12, size.height() + 12}; } -void pLineEdit::onActivate() { - if(lineEdit.onActivate) lineEdit.onActivate(); +auto pLineEdit::setBackgroundColor(Color color) -> void { + _setState(); } -void pLineEdit::onChange() { - lineEdit.state.text = text(); - if(lineEdit.onChange) lineEdit.onChange(); +auto pLineEdit::setEditable(bool editable) -> void { + _setState(); +} + +auto pLineEdit::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pLineEdit::setText(const string& text) -> void { + _setState(); +} + +auto pLineEdit::_setState() -> void { + if(auto color = state().backgroundColor) { + QPalette palette = qtLineEdit->palette(); + palette.setColor(QPalette::Base, QColor(color.red(), color.green(), color.blue())); + qtLineEdit->setPalette(palette); + qtLineEdit->setAutoFillBackground(true); + } else { + //todo + } + qtLineEdit->setReadOnly(!state().editable); + if(auto color = state().foregroundColor) { + QPalette palette = qtLineEdit->palette(); + palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue())); + qtLineEdit->setPalette(palette); + } else { + //todo + } + qtLineEdit->setText(QString::fromUtf8(state().text)); +} + +auto QtLineEdit::onActivate() -> void { + p.self().doActivate(); +} + +auto QtLineEdit::onChange() -> void { + p.state().text = text().toUtf8().constData(); + p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/line-edit.hpp b/hiro/qt/widget/line-edit.hpp new file mode 100644 index 00000000..b229a04b --- /dev/null +++ b/hiro/qt/widget/line-edit.hpp @@ -0,0 +1,21 @@ +#if defined(Hiro_LineEdit) + +namespace hiro { + +struct pLineEdit : pWidget { + Declare(LineEdit, Widget) + + auto minimumSize() const -> Size override; + auto setBackgroundColor(Color color) -> void; + auto setEditable(bool editable) -> void; + auto setForegroundColor(Color color) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void; + + QtLineEdit* qtLineEdit = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/list-view-cell.cpp b/hiro/qt/widget/list-view-cell.cpp new file mode 100644 index 00000000..d747535d --- /dev/null +++ b/hiro/qt/widget/list-view-cell.cpp @@ -0,0 +1,69 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +auto pListViewCell::construct() -> void { +} + +auto pListViewCell::destruct() -> void { +} + +auto pListViewCell::setAlignment(Alignment alignment) -> void { + _setState(); +} + +auto pListViewCell::setBackgroundColor(Color color) -> void { + _setState(); +} + +auto pListViewCell::setCheckable(bool checkable) -> void { + _setState(); +} + +auto pListViewCell::setChecked(bool checked) -> void { + _setState(); +} + +auto pListViewCell::setFont(const string& font) -> void { + _setState(); +} + +auto pListViewCell::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pListViewCell::setIcon(const image& icon) -> void { + _setState(); +} + +auto pListViewCell::setText(const string& text) -> void { + _setState(); +} + +auto pListViewCell::_parent() -> maybe { + if(auto parent = self().parentListViewItem()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pListViewCell::_setState() -> void { + if(auto parent = _parent()) { + parent->qtItem->setBackground(self().offset(), CreateBrush(self().backgroundColor(true))); + if(state().checkable) { + parent->qtItem->setCheckState(self().offset(), state().checked ? Qt::Checked : Qt::Unchecked); + } else { + //extremely unintuitive; but this is the only way to remove an existing checkbox from a cell + parent->qtItem->setData(self().offset(), Qt::CheckStateRole, QVariant()); + } + parent->qtItem->setFont(self().offset(), pFont::create(self().font(true))); + parent->qtItem->setForeground(self().offset(), CreateBrush(self().foregroundColor(true))); + parent->qtItem->setIcon(self().offset(), CreateIcon(state().icon)); + parent->qtItem->setText(self().offset(), QString::fromUtf8(state().text)); + parent->qtItem->setTextAlignment(self().offset(), CalculateAlignment(self().alignment(true))); + } +} + +} + +#endif diff --git a/hiro/qt/widget/list-view-cell.hpp b/hiro/qt/widget/list-view-cell.hpp new file mode 100644 index 00000000..4eddcc5e --- /dev/null +++ b/hiro/qt/widget/list-view-cell.hpp @@ -0,0 +1,23 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +struct pListViewCell : pObject { + Declare(ListViewCell, Object) + + auto setAlignment(Alignment alignment) -> void; + auto setBackgroundColor(Color color) -> void; + auto setCheckable(bool checkable) -> void; + auto setChecked(bool checked) -> void; + auto setFont(const string& font) -> void; + auto setForegroundColor(Color color) -> void; + auto setIcon(const image& icon) -> void; + auto setText(const string& text) -> void; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/widget/list-view-column.cpp b/hiro/qt/widget/list-view-column.cpp new file mode 100644 index 00000000..48b5cc41 --- /dev/null +++ b/hiro/qt/widget/list-view-column.cpp @@ -0,0 +1,99 @@ +#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 string& 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/hiro/qt/widget/list-view-column.hpp b/hiro/qt/widget/list-view-column.hpp new file mode 100644 index 00000000..a3e450a4 --- /dev/null +++ b/hiro/qt/widget/list-view-column.hpp @@ -0,0 +1,30 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +struct pListViewColumn : pObject { + Declare(ListViewColumn, Object) + + auto setActive() -> void; + auto setAlignment(Alignment alignment) -> void; + auto setBackgroundColor(Color color) -> void; + auto setEditable(bool editable) -> void; + auto setExpandable(bool expandable) -> void; + auto setFont(const string& font) -> void override; + auto setForegroundColor(Color color) -> void; + auto setHorizontalAlignment(double alignment) -> void; + auto setIcon(const image& icon) -> void; + auto setResizable(bool resizable) -> void; + auto setSortable(bool sortable) -> void; + auto setText(const string& text) -> void; + auto setVerticalAlignment(double alignment) -> void; + auto setVisible(bool visible) -> void; + auto setWidth(signed width) -> void; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/widget/list-view-header.cpp b/hiro/qt/widget/list-view-header.cpp new file mode 100644 index 00000000..ead448a4 --- /dev/null +++ b/hiro/qt/widget/list-view-header.cpp @@ -0,0 +1,43 @@ +#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/hiro/qt/widget/list-view-header.hpp b/hiro/qt/widget/list-view-header.hpp new file mode 100644 index 00000000..a46855bb --- /dev/null +++ b/hiro/qt/widget/list-view-header.hpp @@ -0,0 +1,18 @@ +#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/hiro/qt/widget/list-view-item.cpp b/hiro/qt/widget/list-view-item.cpp new file mode 100644 index 00000000..bb3bb57b --- /dev/null +++ b/hiro/qt/widget/list-view-item.cpp @@ -0,0 +1,62 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +auto pListViewItem::construct() -> void { +} + +auto pListViewItem::destruct() -> void { + if(qtItem) { + delete qtItem; + qtItem = nullptr; + } +} + +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 string& 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/hiro/qt/widget/list-view-item.hpp b/hiro/qt/widget/list-view-item.hpp new file mode 100644 index 00000000..ed20122b --- /dev/null +++ b/hiro/qt/widget/list-view-item.hpp @@ -0,0 +1,24 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +struct pListViewItem : pObject { + Declare(ListViewItem, Object) + + auto append(sListViewCell cell) -> void; + auto remove(sListViewCell cell) -> void; + auto setAlignment(Alignment alignment) -> void; + auto setBackgroundColor(Color color) -> void; + auto setFont(const string& font) -> void override; + auto setForegroundColor(Color color) -> void; + auto setSelected(bool selected) -> void; + + auto _parent() -> maybe; + auto _setState() -> void; + + QTreeWidgetItem* qtItem = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/list-view.cpp b/hiro/qt/widget/list-view.cpp index 113b6e0b..7f1ac186 100644 --- a/hiro/qt/widget/list-view.cpp +++ b/hiro/qt/widget/list-view.cpp @@ -1,325 +1,200 @@ -namespace phoenix { +#if defined(Hiro_ListView) -void pListView::appendColumn() { - orphan(); -} +namespace hiro { -void pListView::appendItem() { - lock(); - auto item = new QTreeWidgetItem(qtListView); - for(unsigned column = 0; column < listView.columns(); column++) { - auto& state = listView.state.columns[column]; - if(state.backgroundColor) { - item->setBackground(column, QColor( - state.backgroundColor->red, state.backgroundColor->green, state.backgroundColor->blue - )); - } - if(state.font) { - item->setFont(column, pFont::create(*state.font)); - } - if(state.foregroundColor) { - item->setForeground(column, QColor( - state.foregroundColor->red, state.foregroundColor->green, state.foregroundColor->blue - )); - } - item->setTextAlignment(column, calculateAlignment( - state.horizontalAlignment, state.verticalAlignment - )); - } - if(listView.state.checkable) item->setCheckState(0, Qt::Unchecked); - unlock(); -} - -void pListView::removeColumn(unsigned position) { - orphan(); -} - -void pListView::removeItem(unsigned position) { - lock(); - if(auto item = qtListView->topLevelItem(position)) { - delete item; - } - unlock(); -} - -void pListView::reset() { - lock(); - qtListView->clear(); - unlock(); -} - -void pListView::resizeColumns() { -} - -//todo: this doesn't work ... -void pListView::setActiveColumn(unsigned column) { - if(column >= listView.columns()) return; - qtListView->header()->setSortIndicator(column, Qt::DescendingOrder); -} - -void pListView::setBackgroundColor(Color color) { - QPalette palette = qtListView->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); -} - -void pListView::setCheckable(bool checkable) { - lock(); - if(checkable) { - for(unsigned n = 0; n < qtListView->topLevelItemCount(); n++) { - if(auto item = qtListView->topLevelItem(n)) { - item->setCheckState(0, Qt::Unchecked); - } - } - } - unlock(); -} - -void pListView::setChecked(unsigned position, bool checked) { - lock(); - if(auto item = qtListView->topLevelItem(position)) { - item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); - } - unlock(); -} - -void pListView::setChecked(const vector& selections) { - lock(); - setCheckedNone(); - for(auto& position : selections) setChecked(position, true); - unlock(); -} - -void pListView::setCheckedAll() { - lock(); - for(unsigned n = 0; n < qtListView->topLevelItemCount(); n++) { - if(auto item = qtListView->topLevelItem(n)) { - item->setCheckState(0, Qt::Checked); - } - } - unlock(); -} - -void pListView::setCheckedNone() { - lock(); - for(unsigned n = 0; n < qtListView->topLevelItemCount(); n++) { - if(auto item = qtListView->topLevelItem(n)) { - item->setCheckState(0, Qt::Unchecked); - } - } - unlock(); -} - -void pListView::setColumnBackgroundColor(unsigned column, maybe color) { - for(unsigned row = 0; row < listView.items(); row++) { - if(auto item = qtListView->topLevelItem(row)) { - item->setBackground(column, color ? QColor(color->red, color->green, color->blue) : QBrush()); - } - } -} - -void pListView::setColumnEditable(unsigned column, bool editable) { -} - -void pListView::setColumnFont(unsigned column, maybe font) { - auto qtFont = pFont::create(font ? *font : widget.state.font); - for(unsigned row = 0; row < listView.items(); row++) { - if(auto item = qtListView->topLevelItem(row)) { - item->setFont(column, qtFont); - } - } -} - -void pListView::setColumnForegroundColor(unsigned column, maybe color) { - for(unsigned row = 0; row < listView.items(); row++) { - if(auto item = qtListView->topLevelItem(row)) { - item->setForeground(column, color ? QColor(color->red, color->green, color->blue) : QBrush()); - } - } -} - -void pListView::setColumnHorizontalAlignment(unsigned column, double alignment) { - qtListView->headerItem()->setTextAlignment(column, calculateAlignment(alignment, 0.5)); - for(unsigned row = 0; row < listView.items(); row++) { - if(auto item = qtListView->topLevelItem(row)) { - auto& state = listView.state.columns[column]; - item->setTextAlignment(column, calculateAlignment(state.horizontalAlignment, state.verticalAlignment)); - } - } -} - -void pListView::setColumnResizable(unsigned column, bool resizable) { - qtListView->header()->setResizeMode(column, resizable ? QHeaderView::Interactive : QHeaderView::Fixed); -} - -void pListView::setColumnSortable(unsigned column, bool sortable) { - bool clickable = false; - for(auto& column : listView.state.columns) clickable |= column.sortable; - qtListView->header()->setClickable(clickable); -} - -void pListView::setColumnText(unsigned column, const string& text) { - qtListView->headerItem()->setText(column, QString::fromUtf8(text)); -} - -void pListView::setColumnVerticalAlignment(unsigned column, double alignment) { - for(unsigned row = 0; row < listView.items(); row++) { - if(auto item = qtListView->topLevelItem(row)) { - auto& state = listView.state.columns[column]; - item->setTextAlignment(column, calculateAlignment(state.horizontalAlignment, state.verticalAlignment)); - } - } -} - -void pListView::setColumnVisible(unsigned column, bool visible) { - if(column >= listView.columns()) return; - qtListView->setColumnHidden(column, !visible); -} - -void pListView::setColumnWidth(unsigned column, signed width) { - if(column >= listView.columns()) return; - resizeColumns(); -} - -void pListView::setForegroundColor(Color color) { - QPalette palette = qtListView->palette(); - palette.setColor(QPalette::Text, QColor(color.red, color.green, color.blue)); - qtListView->setPalette(palette); -} - -void pListView::setGridVisible(bool visible) { - qtListView->repaint(); -} - -void pListView::setHeaderVisible(bool visible) { - qtListView->setHeaderHidden(!visible); - resizeColumns(); -} - -void pListView::setImage(unsigned row, unsigned column, const nall::image& image) { - if(auto item = qtListView->topLevelItem(row)) { - item->setIcon(column, CreateIcon(image)); - } -} - -void pListView::setSelected(unsigned position, bool selected) { - lock(); - if(auto item = qtListView->topLevelItem(position)) { - item->setSelected(selected); - } - unlock(); -} - -void pListView::setSelected(const vector& selections) { - lock(); - setSelectedNone(); - if(selections.size()) { - if(auto item = qtListView->topLevelItem(selections[0])) { - qtListView->setCurrentItem(item); - } - for(auto& position : selections) setSelected(position, true); - } - unlock(); -} - -void pListView::setSelectedAll() { - lock(); - qtListView->selectAll(); - unlock(); -} - -void pListView::setSelectedNone() { - lock(); - qtListView->clearSelection(); - unlock(); -} - -void pListView::setSingleSelection(bool singleSelection) { - lock(); - qtListView->setSelectionMode(singleSelection ? QAbstractItemView::SingleSelection : QAbstractItemView::ExtendedSelection); - unlock(); -} - -void pListView::setText(unsigned row, unsigned column, string text) { - lock(); - if(auto item = qtListView->topLevelItem(row)) { - item->setText(column, QString::fromUtf8(text)); - } - unlock(); -} - -void pListView::constructor() { - qtWidget = qtListView = new QtTreeWidget(*this); +auto pListView::construct() -> void { + qtWidget = qtListView = new QtListView(*this); qtListView->setAllColumnsShowFocus(true); - qtListView->setAlternatingRowColors(listView.columns() >= 2); - qtListView->setColumnCount(max(1u, listView.columns())); qtListView->setContextMenuPolicy(Qt::CustomContextMenu); qtListView->setRootIsDecorated(false); + qtListView->setHeaderHidden(true); qtListView->header()->setMovable(false); - qtListViewDelegate = new QtTreeWidgetDelegate(*this); + qtListViewDelegate = new QtListViewDelegate(*this); qtListView->setItemDelegate(qtListViewDelegate); - connect(qtListView, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(onActivate())); - connect(qtListView, SIGNAL(itemSelectionChanged()), SLOT(onChange())); - connect(qtListView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onContext())); - connect(qtListView->header(), SIGNAL(sectionClicked(int)), SLOT(onSort(int))); - connect(qtListView, SIGNAL(itemChanged(QTreeWidgetItem*, int)), SLOT(onToggle(QTreeWidgetItem*))); + 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*))); - pWidget::synchronizeState(); - for(unsigned column = 0; column < listView.columns(); column++) { - auto& state = listView.state.columns[column]; - setColumnBackgroundColor(column, state.backgroundColor); - setColumnEditable(column, state.editable); - setColumnFont(column, state.font); - setColumnForegroundColor(column, state.foregroundColor); - //setColumnHorizontalAlignment(column, state.horizontalAlignment); - setColumnResizable(column, state.resizable); - setColumnSortable(column, state.sortable); - setColumnText(column, state.text); - //setColumnVerticalAlignment(column, state.verticalAlignment); - setColumnVisible(column, state.visible); - //setColumnWidth(column, state.width); - qtListView->headerItem()->setTextAlignment(column, calculateAlignment(state.horizontalAlignment, 0.5)); - } - setActiveColumn(listView.state.activeColumn); - setCheckable(listView.state.checkable); -//setGridVisible(listView.state.gridVisible); - setHeaderVisible(listView.state.headerVisible); - setSingleSelection(listView.state.singleSelection); - for(unsigned row = 0; row < listView.items(); row++) { - appendItem(); - setSelected(row, listView.state.items[row].selected); - if(listView.state.checkable) { - setChecked(row, listView.state.items[row].checked); - } - for(unsigned column = 0; column < listView.columns(); column++) { - setImage(row, column, listView.state.items[row].image(column, {})); - setText(row, column, listView.state.items[row].text(column, "")); - } - } - resizeColumns(); + setBackgroundColor(state().backgroundColor); + setBatchable(state().batchable); + setBordered(state().bordered); + setForegroundColor(state().foregroundColor); + + pWidget::construct(); } -void pListView::destructor() { +auto pListView::destruct() -> void { delete qtListViewDelegate; delete qtListView; qtWidget = qtListView = nullptr; qtListViewDelegate = nullptr; } -void pListView::orphan() { - destructor(); - constructor(); +auto pListView::append(sListViewHeader header) -> void { + lock(); + if(auto self = header->self()) { + self->_setState(); + } + unlock(); } -void pListView::onActivate() { - if(!locked() && listView.onActivate) listView.onActivate(); +auto pListView::append(sListViewItem item) -> void { + lock(); + if(auto self = item->self()) { + self->qtItem = new QTreeWidgetItem(qtListView); + self->_setState(); + } + unlock(); } -void pListView::onChange() { +auto pListView::remove(sListViewHeader header) -> void { +} + +auto pListView::remove(sListViewItem item) -> void { +} + +auto pListView::reset() -> void { + lock(); + qtListView->clear(); + unlock(); +} + +auto pListView::resizeColumns() -> void { + lock(); + + if(auto& header = state().header) { + vector widths; + signed minimumWidth = 0; + signed expandable = 0; + for(auto column : range(header->columnCount())) { + signed width = _width(column); + widths.append(width); + minimumWidth += width; + if(header->column(column).expandable()) expandable++; + } + + signed maximumWidth = self().geometry().width() - 6; + if(auto scrollBar = qtListView->verticalScrollBar()) { + if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width(); + } + + signed expandWidth = 0; + if(expandable && maximumWidth > minimumWidth) { + expandWidth = (maximumWidth - minimumWidth) / expandable; + } + + for(auto column : range(header->columnCount())) { + signed width = widths[column]; + if(header->column(column).expandable()) width += expandWidth; + qtListView->setColumnWidth(column, width); + } + } + + unlock(); +} + +auto pListView::setAlignment(Alignment alignment) -> void { +} + +auto pListView::setBackgroundColor(Color color) -> void { + if(color) { + QPalette palette = qtListView->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); + } else { + //todo: set default color + } +} + +auto pListView::setBatchable(bool batchable) -> void { + lock(); + qtListView->setSelectionMode(batchable ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection); + unlock(); +} + +auto pListView::setBordered(bool bordered) -> void { + qtListView->repaint(); +} + +auto pListView::setForegroundColor(Color color) -> void { + if(color) { + QPalette palette = qtListView->palette(); + palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue())); + qtListView->setPalette(palette); + } else { + //todo: set default color + } +} + +//called on resize/show events +auto pListView::_onSize() -> void { + //resize columns only if at least one column is expandable + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(column->expandable()) return resizeColumns(); + } + } +} + +auto pListView::_width(unsigned column) -> unsigned { + if(auto& header = state().header) { + if(auto width = header->column(column).width()) return width; + unsigned width = 1; + if(!header->column(column).visible()) return width; + if(header->visible()) width = max(width, _widthOfColumn(column)); + for(auto row : range(state().items)) { + width = max(width, _widthOfCell(row, column)); + } + return width; + } + return 1; +} + +auto pListView::_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; + } + if(auto& text = column->state.text) { + width += Font::size(column->font(true), text).width(); + } + } + } + return width; +} + +auto pListView::_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; + } + if(auto& icon = cell->state.icon) { + width += icon.width() + 2; + } + if(auto& text = cell->state.text) { + width += Font::size(cell->font(true), text).width(); + } + } + } + return width; +} + +auto QtListView::onActivate() -> void { + if(!p.locked()) p.self().doActivate(); +} + +auto QtListView::onChange() -> void { +/* for(auto& item : listView.state.items) item.selected = false; for(unsigned position = 0; position < qtListView->topLevelItemCount(); position++) { if(auto item = qtListView->topLevelItem(position)) { @@ -327,20 +202,23 @@ void pListView::onChange() { } } if(!locked() && listView.onChange) listView.onChange(); +*/ } -void pListView::onContext() { - if(!locked() && listView.onContext) listView.onContext(); +auto QtListView::onContext() -> void { + if(!p.locked()) p.self().doContext(); } -void pListView::onSort(int column) { - if(column >= listView.columns()) return; - if(listView.state.columns[column].sortable) { - if(!locked() && listView.onSort) listView.onSort(column); +auto QtListView::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); + } } } -void pListView::onToggle(QTreeWidgetItem* item) { +auto QtListView::onToggle(QTreeWidgetItem* item) -> void { +/* maybe row; for(unsigned position = 0; position < qtListView->topLevelItemCount(); position++) { if(auto topLevelItem = qtListView->topLevelItem(position)) { @@ -354,42 +232,38 @@ void pListView::onToggle(QTreeWidgetItem* item) { listView.state.items[*row].checked = (item->checkState(0) == Qt::Checked); if(!locked() && listView.onToggle) listView.onToggle(*row); } +*/ } -int pListView::calculateAlignment(double horizontal, double vertical) { - int alignment = 0; - if(horizontal < 0.333) alignment |= Qt::AlignLeft; - else if(horizontal > 0.666) alignment |= Qt::AlignRight; - else alignment |= Qt::AlignCenter; - if(vertical < 0.333) alignment |= Qt::AlignTop; - else if(vertical > 0.666) alignment |= Qt::AlignBottom; - else alignment |= Qt::AlignVCenter; - return alignment; -} - -void pListView::QtTreeWidget::mousePressEvent(QMouseEvent* event) { +auto QtListView::mousePressEvent(QMouseEvent* event) -> void { QTreeWidget::mousePressEvent(event); - - if(event->button() == Qt::RightButton) { - self.onContext(); - } + if(event->button() == Qt::RightButton) onContext(); } -pListView::QtTreeWidget::QtTreeWidget(pListView& self) : self(self) { +auto QtListView::resizeEvent(QResizeEvent* event) -> void { + QTreeWidget::resizeEvent(event); + p._onSize(); } -void pListView::QtTreeWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { +auto QtListView::showEvent(QShowEvent* event) -> void { + QTreeWidget::showEvent(event); + p._onSize(); +} + +QtListViewDelegate::QtListViewDelegate(pListView& p) : QStyledItemDelegate(p.qtListView), p(p) { +} + +auto QtListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void { QStyledItemDelegate::paint(painter, option, index); - if(self.listView.state.gridVisible) { + if(p.state().bordered) { QPen pen; - pen.setColor(QColor(192, 192, 192)); + pen.setColor(QColor(160, 160, 160)); pen.setWidth(1); painter->setPen(pen); painter->drawRect(option.rect); } } -pListView::QtTreeWidgetDelegate::QtTreeWidgetDelegate(pListView& self) : QStyledItemDelegate(self.qtListView), self(self) { } -} +#endif diff --git a/hiro/qt/widget/list-view.hpp b/hiro/qt/widget/list-view.hpp new file mode 100644 index 00000000..0aa1b7a8 --- /dev/null +++ b/hiro/qt/widget/list-view.hpp @@ -0,0 +1,31 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +struct pListView : pWidget { + Declare(ListView, Widget) + + auto append(sListViewHeader header) -> void; + auto append(sListViewItem item) -> void; + auto remove(sListViewHeader header) -> void; + auto remove(sListViewItem item) -> void; + auto reset() -> void; + auto resizeColumns() -> void; + auto setAlignment(Alignment alignment) -> void; + auto setBackgroundColor(Color color) -> void; + auto setBatchable(bool batchable) -> void; + auto setBordered(bool bordered) -> void; + auto setForegroundColor(Color color) -> void; + + auto _onSize() -> void; + auto _width(unsigned column) -> unsigned; + auto _widthOfColumn(unsigned column) -> unsigned; + auto _widthOfCell(unsigned row, unsigned column) -> unsigned; + + QtListView* qtListView = nullptr; + QtListViewDelegate* qtListViewDelegate = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/progress-bar.cpp b/hiro/qt/widget/progress-bar.cpp index 93d7f6e2..995f5e27 100644 --- a/hiro/qt/widget/progress-bar.cpp +++ b/hiro/qt/widget/progress-bar.cpp @@ -1,30 +1,33 @@ -namespace phoenix { +#if defined(Hiro_ProgressBar) -Size pProgressBar::minimumSize() { - return {0, 25}; -} +namespace hiro { -void pProgressBar::setPosition(unsigned position) { - qtProgressBar->setValue(position); -} - -void pProgressBar::constructor() { +auto pProgressBar::construct() -> void { qtWidget = qtProgressBar = new QProgressBar; qtProgressBar->setRange(0, 100); qtProgressBar->setTextVisible(false); - pWidget::synchronizeState(); - setPosition(progressBar.state.position); + pWidget::construct(); + _setState(); } -void pProgressBar::destructor() { +auto pProgressBar::destruct() -> void { delete qtProgressBar; qtWidget = qtProgressBar = nullptr; } -void pProgressBar::orphan() { - destructor(); - constructor(); +auto pProgressBar::minimumSize() const -> Size { + return {0, 25}; +} + +auto pProgressBar::setPosition(unsigned position) -> void { + _setState(); +} + +auto pProgressBar::_setState() -> void { + qtProgressBar->setValue(state().position); } } + +#endif diff --git a/hiro/qt/widget/progress-bar.hpp b/hiro/qt/widget/progress-bar.hpp new file mode 100644 index 00000000..9e12bdda --- /dev/null +++ b/hiro/qt/widget/progress-bar.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_ProgressBar) + +namespace hiro { + +struct pProgressBar : pWidget { + Declare(ProgressBar, Widget) + + auto minimumSize() const -> Size override; + auto setPosition(unsigned position) -> void; + + auto _setState() -> void; + + QProgressBar* qtProgressBar = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/radio-button.cpp b/hiro/qt/widget/radio-button.cpp index 3ba491ab..be24041e 100644 --- a/hiro/qt/widget/radio-button.cpp +++ b/hiro/qt/widget/radio-button.cpp @@ -1,85 +1,95 @@ -namespace phoenix { +#if defined(Hiro_RadioButton) -Size pRadioButton::minimumSize() { - Size size = pFont::size(qtWidget->font(), radioButton.state.text); +namespace hiro { - if(radioButton.state.orientation == Orientation::Horizontal) { - size.width += radioButton.state.image.width; - size.height = max(radioButton.state.image.height, size.height); - } - - if(radioButton.state.orientation == Orientation::Vertical) { - size.width = max(radioButton.state.image.width, size.width); - size.height += radioButton.state.image.height; - } - - return {size.width + 20, size.height + 12}; -} - -void pRadioButton::setChecked() { - parent().lock(); - for(auto& item : radioButton.state.group) { - bool checked = &item.p == this; - item.p.qtRadioButton->setChecked(item.state.checked = checked); - } - parent().unlock(); -} - -void pRadioButton::setGroup(const group& group) { - parent().lock(); - for(auto& item : radioButton.state.group) { - item.p.qtRadioButton->setChecked(item.state.checked); - } - parent().unlock(); -} - -void pRadioButton::setImage(const image& image, Orientation orientation) { - qtRadioButton->setIconSize(QSize(image.width, image.height)); - qtRadioButton->setIcon(CreateIcon(image)); - qtRadioButton->setStyleSheet("text-align: top;"); - switch(orientation) { - case Orientation::Horizontal: qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break; - case Orientation::Vertical: qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); break; - } -} - -void pRadioButton::setText(string text) { - qtRadioButton->setText(QString::fromUtf8(text)); -} - -pRadioButton& pRadioButton::parent() { - if(radioButton.state.group.size()) return radioButton.state.group.first().p; - return *this; -} - -void pRadioButton::constructor() { - qtWidget = qtRadioButton = new QToolButton; +auto pRadioButton::construct() -> void { + qtWidget = qtRadioButton = new QtRadioButton(*this); qtRadioButton->setCheckable(true); qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextOnly); - connect(qtRadioButton, SIGNAL(toggled(bool)), SLOT(onActivate())); + qtRadioButton->connect(qtRadioButton, SIGNAL(toggled(bool)), SLOT(onActivate())); - pWidget::synchronizeState(); - setGroup(radioButton.state.group); - setText(radioButton.state.text); + pWidget::construct(); + _setState(); } -void pRadioButton::destructor() { +auto pRadioButton::destruct() -> void { if(qtRadioButton) delete qtRadioButton; qtWidget = qtRadioButton = nullptr; } -void pRadioButton::orphan() { - destructor(); - constructor(); +auto pRadioButton::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + + if(state().orientation == Orientation::Horizontal) { + size.setWidth(size.width() + state().icon.width()); + size.setHeight(max(state().icon.height(), size.height())); + } + + if(state().orientation == Orientation::Vertical) { + size.setWidth(max(state().icon.width(), size.width())); + size.setHeight(size.height() + state().icon.height()); + } + + return {size.width() + 20, size.height() + 12}; } -void pRadioButton::onActivate() { - if(parent().locked()) return; - bool wasChecked = radioButton.state.checked; - setChecked(); - if(!wasChecked) { - if(radioButton.onActivate) radioButton.onActivate(); +auto pRadioButton::setBordered(bool bordered) -> void { +} + +auto pRadioButton::setChecked() -> void { + _setState(); +} + +auto pRadioButton::setGroup(sGroup group) -> void { + _setState(); +} + +auto pRadioButton::setIcon(const image& icon) -> void { + _setState(); +} + +auto pRadioButton::setOrientation(Orientation orientation) -> void { + _setState(); +} + +auto pRadioButton::setText(const string& text) -> void { + _setState(); +} + +auto pRadioButton::_setState() -> void { + if(auto& group = state().group) { + group->self()->lock(); + for(auto& weak : group->state.objects) { + if(auto object = weak.acquire()) { + if(auto radioButton = dynamic_cast(object.data())) { + if(auto self = radioButton->self()) { + self->qtRadioButton->setChecked(radioButton->state.checked); + } + } + } + } + group->self()->unlock(); + } + qtRadioButton->setIconSize(QSize(state().icon.width(), state().icon.height())); + qtRadioButton->setIcon(CreateIcon(state().icon)); + qtRadioButton->setStyleSheet("text-align: top;"); + switch(state().orientation) { + case Orientation::Horizontal: qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break; + case Orientation::Vertical: qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); break; + } + qtRadioButton->setText(QString::fromUtf8(state().text)); +} + +auto QtRadioButton::onActivate() -> void { + if(auto& group = p.state().group) { + if(!group->self()->locked()) { + bool wasChecked = p.state().checked; + p.self().setChecked(); + if(!wasChecked) p.self().doActivate(); + } } } } + +#endif diff --git a/hiro/qt/widget/radio-button.hpp b/hiro/qt/widget/radio-button.hpp new file mode 100644 index 00000000..2aec616b --- /dev/null +++ b/hiro/qt/widget/radio-button.hpp @@ -0,0 +1,23 @@ +#if defined(Hiro_RadioButton) + +namespace hiro { + +struct pRadioButton : pWidget { + Declare(RadioButton, Widget) + + auto minimumSize() const -> Size override; + auto setBordered(bool bordered) -> void; + auto setChecked() -> void; + auto setGroup(sGroup group) -> void; + auto setIcon(const image& icon) -> void; + auto setOrientation(Orientation orientation) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void; + + QtRadioButton* qtRadioButton = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/radio-label.cpp b/hiro/qt/widget/radio-label.cpp index cdbf013f..81a7d6f6 100644 --- a/hiro/qt/widget/radio-label.cpp +++ b/hiro/qt/widget/radio-label.cpp @@ -1,63 +1,65 @@ -namespace phoenix { +#if defined(Hiro_RadioLabel) -Size pRadioLabel::minimumSize() { - Size size = pFont::size(qtWidget->font(), radioLabel.state.text); - return {size.width + 26, size.height + 6}; -} +namespace hiro { -void pRadioLabel::setChecked() { - parent().lock(); - for(auto& item : radioLabel.state.group) { - bool checked = &item == &radioLabel; - item.p.qtRadioLabel->setChecked(item.state.checked = checked); - } - parent().unlock(); -} - -void pRadioLabel::setGroup(const group& group) { - parent().lock(); - for(auto& item : radioLabel.state.group) { - item.p.qtRadioLabel->setChecked(item.state.checked); - } - parent().unlock(); -} - -void pRadioLabel::setText(string text) { - qtRadioLabel->setText(QString::fromUtf8(text)); -} - -pRadioLabel& pRadioLabel::parent() { - if(radioLabel.state.group.size()) return radioLabel.state.group.first().p; - return *this; -} - -void pRadioLabel::constructor() { - qtWidget = qtRadioLabel = new QRadioButton; +auto pRadioLabel::construct() -> void { + qtWidget = qtRadioLabel = new QtRadioLabel(*this); qtRadioLabel->setAutoExclusive(false); - connect(qtRadioLabel, SIGNAL(toggled(bool)), SLOT(onActivate())); + qtRadioLabel->connect(qtRadioLabel, SIGNAL(toggled(bool)), SLOT(onActivate())); - pWidget::synchronizeState(); - setGroup(radioLabel.state.group); - setText(radioLabel.state.text); + pWidget::construct(); + _setState(); } -void pRadioLabel::destructor() { +auto pRadioLabel::destruct() -> void { if(qtRadioLabel) delete qtRadioLabel; qtWidget = qtRadioLabel = nullptr; } -void pRadioLabel::orphan() { - destructor(); - constructor(); +auto pRadioLabel::minimumSize() const -> Size { + auto size = pFont::size(qtWidget->font(), state().text); + return {size.width() + 26, size.height() + 6}; } -void pRadioLabel::onActivate() { - if(parent().locked()) return; - bool wasChecked = radioLabel.state.checked; - setChecked(); - if(!wasChecked) { - if(radioLabel.onActivate) radioLabel.onActivate(); +auto pRadioLabel::setChecked() -> void { + _setState(); +} + +auto pRadioLabel::setGroup(sGroup group) -> void { + _setState(); +} + +auto pRadioLabel::setText(const string& text) -> void { + _setState(); +} + +auto pRadioLabel::_setState() -> void { + if(auto& group = state().group) { + group->self()->lock(); + for(auto& weak : group->state.objects) { + if(auto object = weak.acquire()) { + if(auto radioLabel = dynamic_cast(object.data())) { + if(auto self = radioLabel->self()) { + self->qtRadioLabel->setChecked(radioLabel->state.checked); + } + } + } + } + group->self()->unlock(); + } + qtRadioLabel->setText(QString::fromUtf8(state().text)); +} + +auto QtRadioLabel::onActivate() -> void { + if(auto& group = p.state().group) { + if(!group->self()->locked()) { + bool wasChecked = p.state().checked; + p.self().setChecked(); + if(!wasChecked) p.self().doActivate(); + } } } } + +#endif diff --git a/hiro/qt/widget/radio-label.hpp b/hiro/qt/widget/radio-label.hpp new file mode 100644 index 00000000..f6688435 --- /dev/null +++ b/hiro/qt/widget/radio-label.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_RadioLabel) + +namespace hiro { + +struct pRadioLabel : pWidget { + Declare(RadioLabel, Widget) + + auto minimumSize() const -> Size; + auto setChecked() -> void; + auto setGroup(sGroup group) -> void; + auto setText(const string& text) -> void; + + auto _setState() -> void; + + QtRadioLabel* qtRadioLabel = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/tab-frame-item.cpp b/hiro/qt/widget/tab-frame-item.cpp new file mode 100644 index 00000000..82297ca0 --- /dev/null +++ b/hiro/qt/widget/tab-frame-item.cpp @@ -0,0 +1,78 @@ +#if defined(Hiro_TabFrame) + +namespace hiro { + +auto pTabFrameItem::construct() -> void { + qtTabFrameItem = new QWidget; + + if(auto parent = _parent()) { + parent->qtTabFrame->addTab(qtTabFrameItem, ""); + } + + _setState(); +} + +auto pTabFrameItem::destruct() -> void { +} + +auto pTabFrameItem::append(sLayout layout) -> void { +} + +auto pTabFrameItem::remove(sLayout layout) -> void { +} + +auto pTabFrameItem::setClosable(bool closable) -> void { +} + +auto pTabFrameItem::setGeometry(Geometry geometry) -> void { + if(auto layout = state().layout) { + auto offset = qtTabFrameItem->geometry(); + geometry.setPosition({0, 0}); + geometry.setWidth(geometry.width() - (geometry.width() - offset.width())); + geometry.setHeight(geometry.height() - (geometry.height() - offset.height())); + layout->setGeometry(geometry); + } +} + +auto pTabFrameItem::setIcon(const image& icon) -> void { +} + +auto pTabFrameItem::setMovable(bool movable) -> void { +} + +auto pTabFrameItem::setSelected() -> void { +} + +auto pTabFrameItem::setText(const string& text) -> void { + _setState(); +} + +auto pTabFrameItem::setVisible(bool visible) -> void { + _setState(); +} + +auto pTabFrameItem::_parent() -> maybe { + if(auto parent = self().parentTabFrame()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pTabFrameItem::_setState() -> void { + if(auto parent = _parent()) { + parent->qtTabFrame->setTabText(self().offset(), QString::fromUtf8(state().text)); + if(auto layout = state().layout) { + auto geometry = parent->self().geometry(); + auto offset = qtTabFrameItem->geometry(); + geometry.setPosition({0, 0}); + geometry.setWidth(geometry.width() - (geometry.width() - offset.width())); + geometry.setHeight(geometry.height() - (geometry.height() - offset.height())); + layout->setGeometry(geometry); + layout->setVisible(layout->visible(true)); + } + } +} + +} + +#endif diff --git a/hiro/qt/widget/tab-frame-item.hpp b/hiro/qt/widget/tab-frame-item.hpp new file mode 100644 index 00000000..4b8d59c8 --- /dev/null +++ b/hiro/qt/widget/tab-frame-item.hpp @@ -0,0 +1,26 @@ +#if defined(Hiro_TabFrame) + +namespace hiro { + +struct pTabFrameItem : pObject { + Declare(TabFrameItem, Object) + + auto append(sLayout layout) -> void; + auto remove(sLayout layout) -> void; + auto setClosable(bool closable) -> void; + auto setIcon(const image& icon) -> void; + auto setGeometry(Geometry geometry) -> void; + auto setMovable(bool movable) -> void; + auto setSelected() -> void; + auto setText(const string& text) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; + + QWidget* qtTabFrameItem = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/tab-frame.cpp b/hiro/qt/widget/tab-frame.cpp index e2b393f0..d773f4bc 100644 --- a/hiro/qt/widget/tab-frame.cpp +++ b/hiro/qt/widget/tab-frame.cpp @@ -1,10 +1,31 @@ -namespace phoenix { +#if defined(Hiro_TabFrame) -void pTabFrame::append() { - qtTabFrame->addTab(new QWidget, ""); +namespace hiro { + +auto pTabFrame::construct() -> void { + qtWidget = qtTabFrame = new QtTabFrame(*this); + qtTabFrame->connect(qtTabFrame, SIGNAL(currentChanged(int)), SLOT(onChange(int))); + + pWidget::construct(); + _setState(); } -QWidget* pTabFrame::container(Widget& widget) { +auto pTabFrame::destruct() -> void { + delete qtTabFrame; + qtWidget = qtTabFrame = nullptr; +} + +auto pTabFrame::append(sTabFrameItem item) -> void { +} + +auto pTabFrame::remove(sTabFrameItem item) -> void { +} + +auto pTabFrame::setEdge(Edge edge) -> void { +} + +/* +auto pTabFrame::container(Widget& widget) -> QWidget* { Layout* widgetLayout = GetParentWidgetLayout(&widget); unsigned selection = 0; for(auto& layout : tabFrame.state.layout) { @@ -14,22 +35,22 @@ QWidget* pTabFrame::container(Widget& widget) { return nullptr; } -Position pTabFrame::displacement() { +auto pTabFrame::displacement() -> Position { return {5, 33}; } -void pTabFrame::remove(unsigned selection) { +auto pTabFrame::remove(unsigned selection) -> void { qtTabFrame->removeTab(selection); } -void pTabFrame::setEnabled(bool enabled) { +auto pTabFrame::setEnabled(bool enabled) -> void { for(auto& layout : tabFrame.state.layout) { if(layout) layout->setEnabled(layout->enabled()); } pWidget::setEnabled(enabled); } -void pTabFrame::setGeometry(Geometry geometry) { +auto pTabFrame::setGeometry(Geometry geometry) -> void { pWidget::setGeometry(geometry); geometry.x += 0, geometry.width -= 5; geometry.y += 29, geometry.height -= 33; @@ -38,58 +59,70 @@ void pTabFrame::setGeometry(Geometry geometry) { } synchronizeLayout(); } +*/ -void pTabFrame::setImage(unsigned selection, const image& image) { +auto pTabFrame::setGeometry(Geometry geometry) -> void { + pWidget::setGeometry(geometry); + +// geometry.setPosition({0, 0}); +// geometry.setWidth(geometry.width() - 4); +// geometry.setHeight(geometry.height() - 25); + + for(auto& item : state().items) { + if(auto self = item->self()) self->setGeometry(geometry); + } +} + +/* +auto pTabFrame::setIcon(unsigned selection, const image& icon) -> void { qtTabFrame->setTabIcon(selection, CreateIcon(image)); } -void pTabFrame::setSelected(unsigned selection) { +auto pTabFrame::setSelected(unsigned selection) -> void { lock(); qtTabFrame->setCurrentIndex(selection); synchronizeLayout(); unlock(); } -void pTabFrame::setText(unsigned selection, string text) { - qtTabFrame->setTabText(selection, QString::fromUtf8(text)); -} - -void pTabFrame::setVisible(bool visible) { +auto pTabFrame::setVisible(bool visible) -> void { for(auto& layout : tabFrame.state.layout) { if(layout) layout->setVisible(layout->visible()); } pWidget::setVisible(visible); } +*/ -void pTabFrame::constructor() { - qtWidget = qtTabFrame = new QTabWidget; - connect(qtTabFrame, SIGNAL(currentChanged(int)), SLOT(onChange(int))); - - setSelected(tabFrame.state.selection); -} - -void pTabFrame::destructor() { - delete qtTabFrame; - qtWidget = qtTabFrame = nullptr; -} - -void pTabFrame::orphan() { - destructor(); - constructor(); -} - -void pTabFrame::synchronizeLayout() { +/* +auto pTabFrame::synchronizeLayout() -> void { unsigned selection = 0; for(auto& layout : tabFrame.state.layout) { if(layout) layout->setVisible(selection == tabFrame.state.selection); selection++; } } +*/ -void pTabFrame::onChange(int selection) { - tabFrame.state.selection = selection; - synchronizeLayout(); - if(!locked() && tabFrame.onChange) tabFrame.onChange(); +auto pTabFrame::_setState() -> void { + for(auto& item : state().items) { + if(auto self = item->self()) self->_setState(); +// if(auto layout = item->state.layout) { +// item->setVisible(item->visible(true)); +// } + } +} + +auto QtTabFrame::showEvent(QShowEvent* event) -> void { + QTabWidget::showEvent(event); + p._setState(); //needed to capture geometry of TabFrame for TabFrameItem layouts +} + +auto QtTabFrame::onChange(int selection) -> void { +// state().selection = selection; +// synchronizeLayout(); +// if(!p.locked()) p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/tab-frame.hpp b/hiro/qt/widget/tab-frame.hpp new file mode 100644 index 00000000..4345e748 --- /dev/null +++ b/hiro/qt/widget/tab-frame.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_TabFrame) + +namespace hiro { + +struct pTabFrame : pWidget { + Declare(TabFrame, Widget) + + auto append(sTabFrameItem item) -> void; + auto remove(sTabFrameItem item) -> void; + auto setEdge(Edge edge) -> void; + auto setGeometry(Geometry geometry) -> void override; + + auto _setState() -> void; + + QtTabFrame* qtTabFrame = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/text-edit.cpp b/hiro/qt/widget/text-edit.cpp index 8097e2cf..ab3e5ae4 100644 --- a/hiro/qt/widget/text-edit.cpp +++ b/hiro/qt/widget/text-edit.cpp @@ -1,66 +1,82 @@ -namespace phoenix { +#if defined(Hiro_TextEdit) -void pTextEdit::setBackgroundColor(Color color) { - QPalette palette = qtTextEdit->palette(); - palette.setColor(QPalette::Base, QColor(color.red, color.green, color.blue)); - qtTextEdit->setPalette(palette); - qtTextEdit->setAutoFillBackground(true); +namespace hiro { + +auto pTextEdit::construct() -> void { + qtWidget = qtTextEdit = new QtTextEdit(*this); + qtTextEdit->connect(qtTextEdit, SIGNAL(textChanged()), SLOT(onChange())); + + pWidget::construct(); + _setState(); } -void pTextEdit::setCursorPosition(unsigned position) { - QTextCursor cursor = qtTextEdit->textCursor(); - unsigned lastCharacter = strlen(qtTextEdit->toPlainText().toUtf8().constData()); - cursor.setPosition(min(position, lastCharacter)); - qtTextEdit->setTextCursor(cursor); -} - -void pTextEdit::setEditable(bool editable) { - qtTextEdit->setTextInteractionFlags(editable ? Qt::TextEditorInteraction : Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse); -} - -void pTextEdit::setForegroundColor(Color color) { - QPalette palette = qtTextEdit->palette(); - palette.setColor(QPalette::Text, QColor(color.red, color.green, color.blue)); - qtTextEdit->setPalette(palette); -} - -void pTextEdit::setText(string text) { - qtTextEdit->setPlainText(QString::fromUtf8(text)); -} - -void pTextEdit::setWordWrap(bool wordWrap) { - qtTextEdit->setWordWrapMode(wordWrap ? QTextOption::WordWrap : QTextOption::NoWrap); - qtTextEdit->setHorizontalScrollBarPolicy(wordWrap ? Qt::ScrollBarAlwaysOff : Qt::ScrollBarAlwaysOn); - qtTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); -} - -string pTextEdit::text() { - return qtTextEdit->toPlainText().toUtf8().constData(); -} - -void pTextEdit::constructor() { - qtWidget = qtTextEdit = new QTextEdit; - connect(qtTextEdit, SIGNAL(textChanged()), SLOT(onChange())); - - pWidget::synchronizeState(); - setEditable(textEdit.state.editable); - setText(textEdit.state.text); - setWordWrap(textEdit.state.wordWrap); -} - -void pTextEdit::destructor() { +auto pTextEdit::destruct() -> void { delete qtTextEdit; qtWidget = qtTextEdit = nullptr; } -void pTextEdit::orphan() { - destructor(); - constructor(); +auto pTextEdit::setBackgroundColor(Color color) -> void { + _setState(); } -void pTextEdit::onChange() { - textEdit.state.text = text(); - if(textEdit.onChange) textEdit.onChange(); +auto pTextEdit::setCursorPosition(unsigned position) -> void { + _setState(); +} + +auto pTextEdit::setEditable(bool editable) -> void { + _setState(); +} + +auto pTextEdit::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pTextEdit::setText(const string& text) -> void { + qtTextEdit->setPlainText(QString::fromUtf8(text)); +} + +auto pTextEdit::setWordWrap(bool wordWrap) -> void { + _setState(); +} + +auto pTextEdit::text() const -> string { + return qtTextEdit->toPlainText().toUtf8().constData(); +} + +auto pTextEdit::_setState() -> void { + if(auto color = state().backgroundColor) { + QPalette palette = qtTextEdit->palette(); + palette.setColor(QPalette::Base, QColor(color.red(), color.green(), color.blue())); + qtTextEdit->setPalette(palette); + qtTextEdit->setAutoFillBackground(true); + } else { + //todo + } + QTextCursor cursor = qtTextEdit->textCursor(); + unsigned lastCharacter = strlen(qtTextEdit->toPlainText().toUtf8().constData()); + cursor.setPosition(min(state().cursorPosition, lastCharacter)); + qtTextEdit->setTextCursor(cursor); + qtTextEdit->setTextInteractionFlags(state().editable + ? Qt::TextEditorInteraction + : Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse + ); + if(auto color = state().foregroundColor) { + QPalette palette = qtTextEdit->palette(); + palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue())); + qtTextEdit->setPalette(palette); + } else { + //todo + } + qtTextEdit->setWordWrapMode(state().wordWrap ? QTextOption::WordWrap : QTextOption::NoWrap); + qtTextEdit->setHorizontalScrollBarPolicy(state().wordWrap ? Qt::ScrollBarAlwaysOff : Qt::ScrollBarAlwaysOn); + qtTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +auto QtTextEdit::onChange() -> void { +//p.state().text = text(); + p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/text-edit.hpp b/hiro/qt/widget/text-edit.hpp new file mode 100644 index 00000000..882d2881 --- /dev/null +++ b/hiro/qt/widget/text-edit.hpp @@ -0,0 +1,23 @@ +#if defined(Hiro_TextEdit) + +namespace hiro { + +struct pTextEdit : pWidget { + Declare(TextEdit, Widget) + + auto setBackgroundColor(Color color) -> void; + auto setCursorPosition(unsigned position) -> void; + auto setEditable(bool editable) -> void; + auto setForegroundColor(Color color) -> void; + auto setText(const string& text) -> void; + auto setWordWrap(bool wordWrap) -> void; + auto text() const -> string; + + auto _setState() -> void; + + QtTextEdit* qtTextEdit = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/vertical-scroller.cpp b/hiro/qt/widget/vertical-scroller.cpp index ea8fac87..1f18c9ec 100644 --- a/hiro/qt/widget/vertical-scroller.cpp +++ b/hiro/qt/widget/vertical-scroller.cpp @@ -1,43 +1,46 @@ -namespace phoenix { +#if defined(Hiro_VerticalScroller) -Size pVerticalScroller::minimumSize() { +namespace hiro { + +auto pVerticalScroller::construct() -> void { + qtWidget = qtVerticalScroller = new QtVerticalScroller(*this); + qtVerticalScroller->setRange(0, 100); + qtVerticalScroller->setPageStep(101 >> 3); + qtVerticalScroller->connect(qtVerticalScroller, SIGNAL(valueChanged(int)), SLOT(onChange())); + + pWidget::construct(); + _setState(); +} + +auto pVerticalScroller::destruct() -> void { + delete qtVerticalScroller; + qtWidget = qtVerticalScroller = nullptr; +} + +auto pVerticalScroller::minimumSize() const -> Size { return {15, 0}; } -void pVerticalScroller::setLength(unsigned length) { - length += length == 0; - qtScroller->setRange(0, length - 1); - qtScroller->setPageStep(length >> 3); +auto pVerticalScroller::setLength(unsigned length) -> void { + _setState(); } -void pVerticalScroller::setPosition(unsigned position) { - qtScroller->setValue(position); +auto pVerticalScroller::setPosition(unsigned position) -> void { + _setState(); } -void pVerticalScroller::constructor() { - qtWidget = qtScroller = new QScrollBar(Qt::Vertical); - qtScroller->setRange(0, 100); - qtScroller->setPageStep(101 >> 3); - connect(qtScroller, SIGNAL(valueChanged(int)), SLOT(onChange())); - - pWidget::synchronizeState(); - setLength(verticalScroller.state.length); - setPosition(verticalScroller.state.position); +auto pVerticalScroller::_setState() -> void { + signed length = state().length + (state().length == 0); + qtVerticalScroller->setRange(0, length - 1); + qtVerticalScroller->setPageStep(length >> 3); + qtVerticalScroller->setValue(state().position); } -void pVerticalScroller::destructor() { - delete qtScroller; - qtWidget = qtScroller = nullptr; -} - -void pVerticalScroller::orphan() { - destructor(); - constructor(); -} - -void pVerticalScroller::onChange() { - verticalScroller.state.position = qtScroller->value(); - if(verticalScroller.onChange) verticalScroller.onChange(); +auto QtVerticalScroller::onChange() -> void { + p.state().position = value(); + p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/vertical-scroller.hpp b/hiro/qt/widget/vertical-scroller.hpp new file mode 100644 index 00000000..c6d3c6c4 --- /dev/null +++ b/hiro/qt/widget/vertical-scroller.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_VerticalScroller) + +namespace hiro { + +struct pVerticalScroller : pWidget { + Declare(VerticalScroller, Widget) + + auto minimumSize() const -> Size override; + auto setLength(unsigned length) -> void; + auto setPosition(unsigned position) -> void; + + auto _setState() -> void; + + QtVerticalScroller* qtVerticalScroller = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/vertical-slider.cpp b/hiro/qt/widget/vertical-slider.cpp index 30fad0cd..56e27c41 100644 --- a/hiro/qt/widget/vertical-slider.cpp +++ b/hiro/qt/widget/vertical-slider.cpp @@ -1,43 +1,47 @@ -namespace phoenix { +#if defined(Hiro_VerticalSlider) -Size pVerticalSlider::minimumSize() { +namespace hiro { + +auto pVerticalSlider::minimumSize() const -> Size { return {20, 0}; } -void pVerticalSlider::setLength(unsigned length) { - length += length == 0; - qtSlider->setRange(0, length - 1); - qtSlider->setPageStep(length >> 3); +auto pVerticalSlider::setLength(unsigned length) -> void { + _setState(); } -void pVerticalSlider::setPosition(unsigned position) { - qtSlider->setValue(position); +auto pVerticalSlider::setPosition(unsigned position) -> void { + _setState(); } -void pVerticalSlider::constructor() { - qtWidget = qtSlider = new QSlider(Qt::Vertical); - qtSlider->setRange(0, 100); - qtSlider->setPageStep(101 >> 3); - connect(qtSlider, SIGNAL(valueChanged(int)), SLOT(onChange())); +auto pVerticalSlider::construct() -> void { + qtWidget = qtVerticalSlider = new QtVerticalSlider(*this); + qtVerticalSlider->setInvertedAppearance(true); + qtVerticalSlider->setRange(0, 100); + qtVerticalSlider->setPageStep(101 >> 3); + qtVerticalSlider->connect(qtVerticalSlider, SIGNAL(valueChanged(int)), SLOT(onChange())); - pWidget::synchronizeState(); - setLength(verticalSlider.state.length); - setPosition(verticalSlider.state.position); + pWidget::construct(); + _setState(); } -void pVerticalSlider::destructor() { - delete qtSlider; - qtWidget = qtSlider = nullptr; +auto pVerticalSlider::destruct() -> void { + delete qtVerticalSlider; + qtWidget = qtVerticalSlider = nullptr; } -void pVerticalSlider::orphan() { - destructor(); - constructor(); +auto pVerticalSlider::_setState() -> void { + signed length = state().length + (state().length == 0); + qtVerticalSlider->setRange(0, length - 1); + qtVerticalSlider->setPageStep(length >> 3); + qtVerticalSlider->setValue(state().position); } -void pVerticalSlider::onChange() { - verticalSlider.state.position = qtSlider->value(); - if(verticalSlider.onChange) verticalSlider.onChange(); +auto QtVerticalSlider::onChange() -> void { + p.state().position = value(); + p.self().doChange(); } } + +#endif diff --git a/hiro/qt/widget/vertical-slider.hpp b/hiro/qt/widget/vertical-slider.hpp new file mode 100644 index 00000000..5d126ae1 --- /dev/null +++ b/hiro/qt/widget/vertical-slider.hpp @@ -0,0 +1,19 @@ +#if defined(Hiro_VerticalSlider) + +namespace hiro { + +struct pVerticalSlider : pWidget { + Declare(VerticalSlider, Widget) + + auto minimumSize() const -> Size override; + auto setLength(unsigned length) -> void; + auto setPosition(unsigned position) -> void; + + auto _setState() -> void; + + QtVerticalSlider* qtVerticalSlider = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/viewport.cpp b/hiro/qt/widget/viewport.cpp index e812e6fb..8edc159c 100644 --- a/hiro/qt/widget/viewport.cpp +++ b/hiro/qt/widget/viewport.cpp @@ -1,71 +1,68 @@ -namespace phoenix { +#if defined(Hiro_Viewport) -uintptr_t pViewport::handle() { - return (uintptr_t)qtViewport->winId(); -} +namespace hiro { -void pViewport::setDroppable(bool droppable) { - qtViewport->setAcceptDrops(droppable); -} - -void pViewport::constructor() { +auto pViewport::construct() -> void { qtWidget = qtViewport = new QtViewport(*this); qtViewport->setMouseTracking(true); qtViewport->setAttribute(Qt::WA_PaintOnScreen, true); qtViewport->setStyleSheet("background: #000000"); - pWidget::synchronizeState(); + pWidget::construct(); + _setState(); } -void pViewport::destructor() { +auto pViewport::destruct() -> void { delete qtViewport; qtWidget = qtViewport = nullptr; } -void pViewport::orphan() { - destructor(); - constructor(); +auto pViewport::handle() const -> uintptr_t { + return (uintptr_t)qtViewport->winId(); } -void pViewport::QtViewport::dragEnterEvent(QDragEnterEvent* event) { +auto pViewport::setDroppable(bool droppable) -> void { + _setState(); +} + +auto pViewport::_setState() -> void { + qtViewport->setAcceptDrops(state().droppable); +} + +auto QtViewport::dragEnterEvent(QDragEnterEvent* event) -> void { if(event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } -void pViewport::QtViewport::dropEvent(QDropEvent* event) { - lstring paths = DropPaths(event); - if(paths.empty()) return; - if(self.viewport.onDrop) self.viewport.onDrop(paths); +auto QtViewport::dropEvent(QDropEvent* event) -> void { + if(auto paths = DropPaths(event)) p.self().doDrop(paths); } -void pViewport::QtViewport::leaveEvent(QEvent* event) { - if(self.viewport.onMouseLeave) self.viewport.onMouseLeave(); +auto QtViewport::leaveEvent(QEvent* event) -> void { + p.self().doMouseLeave(); } -void pViewport::QtViewport::mouseMoveEvent(QMouseEvent* event) { - if(self.viewport.onMouseMove) self.viewport.onMouseMove({event->pos().x(), event->pos().y()}); +auto QtViewport::mouseMoveEvent(QMouseEvent* event) -> void { + p.self().doMouseMove({event->pos().x(), event->pos().y()}); } -void pViewport::QtViewport::mousePressEvent(QMouseEvent* event) { - if(!self.viewport.onMousePress) return; +auto QtViewport::mousePressEvent(QMouseEvent* event) -> void { switch(event->button()) { - case Qt::LeftButton: self.viewport.onMousePress(Mouse::Button::Left); break; - case Qt::MidButton: self.viewport.onMousePress(Mouse::Button::Middle); break; - case Qt::RightButton: self.viewport.onMousePress(Mouse::Button::Right); break; + case Qt::LeftButton: p.self().doMousePress(Mouse::Button::Left); break; + case Qt::MidButton: p.self().doMousePress(Mouse::Button::Middle); break; + case Qt::RightButton: p.self().doMousePress(Mouse::Button::Right); break; } } -void pViewport::QtViewport::mouseReleaseEvent(QMouseEvent* event) { - if(!self.viewport.onMouseRelease) return; +auto QtViewport::mouseReleaseEvent(QMouseEvent* event) -> void { switch(event->button()) { - case Qt::LeftButton: self.viewport.onMouseRelease(Mouse::Button::Left); break; - case Qt::MidButton: self.viewport.onMouseRelease(Mouse::Button::Middle); break; - case Qt::RightButton: self.viewport.onMouseRelease(Mouse::Button::Right); break; + case Qt::LeftButton: p.self().doMouseRelease(Mouse::Button::Left); break; + case Qt::MidButton: p.self().doMouseRelease(Mouse::Button::Middle); break; + case Qt::RightButton: p.self().doMouseRelease(Mouse::Button::Right); break; } } -pViewport::QtViewport::QtViewport(pViewport& self) : self(self) { } -} +#endif diff --git a/hiro/qt/widget/viewport.hpp b/hiro/qt/widget/viewport.hpp new file mode 100644 index 00000000..82a90dca --- /dev/null +++ b/hiro/qt/widget/viewport.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_Viewport) + +namespace hiro { + +struct pViewport : pWidget { + Declare(Viewport, Widget) + + auto handle() const -> uintptr_t; + auto setDroppable(bool droppable) -> void; + + auto _setState() -> void; + + QtViewport* qtViewport = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/widget/widget.cpp b/hiro/qt/widget/widget.cpp index 6cddbcdf..95335701 100644 --- a/hiro/qt/widget/widget.cpp +++ b/hiro/qt/widget/widget.cpp @@ -1,68 +1,77 @@ -namespace phoenix { +#if defined(Hiro_Widget) -QWidget* pWidget::container(Widget& widget) { +namespace hiro { + +static auto ParentContainer(mObject& object) -> QWidget* { + if(auto frame = object.parentFrame()) { + if(auto self = frame->self()) return self->qtFrame; + } + if(auto tabFrameItem = object.parentTabFrameItem()) { + if(auto self = tabFrameItem->self()) return self->qtTabFrameItem; + } + if(auto window = object.parentWindow()) { + if(auto self = window->self()) return self->qtContainer; + } + if(auto parent = object.parent()) { + return ParentContainer(*parent); + } return nullptr; } -bool pWidget::focused() { +auto pWidget::construct() -> void { + if(!qtWidget) return; + + if(auto container = ParentContainer(self())) { + qtWidget->setParent(container); + } + + setFont(self().font(true)); + setVisible(self().visible(true)); +} + +auto pWidget::destruct() -> void { +} + +auto pWidget::focused() const -> bool { + if(!qtWidget) return false; return qtWidget->hasFocus(); } -Size pWidget::minimumSize() { - return {0, 0}; -} - -void pWidget::setEnabled(bool enabled) { - if(!widget.parent()) enabled = false; - if(widget.state.abstract) enabled = false; - if(!widget.enabledToAll()) enabled = false; +auto pWidget::setEnabled(bool enabled) -> void { + if(!qtWidget) return; qtWidget->setEnabled(enabled); } -void pWidget::setFocused() { +auto pWidget::setFocused() -> void { + if(!qtWidget) return; qtWidget->setFocus(Qt::OtherFocusReason); } -void pWidget::setFont(string font) { +auto pWidget::setFont(const string& font) -> void { + if(!qtWidget) return; qtWidget->setFont(pFont::create(font)); } -void pWidget::setGeometry(Geometry geometry) { - Position displacement = GetDisplacement(&widget); - geometry.x -= displacement.x; - geometry.y -= displacement.y; - - qtWidget->setGeometry(geometry.x, geometry.y, geometry.width, geometry.height); - if(widget.onSize) widget.onSize(); +auto pWidget::setGeometry(Geometry geometry) -> void { + if(!qtWidget) return; +// Position displacement = GetDisplacement(&widget); +// geometry.x -= displacement.x; +// geometry.y -= displacement.y; + qtWidget->setGeometry(geometry.x(), geometry.y(), geometry.width(), geometry.height()); + self().doSize(); } -void pWidget::setVisible(bool visible) { - if(!widget.parent()) visible = false; - if(widget.state.abstract) visible = false; - if(!widget.visibleToAll()) visible = false; +auto pWidget::setVisible(bool visible) -> void { + if(!qtWidget) return; qtWidget->setVisible(visible); } -void pWidget::constructor() { - if(widget.state.abstract) qtWidget = new QWidget; -} - //pWidget::constructor() called before p{Derived}::constructor(); ergo qtWidget is not yet valid //pWidget::synchronizeState() is called to finish construction of p{Derived}::constructor() -void pWidget::synchronizeState() { - setFont(widget.font()); -} - -void pWidget::destructor() { - if(widget.state.abstract) { - delete qtWidget; - qtWidget = nullptr; - } -} - -void pWidget::orphan() { - destructor(); - constructor(); -} +//void pWidget::synchronizeState() { +// setFont(widget.font()); +//} } + +#endif diff --git a/hiro/qt/widget/widget.hpp b/hiro/qt/widget/widget.hpp new file mode 100644 index 00000000..dc714610 --- /dev/null +++ b/hiro/qt/widget/widget.hpp @@ -0,0 +1,20 @@ +#if defined(Hiro_Widget) + +namespace hiro { + +struct pWidget : pSizable { + Declare(Widget, Sizable) + + auto focused() const -> bool override; + auto setEnabled(bool enabled) -> void override; + auto setFocused() -> void override; + auto setFont(const string& font) -> void override; + auto setGeometry(Geometry geometry) -> void override; + auto setVisible(bool visible) -> void override; + + QWidget* qtWidget = nullptr; +}; + +} + +#endif diff --git a/hiro/qt/window.cpp b/hiro/qt/window.cpp index 6c6ae89c..ea83798f 100644 --- a/hiro/qt/window.cpp +++ b/hiro/qt/window.cpp @@ -1,18 +1,202 @@ -namespace phoenix { +#if defined(Hiro_Window) -void pWindow::append(Layout& layout) { - Geometry geometry = window.state.geometry; - geometry.x = geometry.y = 0; - layout.setGeometry(geometry); +namespace hiro { + +auto pWindow::construct() -> void { + qtWindow = new QtWindow(*this); + qtWindow->setWindowTitle(" "); + + //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(string{userpath(), ".local/share/icons/", name, ".png"})); + } else if(file::exists({"/usr/local/share/pixmaps/", name, ".png"})) { + qtWindow->setWindowIcon(QIcon(string{"/usr/local/share/pixmaps/", name, ".png"})); + } else if(file::exists({"/usr/share/pixmaps/", name, ".png"})) { + qtWindow->setWindowIcon(QIcon(string{"/usr/share/pixmaps/", name, ".png"})); + } + } + + qtLayout = new QVBoxLayout(qtWindow); + qtLayout->setMargin(0); + qtLayout->setSpacing(0); + qtWindow->setLayout(qtLayout); + + qtMenuBar = new QMenuBar(qtWindow); + qtMenuBar->setVisible(false); + qtLayout->addWidget(qtMenuBar); + + qtContainer = new QWidget(qtWindow); + qtContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + qtContainer->setVisible(true); + qtLayout->addWidget(qtContainer); + + qtStatusBar = new QStatusBar(qtWindow); + qtStatusBar->setSizeGripEnabled(true); + qtStatusBar->setVisible(false); + qtLayout->addWidget(qtStatusBar); + + setBackgroundColor(state().backgroundColor); + setDroppable(state().droppable); + setGeometry(state().geometry); + setResizable(state().resizable); + setTitle(state().title); } -void pWindow::append(Menu& menu) { - if(window.state.menuFont != "") menu.p.setFont(window.state.menuFont); - else menu.p.setFont(Font::sans(8)); - qtMenu->addMenu(menu.p.qtMenu); +auto pWindow::destruct() -> void { + delete qtStatusBar; + delete qtContainer; + delete qtMenuBar; + delete qtLayout; + delete qtWindow; } -void pWindow::append(Widget& widget) { +auto pWindow::append(sLayout layout) -> void { +} + +auto pWindow::append(sMenuBar menuBar) -> void { +} + +auto pWindow::append(sStatusBar statusBar) -> void { +} + +auto pWindow::focused() const -> bool { + return qtWindow->isActiveWindow() && !qtWindow->isMinimized(); +} + +auto pWindow::frameMargin() const -> Geometry { + if(state().fullScreen) return { + 0, _menuHeight(), + 0, _menuHeight() + _statusHeight() + }; + return { + settings->geometry.frameX, + settings->geometry.frameY + _menuHeight(), + settings->geometry.frameWidth, + settings->geometry.frameHeight + _menuHeight() + _statusHeight() + }; +} + +auto pWindow::remove(sLayout layout) -> void { +} + +auto pWindow::remove(sMenuBar menuBar) -> void { + //QMenuBar::removeMenu() does not exist + //qtMenu->clear(); + //for(auto& menu : window.state.menu) append(menu); +} + +auto pWindow::remove(sStatusBar statusBar) -> void { +} + +/* + //orphan() destroys and recreates widgets (to disassociate them from their parent); + //attempting to create widget again after QApplication::quit() crashes libQtGui + if(qtApplication) widget.p.orphan(); +} +*/ + +auto pWindow::setBackgroundColor(Color color) -> void { + if(color) { + QPalette palette; + palette.setColor(QPalette::Background, QColor(color.red(), color.green(), color.blue() /*, color.alpha() */)); + qtContainer->setPalette(palette); + qtContainer->setAutoFillBackground(true); + //translucency results are very unpleasant without a compositor; so disable for now + //qtWindow->setAttribute(Qt::WA_TranslucentBackground, color.alpha() != 255); + } +} + +auto pWindow::setDroppable(bool droppable) -> void { + qtWindow->setAcceptDrops(droppable); +} + +auto pWindow::setEnabled(bool enabled) -> void { +} + +auto pWindow::setFocused() -> void { + qtWindow->raise(); + qtWindow->activateWindow(); +} + +auto pWindow::setFullScreen(bool fullScreen) -> void { + if(!fullScreen) { + setResizable(state().resizable); + qtWindow->showNormal(); + qtWindow->adjustSize(); + } else { + qtLayout->setSizeConstraint(QLayout::SetDefaultConstraint); + qtContainer->setFixedSize(Desktop::size().width() - frameMargin().width(), Desktop::size().height() - frameMargin().height()); + qtWindow->showFullScreen(); + } +} + +auto pWindow::setGeometry(Geometry geometry) -> void { + lock(); + Application::processEvents(); + QApplication::syncX(); + + setResizable(state().resizable); + qtWindow->move(geometry.x() - frameMargin().x(), geometry.y() - frameMargin().y()); + //qtWindow->adjustSize() fails if larger than 2/3rds screen size + qtWindow->resize(qtWindow->sizeHint()); + if(state().resizable) { + //required to allow shrinking window from default size + qtWindow->setMinimumSize(1, 1); + qtContainer->setMinimumSize(1, 1); + } + +// for(auto& layout : window.state.layout) { +// geometry.x = geometry.y = 0; +// layout.setGeometry(geometry); +// } + unlock(); +} + +auto pWindow::setModal(bool modal) -> void { + if(modal) { + //windowModality can only be enabled while window is invisible + setVisible(false); + qtWindow->setWindowModality(Qt::ApplicationModal); + setVisible(true); + while(!Application::state.quit && state().modal) { + if(Application::state.onMain) { + Application::doMain(); + } else { + usleep(20 * 1000); + } + Application::processEvents(); + } + qtWindow->setWindowModality(Qt::NonModal); + } +} + +auto pWindow::setResizable(bool resizable) -> void { + if(resizable) { + qtLayout->setSizeConstraint(QLayout::SetDefaultConstraint); + qtContainer->setMinimumSize(state().geometry.width(), state().geometry.height()); + } else { + qtLayout->setSizeConstraint(QLayout::SetFixedSize); + qtContainer->setFixedSize(state().geometry.width(), state().geometry.height()); + } + qtStatusBar->setSizeGripEnabled(resizable); +} + +auto pWindow::setTitle(const string& text) -> void { + qtWindow->setWindowTitle(QString::fromUtf8(text)); +} + +auto pWindow::setVisible(bool visible) -> void { + lock(); + qtWindow->setVisible(visible); + if(visible) { + _updateFrameGeometry(); + setGeometry(state().geometry); + } + unlock(); +} + +/* if(widget.font().empty() && !window.state.widgetFont.empty()) { widget.setFont(window.state.widgetFont); } @@ -24,210 +208,23 @@ void pWindow::append(Widget& widget) { } widget.setVisible(widget.visible()); } +*/ -Geometry pWindow::frameMargin() { - unsigned menuHeight = window.state.menuVisible ? settings->geometry.menuHeight : 0; - unsigned statusHeight = window.state.statusVisible ? settings->geometry.statusHeight : 0; - if(window.state.fullScreen) return {0, menuHeight, 0, menuHeight + statusHeight}; - return { - settings->geometry.frameX, - settings->geometry.frameY + menuHeight, - settings->geometry.frameWidth, - settings->geometry.frameHeight + menuHeight + statusHeight - }; -} - -bool pWindow::focused() { - return qtWindow->isActiveWindow() && !qtWindow->isMinimized(); -} - -void pWindow::remove(Layout& layout) { -} - -void pWindow::remove(Menu& menu) { - //QMenuBar::removeMenu() does not exist - qtMenu->clear(); - for(auto& menu : window.state.menu) append(menu); -} - -void pWindow::remove(Widget& widget) { - //orphan() destroys and recreates widgets (to disassociate them from their parent); - //attempting to create widget again after QApplication::quit() crashes libQtGui - if(qtApplication) widget.p.orphan(); -} - -void pWindow::setBackgroundColor(Color color) { - QPalette palette; - palette.setColor(QPalette::Background, QColor(color.red, color.green, color.blue /*, color.alpha */)); - qtContainer->setPalette(palette); - qtContainer->setAutoFillBackground(true); - //translucency results are very unpleasant without a compositor; so disable for now - //qtWindow->setAttribute(Qt::WA_TranslucentBackground, color.alpha != 255); -} - -void pWindow::setDroppable(bool droppable) { - qtWindow->setAcceptDrops(droppable); -} - -void pWindow::setFocused() { - qtWindow->raise(); - qtWindow->activateWindow(); -} - -void pWindow::setFullScreen(bool fullScreen) { - if(fullScreen == false) { - setResizable(window.state.resizable); - qtWindow->showNormal(); - qtWindow->adjustSize(); - } else { - qtLayout->setSizeConstraint(QLayout::SetDefaultConstraint); - qtContainer->setFixedSize(Desktop::size().width - frameMargin().width, Desktop::size().height - frameMargin().height); - qtWindow->showFullScreen(); +auto pWindow::_append(mWidget& widget) -> void { + if(auto self = widget.self()) { + self->qtWidget->setParent(qtContainer); } } -void pWindow::setGeometry(Geometry geometry) { - lock(); - Application::processEvents(); - QApplication::syncX(); - - setResizable(window.state.resizable); - qtWindow->move(geometry.x - frameMargin().x, geometry.y - frameMargin().y); - //qtWindow->adjustSize() fails if larger than 2/3rds screen size - qtWindow->resize(qtWindow->sizeHint()); - if(window.state.resizable) { - //required to allow shrinking window from default size - qtWindow->setMinimumSize(1, 1); - qtContainer->setMinimumSize(1, 1); - } - - for(auto& layout : window.state.layout) { - geometry.x = geometry.y = 0; - layout.setGeometry(geometry); - } - unlock(); +auto pWindow::_menuHeight() const -> signed { + return qtMenuBar->isVisible() ? settings->geometry.menuHeight : 0; } -void pWindow::setMenuFont(string font) { - qtMenu->setFont(pFont::create(font)); - for(auto& item : window.state.menu) item.p.setFont(font); +auto pWindow::_statusHeight() const -> signed { + return qtStatusBar->isVisible() ? settings->geometry.statusHeight : 0; } -void pWindow::setMenuVisible(bool visible) { - qtMenu->setVisible(visible); - setGeometry(window.state.geometry); -} - -void pWindow::setModal(bool modal) { - if(modal == true) { - //windowModality can only be enabled while window is invisible - setVisible(false); - qtWindow->setWindowModality(Qt::ApplicationModal); - setVisible(true); - while(window.state.modal) { - Application::processEvents(); - if(Application::main) { - Application::main(); - } else { - usleep(20 * 1000); - } - } - qtWindow->setWindowModality(Qt::NonModal); - } -} - -void pWindow::setResizable(bool resizable) { - if(resizable) { - qtLayout->setSizeConstraint(QLayout::SetDefaultConstraint); - qtContainer->setMinimumSize(window.state.geometry.width, window.state.geometry.height); - } else { - qtLayout->setSizeConstraint(QLayout::SetFixedSize); - qtContainer->setFixedSize(window.state.geometry.width, window.state.geometry.height); - } - qtStatus->setSizeGripEnabled(resizable); -} - -void pWindow::setStatusFont(string font) { - qtStatus->setFont(pFont::create(font)); -} - -void pWindow::setStatusText(string text) { - qtStatus->showMessage(QString::fromUtf8(text), 0); -} - -void pWindow::setStatusVisible(bool visible) { - qtStatus->setVisible(visible); - setGeometry(window.state.geometry); -} - -void pWindow::setTitle(string text) { - qtWindow->setWindowTitle(QString::fromUtf8(text)); -} - -void pWindow::setVisible(bool visible) { - lock(); - qtWindow->setVisible(visible); - if(visible) { - updateFrameGeometry(); - setGeometry(window.state.geometry); - } - unlock(); -} - -void pWindow::setWidgetFont(string font) { -} - -void pWindow::constructor() { - qtWindow = new QtWindow(*this); - qtWindow->setWindowTitle(" "); - - //if program was given a name, try and set the window taskbar icon to a matching pixmap image - if(applicationState.name.empty() == false) { - if(file::exists({"/usr/share/pixmaps/", applicationState.name, ".png"})) { - qtWindow->setWindowIcon(QIcon(string{"/usr/share/pixmaps/", applicationState.name, ".png"})); - } else if(file::exists({"/usr/local/share/pixmaps/", applicationState.name, ".png"})) { - qtWindow->setWindowIcon(QIcon(string{"/usr/local/share/pixmaps/", applicationState.name, ".png"})); - } else if(file::exists({userpath(), ".local/share/icons/", applicationState.name, ".png"})) { - qtWindow->setWindowIcon(QIcon(string{userpath(), ".local/share/icons/", applicationState.name, ".png"})); - } - } - - qtLayout = new QVBoxLayout(qtWindow); - qtLayout->setMargin(0); - qtLayout->setSpacing(0); - qtWindow->setLayout(qtLayout); - - qtMenu = new QMenuBar(qtWindow); - qtMenu->setVisible(false); - qtLayout->addWidget(qtMenu); - - qtContainer = new QWidget(qtWindow); - qtContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - qtContainer->setVisible(true); - qtLayout->addWidget(qtContainer); - - qtStatus = new QStatusBar(qtWindow); - qtStatus->setSizeGripEnabled(true); - qtStatus->setVisible(false); - qtLayout->addWidget(qtStatus); - - setGeometry(window.state.geometry); - setMenuFont(Font::sans(8)); - setStatusFont(Font::sans(8)); - - QColor color = qtWindow->palette().color(QPalette::ColorRole::Window); - window.state.backgroundColor = Color((uint8_t)color.red(), (uint8_t)color.green(), (uint8_t)color.blue(), (uint8_t)color.alpha()); -} - -void pWindow::destructor() { - delete qtStatus; - delete qtContainer; - delete qtMenu; - delete qtLayout; - delete qtWindow; -} - -void pWindow::updateFrameGeometry() { +auto pWindow::_updateFrameGeometry() -> void { pApplication::syncX(); QRect border = qtWindow->frameGeometry(); QRect client = qtWindow->geometry(); @@ -237,78 +234,80 @@ void pWindow::updateFrameGeometry() { settings->geometry.frameWidth = border.width() - client.width(); settings->geometry.frameHeight = border.height() - client.height(); - if(window.state.menuVisible) { + if(qtMenuBar->isVisible()) { pApplication::syncX(); - settings->geometry.menuHeight = qtMenu->height(); + settings->geometry.menuHeight = qtMenuBar->height(); } - if(window.state.statusVisible) { + if(qtStatusBar->isVisible()) { pApplication::syncX(); - settings->geometry.statusHeight = qtStatus->height(); + settings->geometry.statusHeight = qtStatusBar->height(); } settings->save(); } -void pWindow::QtWindow::closeEvent(QCloseEvent* event) { +auto QtWindow::closeEvent(QCloseEvent* event) -> void { event->ignore(); - if(self.window.onClose) self.window.onClose(); - else self.window.setVisible(false); - if(self.window.state.modal && !self.window.visible()) self.window.setModal(false); + if(p.state().onClose) p.self().doClose(); + else p.self().setVisible(false); + if(p.state().modal && !p.self().visible()) p.self().setModal(false); } -void pWindow::QtWindow::moveEvent(QMoveEvent* event) { - if(!self.locked() && self.window.state.fullScreen == false && self.qtWindow->isVisible() == true) { - self.window.state.geometry.x += event->pos().x() - event->oldPos().x(); - self.window.state.geometry.y += event->pos().y() - event->oldPos().y(); +auto QtWindow::moveEvent(QMoveEvent* event) -> void { + if(!p.locked() && !p.state().fullScreen && p.qtWindow->isVisible()) { + p.state().geometry.setX(p.state().geometry.x() + event->pos().x() - event->oldPos().x()); + p.state().geometry.setY(p.state().geometry.y() + event->pos().y() - event->oldPos().y()); } - if(!self.locked() && self.window.onMove) self.window.onMove(); + if(!p.locked()) { + p.self().doMove(); + } } -void pWindow::QtWindow::dragEnterEvent(QDragEnterEvent* event) { +auto QtWindow::dragEnterEvent(QDragEnterEvent* event) -> void { if(event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } -void pWindow::QtWindow::dropEvent(QDropEvent* event) { - lstring paths = DropPaths(event); - if(paths.empty()) return; - if(self.window.onDrop) self.window.onDrop(paths); +auto QtWindow::dropEvent(QDropEvent* event) -> void { + if(auto paths = DropPaths(event)) p.self().doDrop(paths); } -void pWindow::QtWindow::keyPressEvent(QKeyEvent* event) { - Keyboard::Keycode sym = Keysym(event->nativeVirtualKey()); - if(sym != Keyboard::Keycode::None && self.window.onKeyPress) self.window.onKeyPress(sym); +auto QtWindow::keyPressEvent(QKeyEvent* event) -> void { +// Keyboard::Keycode sym = Keysym(event->nativeVirtualKey()); +// if(sym != Keyboard::Keycode::None && self.window.onKeyPress) self.window.onKeyPress(sym); } -void pWindow::QtWindow::keyReleaseEvent(QKeyEvent* event) { - Keyboard::Keycode sym = Keysym(event->nativeVirtualKey()); - if(sym != Keyboard::Keycode::None && self.window.onKeyRelease) self.window.onKeyRelease(sym); +auto QtWindow::keyReleaseEvent(QKeyEvent* event) -> void { +// Keyboard::Keycode sym = Keysym(event->nativeVirtualKey()); +// if(sym != Keyboard::Keycode::None && self.window.onKeyRelease) self.window.onKeyRelease(sym); } -void pWindow::QtWindow::resizeEvent(QResizeEvent*) { - if(!self.locked() && self.window.state.fullScreen == false && self.qtWindow->isVisible() == true) { - self.window.state.geometry.width = self.qtContainer->geometry().width(); - self.window.state.geometry.height = self.qtContainer->geometry().height(); +auto QtWindow::resizeEvent(QResizeEvent*) -> void { + if(!p.locked() && !p.state().fullScreen && p.qtWindow->isVisible()) { + p.state().geometry.setWidth(p.qtContainer->geometry().width()); + p.state().geometry.setHeight(p.qtContainer->geometry().height()); } - for(auto& layout : self.window.state.layout) { - Geometry geometry = self.window.state.geometry; - geometry.x = geometry.y = 0; - layout.setGeometry(geometry); + if(auto& layout = p.state().layout) { + layout->setGeometry(p.self().geometry().setPosition(0, 0)); } - if(!self.locked() && self.window.onSize) self.window.onSize(); + if(!p.locked()) { + p.self().doSize(); + } } -QSize pWindow::QtWindow::sizeHint() const { - unsigned width = self.window.state.geometry.width; - unsigned height = self.window.state.geometry.height; - if(self.window.state.menuVisible) height += settings->geometry.menuHeight; - if(self.window.state.statusVisible) height += settings->geometry.statusHeight; +auto QtWindow::sizeHint() const -> QSize { + unsigned width = p.state().geometry.width(); + unsigned height = p.state().geometry.height(); + if(p.qtMenuBar->isVisible()) height += settings->geometry.menuHeight; + if(p.qtStatusBar->isVisible()) height += settings->geometry.statusHeight; return QSize(width, height); } } + +#endif diff --git a/hiro/qt/window.hpp b/hiro/qt/window.hpp new file mode 100644 index 00000000..2f0a0476 --- /dev/null +++ b/hiro/qt/window.hpp @@ -0,0 +1,41 @@ +#if defined(Hiro_Window) + +namespace hiro { + +struct pWindow : pObject { + Declare(Window, Object) + + auto append(sLayout layout) -> void; + auto append(sMenuBar menuBar) -> void; + auto append(sStatusBar statusBar) -> void; + auto focused() const -> bool override; + auto frameMargin() const -> Geometry; + auto remove(sLayout layout) -> void; + auto remove(sMenuBar menuBar) -> void; + auto remove(sStatusBar statusBar) -> void; + auto setBackgroundColor(Color color) -> void; + auto setDroppable(bool droppable) -> void; + auto setEnabled(bool enabled) -> void override; + auto setFocused() -> void override; + auto setFullScreen(bool fullScreen) -> void; + auto setGeometry(Geometry geometry) -> void; + auto setModal(bool modal) -> void; + auto setResizable(bool resizable) -> void; + auto setTitle(const string& text) -> void; + auto setVisible(bool visible) -> void; + + auto _append(mWidget& widget) -> void; + auto _menuHeight() const -> signed; + auto _statusHeight() const -> signed; + auto _updateFrameGeometry() -> void; + + QtWindow* qtWindow = nullptr; + QVBoxLayout* qtLayout = nullptr; + QMenuBar* qtMenuBar = nullptr; + QStatusBar* qtStatusBar = nullptr; + QWidget* qtContainer = nullptr; +}; + +} + +#endif diff --git a/hiro/windows/platform.cpp b/hiro/windows/platform.cpp index c32c77f6..f42e12db 100644 --- a/hiro/windows/platform.cpp +++ b/hiro/windows/platform.cpp @@ -43,6 +43,7 @@ #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" diff --git a/hiro/windows/platform.hpp b/hiro/windows/platform.hpp index b9961d50..9d273910 100644 --- a/hiro/windows/platform.hpp +++ b/hiro/windows/platform.hpp @@ -72,6 +72,7 @@ static vector windows; #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" diff --git a/hiro/windows/utility.cpp b/hiro/windows/utility.cpp index a87e81e2..480b9609 100644 --- a/hiro/windows/utility.cpp +++ b/hiro/windows/utility.cpp @@ -301,6 +301,10 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms listView->self()->onSort(lparam); break; } + if(header->code == NM_CLICK || header->code == NM_DBLCLK) { + listView->self()->onToggle(lparam); + break; + } if(header->code == NM_RCLICK) { listView->self()->onContext(lparam); break; diff --git a/hiro/windows/widget/hex-edit.cpp b/hiro/windows/widget/hex-edit.cpp index c241675a..7ef58eca 100644 --- a/hiro/windows/widget/hex-edit.cpp +++ b/hiro/windows/widget/hex-edit.cpp @@ -73,9 +73,9 @@ auto pHexEdit::construct() -> void { SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)HexEdit_windowProc); pWidget::_setState(); + setAddress(state().address); setBackgroundColor(state().backgroundColor); setLength(state().length); - setOffset(state().offset); update(); PostMessage(hwnd, EM_SETSEL, 10, 10); } @@ -84,6 +84,11 @@ auto pHexEdit::destruct() -> void { DestroyWindow(hwnd); } +auto pHexEdit::setAddress(unsigned address) -> void { + SetScrollPos(scrollBar, SB_CTL, address / state().columns, true); + update(); +} + auto pHexEdit::setBackgroundColor(Color color) -> void { if(backgroundBrush) DeleteObject(backgroundBrush); backgroundBrush = CreateSolidBrush(color ? CreateRGB(color) : GetSysColor(COLOR_WINDOW)); @@ -102,11 +107,6 @@ auto pHexEdit::setLength(unsigned length) -> void { update(); } -auto pHexEdit::setOffset(unsigned offset) -> void { - SetScrollPos(scrollBar, SB_CTL, offset / state().columns, true); - update(); -} - auto pHexEdit::setRows(unsigned rows) -> void { update(); } @@ -120,16 +120,16 @@ auto pHexEdit::update() -> void { unsigned cursorPosition = Edit_GetSel(hwnd); string output; - unsigned offset = state().offset; + unsigned address = state().address; for(auto row : range(state().rows)) { - output.append(hex(offset, 8L)); + output.append(hex(address, 8L)); output.append(" "); string hexdata; string ansidata = " "; for(auto column : range(state().columns)) { - if(offset < state().length) { - uint8_t data = self().doRead(offset++); + if(address < state().length) { + uint8_t data = self().doRead(address++); hexdata.append(hex(data, 2L)); hexdata.append(" "); ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.'); @@ -141,7 +141,7 @@ auto pHexEdit::update() -> void { output.append(hexdata); output.append(ansidata); - if(offset >= state().length) break; + if(address >= state().length) break; if(row != state().rows - 1) output.append("\r\n"); } @@ -199,7 +199,7 @@ bool pHexEdit::keyPress(unsigned scancode) { else return false; if(cursorX >= 10) { - //not on an offset + //not on an address cursorX -= 10; if((cursorX % 3) != 2) { //not on a space @@ -207,10 +207,10 @@ bool pHexEdit::keyPress(unsigned scancode) { cursorX /= 3; if(cursorX < state().columns) { //not in ANSI region - unsigned offset = state().offset + (cursorY * state().columns + cursorX); + unsigned address = state().address + (cursorY * state().columns + cursorX); - if(offset >= state().length) return false; //do not edit past end of data - uint8_t data = self().doRead(offset); + if(address >= state().length) return false; //do not edit past end of data + uint8_t data = self().doRead(address); //write modified value if(cursorNibble == 1) { @@ -218,7 +218,7 @@ bool pHexEdit::keyPress(unsigned scancode) { } else { data = (data & 0x0f) | (scancode << 4); } - self().doWrite(offset, data); + self().doWrite(address, data); //auto-advance cursor to next nibble or byte position++; @@ -243,14 +243,14 @@ signed pHexEdit::rowsScrollable() { } signed pHexEdit::scrollPosition() { - return state().offset / state().columns; + return state().address / state().columns; } void pHexEdit::scrollTo(signed position) { if(position > rowsScrollable()) position = rowsScrollable(); if(position < 0) position = 0; if(position == scrollPosition()) return; - self().setOffset(position * state().columns); + self().setAddress(position * state().columns); } } diff --git a/hiro/windows/widget/hex-edit.hpp b/hiro/windows/widget/hex-edit.hpp index cd8ff7e6..ce2240a5 100644 --- a/hiro/windows/widget/hex-edit.hpp +++ b/hiro/windows/widget/hex-edit.hpp @@ -5,11 +5,11 @@ namespace hiro { struct pHexEdit : pWidget { Declare(HexEdit, Widget) + auto setAddress(unsigned address) -> void; auto setBackgroundColor(Color color) -> void; auto setColumns(unsigned columns) -> void; auto setForegroundColor(Color color) -> void; auto setLength(unsigned length) -> void; - auto setOffset(unsigned offset) -> void; auto setRows(unsigned rows) -> void; auto update() -> void; diff --git a/hiro/windows/widget/label.cpp b/hiro/windows/widget/label.cpp index 19709d0f..552639e6 100644 --- a/hiro/windows/widget/label.cpp +++ b/hiro/windows/widget/label.cpp @@ -8,6 +8,7 @@ auto pLabel::construct() -> void { 0, 0, 0, 0, _parentHandle(), nullptr, GetModuleHandle(0), 0); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&reference); pWidget::_setState(); + setAlignment(state().alignment); setText(state().text); } @@ -16,11 +17,12 @@ auto pLabel::destruct() -> void { } auto pLabel::minimumSize() const -> Size { - Size size = pFont::size(hfont, state().text); + auto size = pFont::size(hfont, state().text); return {size.width(), size.height()}; } -auto pLabel::setHorizontalAlignment(double alignment) -> void { +auto pLabel::setAlignment(Alignment alignment) -> void { + InvalidateRect(hwnd, 0, false); } auto pLabel::setText(const string& text) -> void { @@ -28,9 +30,6 @@ auto pLabel::setText(const string& text) -> void { InvalidateRect(hwnd, 0, false); } -auto pLabel::setVerticalAlignment(double alignment) -> void { -} - static auto CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { auto label = (mLabel*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if(!label) return DefWindowProc(hwnd, msg, wparam, lparam); diff --git a/hiro/windows/widget/label.hpp b/hiro/windows/widget/label.hpp index 60d09c4f..91e99f6d 100644 --- a/hiro/windows/widget/label.hpp +++ b/hiro/windows/widget/label.hpp @@ -6,9 +6,8 @@ struct pLabel : pWidget { Declare(Label, Widget) auto minimumSize() const -> Size override; - auto setHorizontalAlignment(double alignment) -> void; + auto setAlignment(Alignment alignment) -> void; auto setText(const string& text) -> void; - auto setVerticalAlignment(double alignment) -> void; }; } diff --git a/hiro/windows/widget/list-view-cell.cpp b/hiro/windows/widget/list-view-cell.cpp index 4cde02fa..0b912aae 100644 --- a/hiro/windows/widget/list-view-cell.cpp +++ b/hiro/windows/widget/list-view-cell.cpp @@ -8,22 +8,31 @@ 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 { - 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); - } - } + _repaint(); } auto pListViewCell::_parent() -> maybe { @@ -33,16 +42,24 @@ auto pListViewCell::_parent() -> maybe { 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 | LVIF_IMAGE; + lvItem.mask = LVIF_TEXT; lvItem.iItem = item->self().offset(); lvItem.iSubItem = self().offset(); - lvItem.iImage = parent->self().columns(); lvItem.pszText = text; ListView_SetItem(parent->hwnd, &lvItem); parent->unlock(); diff --git a/hiro/windows/widget/list-view-cell.hpp b/hiro/windows/widget/list-view-cell.hpp index 3f4f0a6e..d5c62923 100644 --- a/hiro/windows/widget/list-view-cell.hpp +++ b/hiro/windows/widget/list-view-cell.hpp @@ -5,12 +5,16 @@ namespace hiro { struct pListViewCell : pObject { Declare(ListViewCell, Object) + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; + auto setCheckable(bool checkable) -> void; + auto setChecked(bool checked) -> void; auto setForegroundColor(Color color) -> void; auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; auto _parent() -> maybe; + auto _repaint() -> void; auto _setState() -> void; }; diff --git a/hiro/windows/widget/list-view-column.cpp b/hiro/windows/widget/list-view-column.cpp index 86bcdee2..ef2871b3 100644 --- a/hiro/windows/widget/list-view-column.cpp +++ b/hiro/windows/widget/list-view-column.cpp @@ -3,15 +3,35 @@ namespace hiro { auto pListViewColumn::construct() -> void { + if(auto grandparent = _grandparent()) { + grandparent->lock(); + wchar_t text[] = L""; + LVCOLUMN lvColumn{0}; + lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM; + lvColumn.fmt = LVCFMT_LEFT; + lvColumn.iSubItem = self().offset(); + lvColumn.pszText = text; + ListView_InsertColumn(grandparent->hwnd, self().offset(), &lvColumn); + _setState(); + grandparent->unlock(); + } } auto pListViewColumn::destruct() -> void { + if(auto grandparent = _grandparent()) { + grandparent->lock(); + ListView_DeleteColumn(grandparent->hwnd, self().offset()); + grandparent->unlock(); + } } auto pListViewColumn::setActive() -> void { //unsupported } +auto pListViewColumn::setAlignment(Alignment alignment) -> void { +} + auto pListViewColumn::setBackgroundColor(Color color) -> void { } @@ -37,6 +57,9 @@ auto pListViewColumn::setResizable(bool resizable) -> void { _setState(); } +auto pListViewColumn::setSortable(bool sortable) -> void { +} + auto pListViewColumn::setText(const string& text) -> void { _setState(); } @@ -48,17 +71,22 @@ auto pListViewColumn::setWidth(signed width) -> void { _setState(); } -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListView()) { +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; } auto pListViewColumn::_setState() -> void { - if(auto parent = _parent()) { - parent->lock(); - parent->_setIcons(); + if(auto grandparent = _grandparent()) { + grandparent->lock(); + grandparent->_setIcons(); utf16_t text(state().text); LVCOLUMN lvColumn; lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH; @@ -71,8 +99,8 @@ auto pListViewColumn::_setState() -> void { if(state().horizontalAlignment > 0.666) lvColumn.fmt = LVCFMT_RIGHT; if(state().icon) lvColumn.mask |= LVCF_IMAGE; if(!state().resizable) lvColumn.fmt |= LVCFMT_FIXED_WIDTH; - ListView_SetColumn(parent->hwnd, self().offset(), &lvColumn); - parent->unlock(); + ListView_SetColumn(grandparent->hwnd, self().offset(), &lvColumn); + grandparent->unlock(); } } diff --git a/hiro/windows/widget/list-view-column.hpp b/hiro/windows/widget/list-view-column.hpp index 326d7767..2c00c654 100644 --- a/hiro/windows/widget/list-view-column.hpp +++ b/hiro/windows/widget/list-view-column.hpp @@ -6,6 +6,7 @@ struct pListViewColumn : pObject { Declare(ListViewColumn, Object) auto setActive() -> void; + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setEditable(bool editable) -> void; auto setExpandable(bool expandable) -> void; @@ -13,11 +14,13 @@ struct pListViewColumn : pObject { auto setHorizontalAlignment(double alignment) -> void; auto setIcon(const image& icon) -> void; auto setResizable(bool resizable) -> void; + auto setSortable(bool sortable) -> void; auto setText(const string& text) -> void; auto setVerticalAlignment(double alignment) -> void; auto setWidth(signed width) -> void; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; signed _width = 128; //computed width (via ListView::resizeColumns) diff --git a/hiro/windows/widget/list-view-header.cpp b/hiro/windows/widget/list-view-header.cpp new file mode 100644 index 00000000..fbce80c5 --- /dev/null +++ b/hiro/windows/widget/list-view-header.cpp @@ -0,0 +1,42 @@ +#if defined(Hiro_ListView) + +namespace hiro { + +auto pListViewHeader::construct() -> void { + _setState(); +} + +auto pListViewHeader::destruct() -> void { +} + +auto pListViewHeader::append(sListViewColumn column) -> void { +} + +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()) { + auto style = GetWindowLong(parent->hwnd, GWL_STYLE); + self().visible() ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER; + SetWindowLong(parent->hwnd, GWL_STYLE, style); + for(auto& column : state().columns) { + if(auto self = column->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/hiro/windows/widget/list-view-header.hpp b/hiro/windows/widget/list-view-header.hpp new file mode 100644 index 00000000..a46855bb --- /dev/null +++ b/hiro/windows/widget/list-view-header.hpp @@ -0,0 +1,18 @@ +#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/hiro/windows/widget/list-view-item.cpp b/hiro/windows/widget/list-view-item.cpp index 34e19b32..b9562862 100644 --- a/hiro/windows/widget/list-view-item.cpp +++ b/hiro/windows/widget/list-view-item.cpp @@ -3,9 +3,26 @@ namespace hiro { auto pListViewItem::construct() -> void { + if(auto parent = _parent()) { + parent->lock(); + wchar_t text[] = L""; + LVITEM lvItem{0}; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = self().offset(); + lvItem.iSubItem = 0; + lvItem.pszText = text; + ListView_InsertItem(parent->hwnd, &lvItem); + _setState(); + parent->unlock(); + } } auto pListViewItem::destruct() -> void { + if(auto parent = _parent()) { + parent->lock(); + ListView_DeleteItem(parent->hwnd, self().offset()); + parent->unlock(); + } } auto pListViewItem::append(sListViewCell cell) -> void { @@ -14,20 +31,12 @@ auto pListViewItem::append(sListViewCell cell) -> void { auto pListViewItem::remove(sListViewCell cell) -> void { } +auto pListViewItem::setAlignment(Alignment alignment) -> void { +} + auto pListViewItem::setBackgroundColor(Color color) -> void { } -auto pListViewItem::setCheckable(bool checkable) -> void { -} - -auto pListViewItem::setChecked(bool checked) -> void { - if(auto parent = _parent()) { - parent->lock(); - ListView_SetCheckState(parent->hwnd, self().offset(), checked); - parent->unlock(); - } -} - auto pListViewItem::setFocused() -> void { if(auto parent = _parent()) { parent->lock(); @@ -40,12 +49,7 @@ auto pListViewItem::setForegroundColor(Color color) -> void { } auto pListViewItem::setSelected(bool selected) -> void { - if(auto parent = _parent()) { - parent->lock(); - unsigned state = selected ? LVIS_SELECTED : 0; - ListView_SetItemState(parent->hwnd, self().offset(), state, LVIS_SELECTED); - parent->unlock(); - } + _setState(); } auto pListViewItem::_parent() -> maybe { @@ -55,6 +59,17 @@ auto pListViewItem::_parent() -> maybe { return nothing; } +auto pListViewItem::_setState() -> void { + if(auto parent = _parent()) { + parent->lock(); + ListView_SetItemState(parent->hwnd, self().offset(), state().selected ? LVIS_SELECTED : 0, LVIS_SELECTED); + for(auto& cell : state().cells) { + if(auto self = cell->self()) self->_setState(); + } + parent->unlock(); + } +} + } #endif diff --git a/hiro/windows/widget/list-view-item.hpp b/hiro/windows/widget/list-view-item.hpp index 159c9d61..bc0d3c26 100644 --- a/hiro/windows/widget/list-view-item.hpp +++ b/hiro/windows/widget/list-view-item.hpp @@ -7,14 +7,14 @@ struct pListViewItem : pObject { auto append(sListViewCell cell) -> void; auto remove(sListViewCell cell) -> void; + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; - auto setCheckable(bool checkable) -> void; - auto setChecked(bool checked) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; auto _parent() -> maybe; + auto _setState() -> void; }; } diff --git a/hiro/windows/widget/list-view.cpp b/hiro/windows/widget/list-view.cpp index 66c89ab5..572eb291 100644 --- a/hiro/windows/widget/list-view.cpp +++ b/hiro/windows/widget/list-view.cpp @@ -34,72 +34,27 @@ auto pListView::construct() -> void { pWidget::_setState(); setBackgroundColor(state().backgroundColor); setBatchable(state().batchable); - setCheckable(state().checkable); - setGridVisible(state().gridVisible); - setHeaderVisible(state().headerVisible); - setSortable(state().sortable); + setBordered(state().bordered); _setIcons(); + _setSortable(); resizeColumns(); } auto pListView::destruct() -> void { - if(imageList) { ImageList_Destroy(imageList); imageList = 0; } + if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; } DestroyWindow(hwnd); } -auto pListView::append(sListViewColumn column) -> void { - lock(); - wchar_t text[] = L""; - LVCOLUMN lvColumn; - lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM; - lvColumn.fmt = LVCFMT_LEFT; - lvColumn.iSubItem = column->offset(); - lvColumn.pszText = text; - ListView_InsertColumn(hwnd, column->offset(), &lvColumn); - if(auto self = column->self()) { - self->_setState(); - } - resizeColumns(); - unlock(); +auto pListView::append(sListViewHeader header) -> void { } auto pListView::append(sListViewItem item) -> void { - lock(); - wchar_t text[] = L""; - LVITEM lvItem; - lvItem.mask = LVIF_TEXT; - lvItem.iItem = item->offset(); - lvItem.iSubItem = 0; - lvItem.pszText = text; - ListView_InsertItem(hwnd, &lvItem); - if(auto self = item->self()) { - self->setChecked(item->state.checked); - self->setSelected(item->state.selected); - } - for(auto& cell : item->state.cells) { - if(auto self = cell->self()) { - self->_setState(); - } - } - unlock(); } -auto pListView::checkAll() -> void { - for(auto& item : state().items) { - item->self()->setChecked(true); - } -} - -auto pListView::remove(sListViewColumn column) -> void { - lock(); - ListView_DeleteColumn(hwnd, column->offset()); - unlock(); +auto pListView::remove(sListViewHeader header) -> void { } auto pListView::remove(sListViewItem item) -> void { - lock(); - ListView_DeleteItem(hwnd, item->offset()); - unlock(); } auto pListView::reset() -> void { @@ -114,45 +69,44 @@ auto pListView::reset() -> void { auto pListView::resizeColumns() -> void { lock(); - vector widths; - signed minimumWidth = 0; - signed expandable = 0; - for(auto column : range(state().columns)) { - signed width = _width(column); - widths.append(width); - minimumWidth += width; - if(state().columns[column]->expandable()) expandable++; - } - - signed maximumWidth = self().geometry().width() - 4; - SCROLLBARINFO sbInfo{sizeof(SCROLLBARINFO)}; - if(GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sbInfo)) { - if(!(sbInfo.rgstate[0] & STATE_SYSTEM_INVISIBLE)) { - maximumWidth -= sbInfo.rcScrollBar.right - sbInfo.rcScrollBar.left; + if(auto& header = state().header) { + vector widths; + signed minimumWidth = 0; + signed expandable = 0; + for(auto column : range(header->columnCount())) { + signed width = _width(column); + widths.append(width); + minimumWidth += width; + if(header->column(column).expandable()) expandable++; } - } - signed expandWidth = 0; - if(expandable && maximumWidth > minimumWidth) { - expandWidth = (maximumWidth - minimumWidth) / expandable; - } + signed maximumWidth = self().geometry().width() - 4; + SCROLLBARINFO sbInfo{sizeof(SCROLLBARINFO)}; + if(GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sbInfo)) { + if(!(sbInfo.rgstate[0] & STATE_SYSTEM_INVISIBLE)) { + maximumWidth -= sbInfo.rcScrollBar.right - sbInfo.rcScrollBar.left; + } + } - for(auto column : range(state().columns)) { - if(auto self = state().columns[column]->self()) { - signed width = widths[column]; - if(self->state().expandable) width += expandWidth; - self->_width = width; - self->_setState(); + signed expandWidth = 0; + if(expandable && maximumWidth > minimumWidth) { + expandWidth = (maximumWidth - minimumWidth) / expandable; + } + + for(auto column : range(header->columnCount())) { + if(auto self = header->state.columns[column]->self()) { + signed width = widths[column]; + if(self->state().expandable) width += expandWidth; + self->_width = width; + self->_setState(); + } } } unlock(); } -auto pListView::selectAll() -> void { - lock(); - ListView_SetItemState(hwnd, -1, LVIS_SELECTED, LVIS_SELECTED); - unlock(); +auto pListView::setAlignment(Alignment alignment) -> void { } auto pListView::setBackgroundColor(Color color) -> void { @@ -166,42 +120,27 @@ auto pListView::setBatchable(bool batchable) -> void { SetWindowLong(hwnd, GWL_STYLE, style); } -auto pListView::setCheckable(bool checkable) -> void { - auto style = ListView_GetExtendedListViewStyle(hwnd); - checkable ? style |= LVS_EX_CHECKBOXES : style &=~ LVS_EX_CHECKBOXES; - ListView_SetExtendedListViewStyle(hwnd, style); +auto pListView::setBordered(bool bordered) -> void { + //rendered via onCustomDraw } auto pListView::setForegroundColor(Color color) -> void { } -auto pListView::setGridVisible(bool visible) -> void { - //rendered via onCustomDraw -} - -auto pListView::setHeaderVisible(bool visible) -> void { - auto style = GetWindowLong(hwnd, GWL_STYLE); - !visible ? style |= LVS_NOCOLUMNHEADER : style &=~ LVS_NOCOLUMNHEADER; - SetWindowLong(hwnd, GWL_STYLE, style); -} - -auto pListView::setSortable(bool sortable) -> void { - auto style = GetWindowLong(hwnd, GWL_STYLE); - !sortable ? style |= LVS_NOSORTHEADER : style &=~ LVS_NOSORTHEADER; - SetWindowLong(hwnd, GWL_STYLE, style); -} - -auto pListView::uncheckAll() -> void { - for(auto& item : state().items) { - item->self()->setChecked(false); +auto pListView::setGeometry(Geometry geometry) -> void { + pWidget::setGeometry(geometry); + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(column->state.expandable) return resizeColumns(); + } } } -auto pListView::unselectAll() -> void { - lock(); - ListView_SetItemState(hwnd, -1, 0, LVIS_FOCUSED | LVIS_SELECTED); - unlock(); -} +/*auto pListView::setHeaderVisible(bool visible) -> void { + auto style = GetWindowLong(hwnd, GWL_STYLE); + !visible ? style |= LVS_NOCOLUMNHEADER : style &=~ LVS_NOCOLUMNHEADER; + SetWindowLong(hwnd, GWL_STYLE, style); +}*/ auto pListView::onActivate(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; @@ -231,20 +170,6 @@ auto pListView::onChange(LPARAM lparam) -> void { //we use a delayed AppMessage so that only one callback event is fired off PostMessageOnce(_parentHandle(), AppMessage::ListView_onChange, 0, (LPARAM)&reference); } - - if(!locked()) { - unsigned row = nmlistview->iItem; - unsigned mask = nmlistview->uNewState & LVIS_STATEIMAGEMASK; - if(mask == 0x1000 || mask == 0x2000) { - bool checked = mask == 0x2000; - if(auto item = self().item(row)) { - if(checked != item->state.checked) { //WC_LISTVIEW sends this message twice - item->state.checked = checked; - self().doToggle(item); - } - } - } - } } auto pListView::onContext(LPARAM lparam) -> void { @@ -264,59 +189,71 @@ auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { HDC hdc = lvcd->nmcd.hdc; HDC hdcSource = CreateCompatibleDC(hdc); unsigned row = lvcd->nmcd.dwItemSpec; - for(auto column : range(state().columns)) { + auto& header = state().header; + if(!header) break; + for(auto column : range(header->columnCount())) { RECT rc, rcLabel; ListView_GetSubItemRect(hwnd, row, column, LVIR_BOUNDS, &rc); ListView_GetSubItemRect(hwnd, row, column, LVIR_LABEL, &rcLabel); rc.right = rcLabel.right; //bounds of column 0 returns width of entire item signed iconSize = rc.bottom - rc.top - 1; - bool checked = state().items(row)->state.checked; bool selected = state().items(row)->state.selected; - HBRUSH brush = CreateSolidBrush(selected ? GetSysColor(COLOR_HIGHLIGHT) : CreateRGB(_backgroundColor(row, column))); - FillRect(hdc, &rc, brush); - DeleteObject(brush); - if(state().checkable && self().item(row).checkable() && column == 0) { - if(auto htheme = OpenThemeData(hwnd, L"BUTTON")) { - unsigned state = checked ? CBS_CHECKEDNORMAL : CBS_UNCHECKEDNORMAL; - SIZE size; - GetThemePartSize(htheme, hdc, BP_CHECKBOX, state, NULL, TS_TRUE, &size); - signed center = max(0, (rc.bottom - rc.top - size.cy) / 2); - RECT rd{rc.left + center, rc.top + center, rc.left + center + size.cx, rc.top + center + size.cy}; - DrawThemeBackground(htheme, hdc, BP_CHECKBOX, state, &rd, NULL); - CloseThemeData(htheme); + + if(auto cell = self().item(row)->cell(column)) { + HBRUSH brush = CreateSolidBrush(selected ? GetSysColor(COLOR_HIGHLIGHT) : CreateRGB(cell->backgroundColor(true))); + FillRect(hdc, &rc, brush); + DeleteObject(brush); + + if(cell->state.checkable) { + if(auto htheme = OpenThemeData(hwnd, L"BUTTON")) { + unsigned state = cell->state.checked ? CBS_CHECKEDNORMAL : CBS_UNCHECKEDNORMAL; + SIZE size; + GetThemePartSize(htheme, hdc, BP_CHECKBOX, state, nullptr, TS_TRUE, &size); + signed center = max(0, (rc.bottom - rc.top - size.cy) / 2); + RECT rd{rc.left + center, rc.top + center, rc.left + center + size.cx, rc.top + center + size.cy}; + DrawThemeBackground(htheme, hdc, BP_CHECKBOX, state, &rd, nullptr); + CloseThemeData(htheme); + } + rc.left += iconSize + 2; + } else { + rc.left += 2; + } + + if(auto icon = cell->state.icon) { + icon.scale(iconSize, iconSize); + icon.transform(); + auto bitmap = CreateBitmap(icon); + SelectBitmap(hdcSource, bitmap); + BLENDFUNCTION blend{AC_SRC_OVER, 0, (BYTE)(selected ? 128 : 255), AC_SRC_ALPHA}; + AlphaBlend(hdc, rc.left, rc.top, iconSize, iconSize, hdcSource, 0, 0, iconSize, iconSize, blend); + DeleteObject(bitmap); + rc.left += iconSize + 2; + } + + if(auto text = cell->state.text) { + auto alignment = cell->alignment(true); + if(!alignment) alignment = {0.0, 0.5}; + utf16_t wText(text); + SetBkMode(hdc, TRANSPARENT); + SetTextColor(hdc, selected ? GetSysColor(COLOR_HIGHLIGHTTEXT) : CreateRGB(cell->foregroundColor(true))); + auto style = DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS; + style |= alignment.horizontal() < 0.333 ? DT_LEFT : alignment.horizontal() > 0.666 ? DT_RIGHT : DT_CENTER; + style |= alignment.vertical() < 0.333 ? DT_TOP : alignment.vertical() > 0.666 ? DT_BOTTOM : DT_VCENTER; + rc.right -= 2; + auto font = pFont::create(cell->font(true)); + SelectObject(hdc, font); + DrawText(hdc, wText, -1, &rc, style); + DeleteObject(font); } - rc.left += iconSize + 2; } else { - rc.left += 2; + auto color = state().backgroundColor; + if(!color) color = {255, 255, 255}; + HBRUSH brush = CreateSolidBrush(selected ? GetSysColor(COLOR_HIGHLIGHT) : CreateRGB(color)); + FillRect(hdc, &rc, brush); + DeleteObject(brush); } - auto cell = self().item(row)->cell(column); - if(!cell) continue; - if(auto icon = cell->state.icon) { - icon.scale(iconSize, iconSize); - icon.transform(); - auto bitmap = CreateBitmap(icon); - SelectBitmap(hdcSource, bitmap); - BLENDFUNCTION blend{AC_SRC_OVER, 0, (BYTE)(selected ? 128 : 255), AC_SRC_ALPHA}; - AlphaBlend(hdc, rc.left, rc.top, iconSize, iconSize, hdcSource, 0, 0, iconSize, iconSize, blend); - DeleteObject(bitmap); - rc.left += iconSize + 2; - } - if(auto text = cell->state.text) { - auto halign = state().columns(column)->state.horizontalAlignment; - auto valign = state().columns(column)->state.verticalAlignment; - utf16_t wText(text); - SetBkMode(hdc, TRANSPARENT); - SetTextColor(hdc, selected ? GetSysColor(COLOR_HIGHLIGHTTEXT) : CreateRGB(_foregroundColor(row, column))); - auto style = DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS; - style |= halign < 0.333 ? DT_LEFT : halign > 0.666 ? DT_RIGHT : DT_CENTER; - style |= valign < 0.333 ? DT_TOP : valign > 0.666 ? DT_BOTTOM : DT_VCENTER; - rc.right -= 2; - auto font = pFont::create(_font(row, column)); - SelectObject(hdc, font); - DrawText(hdc, wText, -1, &rc, style); - DeleteObject(font); - } - if(state().gridVisible) { + + if(state().bordered) { ListView_GetSubItemRect(hwnd, row, column, LVIR_BOUNDS, &rc); rc.top = rc.bottom - 1; FillRect(hdc, &rc, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); @@ -329,11 +266,33 @@ auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { return CDRF_SKIPDEFAULT; } } + + return CDRF_SKIPDEFAULT; } auto pListView::onSort(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; - self().doSort(self().column(nmlistview->iSubItem)); + if(auto& header = state().header) { + if(auto column = header->column(nmlistview->iSubItem)) { + if(column->sortable()) self().doSort(column); + } + } +} + +auto pListView::onToggle(LPARAM lparam) -> void { + auto itemActivate = (LPNMITEMACTIVATE)lparam; + LVHITTESTINFO hitTestInfo{0}; + hitTestInfo.pt = itemActivate->ptAction; + ListView_SubItemHitTest(hwnd, &hitTestInfo); + + if(auto cell = self().item(hitTestInfo.iItem).cell(hitTestInfo.iSubItem)) { + if(cell->state.checkable) { + 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); + } + } } auto pListView::_backgroundColor(unsigned _row, unsigned _column) -> Color { @@ -343,19 +302,21 @@ auto pListView::_backgroundColor(unsigned _row, unsigned _column) -> Color { } if(auto color = item->backgroundColor()) return color; } - if(auto column = self().column(_column)) { - if(auto color = column->backgroundColor()) return color; - } +// if(auto column = self().column(_column)) { +// if(auto color = column->backgroundColor()) return color; +// } if(auto color = self().backgroundColor()) return color; - if(state().columns.size() >= 2 && _row % 2) return {240, 240, 240}; +// if(state().columns.size() >= 2 && _row % 2) return {240, 240, 240}; return {255, 255, 255}; } auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { unsigned width = 6; - if(state().checkable && _column == 0) width += 16 + 2; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { + if(cell->state.checkable) { + width += 16 + 2; + } if(auto& icon = cell->state.icon) { width += 16 + 2; } @@ -369,12 +330,14 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { auto pListView::_columnWidth(unsigned _column) -> unsigned { unsigned width = 12; - if(auto column = self().column(_column)) { - if(auto& icon = column->state.icon) { - width += 16 + 12; //yes; icon spacing in column headers is excessive - } - if(auto& text = column->state.text) { - width += Font::size(self().font(true), text).width(); + if(auto header = state().header) { + if(auto column = header->column(_column)) { + if(auto& icon = column->state.icon) { + width += 16 + 12; //yes; icon spacing in column headers is excessive + } + if(auto& text = column->state.text) { + width += Font::size(self().font(true), text).width(); + } } } return width; @@ -387,9 +350,9 @@ auto pListView::_font(unsigned _row, unsigned _column) -> string { } if(auto font = item->font()) return font; } - if(auto column = self().column(_column)) { - if(auto font = column->font()) return font; - } +// if(auto column = self().column(_column)) { +// if(auto font = column->font()) return font; +// } if(auto font = self().font(true)) return font; return Font::sans(8); } @@ -401,31 +364,33 @@ auto pListView::_foregroundColor(unsigned _row, unsigned _column) -> Color { } if(auto color = item->foregroundColor()) return color; } - if(auto column = self().column(_column)) { - if(auto color = column->foregroundColor()) return color; - } +// if(auto column = self().column(_column)) { +// if(auto color = column->foregroundColor()) return color; +// } if(auto color = self().foregroundColor()) return color; return {0, 0, 0}; } auto pListView::_setIcons() -> void { - ListView_SetImageList(hwnd, NULL, LVSIL_SMALL); + ListView_SetImageList(hwnd, nullptr, LVSIL_SMALL); if(imageList) ImageList_Destroy(imageList); imageList = ImageList_Create(16, 16, ILC_COLOR32, 1, 0); ListView_SetImageList(hwnd, imageList, LVSIL_SMALL); - for(auto column : range(state().columns)) { - auto icon = state().columns(column)->state.icon; - if(icon) { - icon.scale(16, 16); - icon.transform(); - } else { - icon.allocate(16, 16); - icon.fill(0x00ffffff); + if(auto& header = state().header) { + for(auto column : range(header->columnCount())) { + auto icon = header->state.columns[column]->state.icon; + if(icon) { + icon.scale(16, 16); + icon.transform(); + } else { + icon.allocate(16, 16); + icon.fill(0x00ffffff); + } + auto bitmap = CreateBitmap(icon); + ImageList_Add(imageList, bitmap, nullptr); + DeleteObject(bitmap); } - auto bitmap = CreateBitmap(icon); - ImageList_Add(imageList, bitmap, NULL); - DeleteObject(bitmap); } //empty icon used for ListViewItems (drawn manually via onCustomDraw) @@ -433,20 +398,35 @@ auto pListView::_setIcons() -> void { icon.allocate(16, 16); icon.fill(0x00ffffff); auto bitmap = CreateBitmap(icon); - ImageList_Add(imageList, bitmap, NULL); + ImageList_Add(imageList, bitmap, nullptr); DeleteObject(bitmap); } +auto pListView::_setSortable() -> void { + bool sortable = false; + if(auto& header = state().header) { + for(auto& column : header->state.columns) { + if(column->sortable()) sortable = true; + } + } + + //note: this won't change the visual style: WC_LISTVIEW caches this in CreateWindow + auto style = GetWindowLong(hwnd, GWL_STYLE); + !sortable ? style |= LVS_NOSORTHEADER : style &=~ LVS_NOSORTHEADER; + SetWindowLong(hwnd, GWL_STYLE, style); +} + auto pListView::_width(unsigned column) -> unsigned { - if(auto width = state().columns[column]->width()) return width; - unsigned width = 1; - if(state().headerVisible) { - width = max(width, _columnWidth(column)); + if(auto& header = state().header) { + if(auto width = header->state.columns[column]->width()) return width; + unsigned width = 1; + if(header->visible()) width = max(width, _columnWidth(column)); + for(auto row : range(state().items)) { + width = max(width, _cellWidth(row, column)); + } + return width; } - for(auto row : range(state().items)) { - width = max(width, _cellWidth(row, column)); - } - return width; + return 1; } } diff --git a/hiro/windows/widget/list-view.hpp b/hiro/windows/widget/list-view.hpp index 107e8f8a..3fc58203 100644 --- a/hiro/windows/widget/list-view.hpp +++ b/hiro/windows/widget/list-view.hpp @@ -5,30 +5,25 @@ namespace hiro { struct pListView : pWidget { Declare(ListView, Widget) - auto append(sListViewColumn column) -> void; + auto append(sListViewHeader header) -> void; auto append(sListViewItem item) -> void; - auto checkAll() -> void; - auto remove(sListViewColumn column) -> void; + auto remove(sListViewHeader header) -> void; auto remove(sListViewItem item) -> void; auto reset() -> void; auto resizeColumns() -> void; - auto selectAll() -> void; + auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setBatchable(bool batchable) -> void; - auto setCheckable(bool checkable) -> void; - auto setChecked(bool checked) -> void; + auto setBordered(bool bordered) -> void; auto setForegroundColor(Color color) -> void; - auto setGridVisible(bool visible) -> void; - auto setHeaderVisible(bool visible) -> void; - auto setSortable(bool sortable) -> void; - auto uncheckAll() -> void; - auto unselectAll() -> void; + auto setGeometry(Geometry geometry) -> void override; auto onActivate(LPARAM lparam) -> void; auto onChange(LPARAM lparam) -> void; auto onContext(LPARAM lparam) -> void; auto onCustomDraw(LPARAM lparam) -> LRESULT; auto onSort(LPARAM lparam) -> void; + auto onToggle(LPARAM lparam) -> void; auto _backgroundColor(unsigned row, unsigned column) -> Color; auto _cellWidth(unsigned row, unsigned column) -> unsigned; @@ -36,6 +31,7 @@ struct pListView : pWidget { auto _font(unsigned row, unsigned column) -> string; auto _foregroundColor(unsigned row, unsigned column) -> Color; auto _setIcons() -> void; + auto _setSortable() -> void; auto _width(unsigned column) -> unsigned; WindowProc windowProc = nullptr; diff --git a/sfc/alt/cpu/cpu.cpp b/sfc/alt/cpu/cpu.cpp index 7121e406..f1039478 100644 --- a/sfc/alt/cpu/cpu.cpp +++ b/sfc/alt/cpu/cpu.cpp @@ -72,14 +72,10 @@ void CPU::enter() { op_irq(); } - op_step(); + op_exec(); } } -alwaysinline void CPU::op_step() { - (this->*opcode_table[op_readpc()])(); -} - void CPU::enable() { function reader = {&CPU::mmio_read, (CPU*)&cpu}; function writer = {&CPU::mmio_write, (CPU*)&cpu}; @@ -128,7 +124,6 @@ void CPU::reset() { regs.e = 1; regs.mdr = 0x00; regs.wai = false; - update_table(); regs.pc.l = bus.read(0xfffc); regs.pc.h = bus.read(0xfffd); diff --git a/sfc/alt/cpu/cpu.hpp b/sfc/alt/cpu/cpu.hpp index 61c7067b..0573e532 100644 --- a/sfc/alt/cpu/cpu.hpp +++ b/sfc/alt/cpu/cpu.hpp @@ -33,7 +33,6 @@ struct CPU : Processor::R65816, Thread, public PPUcounter { private: //cpu static void Enter(); - void op_step(); //timing struct QueueEvent { diff --git a/target-tomoko/presentation/presentation.cpp b/target-tomoko/presentation/presentation.cpp index 2e7fc89a..7b6f06a8 100644 --- a/target-tomoko/presentation/presentation.cpp +++ b/target-tomoko/presentation/presentation.cpp @@ -129,7 +129,7 @@ auto Presentation::updateEmulator() -> void { }); devices.append(item); } - if(devices.objects() > 1) menu.setVisible(); + if(devices.objectCount() > 1) menu.setVisible(); } systemMenuSeparatorPorts.setVisible(inputPort1.visible() || inputPort2.visible()); diff --git a/target-tomoko/settings/hotkeys.cpp b/target-tomoko/settings/hotkeys.cpp index aee342a9..b63d3331 100644 --- a/target-tomoko/settings/hotkeys.cpp +++ b/target-tomoko/settings/hotkeys.cpp @@ -3,7 +3,6 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) { setText("Hotkeys"); layout.setMargin(5); - mappingList.setHeaderVisible(); mappingList.onActivate([&] { assignMapping(); }); mappingList.onChange([&] { eraseButton.setEnabled((bool)mappingList.selected()); @@ -27,9 +26,11 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) { auto HotkeySettings::reloadMappings() -> void { mappingList.reset(); - mappingList.append(ListViewColumn().setText("Name")); - mappingList.append(ListViewColumn().setText("Mapping").setExpandable()); - mappingList.append(ListViewColumn().setText("Device")); + mappingList.append(ListViewHeader().setVisible() + .append(ListViewColumn().setText("Name")) + .append(ListViewColumn().setText("Mapping").setExpandable()) + .append(ListViewColumn().setText("Device")) + ); for(auto& hotkey : inputManager->hotkeys) { mappingList.append(ListViewItem() .append(ListViewCell().setText(hotkey->name)) diff --git a/target-tomoko/settings/input.cpp b/target-tomoko/settings/input.cpp index 99aec66f..df168b71 100644 --- a/target-tomoko/settings/input.cpp +++ b/target-tomoko/settings/input.cpp @@ -9,7 +9,6 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) { emulatorList.onChange([&] { reloadPorts(); }); portList.onChange([&] { reloadDevices(); }); deviceList.onChange([&] { reloadMappings(); }); - mappingList.setHeaderVisible(); mappingList.onActivate([&] { assignMapping(); }); mappingList.onChange([&] { updateControls(); }); assignMouse1.setVisible(false).onActivate([&] { assignMouseInput(0); }); @@ -82,9 +81,11 @@ auto InputSettings::reloadDevices() -> void { auto InputSettings::reloadMappings() -> void { eraseButton.setEnabled(false); mappingList.reset(); - mappingList.append(ListViewColumn().setText("Name")); - mappingList.append(ListViewColumn().setText("Mapping").setExpandable()); - mappingList.append(ListViewColumn().setText("Device").setForegroundColor({0, 128, 0})); + mappingList.append(ListViewHeader().setVisible() + .append(ListViewColumn().setText("Name")) + .append(ListViewColumn().setText("Mapping").setExpandable()) + .append(ListViewColumn().setText("Device").setForegroundColor({0, 128, 0})) + ); for(auto& mapping : activeDevice().mappings) { mappingList.append(ListViewItem() .append(ListViewCell().setText(mapping->name)) diff --git a/target-tomoko/settings/settings.cpp b/target-tomoko/settings/settings.cpp index 233acc01..ad55c400 100644 --- a/target-tomoko/settings/settings.cpp +++ b/target-tomoko/settings/settings.cpp @@ -15,7 +15,7 @@ SettingsManager::SettingsManager() { setTitle("Configuration Settings"); setSize({600, 400}); - setPlacement(0.0, 1.0); + setAlignment({0.0, 1.0}); onSize([&] { input.mappingList.resizeColumns(); diff --git a/target-tomoko/tools/cheat-database.cpp b/target-tomoko/tools/cheat-database.cpp index f6fd8a37..5c4cad9a 100644 --- a/target-tomoko/tools/cheat-database.cpp +++ b/target-tomoko/tools/cheat-database.cpp @@ -2,13 +2,16 @@ CheatDatabase::CheatDatabase() { cheatDatabase = this; layout.setMargin(5); - cheatList.setCheckable(); - selectAllButton.setText("Select All").onActivate([&] { cheatList.checkAll(); }); - unselectAllButton.setText("Unselect All").onActivate([&] { cheatList.uncheckAll(); }); + selectAllButton.setText("Select All").onActivate([&] { + for(auto& item : cheatList.items()) item.cell(0).setChecked(true); + }); + unselectAllButton.setText("Unselect All").onActivate([&] { + for(auto& item : cheatList.items()) item.cell(0).setChecked(false); + }); addCodesButton.setText("Add Codes").onActivate([&] { addCodes(); }); setSize({800, 400}); - setPlacement(0.5, 1.0); + setAlignment({0.5, 1.0}); onSize([&] { cheatList.resizeColumns(); }); } @@ -25,11 +28,13 @@ auto CheatDatabase::findCodes() -> void { codes.reset(); cheatList.reset(); - cheatList.append(ListViewColumn().setExpandable()); + cheatList.append(ListViewHeader().setVisible(false) + .append(ListViewColumn().setExpandable()) + ); for(auto cheat : cartridge.find("cheat")) { codes.append(cheat["code"].text()); cheatList.append(ListViewItem() - .append(ListViewCell().setText(cheat["description"].text())) + .append(ListViewCell().setCheckable().setText(cheat["description"].text())) ); } @@ -43,9 +48,11 @@ auto CheatDatabase::findCodes() -> void { } auto CheatDatabase::addCodes() -> void { - for(auto item : cheatList.checked()) { - string code = codes(item->offset(), ""); - string description = item->cell(0)->text(); + for(auto& item : cheatList.items()) { + if(!item.cell(0).checked()) continue; + + string code = codes(item.offset(), ""); + string description = item.cell(0).text(); if(toolsManager->cheatEditor.addCode(code, description) == false) { MessageDialog().setParent(*this).setText("Free slots exhausted. Not all codes could be added.").warning(); break; diff --git a/target-tomoko/tools/cheat-editor.cpp b/target-tomoko/tools/cheat-editor.cpp index 51c00cba..f1b5cb86 100644 --- a/target-tomoko/tools/cheat-editor.cpp +++ b/target-tomoko/tools/cheat-editor.cpp @@ -3,21 +3,21 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) { setText("Cheat Editor"); layout.setMargin(5); - cheatList.append(ListViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setHorizontalAlignment(1.0)); - cheatList.append(ListViewColumn().setText("Code(s)")); - cheatList.append(ListViewColumn().setText("Description").setExpandable()); + cheatList.append(ListViewHeader().setVisible() + .append(ListViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) + .append(ListViewColumn().setText("Code(s)")) + .append(ListViewColumn().setText("Description").setExpandable()) + ); for(auto slot : range(Slots)) { cheatList.append(ListViewItem() - .append(ListViewCell().setText(1 + slot)) + .append(ListViewCell().setCheckable().setText(1 + slot)) .append(ListViewCell()) .append(ListViewCell()) ); } - cheatList.setCheckable(); - cheatList.setHeaderVisible(); cheatList.onChange([&] { doChangeSelected(); }); - cheatList.onToggle([&](ListViewItem item) { - cheats[item.offset()].enabled = item.checked(); + cheatList.onToggle([&](ListViewCell cell) { + cheats[cell.parent().offset()].enabled = cell.checked(); synchronizeCodes(); }); codeLabel.setText("Code(s):"); @@ -58,11 +58,11 @@ auto CheatEditor::doRefresh() -> void { if(cheat.code || cheat.description) { lstring codes = cheat.code.split("+"); if(codes.size() > 1) codes[0].append("+..."); - cheatList.item(slot).setChecked(cheat.enabled); + cheatList.item(slot).cell(0).setChecked(cheat.enabled); cheatList.item(slot).cell(1).setText(codes[0]); cheatList.item(slot).cell(2).setText(cheat.description).setForegroundColor({0, 0, 0}); } else { - cheatList.item(slot).setChecked(false); + cheatList.item(slot).cell(0).setChecked(false); cheatList.item(slot).cell(1).setText(""); cheatList.item(slot).cell(2).setText("(empty)").setForegroundColor({128, 128, 128}); } @@ -78,7 +78,9 @@ auto CheatEditor::doReset(bool force) -> void { cheat.code = ""; cheat.description = ""; } - cheatList.unselectAll(); + for(auto& item : cheatList.items()) { + item.cell(0).setChecked(false); + } doChangeSelected(); doRefresh(); synchronizeCodes(); diff --git a/target-tomoko/tools/state-manager.cpp b/target-tomoko/tools/state-manager.cpp index aae0463f..0c8912f8 100644 --- a/target-tomoko/tools/state-manager.cpp +++ b/target-tomoko/tools/state-manager.cpp @@ -3,15 +3,16 @@ StateManager::StateManager(TabFrame* parent) : TabFrameItem(parent) { setText("State Manager"); layout.setMargin(5); - stateList.append(ListViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setHorizontalAlignment(1.0)); - stateList.append(ListViewColumn().setText("Description").setExpandable()); + stateList.append(ListViewHeader().setVisible() + .append(ListViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) + .append(ListViewColumn().setText("Description").setExpandable()) + ); for(auto slot : range(Slots)) { stateList.append(ListViewItem() .append(ListViewCell().setText(1 + slot)) .append(ListViewCell()) ); } - stateList.setHeaderVisible(); stateList.onActivate([&] { doLoad(); }); stateList.onChange([&] { doChangeSelected(); }); descriptionLabel.setText("Description:"); diff --git a/target-tomoko/tools/tools.cpp b/target-tomoko/tools/tools.cpp index 30bb198b..de5ffd45 100644 --- a/target-tomoko/tools/tools.cpp +++ b/target-tomoko/tools/tools.cpp @@ -12,7 +12,7 @@ ToolsManager::ToolsManager() { setTitle("Tools"); setSize({600, 400}); - setPlacement(1.0, 1.0); + setAlignment({1.0, 1.0}); onSize([&] { cheatEditor.cheatList.resizeColumns();