From 6ae0abe3d323c3c746ff4f2ebf7ca1cb3dc488c4 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Wed, 4 May 2016 20:07:13 +1000 Subject: [PATCH] Update to v098r09 release. byuu says: Changelog: - fixed major nall/vector/prepend bug - renamed hiro/ListView to hiro/TableView - added new hiro/ListView control which is a simplified abstraction of hiro/TableView - updated higan's cheat database window and icarus' scan dialog to use the new ListView control - compilation works once again on all platforms (Windows, Cocoa, GTK, Qt) - the loki skeleton compiles once again (removed nall/DSP references; updated port/device ID names) Small catch: need to capture layout resize events internally in Windows to call resizeColumns. For now, just resize the icarus window to get it to use the full window width for list view items. --- higan/emulator/emulator.hpp | 2 +- higan/sfc/coprocessor/sdd1/sdd1.cpp | 2 +- higan/target-loki/program/interface.cpp | 11 +- higan/target-loki/program/media.cpp | 14 +- higan/target-loki/program/program.hpp | 1 - higan/target-tomoko/settings/hotkeys.cpp | 24 +- higan/target-tomoko/settings/input.cpp | 24 +- higan/target-tomoko/settings/settings.hpp | 4 +- higan/target-tomoko/tools/cheat-database.cpp | 18 +- higan/target-tomoko/tools/cheat-editor.cpp | 18 +- higan/target-tomoko/tools/state-manager.cpp | 12 +- higan/target-tomoko/tools/tools.hpp | 4 +- hiro/cocoa/header.hpp | 10 +- hiro/cocoa/platform.cpp | 10 +- hiro/cocoa/platform.hpp | 10 +- hiro/cocoa/widget/canvas.cpp | 2 +- hiro/cocoa/widget/list-view-cell.cpp | 50 --- hiro/cocoa/widget/list-view-column.cpp | 87 ---- hiro/cocoa/widget/list-view-header.cpp | 38 -- hiro/cocoa/widget/list-view-header.hpp | 17 - hiro/cocoa/widget/list-view-item.cpp | 51 --- hiro/cocoa/widget/table-view-cell.cpp | 50 +++ ...list-view-cell.hpp => table-view-cell.hpp} | 10 +- hiro/cocoa/widget/table-view-column.cpp | 87 ++++ ...-view-column.hpp => table-view-column.hpp} | 10 +- hiro/cocoa/widget/table-view-header.cpp | 38 ++ hiro/cocoa/widget/table-view-header.hpp | 17 + hiro/cocoa/widget/table-view-item.cpp | 51 +++ ...list-view-item.hpp => table-view-item.hpp} | 12 +- .../widget/{list-view.cpp => table-view.cpp} | 158 +++---- .../widget/{list-view.hpp => table-view.hpp} | 36 +- hiro/cocoa/widget/viewport.cpp | 2 +- hiro/cocoa/window.cpp | 2 +- hiro/components.hpp | 8 +- hiro/core/core.cpp | 10 +- hiro/core/core.hpp | 416 +++++++++--------- hiro/core/object.cpp | 60 +-- hiro/core/shared.hpp | 262 +++++------ hiro/core/widget/list-view-column.cpp | 153 ------- hiro/core/widget/list-view-header.cpp | 53 --- hiro/core/widget/list-view-item.cpp | 98 ----- ...list-view-cell.cpp => table-view-cell.cpp} | 52 +-- hiro/core/widget/table-view-column.cpp | 153 +++++++ hiro/core/widget/table-view-header.cpp | 58 +++ hiro/core/widget/table-view-item.cpp | 103 +++++ .../widget/{list-view.cpp => table-view.cpp} | 82 ++-- hiro/extension/browser-dialog.cpp | 20 +- hiro/extension/extension.cpp | 2 + hiro/extension/extension.hpp | 2 + hiro/extension/list-view-item.cpp | 49 +++ hiro/extension/list-view-item.hpp | 24 + hiro/extension/list-view.cpp | 51 +++ hiro/extension/list-view.hpp | 27 ++ hiro/extension/shared.hpp | 53 +++ hiro/gtk/platform.cpp | 10 +- hiro/gtk/platform.hpp | 10 +- hiro/gtk/widget/list-view-header.cpp | 41 -- hiro/gtk/widget/list-view-header.hpp | 18 - ...list-view-cell.cpp => table-view-cell.cpp} | 28 +- ...list-view-cell.hpp => table-view-cell.hpp} | 10 +- ...-view-column.cpp => table-view-column.cpp} | 52 +-- ...-view-column.hpp => table-view-column.hpp} | 10 +- hiro/gtk/widget/table-view-header.cpp | 41 ++ hiro/gtk/widget/table-view-header.hpp | 18 + ...list-view-item.cpp => table-view-item.cpp} | 26 +- ...list-view-item.hpp => table-view-item.hpp} | 12 +- .../widget/{list-view.cpp => table-view.cpp} | 96 ++-- .../widget/{list-view.hpp => table-view.hpp} | 14 +- hiro/qt/platform.cpp | 10 +- hiro/qt/platform.hpp | 10 +- hiro/qt/qt.hpp | 50 ++- hiro/qt/qt.moc | 168 +++---- hiro/qt/widget/list-view-column.cpp | 99 ----- hiro/qt/widget/list-view-header.cpp | 43 -- hiro/qt/widget/list-view-header.hpp | 18 - hiro/qt/widget/list-view-item.cpp | 64 --- ...list-view-cell.cpp => table-view-cell.cpp} | 28 +- ...list-view-cell.hpp => table-view-cell.hpp} | 8 +- hiro/qt/widget/table-view-column.cpp | 99 +++++ ...-view-column.hpp => table-view-column.hpp} | 8 +- hiro/qt/widget/table-view-header.cpp | 43 ++ hiro/qt/widget/table-view-header.hpp | 18 + hiro/qt/widget/table-view-item.cpp | 66 +++ ...list-view-item.hpp => table-view-item.hpp} | 12 +- .../widget/{list-view.cpp => table-view.cpp} | 114 ++--- .../widget/{list-view.hpp => table-view.hpp} | 18 +- hiro/windows/application.cpp | 6 +- hiro/windows/platform.cpp | 10 +- hiro/windows/platform.hpp | 16 +- hiro/windows/utility.cpp | 34 +- hiro/windows/widget/canvas.cpp | 3 +- hiro/windows/widget/list-view-cell.cpp | 72 --- hiro/windows/widget/list-view-header.hpp | 18 - hiro/windows/widget/table-view-cell.cpp | 72 +++ ...list-view-cell.hpp => table-view-cell.hpp} | 8 +- ...-view-column.cpp => table-view-column.cpp} | 40 +- ...-view-column.hpp => table-view-column.hpp} | 12 +- ...-view-header.cpp => table-view-header.cpp} | 18 +- hiro/windows/widget/table-view-header.hpp | 18 + ...list-view-item.cpp => table-view-item.cpp} | 26 +- ...list-view-item.hpp => table-view-item.hpp} | 12 +- .../widget/{list-view.cpp => table-view.cpp} | 72 +-- .../widget/{list-view.hpp => table-view.hpp} | 14 +- hiro/windows/window.cpp | 3 +- icarus/ui/scan-dialog.cpp | 16 +- nall/vector/memory.hpp | 6 +- nall/windows/registry.hpp | 20 +- ruby/audio/wasapi.cpp | 4 +- 108 files changed, 2299 insertions(+), 2081 deletions(-) delete mode 100644 hiro/cocoa/widget/list-view-cell.cpp delete mode 100644 hiro/cocoa/widget/list-view-column.cpp delete mode 100644 hiro/cocoa/widget/list-view-header.cpp delete mode 100644 hiro/cocoa/widget/list-view-header.hpp delete mode 100644 hiro/cocoa/widget/list-view-item.cpp create mode 100644 hiro/cocoa/widget/table-view-cell.cpp rename hiro/cocoa/widget/{list-view-cell.hpp => table-view-cell.hpp} (65%) create mode 100644 hiro/cocoa/widget/table-view-column.cpp rename hiro/cocoa/widget/{list-view-column.hpp => table-view-column.hpp} (78%) create mode 100644 hiro/cocoa/widget/table-view-header.cpp create mode 100644 hiro/cocoa/widget/table-view-header.hpp create mode 100644 hiro/cocoa/widget/table-view-item.cpp rename hiro/cocoa/widget/{list-view-item.hpp => table-view-item.hpp} (53%) rename hiro/cocoa/widget/{list-view.cpp => table-view.cpp} (66%) rename hiro/cocoa/widget/{list-view.hpp => table-view.hpp} (70%) delete mode 100644 hiro/core/widget/list-view-column.cpp delete mode 100644 hiro/core/widget/list-view-header.cpp delete mode 100644 hiro/core/widget/list-view-item.cpp rename hiro/core/widget/{list-view-cell.cpp => table-view-cell.cpp} (66%) create mode 100644 hiro/core/widget/table-view-column.cpp create mode 100644 hiro/core/widget/table-view-header.cpp create mode 100644 hiro/core/widget/table-view-item.cpp rename hiro/core/widget/{list-view.cpp => table-view.cpp} (55%) create mode 100644 hiro/extension/list-view-item.cpp create mode 100644 hiro/extension/list-view-item.hpp create mode 100644 hiro/extension/list-view.cpp create mode 100644 hiro/extension/list-view.hpp delete mode 100644 hiro/gtk/widget/list-view-header.cpp delete mode 100644 hiro/gtk/widget/list-view-header.hpp rename hiro/gtk/widget/{list-view-cell.cpp => table-view-cell.cpp} (50%) rename hiro/gtk/widget/{list-view-cell.hpp => table-view-cell.hpp} (67%) rename hiro/gtk/widget/{list-view-column.cpp => table-view-column.cpp} (67%) rename hiro/gtk/widget/{list-view-column.hpp => table-view-column.hpp} (84%) create mode 100644 hiro/gtk/widget/table-view-header.cpp create mode 100644 hiro/gtk/widget/table-view-header.hpp rename hiro/gtk/widget/{list-view-item.cpp => table-view-item.cpp} (63%) rename hiro/gtk/widget/{list-view-item.hpp => table-view-item.hpp} (57%) rename hiro/gtk/widget/{list-view.cpp => table-view.cpp} (78%) rename hiro/gtk/widget/{list-view.hpp => table-view.hpp} (84%) delete mode 100644 hiro/qt/widget/list-view-column.cpp delete mode 100644 hiro/qt/widget/list-view-header.cpp delete mode 100644 hiro/qt/widget/list-view-header.hpp delete mode 100644 hiro/qt/widget/list-view-item.cpp rename hiro/qt/widget/{list-view-cell.cpp => table-view-cell.cpp} (63%) rename hiro/qt/widget/{list-view-cell.hpp => table-view-cell.hpp} (75%) create mode 100644 hiro/qt/widget/table-view-column.cpp rename hiro/qt/widget/{list-view-column.hpp => table-view-column.hpp} (83%) create mode 100644 hiro/qt/widget/table-view-header.cpp create mode 100644 hiro/qt/widget/table-view-header.hpp create mode 100644 hiro/qt/widget/table-view-item.cpp rename hiro/qt/widget/{list-view-item.hpp => table-view-item.hpp} (60%) rename hiro/qt/widget/{list-view.cpp => table-view.cpp} (56%) rename hiro/qt/widget/{list-view.hpp => table-view.hpp} (57%) delete mode 100644 hiro/windows/widget/list-view-cell.cpp delete mode 100644 hiro/windows/widget/list-view-header.hpp create mode 100644 hiro/windows/widget/table-view-cell.cpp rename hiro/windows/widget/{list-view-cell.hpp => table-view-cell.hpp} (74%) rename hiro/windows/widget/{list-view-column.cpp => table-view-column.cpp} (58%) rename hiro/windows/widget/{list-view-column.hpp => table-view-column.hpp} (71%) rename hiro/windows/widget/{list-view-header.cpp => table-view-header.cpp} (51%) create mode 100644 hiro/windows/widget/table-view-header.hpp rename hiro/windows/widget/{list-view-item.cpp => table-view-item.cpp} (60%) rename hiro/windows/widget/{list-view-item.hpp => table-view-item.hpp} (55%) rename hiro/windows/widget/{list-view.cpp => table-view.cpp} (85%) rename hiro/windows/widget/{list-view.hpp => table-view.hpp} (80%) diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 5e5eb6c4..a4ac20fc 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -8,7 +8,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "098.08"; + static const string Version = "098.09"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/sfc/coprocessor/sdd1/sdd1.cpp b/higan/sfc/coprocessor/sdd1/sdd1.cpp index 44cd432f..e862acc1 100644 --- a/higan/sfc/coprocessor/sdd1/sdd1.cpp +++ b/higan/sfc/coprocessor/sdd1/sdd1.cpp @@ -98,7 +98,7 @@ auto SDD1::mmcRead(uint24 addr) -> uint8 { //map address=00-3f,80-bf:8000-ffff //map address=c0-ff:0000-ffff auto SDD1::mcuromRead(uint24 addr, uint8 data) -> uint8 { - //map address=00-3f,80-bf:8000-ffff mask=0x808000 => 00-1f:0000-ffff + //map address=00-3f,80-bf:8000-ffff if(!addr.bit(22)) { if(!addr.bit(23) && addr.bit(21) && r4805.bit(7)) addr.bit(21) = 0; //20-3f:8000-ffff if( addr.bit(23) && addr.bit(21) && r4807.bit(7)) addr.bit(21) = 0; //a0-bf:8000-ffff diff --git a/higan/target-loki/program/interface.cpp b/higan/target-loki/program/interface.cpp index 9e4e9820..17744439 100644 --- a/higan/target-loki/program/interface.cpp +++ b/higan/target-loki/program/interface.cpp @@ -60,12 +60,7 @@ auto Program::videoRefresh(const uint32* data, uint pitch, uint width, uint heig } auto Program::audioSample(int16 left, int16 right) -> void { - int samples[] = {left, right}; - dsp.sample(samples); - while(dsp.pending()) { - dsp.read(samples); - audio->sample(samples[0], samples[1]); - } + audio->sample(left, right); } auto Program::inputPoll(uint port, uint device, uint input) -> int16 { @@ -79,8 +74,8 @@ auto Program::inputPoll(uint port, uint device, uint input) -> int16 { } } - if(port == (uint)SFC::Device::Port::Controller1) { - if(device == (uint)SFC::Device::ID::Gamepad) { + if(port == (uint)SFC::Port::Controller1) { + if(device == (uint)SFC::Device::Gamepad) { #define map(id, name) \ case id: \ if(auto code = keyboard->buttons().find(name)) { \ diff --git a/higan/target-loki/program/media.cpp b/higan/target-loki/program/media.cpp index a9f0ef59..27d06013 100644 --- a/higan/target-loki/program/media.cpp +++ b/higan/target-loki/program/media.cpp @@ -22,19 +22,15 @@ auto Program::loadMedia(Emulator::Interface::Media& media, string location) -> v emulator->set("Color Emulation", false); emulator->set("Scanline Emulation", false); - emulator->connect((uint)SFC::Device::Port::Controller1, (uint)SFC::Device::ID::Gamepad); - emulator->connect((uint)SFC::Device::Port::Controller2, (uint)SFC::Device::ID::None); - emulator->connect((uint)SFC::Device::Port::Expansion, (uint)SFC::Device::ID::None); + Emulator::audio.reset(); + Emulator::audio.setFrequency(audio->get(Audio::Frequency).get()); + emulator->connect((uint)SFC::Port::Controller1, (uint)SFC::Device::Gamepad); + emulator->connect((uint)SFC::Port::Controller2, (uint)SFC::Device::None); + emulator->connect((uint)SFC::Port::Expansion, (uint)SFC::Device::None); emulator->load(media.id); emulator->power(); - dsp.setResampler(DSP::ResampleEngine::Sinc); - dsp.setResamplerFrequency(96000.0); - double inputRatio = emulator->audioFrequency() / emulator->videoFrequency(); - double outputRatio = 96000.0 / 60.0; - dsp.setFrequency(inputRatio / outputRatio * 96000.0); - presentation->setTitle(emulator->title()); } diff --git a/higan/target-loki/program/program.hpp b/higan/target-loki/program/program.hpp index 9f175160..4354d032 100644 --- a/higan/target-loki/program/program.hpp +++ b/higan/target-loki/program/program.hpp @@ -21,7 +21,6 @@ struct Program : Emulator::Interface::Bind { auto path(uint group) -> string override; auto notify(string text) -> void override; - DSP dsp; vector> devices; vector mediaPaths; vector folderPaths; diff --git a/higan/target-tomoko/settings/hotkeys.cpp b/higan/target-tomoko/settings/hotkeys.cpp index de30aca0..fc585a29 100644 --- a/higan/target-tomoko/settings/hotkeys.cpp +++ b/higan/target-tomoko/settings/hotkeys.cpp @@ -15,7 +15,7 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) { }); eraseButton.setText("Erase").onActivate([&] { if(auto item = mappingList.selected()) { - inputManager->hotkeys[item->offset()]->unbind(); + inputManager->hotkeys[item.offset()]->unbind(); refreshMappings(); } }); @@ -26,16 +26,16 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) { auto HotkeySettings::reloadMappings() -> void { mappingList.reset(); - mappingList.append(ListViewHeader().setVisible() - .append(ListViewColumn().setText("Name")) - .append(ListViewColumn().setText("Mapping").setExpandable()) - .append(ListViewColumn().setText("Device").setAlignment(1.0).setForegroundColor({0, 128, 0})) + mappingList.append(TableViewHeader().setVisible() + .append(TableViewColumn().setText("Name")) + .append(TableViewColumn().setText("Mapping").setExpandable()) + .append(TableViewColumn().setText("Device").setAlignment(1.0).setForegroundColor({0, 128, 0})) ); for(auto& hotkey : inputManager->hotkeys) { - mappingList.append(ListViewItem() - .append(ListViewCell().setText(hotkey->name)) - .append(ListViewCell()) - .append(ListViewCell()) + mappingList.append(TableViewItem() + .append(TableViewCell().setText(hotkey->name)) + .append(TableViewCell()) + .append(TableViewCell()) ); } mappingList.resizeColumns(); @@ -44,8 +44,8 @@ auto HotkeySettings::reloadMappings() -> void { auto HotkeySettings::refreshMappings() -> void { uint position = 0; for(auto& hotkey : inputManager->hotkeys) { - mappingList.item(position)->cell(1)->setText(hotkey->assignmentName()); - mappingList.item(position)->cell(2)->setText(hotkey->deviceName()); + mappingList.item(position).cell(1).setText(hotkey->assignmentName()); + mappingList.item(position).cell(2).setText(hotkey->deviceName()); position++; } mappingList.resizeColumns(); @@ -55,7 +55,7 @@ auto HotkeySettings::assignMapping() -> void { inputManager->poll(); //clear any pending events first if(auto item = mappingList.selected()) { - activeMapping = inputManager->hotkeys[item->offset()]; + activeMapping = inputManager->hotkeys[item.offset()]; settingsManager->layout.setEnabled(false); settingsManager->statusBar.setText({"Press a key or button to map [", activeMapping->name, "] ..."}); } diff --git a/higan/target-tomoko/settings/input.cpp b/higan/target-tomoko/settings/input.cpp index 7cd6d965..56d960a9 100644 --- a/higan/target-tomoko/settings/input.cpp +++ b/higan/target-tomoko/settings/input.cpp @@ -30,7 +30,7 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) { }); eraseButton.setText("Erase").onActivate([&] { if(auto mapping = mappingList.selected()) { - activeDevice().mappings[mapping->offset()]->unbind(); + activeDevice().mappings[mapping.offset()]->unbind(); refreshMappings(); } }); @@ -45,7 +45,7 @@ auto InputSettings::updateControls() -> void { assignMouse3.setVisible(false); if(auto mapping = mappingList.selected()) { - auto input = activeDevice().mappings[mapping->offset()]; + auto input = activeDevice().mappings[mapping.offset()]; if(input->isDigital()) { assignMouse1.setVisible().setText("Mouse Left"); @@ -92,16 +92,16 @@ auto InputSettings::reloadDevices() -> void { auto InputSettings::reloadMappings() -> void { eraseButton.setEnabled(false); mappingList.reset(); - mappingList.append(ListViewHeader().setVisible() - .append(ListViewColumn().setText("Name")) - .append(ListViewColumn().setText("Mapping").setExpandable()) - .append(ListViewColumn().setText("Device").setAlignment(1.0).setForegroundColor({0, 128, 0})) + mappingList.append(TableViewHeader().setVisible() + .append(TableViewColumn().setText("Name")) + .append(TableViewColumn().setText("Mapping").setExpandable()) + .append(TableViewColumn().setText("Device").setAlignment(1.0).setForegroundColor({0, 128, 0})) ); for(auto& mapping : activeDevice().mappings) { - mappingList.append(ListViewItem() - .append(ListViewCell().setText(mapping->name)) - .append(ListViewCell()) - .append(ListViewCell()) + mappingList.append(TableViewItem() + .append(TableViewCell().setText(mapping->name)) + .append(TableViewCell()) + .append(TableViewCell()) ); } refreshMappings(); @@ -110,8 +110,8 @@ auto InputSettings::reloadMappings() -> void { auto InputSettings::refreshMappings() -> void { uint position = 0; for(auto& mapping : activeDevice().mappings) { - mappingList.item(position)->cell(1)->setText(mapping->assignmentName()); - mappingList.item(position)->cell(2)->setText(mapping->deviceName()); + mappingList.item(position).cell(1).setText(mapping->assignmentName()); + mappingList.item(position).cell(2).setText(mapping->deviceName()); position++; } mappingList.resizeColumns(); diff --git a/higan/target-tomoko/settings/settings.hpp b/higan/target-tomoko/settings/settings.hpp index ef690936..f5432d4e 100644 --- a/higan/target-tomoko/settings/settings.hpp +++ b/higan/target-tomoko/settings/settings.hpp @@ -90,7 +90,7 @@ struct InputSettings : TabFrameItem { ComboButton emulatorList{&selectionLayout, Size{~0, 0}}; ComboButton portList{&selectionLayout, Size{~0, 0}}; ComboButton deviceList{&selectionLayout, Size{~0, 0}}; - ListView mappingList{&layout, Size{~0, ~0}}; + TableView mappingList{&layout, Size{~0, ~0}}; HorizontalLayout controlLayout{&layout, Size{~0, 0}}; Button assignMouse1{&controlLayout, Size{100, 0}}; Button assignMouse2{&controlLayout, Size{100, 0}}; @@ -111,7 +111,7 @@ struct HotkeySettings : TabFrameItem { Timer timer; VerticalLayout layout{this}; - ListView mappingList{&layout, Size{~0, ~0}}; + TableView mappingList{&layout, Size{~0, ~0}}; HorizontalLayout controlLayout{&layout, Size{~0, 0}}; Widget spacer{&controlLayout, Size{~0, 0}}; Button resetButton{&controlLayout, Size{80, 0}}; diff --git a/higan/target-tomoko/tools/cheat-database.cpp b/higan/target-tomoko/tools/cheat-database.cpp index b3c38e22..78fec79a 100644 --- a/higan/target-tomoko/tools/cheat-database.cpp +++ b/higan/target-tomoko/tools/cheat-database.cpp @@ -3,17 +3,15 @@ CheatDatabase::CheatDatabase() { layout.setMargin(5); selectAllButton.setText("Select All").onActivate([&] { - for(auto& item : cheatList.items()) item.cell(0).setChecked(true); + for(auto& item : cheatList.items()) item.setChecked(true); }); unselectAllButton.setText("Unselect All").onActivate([&] { - for(auto& item : cheatList.items()) item.cell(0).setChecked(false); + for(auto& item : cheatList.items()) item.setChecked(false); }); addCodesButton.setText("Add Codes").onActivate([&] { addCodes(); }); setSize({800, 400}); setAlignment({0.5, 1.0}); - - onSize([&] { cheatList.resizeColumns(); }); } auto CheatDatabase::findCodes() -> void { @@ -28,19 +26,13 @@ auto CheatDatabase::findCodes() -> void { codes.reset(); cheatList.reset(); - cheatList.append(ListViewHeader().setVisible(false) - .append(ListViewColumn().setExpandable()) - ); for(auto cheat : cartridge.find("cheat")) { codes.append(cheat["code"].text()); - cheatList.append(ListViewItem() - .append(ListViewCell().setCheckable().setText(cheat["description"].text())) - ); + cheatList.append(ListViewItem().setCheckable().setText(cheat["description"].text())); } setTitle(cartridge["name"].text()); setVisible(); - cheatList.resizeColumns(); return; } @@ -49,10 +41,10 @@ auto CheatDatabase::findCodes() -> void { auto CheatDatabase::addCodes() -> void { for(auto& item : cheatList.items()) { - if(!item.cell(0).checked()) continue; + if(!item.checked()) continue; string code = codes(item.offset(), ""); - string description = item.cell(0).text(); + string description = item.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/higan/target-tomoko/tools/cheat-editor.cpp b/higan/target-tomoko/tools/cheat-editor.cpp index 4678e959..49732716 100644 --- a/higan/target-tomoko/tools/cheat-editor.cpp +++ b/higan/target-tomoko/tools/cheat-editor.cpp @@ -3,20 +3,20 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) { setText("Cheat Editor"); layout.setMargin(5); - 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()) + cheatList.append(TableViewHeader().setVisible() + .append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) + .append(TableViewColumn().setText("Code(s)")) + .append(TableViewColumn().setText("Description").setExpandable()) ); for(auto slot : range(Slots)) { - cheatList.append(ListViewItem() - .append(ListViewCell().setCheckable().setText(1 + slot)) - .append(ListViewCell()) - .append(ListViewCell()) + cheatList.append(TableViewItem() + .append(TableViewCell().setCheckable().setText(1 + slot)) + .append(TableViewCell()) + .append(TableViewCell()) ); } cheatList.onChange([&] { doChangeSelected(); }); - cheatList.onToggle([&](ListViewCell cell) { + cheatList.onToggle([&](TableViewCell cell) { cheats[cell.parent().offset()].enabled = cell.checked(); synchronizeCodes(); }); diff --git a/higan/target-tomoko/tools/state-manager.cpp b/higan/target-tomoko/tools/state-manager.cpp index 7da20ba5..4e7c86d8 100644 --- a/higan/target-tomoko/tools/state-manager.cpp +++ b/higan/target-tomoko/tools/state-manager.cpp @@ -3,14 +3,14 @@ StateManager::StateManager(TabFrame* parent) : TabFrameItem(parent) { setText("State Manager"); layout.setMargin(5); - stateList.append(ListViewHeader().setVisible() - .append(ListViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) - .append(ListViewColumn().setText("Description").setExpandable()) + stateList.append(TableViewHeader().setVisible() + .append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) + .append(TableViewColumn().setText("Description").setExpandable()) ); for(auto slot : range(Slots)) { - stateList.append(ListViewItem() - .append(ListViewCell().setText(1 + slot)) - .append(ListViewCell()) + stateList.append(TableViewItem() + .append(TableViewCell().setText(1 + slot)) + .append(TableViewCell()) ); } stateList.onActivate([&] { doLoad(); }); diff --git a/higan/target-tomoko/tools/tools.hpp b/higan/target-tomoko/tools/tools.hpp index b30a56d2..a00158ea 100644 --- a/higan/target-tomoko/tools/tools.hpp +++ b/higan/target-tomoko/tools/tools.hpp @@ -36,7 +36,7 @@ struct CheatEditor : TabFrameItem { Cheat cheats[Slots]; VerticalLayout layout{this}; - ListView cheatList{&layout, Size{~0, ~0}}; + TableView cheatList{&layout, Size{~0, ~0}}; HorizontalLayout codeLayout{&layout, Size{~0, 0}}; Label codeLabel{&codeLayout, Size{70, 0}}; LineEdit codeValue{&codeLayout, Size{~0, 0}}; @@ -64,7 +64,7 @@ struct StateManager : TabFrameItem { auto doErase() -> void; VerticalLayout layout{this}; - ListView stateList{&layout, Size{~0, ~0}}; + TableView stateList{&layout, Size{~0, ~0}}; HorizontalLayout descriptionLayout{&layout, Size{~0, 0}}; Label descriptionLabel{&descriptionLayout, Size{70, 0}}; LineEdit descriptionValue{&descriptionLayout, Size{~0, 0}}; diff --git a/hiro/cocoa/header.hpp b/hiro/cocoa/header.hpp index 776e1d6f..e09bcb5a 100644 --- a/hiro/cocoa/header.hpp +++ b/hiro/cocoa/header.hpp @@ -1,6 +1,14 @@ -#define decimal CocoaDecimal +#define decimal decimal_cocoa +#define uint8 uint8_cocoa +#define uint16 uint16_cocoa +#define uint32 uint32_cocoa +#define uint64 uint64_cocoa #import #import #undef decimal +#undef uint8 +#undef uint16 +#undef uint32 +#undef uint64 #include diff --git a/hiro/cocoa/platform.cpp b/hiro/cocoa/platform.cpp index 1da44744..2058fe52 100644 --- a/hiro/cocoa/platform.cpp +++ b/hiro/cocoa/platform.cpp @@ -42,16 +42,16 @@ #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" diff --git a/hiro/cocoa/platform.hpp b/hiro/cocoa/platform.hpp index 324d6c0f..66c1e4c8 100644 --- a/hiro/cocoa/platform.hpp +++ b/hiro/cocoa/platform.hpp @@ -54,16 +54,16 @@ namespace hiro { #include "widget/horizontal-slider.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/vertical-scroll-bar.hpp" #include "widget/vertical-slider.hpp" diff --git a/hiro/cocoa/widget/canvas.cpp b/hiro/cocoa/widget/canvas.cpp index 6f2730e3..463574f3 100644 --- a/hiro/cocoa/widget/canvas.cpp +++ b/hiro/cocoa/widget/canvas.cpp @@ -21,7 +21,7 @@ -(BOOL) performDragOperation:(id)sender { lstring paths = DropPaths(sender); - if(paths.empty()) return NO; + if(!paths) return NO; canvas->doDrop(paths); return YES; } diff --git a/hiro/cocoa/widget/list-view-cell.cpp b/hiro/cocoa/widget/list-view-cell.cpp deleted file mode 100644 index ef43cedc..00000000 --- a/hiro/cocoa/widget/list-view-cell.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewCell::construct() -> void { -} - -auto pListViewCell::destruct() -> void { -} - -auto pListViewCell::setAlignment(Alignment alignment) -> void { -} - -auto pListViewCell::setBackgroundColor(Color color) -> void { -} - -auto pListViewCell::setCheckable(bool checkable) -> void { -} - -auto pListViewCell::setChecked(bool checked) -> void { -} - -auto pListViewCell::setForegroundColor(Color color) -> void { -} - -auto pListViewCell::setIcon(const image& icon) -> void { -} - -auto pListViewCell::setText(const string& text) -> void { - @autoreleasepool { - if(auto pListView = _grandparent()) { - [[pListView->cocoaView content] reloadData]; - } - } -} - -auto pListViewCell::_grandparent() -> maybe { - if(auto parent = _parent()) return parent->_parent(); -} - -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/hiro/cocoa/widget/list-view-column.cpp b/hiro/cocoa/widget/list-view-column.cpp deleted file mode 100644 index a2016c14..00000000 --- a/hiro/cocoa/widget/list-view-column.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewColumn::construct() -> void { - @autoreleasepool { - if(auto listView = _grandparent()) { - [listView->cocoaView reloadColumns]; - } - } -} - -auto pListViewColumn::destruct() -> void { - @autoreleasepool { - if(auto listView = _grandparent()) { - [listView->cocoaView reloadColumns]; - } - } -} - -auto pListViewColumn::setActive() -> void { -} - -auto pListViewColumn::setAlignment(Alignment alignment) -> void { -} - -auto pListViewColumn::setBackgroundColor(Color color) -> void { -} - -auto pListViewColumn::setEditable(bool editable) -> void { -} - -auto pListViewColumn::setExpandable(bool expandable) -> void { -} - -auto pListViewColumn::setFont(const Font& font) -> void { -} - -auto pListViewColumn::setForegroundColor(Color color) -> void { -} - -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { -} - -auto pListViewColumn::setIcon(const image& icon) -> void { -} - -auto pListViewColumn::setResizable(bool resizable) -> void { -} - -auto pListViewColumn::setSortable(bool sortable) -> void { -} - -auto pListViewColumn::setText(const string& text) -> void { - @autoreleasepool { - if(auto pListView = _grandparent()) { - NSTableColumn* tableColumn = [[pListView->cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:self().offset()] stringValue]]; - [[tableColumn headerCell] setStringValue:[NSString stringWithUTF8STring:text]]; - [[pListView->cocoaView headerView] setNeedsDisplay:YES]; - } - } -} - -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { -} - -auto pListViewColumn::setVisible(bool visible) -> void { -} - -auto pListViewColumn::setWidth(signed width) -> void { -} - -auto pListViewColumn::_grandparent() -> maybe { - if(auto parent = _parent()) return parent->_parent(); - return nothing; -} - -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/hiro/cocoa/widget/list-view-header.cpp b/hiro/cocoa/widget/list-view-header.cpp deleted file mode 100644 index 2b2756a1..00000000 --- a/hiro/cocoa/widget/list-view-header.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewHeader::construct() -> void { -} - -auto pListViewHeader::destruct() -> void { -} - -auto pListViewHeader::append(sListViewColumn column) -> void { -} - -auto pListViewHeader::remove(sListViewColumn column) -> void { -} - -auto pListViewHeader::setVisible(bool visible) -> void { - @autoreleasepool { - if(auto pListView = _parent()) { - if(visible) { - [[pListView->cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]]; - } else { - [[pListView->cocoaView content] setHeaderView:nil]; - } - } - } -} - -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/hiro/cocoa/widget/list-view-header.hpp b/hiro/cocoa/widget/list-view-header.hpp deleted file mode 100644 index b2c1aa89..00000000 --- a/hiro/cocoa/widget/list-view-header.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; -}; - -} - -#endif diff --git a/hiro/cocoa/widget/list-view-item.cpp b/hiro/cocoa/widget/list-view-item.cpp deleted file mode 100644 index 0f043877..00000000 --- a/hiro/cocoa/widget/list-view-item.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewItem::construct() -> void { -} - -auto pListViewItem::destruct() -> void { -} - -auto pListViewItem::append(sListViewCell cell) -> void { - @autoreleasepool { - if(auto listView = _parent()) { - [[listView->cocoaView content] reloadData]; - } - } -} - -auto pListViewItem::remove(sListViewCell cell) -> void { - @autoreleasepool { - if(auto listView = _parent()) { - [[listView->cocoaView content] reloadData]; - } - } -} - -auto pListViewItem::setAlignment(Alignment alignment) -> void { -} - -auto pListViewItem::setBackgroundColor(Color color) -> void { -} - -auto pListViewItem::setFocused() -> void { -} - -auto pListViewItem::setForegroundColor(Color color) -> void { -} - -auto pListViewItem::setSelected(bool selected) -> void { -} - -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/hiro/cocoa/widget/table-view-cell.cpp b/hiro/cocoa/widget/table-view-cell.cpp new file mode 100644 index 00000000..2da1596a --- /dev/null +++ b/hiro/cocoa/widget/table-view-cell.cpp @@ -0,0 +1,50 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewCell::construct() -> void { +} + +auto pTableViewCell::destruct() -> void { +} + +auto pTableViewCell::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewCell::setBackgroundColor(Color color) -> void { +} + +auto pTableViewCell::setCheckable(bool checkable) -> void { +} + +auto pTableViewCell::setChecked(bool checked) -> void { +} + +auto pTableViewCell::setForegroundColor(Color color) -> void { +} + +auto pTableViewCell::setIcon(const image& icon) -> void { +} + +auto pTableViewCell::setText(const string& text) -> void { + @autoreleasepool { + if(auto pTableView = _grandparent()) { + [[pTableView->cocoaView content] reloadData]; + } + } +} + +auto pTableViewCell::_grandparent() -> maybe { + if(auto parent = _parent()) return parent->_parent(); +} + +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/hiro/cocoa/widget/list-view-cell.hpp b/hiro/cocoa/widget/table-view-cell.hpp similarity index 65% rename from hiro/cocoa/widget/list-view-cell.hpp rename to hiro/cocoa/widget/table-view-cell.hpp index 33b33f39..0843729a 100644 --- a/hiro/cocoa/widget/list-view-cell.hpp +++ b/hiro/cocoa/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -13,8 +13,8 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/hiro/cocoa/widget/table-view-column.cpp b/hiro/cocoa/widget/table-view-column.cpp new file mode 100644 index 00000000..94fc6a5d --- /dev/null +++ b/hiro/cocoa/widget/table-view-column.cpp @@ -0,0 +1,87 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewColumn::construct() -> void { + @autoreleasepool { + if(auto tableView = _grandparent()) { + [tableView->cocoaView reloadColumns]; + } + } +} + +auto pTableViewColumn::destruct() -> void { + @autoreleasepool { + if(auto tableView = _grandparent()) { + [tableView->cocoaView reloadColumns]; + } + } +} + +auto pTableViewColumn::setActive() -> void { +} + +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewColumn::setBackgroundColor(Color color) -> void { +} + +auto pTableViewColumn::setEditable(bool editable) -> void { +} + +auto pTableViewColumn::setExpandable(bool expandable) -> void { +} + +auto pTableViewColumn::setFont(const Font& font) -> void { +} + +auto pTableViewColumn::setForegroundColor(Color color) -> void { +} + +auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { +} + +auto pTableViewColumn::setIcon(const image& icon) -> void { +} + +auto pTableViewColumn::setResizable(bool resizable) -> void { +} + +auto pTableViewColumn::setSortable(bool sortable) -> void { +} + +auto pTableViewColumn::setText(const string& text) -> void { + @autoreleasepool { + if(auto pTableView = _grandparent()) { + NSTableColumn* tableColumn = [[pTableView->cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:self().offset()] stringValue]]; + [[tableColumn headerCell] setStringValue:[NSString stringWithUTF8STring:text]]; + [[pTableView->cocoaView headerView] setNeedsDisplay:YES]; + } + } +} + +auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { +} + +auto pTableViewColumn::setVisible(bool visible) -> void { +} + +auto pTableViewColumn::setWidth(signed width) -> void { +} + +auto pTableViewColumn::_grandparent() -> maybe { + if(auto parent = _parent()) return parent->_parent(); + return nothing; +} + +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/hiro/cocoa/widget/list-view-column.hpp b/hiro/cocoa/widget/table-view-column.hpp similarity index 78% rename from hiro/cocoa/widget/list-view-column.hpp rename to hiro/cocoa/widget/table-view-column.hpp index 59b45288..e75045a5 100644 --- a/hiro/cocoa/widget/list-view-column.hpp +++ b/hiro/cocoa/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -21,8 +21,8 @@ struct pListViewColumn : pObject { auto setVisible(bool visible) -> void override; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/hiro/cocoa/widget/table-view-header.cpp b/hiro/cocoa/widget/table-view-header.cpp new file mode 100644 index 00000000..72d9e99c --- /dev/null +++ b/hiro/cocoa/widget/table-view-header.cpp @@ -0,0 +1,38 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewHeader::construct() -> void { +} + +auto pTableViewHeader::destruct() -> void { +} + +auto pTableViewHeader::append(sTableViewColumn column) -> void { +} + +auto pTableViewHeader::remove(sTableViewColumn column) -> void { +} + +auto pTableViewHeader::setVisible(bool visible) -> void { + @autoreleasepool { + if(auto pTableView = _parent()) { + if(visible) { + [[pTableView->cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]]; + } else { + [[pTableView->cocoaView content] setHeaderView:nil]; + } + } + } +} + +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/hiro/cocoa/widget/table-view-header.hpp b/hiro/cocoa/widget/table-view-header.hpp new file mode 100644 index 00000000..7027afcb --- /dev/null +++ b/hiro/cocoa/widget/table-view-header.hpp @@ -0,0 +1,17 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; +}; + +} + +#endif diff --git a/hiro/cocoa/widget/table-view-item.cpp b/hiro/cocoa/widget/table-view-item.cpp new file mode 100644 index 00000000..d4191745 --- /dev/null +++ b/hiro/cocoa/widget/table-view-item.cpp @@ -0,0 +1,51 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewItem::construct() -> void { +} + +auto pTableViewItem::destruct() -> void { +} + +auto pTableViewItem::append(sTableViewCell cell) -> void { + @autoreleasepool { + if(auto tableView = _parent()) { + [[tableView->cocoaView content] reloadData]; + } + } +} + +auto pTableViewItem::remove(sTableViewCell cell) -> void { + @autoreleasepool { + if(auto tableView = _parent()) { + [[tableView->cocoaView content] reloadData]; + } + } +} + +auto pTableViewItem::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewItem::setBackgroundColor(Color color) -> void { +} + +auto pTableViewItem::setFocused() -> void { +} + +auto pTableViewItem::setForegroundColor(Color color) -> void { +} + +auto pTableViewItem::setSelected(bool selected) -> void { +} + +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +} + +#endif diff --git a/hiro/cocoa/widget/list-view-item.hpp b/hiro/cocoa/widget/table-view-item.hpp similarity index 53% rename from hiro/cocoa/widget/list-view-item.hpp rename to hiro/cocoa/widget/table-view-item.hpp index c95ff096..5b2051c5 100644 --- a/hiro/cocoa/widget/list-view-item.hpp +++ b/hiro/cocoa/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/hiro/cocoa/widget/list-view.cpp b/hiro/cocoa/widget/table-view.cpp similarity index 66% rename from hiro/cocoa/widget/list-view.cpp rename to hiro/cocoa/widget/table-view.cpp index 987f549b..0792c199 100644 --- a/hiro/cocoa/widget/list-view.cpp +++ b/hiro/cocoa/widget/table-view.cpp @@ -1,11 +1,11 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -@implementation CocoaListView : NSScrollView +@implementation CocoaTableView : NSScrollView --(id) initWith:(hiro::mListView&)listViewReference { +-(id) initWith:(hiro::mTableView&)tableViewReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { - listView = &listViewReference; - content = [[CocoaListViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; + tableView = &tableViewReference; + content = [[CocoaTableViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; [self setDocumentView:content]; [self setBorderType:NSBezelBorder]; @@ -34,7 +34,7 @@ [super dealloc]; } --(CocoaListViewContent*) content { +-(CocoaTableViewContent*) content { return content; } @@ -59,13 +59,13 @@ [content removeTableColumn:[[content tableColumns] lastObject]]; } - if(auto listViewHeader = listView->state.header) { - for(auto& listViewColumn : listViewHeader->state.columns) { - auto column = listViewColumn->offset(); + if(auto tableViewHeader = tableView->state.header) { + for(auto& tableViewColumn : tableViewHeader->state.columns) { + auto column = tableViewColumn->offset(); NSTableColumn* tableColumn = [[NSTableColumn alloc] initWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; - NSTableHeaderCell* headerCell = [[NSTableHeaderCell alloc] initTextCell:[NSString stringWithUTF8String:listViewColumn->state.text]]; - CocoaListViewCell* dataCell = [[CocoaListViewCell alloc] initWith:*listView]; + NSTableHeaderCell* headerCell = [[NSTableHeaderCell alloc] initTextCell:[NSString stringWithUTF8String:tableViewColumn->state.text]]; + CocoaTableViewCell* dataCell = [[CocoaTableViewCell alloc] initWith:*tableView]; [dataCell setEditable:NO]; @@ -79,13 +79,13 @@ } -(NSInteger) numberOfRowsInTableView:(NSTableView*)table { - return listView->state.items.size(); + return tableView->state.items.size(); } -(id) tableView:(NSTableView*)table objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { - if(auto listViewItem = listView->item(row)) { - if(auto listViewCell = listViewItem->cell([[tableColumn identifier] integerValue])) { - NSString* text = [NSString stringWithUTF8String:listViewCell->state.text]; + if(auto tableViewItem = tableView->item(row)) { + if(auto tableViewCell = tableViewItem->cell([[tableColumn identifier] integerValue])) { + NSString* text = [NSString stringWithUTF8String:tableViewCell->state.text]; return @{ @"text":text }; //used by type-ahead } } @@ -105,14 +105,14 @@ } -(void) tableViewSelectionDidChange:(NSNotification*)notification { - for(auto& listViewItem : listView->state.items) { - listViewItem->state.selected = listViewItem->offset() == [content selectedRow]; + for(auto& tableViewItem : tableView->state.items) { + tableViewItem->state.selected = tableViewItem->offset() == [content selectedRow]; } - listView->doChange(); + tableView->doChange(); } -(IBAction) activate:(id)sender { - listView->doActivate(); + tableView->doActivate(); } -(IBAction) doubleAction:(id)sender { @@ -123,7 +123,7 @@ @end -@implementation CocoaListViewContent : NSTableView +@implementation CocoaTableViewContent : NSTableView -(void) keyDown:(NSEvent*)event { auto character = [[event characters] characterAtIndex:0]; @@ -139,11 +139,11 @@ @end -@implementation CocoaListViewCell : NSCell +@implementation CocoaTableViewCell : NSCell --(id) initWith:(hiro::mListView&)listViewReference { +-(id) initWith:(hiro::mTableView&)tableViewReference { if(self = [super initTextCell:@""]) { - listView = &listViewReference; + tableView = &tableViewReference; buttonCell = [[NSButtonCell alloc] initTextCell:@""]; [buttonCell setButtonType:NSSwitchButton]; [buttonCell setControlSize:NSSmallControlSize]; @@ -159,27 +159,27 @@ } -(void) drawWithFrame:(NSRect)frame inView:(NSView*)view { - if(auto listViewItem = listView->item([view rowAtPoint:frame.origin])) { - if(auto listViewCell = listViewItem->cell([view columnAtPoint:frame.origin])) { + if(auto tableViewItem = tableView->item([view rowAtPoint:frame.origin])) { + if(auto tableViewCell = tableViewItem->cell([view columnAtPoint:frame.origin])) { NSColor* backgroundColor = nil; if([self isHighlighted]) backgroundColor = [NSColor alternateSelectedControlColor]; - else if(!listView->enabled(true)) backgroundColor = [NSColor controlBackgroundColor]; - else if(auto color = listViewCell->state.backgroundColor) backgroundColor = NSMakeColor(color); + else if(!tableView->enabled(true)) backgroundColor = [NSColor controlBackgroundColor]; + else if(auto color = tableViewCell->state.backgroundColor) backgroundColor = NSMakeColor(color); else backgroundColor = [NSColor controlBackgroundColor]; [backgroundColor set]; [NSBezierPath fillRect:frame]; - if(listViewCell->state.checkable) { + if(tableViewCell->state.checkable) { [buttonCell setHighlighted:YES]; - [buttonCell setState:(listViewCell->state.checked ? NSOnState : NSOffState)]; + [buttonCell setState:(tableViewCell->state.checked ? NSOnState : NSOffState)]; [buttonCell drawWithFrame:frame inView:view]; frame.origin.x += frame.size.height + 2; frame.size.width -= frame.size.height + 2; } - if(listViewCell->state.icon) { - NSImage* image = NSMakeImage(listViewCell->state.icon, frame.size.height, frame.size.height); + if(tableViewCell->state.icon) { + NSImage* image = NSMakeImage(tableViewCell->state.icon, frame.size.height, frame.size.height); [[NSGraphicsContext currentContext] saveGraphicsState]; NSRect targetRect = NSMakeRect(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height); NSRect sourceRect = NSMakeRect(0, 0, [image size].width, [image size].height); @@ -189,21 +189,21 @@ frame.size.width -= frame.size.height + 2; } - if(listViewCell->state.text) { + if(tableViewCell->state.text) { NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.alignment = NSTextAlignmentCenter; - if(listViewCell->state.alignment.horizontal() < 0.333) paragraphStyle.alignment = NSTextAlignmentLeft; - if(listViewCell->state.alignment.horizontal() > 0.666) paragraphStyle.alignment = NSTextAlignmentRight; + if(tableViewCell->state.alignment.horizontal() < 0.333) paragraphStyle.alignment = NSTextAlignmentLeft; + if(tableViewCell->state.alignment.horizontal() > 0.666) paragraphStyle.alignment = NSTextAlignmentRight; NSColor* foregroundColor = nil; if([self isHighlighted]) foregroundColor = [NSColor alternateSelectedControlTextColor]; - else if(!listView->enabled(true)) foregroundColor = [NSColor disabledControlTextColor]; - else if(auto color = listViewCell->state.foregroundColor) foregroundColor = NSMakeColor(color); + else if(!tableView->enabled(true)) foregroundColor = [NSColor disabledControlTextColor]; + else if(auto color = tableViewCell->state.foregroundColor) foregroundColor = NSMakeColor(color); else foregroundColor = [NSColor textColor]; - NSString* text = [NSString stringWithUTF8String:listViewCell->state.text]; + NSString* text = [NSString stringWithUTF8String:tableViewCell->state.text]; [text drawInRect:frame withAttributes:@{ NSBackgroundColorAttributeName:backgroundColor, NSForegroundColorAttributeName:foregroundColor, - NSFontAttributeName:hiro::pFont::create(listViewCell->font(true)), + NSFontAttributeName:hiro::pFont::create(tableViewCell->font(true)), NSParagraphStyleAttributeName:paragraphStyle }]; } @@ -233,10 +233,10 @@ NSPoint point = [view convertPointFromBase:[nextEvent locationInWindow]]; NSRect rect = NSMakeRect(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height); if(NSMouseInRect(point, rect, [view isFlipped])) { - if(auto listViewItem = listView->item([view rowAtPoint:point])) { - if(auto listViewCell = listViewItem->cell([view columnAtPoint:point])) { - listViewCell->state.checked = !listViewCell->state.checked; - listView->doToggle(listViewCell->instance); + if(auto tableViewItem = tableView->item([view rowAtPoint:point])) { + if(auto tableViewCell = tableViewItem->cell([view columnAtPoint:point])) { + tableViewCell->state.checked = !tableViewCell->state.checked; + tableView->doToggle(tableViewCell->instance); } } } @@ -255,9 +255,9 @@ namespace hiro { -auto pListView::construct() -> void { +auto pTableView::construct() -> void { @autoreleasepool { - cocoaView = cocoaListView = [[CocoaListView alloc] initWith:self()]; + cocoaView = cocoaTableView = [[CocoaTableView alloc] initWith:self()]; pWidget::construct(); setAlignment(state().alignment); @@ -269,14 +269,14 @@ auto pListView::construct() -> void { } } -auto pListView::destruct() -> void { +auto pTableView::destruct() -> void { @autoreleasepool { [cocoaView removeFromSuperview]; [cocoaView release]; } } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { @autoreleasepool { [cocoaView reloadColumns]; @@ -284,25 +284,25 @@ auto pListView::append(sListViewHeader header) -> void { } } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { @autoreleasepool { [[cocoaView content] reloadData]; } } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { @autoreleasepool { [cocoaView reloadColumns]; } } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { @autoreleasepool { [[cocoaView content] reloadData]; } } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { @autoreleasepool { if(auto& header = state().header) { vector widths; @@ -333,71 +333,71 @@ auto pListView::resizeColumns() -> void { } } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { @autoreleasepool { [[cocoaView content] setAllowsMultipleSelection:(batchable ? YES : NO)]; } } -auto pListView::setBordered(bool bordered) -> void { +auto pTableView::setBordered(bool bordered) -> void { } -auto pListView::setEnabled(bool enabled) -> void { +auto pTableView::setEnabled(bool enabled) -> void { pWidget::setEnabled(enabled); @autoreleasepool { [[cocoaView content] setEnabled:enabled]; } } -auto pListView::setFont(const Font& font) -> void { +auto pTableView::setFont(const Font& font) -> void { @autoreleasepool { [cocoaView setFont:pFont::create(font)]; } } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { } -auto pListView::_cellWidth(uint row, uint column) -> uint { +auto pTableView::_cellWidth(uint row, uint column) -> uint { uint width = 8; - if(auto pListViewItem = self().item(row)) { - if(auto pListViewCell = pListViewItem->cell(column)) { - if(pListViewCell->state.checkable) { + if(auto pTableViewItem = self().item(row)) { + if(auto pTableViewCell = pTableViewItem->cell(column)) { + if(pTableViewCell->state.checkable) { width += 24; } - if(auto& icon = pListViewCell->state.icon) { + if(auto& icon = pTableViewCell->state.icon) { width += icon.width() + 2; } - if(auto& text = pListViewCell->state.text) { - width += pFont::size(pListViewCell->font(true), text).width(); + if(auto& text = pTableViewCell->state.text) { + width += pFont::size(pTableViewCell->font(true), text).width(); } } } return width; } -auto pListView::_columnWidth(uint column) -> uint { +auto pTableView::_columnWidth(uint column) -> uint { uint width = 8; if(auto& header = state().header) { - if(auto pListViewColumn = header->column(column)) { - if(auto& icon = pListViewColumn->state.icon) { + if(auto pTableViewColumn = header->column(column)) { + if(auto& icon = pTableViewColumn->state.icon) { width += icon.width() + 2; } - if(auto& text = pListViewColumn->state.text) { - width += pFont::size(pListViewColumn->font(true), text).width(); + if(auto& text = pTableViewColumn->state.text) { + width += pFont::size(pTableViewColumn->font(true), text).width(); } } } return width; } -auto pListView::_width(uint column) -> uint { +auto pTableView::_width(uint column) -> uint { if(auto& header = state().header) { if(auto width = header->column(column).width()) return width; uint width = 1; @@ -412,20 +412,20 @@ auto pListView::_width(uint column) -> uint { } /* -auto pListView::autoSizeColumns() -> void { +auto pTableView::autoSizeColumns() -> void { @autoreleasepool { - if(listView.state.checkable) { + if(tableView.state.checkable) { NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:@"check"]; [tableColumn setWidth:20.0]; } unsigned height = [[cocoaView content] rowHeight]; - for(unsigned column = 0; column < max(1u, listView.state.headerText.size()); column++) { + for(unsigned column = 0; column < max(1u, tableView.state.headerText.size()); column++) { NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; - unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], listView.state.headerText(column)).width + 4; - for(unsigned row = 0; row < listView.state.text.size(); row++) { - unsigned width = pFont::size([cocoaView font], listView.state.text(row)(column)).width + 2; - if(listView.state.image(row)(height).empty() == false) width += height + 2; + unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], tableView.state.headerText(column)).width + 4; + for(unsigned row = 0; row < tableView.state.text.size(); row++) { + unsigned width = pFont::size([cocoaView font], tableView.state.text(row)(column)).width + 2; + if(tableView.state.image(row)(height).empty() == false) width += height + 2; if(width > minimumWidth) minimumWidth = width; } [tableColumn setWidth:minimumWidth]; @@ -435,7 +435,7 @@ auto pListView::autoSizeColumns() -> void { } } -auto pListView::setSelected(bool selected) -> void { +auto pTableView::setSelected(bool selected) -> void { @autoreleasepool { if(selected == false) { [[cocoaView content] deselectAll:nil]; @@ -443,7 +443,7 @@ auto pListView::setSelected(bool selected) -> void { } } -auto pListView::setSelection(unsigned selection) -> void { +auto pTableView::setSelection(unsigned selection) -> void { @autoreleasepool { [[cocoaView content] selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(selection, 1)] byExtendingSelection:NO]; } diff --git a/hiro/cocoa/widget/list-view.hpp b/hiro/cocoa/widget/table-view.hpp similarity index 70% rename from hiro/cocoa/widget/list-view.hpp rename to hiro/cocoa/widget/table-view.hpp index e1f3fbac..548587e3 100644 --- a/hiro/cocoa/widget/list-view.hpp +++ b/hiro/cocoa/widget/table-view.hpp @@ -1,16 +1,16 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -@class CocoaListViewContent; +@class CocoaTableViewContent; -@interface CocoaListView : NSScrollView { +@interface CocoaTableView : NSScrollView { @public - hiro::mListView* listView; - CocoaListViewContent* content; + hiro::mTableView* tableView; + CocoaTableViewContent* content; NSFont* font; } --(id) initWith:(hiro::mListView&)listView; +-(id) initWith:(hiro::mTableView&)tableView; -(void) dealloc; --(CocoaListViewContent*) content; +-(CocoaTableViewContent*) content; -(NSFont*) font; -(void) setFont:(NSFont*)font; -(void) reloadColumns; @@ -24,16 +24,16 @@ -(IBAction) doubleAction:(id)sender; @end -@interface CocoaListViewContent : NSTableView { +@interface CocoaTableViewContent : NSTableView { } -(void) keyDown:(NSEvent*)event; @end -@interface CocoaListViewCell : NSCell { - hiro::mListView* listView; +@interface CocoaTableViewCell : NSCell { + hiro::mTableView* tableView; NSButtonCell* buttonCell; } --(id) initWith:(hiro::mListView&)listViewReference; +-(id) initWith:(hiro::mTableView&)tableViewReference; -(NSString*) stringValue; -(void) drawWithFrame:(NSRect)frame inView:(NSView*)view; -(NSUInteger) hitTestForEvent:(NSEvent*)event inRect:(NSRect)frame ofView:(NSView*)view; @@ -43,13 +43,13 @@ namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader header) -> void; - auto append(sListViewItem item) -> void; - auto remove(sListViewHeader header) -> void; - auto remove(sListViewItem item) -> void; + auto append(sTableViewHeader header) -> void; + auto append(sTableViewItem item) -> void; + auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -63,7 +63,7 @@ struct pListView : pWidget { auto _columnWidth(uint column) -> uint; auto _width(uint column) -> uint; - CocoaListView* cocoaListView = nullptr; + CocoaTableView* cocoaTableView = nullptr; }; } diff --git a/hiro/cocoa/widget/viewport.cpp b/hiro/cocoa/widget/viewport.cpp index c03202d3..52fcf14d 100644 --- a/hiro/cocoa/widget/viewport.cpp +++ b/hiro/cocoa/widget/viewport.cpp @@ -24,7 +24,7 @@ -(BOOL) performDragOperation:(id)sender { lstring paths = DropPaths(sender); - if(paths.empty()) return NO; + if(!paths) return NO; viewport->doDrop(paths); return YES; } diff --git a/hiro/cocoa/window.cpp b/hiro/cocoa/window.cpp index 0debae81..b87b00ac 100644 --- a/hiro/cocoa/window.cpp +++ b/hiro/cocoa/window.cpp @@ -122,7 +122,7 @@ -(BOOL) performDragOperation:(id)sender { lstring paths = DropPaths(sender); - if(paths.empty()) return NO; + if(!paths) return NO; window->doDrop(paths); return YES; } diff --git a/hiro/components.hpp b/hiro/components.hpp index cd48b86c..147f8376 100644 --- a/hiro/components.hpp +++ b/hiro/components.hpp @@ -62,12 +62,12 @@ #define Hiro_IconView #define Hiro_Label #define Hiro_LineEdit -#define Hiro_ListView #define Hiro_ProgressBar #define Hiro_RadioButton #define Hiro_RadioLabel #define Hiro_SourceEdit #define Hiro_TabFrame +#define Hiro_TableView #define Hiro_TextEdit #define Hiro_TreeView #define Hiro_VerticalScrollBar @@ -89,10 +89,14 @@ #undef Hiro_HexEdit #endif +#if defined(Hiro_TableView) + #define Hiro_ListView +#endif + #if defined(Hiro_Button) && defined(Hiro_Canvas) && defined(Hiro_Label) #define Hiro_MessageDialog #endif -#if defined(Hiro_Button) && defined(Hiro_ComboButton) && defined(Hiro_LineEdit) && defined(Hiro_ListView) && defined(Hiro_MessageDialog) +#if defined(Hiro_Button) && defined(Hiro_ComboButton) && defined(Hiro_LineEdit) && defined(Hiro_TableView) && defined(Hiro_MessageDialog) #define Hiro_BrowserDialog #endif diff --git a/hiro/core/core.cpp b/hiro/core/core.cpp index d6fd5e17..2946f9a7 100644 --- a/hiro/core/core.cpp +++ b/hiro/core/core.cpp @@ -86,17 +86,17 @@ namespace hiro { #include "widget/icon-view-item.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" - #include "widget/list-view.cpp" - #include "widget/list-view-header.cpp" - #include "widget/list-view-column.cpp" - #include "widget/list-view-item.cpp" - #include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/source-edit.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" + #include "widget/table-view.cpp" + #include "widget/table-view-header.cpp" + #include "widget/table-view-column.cpp" + #include "widget/table-view-item.cpp" + #include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/tree-view.cpp" #include "widget/tree-view-item.cpp" diff --git a/hiro/core/core.hpp b/hiro/core/core.hpp index c33f9d59..9541c4d4 100644 --- a/hiro/core/core.hpp +++ b/hiro/core/core.hpp @@ -67,17 +67,17 @@ Declare(IconView) Declare(IconViewItem) Declare(Label) Declare(LineEdit) -Declare(ListView) -Declare(ListViewHeader) -Declare(ListViewColumn) -Declare(ListViewItem) -Declare(ListViewCell) Declare(ProgressBar) Declare(RadioButton) Declare(RadioLabel) Declare(SourceEdit) Declare(TabFrame) Declare(TabFrameItem) +Declare(TableView) +Declare(TableViewHeader) +Declare(TableViewColumn) +Declare(TableViewItem) +Declare(TableViewCell) Declare(TextEdit) Declare(TreeView) Declare(TreeViewItem) @@ -575,15 +575,15 @@ struct mObject { auto parentFrame(bool recursive = false) const -> mFrame*; auto parentIconView(bool recursive = false) const -> mIconView*; auto parentLayout(bool recursive = false) const -> mLayout*; - auto parentListView(bool recursive = false) const -> mListView*; - auto parentListViewHeader(bool recursive = false) const -> mListViewHeader*; - auto parentListViewItem(bool recursive = false) const -> mListViewItem*; auto parentMenu(bool recursive = false) const -> mMenu*; auto parentMenuBar(bool recursive = false) const -> mMenuBar*; auto parentPopupMenu(bool recursive = false) const -> mPopupMenu*; auto parentSizable(bool recursive = false) const -> mSizable*; auto parentTabFrame(bool recursive = false) const -> mTabFrame*; auto parentTabFrameItem(bool recursive = false) const -> mTabFrameItem*; + auto parentTableView(bool recursive = false) const -> mTableView*; + auto parentTableViewHeader(bool recursive = false) const -> mTableViewHeader*; + auto parentTableViewItem(bool recursive = false) const -> mTableViewItem*; auto parentTreeView(bool recursive = false) const -> mTreeView*; auto parentTreeViewItem(bool recursive = false) const -> mTreeViewItem*; auto parentWidget(bool recursive = false) const -> mWidget*; @@ -1356,205 +1356,6 @@ struct mLineEdit : mWidget { }; #endif -#if defined(Hiro_ListView) -struct mListView : mWidget { - Declare(ListView) - using mObject::remove; - - auto alignment() const -> Alignment; - auto append(sListViewHeader column) -> type&; - auto append(sListViewItem item) -> type&; - auto backgroundColor() const -> Color; - auto batchable() const -> bool; - auto batched() const -> vector; - auto bordered() const -> bool; - auto doActivate() const -> void; - auto doChange() const -> void; - auto doContext() const -> void; - auto doEdit(sListViewCell cell) const -> void; - auto doSort(sListViewColumn column) const -> void; - auto doToggle(sListViewCell cell) const -> void; - auto foregroundColor() const -> Color; - auto header() const -> ListViewHeader; - auto item(unsigned position) const -> ListViewItem; - auto itemCount() const -> unsigned; - auto items() const -> vector; - auto onActivate(const function& callback = {}) -> type&; - auto onChange(const function& callback = {}) -> type&; - auto onContext(const function& callback = {}) -> type&; - auto onEdit(const function& callback = {}) -> type&; - auto onSort(const function& callback = {}) -> type&; - auto onToggle(const function& callback = {}) -> type&; - auto remove(sListViewHeader column) -> type&; - auto remove(sListViewItem item) -> type&; - auto reset() -> type&; - auto resizeColumns() -> type&; - auto selected() const -> ListViewItem; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setBatchable(bool batchable = true) -> type&; - auto setBordered(bool bordered = true) -> type&; - auto setForegroundColor(Color color = {}) -> type&; - auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - -//private: - struct State { - unsigned activeColumn = 0; - Alignment alignment; - Color backgroundColor; - bool batchable = false; - bool bordered = false; - Color foregroundColor; - sListViewHeader header; - vector items; - function onActivate; - function onChange; - function onContext; - function onEdit; - function onSort; - function onToggle; - } state; - - auto destruct() -> void override; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewHeader : mObject { - Declare(ListViewHeader) - - auto append(sListViewColumn column) -> type&; - auto column(unsigned position) const -> ListViewColumn; - auto columnCount() const -> unsigned; - auto columns() const -> vector; - auto remove() -> type& override; - auto remove(sListViewColumn column) -> type&; - auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - -//private: - struct State { - vector columns; - } state; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewColumn : mObject { - Declare(ListViewColumn) - - auto active() const -> bool; - auto alignment() const -> Alignment; - auto backgroundColor() const -> Color; - auto editable() const -> bool; - auto expandable() const -> bool; - auto foregroundColor() const -> Color; - auto horizontalAlignment() const -> double; - auto icon() const -> image; - auto remove() -> type& override; - auto resizable() const -> bool; - auto setActive() -> type&; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setEditable(bool editable = true) -> type&; - auto setExpandable(bool expandable = true) -> type&; - auto setForegroundColor(Color color = {}) -> type&; - auto setHorizontalAlignment(double alignment = 0.0) -> type&; - auto setIcon(const image& icon = {}) -> type&; - auto setResizable(bool resizable = true) -> type&; - auto setSortable(bool sortable = true) -> type&; - auto setText(const string& text = "") -> type&; - auto setVerticalAlignment(double alignment = 0.5) -> type&; - auto setVisible(bool visible = true) -> type&; - auto setWidth(signed width = 0) -> type&; - auto sortable() const -> bool; - auto text() const -> string; - auto verticalAlignment() const -> double; - auto width() const -> signed; - -//private: - struct State { - Alignment alignment; - Color backgroundColor; - bool editable = false; - bool expandable = false; - Color foregroundColor; - double horizontalAlignment = 0.0; - image icon; - bool resizable = true; - bool sortable = false; - string text; - double verticalAlignment = 0.5; - bool visible = true; - signed width = 0; - } state; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewItem : mObject { - Declare(ListViewItem) - - auto alignment() const -> Alignment; - auto append(sListViewCell cell) -> type&; - auto backgroundColor() const -> Color; - auto cell(unsigned position) const -> ListViewCell; - auto cellCount() const -> unsigned; - auto cells() const -> vector; - auto foregroundColor() const -> Color; - auto remove() -> type& override; - auto remove(sListViewCell cell) -> type&; - auto selected() const -> bool; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setFocused() -> type& override; - auto setForegroundColor(Color color = {}) -> type&; - auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; - auto setSelected(bool selected = true) -> type&; - -//private: - struct State { - Alignment alignment; - Color backgroundColor; - vector cells; - Color foregroundColor; - bool selected = false; - } state; -}; -#endif - -#if defined(Hiro_ListView) -struct mListViewCell : mObject { - Declare(ListViewCell) - - auto alignment(bool recursive = false) const -> Alignment; - auto backgroundColor(bool recursive = false) const -> Color; - auto checkable() const -> bool; - auto checked() const -> bool; - auto font(bool recursive = false) const -> Font; - auto foregroundColor(bool recursive = false) const -> Color; - auto icon() const -> image; - auto setAlignment(Alignment alignment = {}) -> type&; - auto setBackgroundColor(Color color = {}) -> type&; - auto setCheckable(bool checkable = true) -> type&; - auto setChecked(bool checked = true) -> type&; - auto setForegroundColor(Color color = {}) -> type&; - auto setIcon(const image& icon = {}) -> type&; - auto setText(const string& text = "") -> type&; - auto text() const -> string; - -//private: - struct State { - Alignment alignment; - Color backgroundColor; - bool checkable = false; - bool checked = false; - Color foregroundColor; - image icon; - string text; - } state; -}; -#endif - #if defined(Hiro_ProgressBar) struct mProgressBar : mWidget { Declare(ProgressBar) @@ -1718,6 +1519,207 @@ struct mTabFrameItem : mObject { }; #endif +#if defined(Hiro_TableView) +struct mTableView : mWidget { + Declare(TableView) + using mObject::remove; + + auto alignment() const -> Alignment; + auto append(sTableViewHeader column) -> type&; + auto append(sTableViewItem item) -> type&; + auto backgroundColor() const -> Color; + auto batchable() const -> bool; + auto batched() const -> vector; + auto bordered() const -> bool; + auto doActivate() const -> void; + auto doChange() const -> void; + auto doContext() const -> void; + auto doEdit(sTableViewCell cell) const -> void; + auto doSort(sTableViewColumn column) const -> void; + auto doToggle(sTableViewCell cell) const -> void; + auto foregroundColor() const -> Color; + auto header() const -> TableViewHeader; + auto item(unsigned position) const -> TableViewItem; + auto itemCount() const -> unsigned; + auto items() const -> vector; + auto onActivate(const function& callback = {}) -> type&; + auto onChange(const function& callback = {}) -> type&; + auto onContext(const function& callback = {}) -> type&; + auto onEdit(const function& callback = {}) -> type&; + auto onSort(const function& callback = {}) -> type&; + auto onToggle(const function& callback = {}) -> type&; + auto remove(sTableViewHeader column) -> type&; + auto remove(sTableViewItem item) -> type&; + auto reset() -> type&; + auto resizeColumns() -> type&; + auto selected() const -> TableViewItem; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setBatchable(bool batchable = true) -> type&; + auto setBordered(bool bordered = true) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; + +//private: + struct State { + unsigned activeColumn = 0; + Alignment alignment; + Color backgroundColor; + bool batchable = false; + bool bordered = false; + Color foregroundColor; + sTableViewHeader header; + vector items; + function onActivate; + function onChange; + function onContext; + function onEdit; + function onSort; + function onToggle; + } state; + + auto destruct() -> void override; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewHeader : mObject { + Declare(TableViewHeader) + + auto append(sTableViewColumn column) -> type&; + auto column(unsigned position) const -> TableViewColumn; + auto columnCount() const -> unsigned; + auto columns() const -> vector; + auto remove() -> type& override; + auto remove(sTableViewColumn column) -> type&; + auto reset() -> type&; + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; + +//private: + struct State { + vector columns; + } state; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewColumn : mObject { + Declare(TableViewColumn) + + auto active() const -> bool; + auto alignment() const -> Alignment; + auto backgroundColor() const -> Color; + auto editable() const -> bool; + auto expandable() const -> bool; + auto foregroundColor() const -> Color; + auto horizontalAlignment() const -> double; + auto icon() const -> image; + auto remove() -> type& override; + auto resizable() const -> bool; + auto setActive() -> type&; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setEditable(bool editable = true) -> type&; + auto setExpandable(bool expandable = true) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setHorizontalAlignment(double alignment = 0.0) -> type&; + auto setIcon(const image& icon = {}) -> type&; + auto setResizable(bool resizable = true) -> type&; + auto setSortable(bool sortable = true) -> type&; + auto setText(const string& text = "") -> type&; + auto setVerticalAlignment(double alignment = 0.5) -> type&; + auto setVisible(bool visible = true) -> type&; + auto setWidth(signed width = 0) -> type&; + auto sortable() const -> bool; + auto text() const -> string; + auto verticalAlignment() const -> double; + auto width() const -> signed; + +//private: + struct State { + Alignment alignment; + Color backgroundColor; + bool editable = false; + bool expandable = false; + Color foregroundColor; + double horizontalAlignment = 0.0; + image icon; + bool resizable = true; + bool sortable = false; + string text; + double verticalAlignment = 0.5; + bool visible = true; + signed width = 0; + } state; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewItem : mObject { + Declare(TableViewItem) + + auto alignment() const -> Alignment; + auto append(sTableViewCell cell) -> type&; + auto backgroundColor() const -> Color; + auto cell(unsigned position) const -> TableViewCell; + auto cellCount() const -> unsigned; + auto cells() const -> vector; + auto foregroundColor() const -> Color; + auto remove() -> type& override; + auto remove(sTableViewCell cell) -> type&; + auto reset() -> type&; + auto selected() const -> bool; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setFocused() -> type& override; + auto setForegroundColor(Color color = {}) -> type&; + auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; + auto setSelected(bool selected = true) -> type&; + +//private: + struct State { + Alignment alignment; + Color backgroundColor; + vector cells; + Color foregroundColor; + bool selected = false; + } state; +}; +#endif + +#if defined(Hiro_TableView) +struct mTableViewCell : mObject { + Declare(TableViewCell) + + auto alignment(bool recursive = false) const -> Alignment; + auto backgroundColor(bool recursive = false) const -> Color; + auto checkable() const -> bool; + auto checked() const -> bool; + auto font(bool recursive = false) const -> Font; + auto foregroundColor(bool recursive = false) const -> Color; + auto icon() const -> image; + auto setAlignment(Alignment alignment = {}) -> type&; + auto setBackgroundColor(Color color = {}) -> type&; + auto setCheckable(bool checkable = true) -> type&; + auto setChecked(bool checked = true) -> type&; + auto setForegroundColor(Color color = {}) -> type&; + auto setIcon(const image& icon = {}) -> type&; + auto setText(const string& text = "") -> type&; + auto text() const -> string; + +//private: + struct State { + Alignment alignment; + Color backgroundColor; + bool checkable = false; + bool checked = false; + Color foregroundColor; + image icon; + string text; + } state; +}; +#endif + #if defined(Hiro_TextEdit) struct mTextEdit : mWidget { Declare(TextEdit) diff --git a/hiro/core/object.cpp b/hiro/core/object.cpp index 810e9e0b..f92d4cbc 100644 --- a/hiro/core/object.cpp +++ b/hiro/core/object.cpp @@ -130,36 +130,6 @@ auto mObject::parentLayout(bool recursive) const -> mLayout* { } #endif -#if defined(Hiro_ListView) -auto mObject::parentListView(bool recursive) const -> mListView* { - if(auto listView = dynamic_cast(parent())) return listView; - if(recursive) { - if(auto object = parent()) return object->parentListView(true); - } - return nullptr; -} -#endif - -#if defined(Hiro_ListView) -auto mObject::parentListViewHeader(bool recursive) const -> mListViewHeader* { - if(auto listViewHeader = dynamic_cast(parent())) return listViewHeader; - if(recursive) { - if(auto object = parent()) return object->parentListViewHeader(true); - } - return nullptr; -} -#endif - -#if defined(Hiro_ListView) -auto mObject::parentListViewItem(bool recursive) const -> mListViewItem* { - if(auto listViewItem = dynamic_cast(parent())) return listViewItem; - if(recursive) { - if(auto object = parent()) return object->parentListViewItem(true); - } - return nullptr; -} -#endif - #if defined(Hiro_Menu) auto mObject::parentMenu(bool recursive) const -> mMenu* { if(auto menu = dynamic_cast(parent())) return menu; @@ -220,6 +190,36 @@ auto mObject::parentTabFrameItem(bool recursive) const -> mTabFrameItem* { } #endif +#if defined(Hiro_TableView) +auto mObject::parentTableView(bool recursive) const -> mTableView* { + if(auto tableView = dynamic_cast(parent())) return tableView; + if(recursive) { + if(auto object = parent()) return object->parentTableView(true); + } + return nullptr; +} +#endif + +#if defined(Hiro_TableView) +auto mObject::parentTableViewHeader(bool recursive) const -> mTableViewHeader* { + if(auto tableViewHeader = dynamic_cast(parent())) return tableViewHeader; + if(recursive) { + if(auto object = parent()) return object->parentTableViewHeader(true); + } + return nullptr; +} +#endif + +#if defined(Hiro_TableView) +auto mObject::parentTableViewItem(bool recursive) const -> mTableViewItem* { + if(auto tableViewItem = dynamic_cast(parent())) return tableViewItem; + if(recursive) { + if(auto object = parent()) return object->parentTableViewItem(true); + } + return nullptr; +} +#endif + #if defined(Hiro_TreeView) auto mObject::parentTreeView(bool recursive) const -> mTreeView* { if(auto treeView = dynamic_cast(parent())) return treeView; diff --git a/hiro/core/shared.hpp b/hiro/core/shared.hpp index 03762527..9030251e 100644 --- a/hiro/core/shared.hpp +++ b/hiro/core/shared.hpp @@ -485,136 +485,6 @@ struct LineEdit : sLineEdit { }; #endif -#if defined(Hiro_ListView) -struct ListViewColumn : sListViewColumn { - DeclareSharedObject(ListViewColumn) - using internalType = mListViewColumn; - - auto active() const { return self().active(); } - auto alignment() const { return self().alignment(); } - auto backgroundColor() const { return self().backgroundColor(); } - auto editable() const { return self().editable(); } - auto expandable() const { return self().expandable(); } - auto foregroundColor() const { return self().foregroundColor(); } - auto horizontalAlignment() const { return self().horizontalAlignment(); } - auto icon() const { return self().icon(); } - auto resizable() const { return self().resizable(); } - auto setActive() { return self().setActive(), *this; } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setEditable(bool editable = true) { return self().setEditable(editable), *this; } - auto setExpandable(bool expandable = true) { return self().setExpandable(expandable), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } - auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; } - auto setSortable(bool sortable = true) { return self().setSortable(sortable), *this; } - auto setText(const string& text = "") { return self().setText(text), *this; } - auto setWidth(signed width = 0) { return self().setWidth(width), *this; } - auto sortable() const { return self().sortable(); } - auto text() const { return self().text(); } - auto verticalAlignment() const { return self().verticalAlignment(); } - auto width() const { return self().width(); } -}; -#endif - -#if defined(Hiro_ListView) -struct ListViewHeader : sListViewHeader { - DeclareSharedObject(ListViewHeader) - using internalType = mListViewHeader; - - auto append(sListViewColumn column) { return self().append(column), *this; } - auto column(unsigned position) const { return self().column(position); } - auto columnCount() const { return self().columnCount(); } - auto columns() const { return self().columns(); } - auto remove(sListViewColumn column) { return self().remove(column), *this; } -}; -#endif - -#if defined(Hiro_ListView) -struct ListViewCell : sListViewCell { - DeclareSharedObject(ListViewCell) - using internalType = mListViewCell; - - auto alignment() const { return self().alignment(); } - auto backgroundColor() const { return self().backgroundColor(); } - auto checkable() const { return self().checkable(); } - auto checked() const { return self().checked(); } - auto foregroundColor() const { return self().foregroundColor(); } - auto icon() const { return self().icon(); } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setCheckable(bool checkable = true) const { return self().setCheckable(checkable), *this; } - auto setChecked(bool checked = true) const { return self().setChecked(checked), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } - auto setText(const string& text = "") { return self().setText(text), *this; } - auto text() const { return self().text(); } -}; -#endif - -#if defined(Hiro_ListView) -struct ListViewItem : sListViewItem { - DeclareSharedObject(ListViewItem) - using internalType = mListViewItem; - - auto alignment() const { return self().alignment(); } - auto append(sListViewCell cell) { return self().append(cell), *this; } - auto backgroundColor() const { return self().backgroundColor(); } - auto cell(unsigned position) const { return self().cell(position); } - auto cellCount() const { return self().cellCount(); } - auto cells() const { return self().cells(); } - auto foregroundColor() const { return self().foregroundColor(); } - auto remove(sListViewCell cell) { return self().remove(cell), *this; } - auto selected() const { return self().selected(); } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } - auto setSelected(bool selected = true) { return self().setSelected(selected), *this; } -}; -#endif - -#if defined(Hiro_ListView) -struct ListView : sListView { - DeclareSharedWidget(ListView) - using internalType = mListView; - - auto alignment() const { return self().alignment(); } - auto append(sListViewHeader header) { return self().append(header), *this; } - auto append(sListViewItem item) { return self().append(item), *this; } - auto backgroundColor() const { return self().backgroundColor(); } - auto batchable() const { return self().batchable(); } - auto batched() const { return self().batched(); } - auto bordered() const { return self().bordered(); } - auto doActivate() const { return self().doActivate(); } - auto doChange() const { return self().doChange(); } - auto doContext() const { return self().doContext(); } - auto doEdit(sListViewCell cell) const { return self().doEdit(cell); } - auto doSort(sListViewColumn column) const { return self().doSort(column); } - auto doToggle(sListViewCell cell) const { return self().doToggle(cell); } - auto foregroundColor() const { return self().foregroundColor(); } - auto header() const { return self().header(); } - auto item(unsigned position) const { return self().item(position); } - auto itemCount() const { return self().itemCount(); } - auto items() const { return self().items(); } - auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } - auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } - auto onContext(const function& callback = {}) { return self().onContext(callback), *this; } - auto onEdit(const function& callback = {}) { return self().onEdit(callback), *this; } - auto onSort(const function& callback = {}) { return self().onSort(callback), *this; } - auto onToggle(const function& callback = {}) { return self().onToggle(callback), *this; } - auto remove(sListViewHeader header) { return self().remove(header), *this; } - auto remove(sListViewItem item) { return self().remove(item), *this; } - auto reset() { return self().reset(), *this; } - auto resizeColumns() { return self().resizeColumns(), *this; } - auto selected() const { return self().selected(); } - auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } - auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } - auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; } - auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; } - auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } -}; -#endif - #if defined(Hiro_ProgressBar) struct ProgressBar : sProgressBar { DeclareSharedWidget(ProgressBar) @@ -722,6 +592,138 @@ struct TabFrame : sTabFrame { }; #endif +#if defined(Hiro_TableView) +struct TableViewColumn : sTableViewColumn { + DeclareSharedObject(TableViewColumn) + using internalType = mTableViewColumn; + + auto active() const { return self().active(); } + auto alignment() const { return self().alignment(); } + auto backgroundColor() const { return self().backgroundColor(); } + auto editable() const { return self().editable(); } + auto expandable() const { return self().expandable(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto horizontalAlignment() const { return self().horizontalAlignment(); } + auto icon() const { return self().icon(); } + auto resizable() const { return self().resizable(); } + auto setActive() { return self().setActive(), *this; } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setEditable(bool editable = true) { return self().setEditable(editable), *this; } + auto setExpandable(bool expandable = true) { return self().setExpandable(expandable), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; } + auto setSortable(bool sortable = true) { return self().setSortable(sortable), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto setWidth(signed width = 0) { return self().setWidth(width), *this; } + auto sortable() const { return self().sortable(); } + auto text() const { return self().text(); } + auto verticalAlignment() const { return self().verticalAlignment(); } + auto width() const { return self().width(); } +}; +#endif + +#if defined(Hiro_TableView) +struct TableViewHeader : sTableViewHeader { + DeclareSharedObject(TableViewHeader) + using internalType = mTableViewHeader; + + auto append(sTableViewColumn column) { return self().append(column), *this; } + auto column(unsigned position) const { return self().column(position); } + auto columnCount() const { return self().columnCount(); } + auto columns() const { return self().columns(); } + auto remove(sTableViewColumn column) { return self().remove(column), *this; } + auto reset() { return self().reset(), *this; } +}; +#endif + +#if defined(Hiro_TableView) +struct TableViewCell : sTableViewCell { + DeclareSharedObject(TableViewCell) + using internalType = mTableViewCell; + + auto alignment() const { return self().alignment(); } + auto backgroundColor() const { return self().backgroundColor(); } + auto checkable() const { return self().checkable(); } + auto checked() const { return self().checked(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto icon() const { return self().icon(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setCheckable(bool checkable = true) const { return self().setCheckable(checkable), *this; } + auto setChecked(bool checked = true) const { return self().setChecked(checked), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto text() const { return self().text(); } +}; +#endif + +#if defined(Hiro_TableView) +struct TableViewItem : sTableViewItem { + DeclareSharedObject(TableViewItem) + using internalType = mTableViewItem; + + auto alignment() const { return self().alignment(); } + auto append(sTableViewCell cell) { return self().append(cell), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto cell(unsigned position) const { return self().cell(position); } + auto cellCount() const { return self().cellCount(); } + auto cells() const { return self().cells(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto remove(sTableViewCell cell) { return self().remove(cell), *this; } + auto reset() { return self().reset(), *this; } + auto selected() const { return self().selected(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setSelected(bool selected = true) { return self().setSelected(selected), *this; } +}; +#endif + +#if defined(Hiro_TableView) +struct TableView : sTableView { + DeclareSharedWidget(TableView) + using internalType = mTableView; + + auto alignment() const { return self().alignment(); } + auto append(sTableViewHeader header) { return self().append(header), *this; } + auto append(sTableViewItem item) { return self().append(item), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto batchable() const { return self().batchable(); } + auto batched() const { return self().batched(); } + auto bordered() const { return self().bordered(); } + auto doActivate() const { return self().doActivate(); } + auto doChange() const { return self().doChange(); } + auto doContext() const { return self().doContext(); } + auto doEdit(sTableViewCell cell) const { return self().doEdit(cell); } + auto doSort(sTableViewColumn column) const { return self().doSort(column); } + auto doToggle(sTableViewCell cell) const { return self().doToggle(cell); } + auto foregroundColor() const { return self().foregroundColor(); } + auto header() const { return self().header(); } + auto item(unsigned position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } + auto items() const { return self().items(); } + auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } + auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } + auto onContext(const function& callback = {}) { return self().onContext(callback), *this; } + auto onEdit(const function& callback = {}) { return self().onEdit(callback), *this; } + auto onSort(const function& callback = {}) { return self().onSort(callback), *this; } + auto onToggle(const function& callback = {}) { return self().onToggle(callback), *this; } + auto remove(sTableViewHeader header) { return self().remove(header), *this; } + auto remove(sTableViewItem item) { return self().remove(item), *this; } + auto reset() { return self().reset(), *this; } + auto resizeColumns() { return self().resizeColumns(), *this; } + auto selected() const { return self().selected(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; } + auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } +}; +#endif + #if defined(Hiro_TextEdit) struct TextEdit : sTextEdit { DeclareSharedWidget(TextEdit) diff --git a/hiro/core/widget/list-view-column.cpp b/hiro/core/widget/list-view-column.cpp deleted file mode 100644 index e23e67df..00000000 --- a/hiro/core/widget/list-view-column.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#if defined(Hiro_ListView) - -auto mListViewColumn::allocate() -> pObject* { - return new pListViewColumn(*this); -} - -// - -auto mListViewColumn::active() const -> bool { - if(auto listView = parentListView()) return listView->state.activeColumn == offset(); - return false; -} - -auto mListViewColumn::alignment() const -> Alignment { - return state.alignment; -} - -auto mListViewColumn::backgroundColor() const -> Color { - return state.backgroundColor; -} - -auto mListViewColumn::editable() const -> bool { - return state.editable; -} - -auto mListViewColumn::expandable() const -> bool { - return state.expandable; -} - -auto mListViewColumn::foregroundColor() const -> Color { - return state.foregroundColor; -} - -auto mListViewColumn::horizontalAlignment() const -> double { - return state.horizontalAlignment; -} - -auto mListViewColumn::icon() const -> image { - return state.icon; -} - -auto mListViewColumn::remove() -> type& { - if(auto listView = parentListViewHeader()) listView->remove(*this); - return *this; -} - -auto mListViewColumn::resizable() const -> bool { - return state.resizable; -} - -auto mListViewColumn::setActive() -> type& { - if(auto listView = parentListView()) listView->state.activeColumn = offset(); - signal(setActive); - return *this; -} - -auto mListViewColumn::setAlignment(Alignment alignment) -> type& { - state.alignment = alignment; - signal(setAlignment, alignment); - return *this; -} - -auto mListViewColumn::setBackgroundColor(Color color) -> type& { - state.backgroundColor = color; - signal(setBackgroundColor, color); - return *this; -} - -auto mListViewColumn::setEditable(bool editable) -> type& { - state.editable = editable; - signal(setEditable, editable); - return *this; -} - -auto mListViewColumn::setExpandable(bool expandable) -> type& { - state.expandable = expandable; - signal(setExpandable, expandable); - return *this; -} - -auto mListViewColumn::setForegroundColor(Color color) -> type& { - state.foregroundColor = color; - signal(setForegroundColor, color); - return *this; -} - -auto mListViewColumn::setHorizontalAlignment(double alignment) -> type& { - alignment = max(0.0, min(1.0, alignment)); - state.horizontalAlignment = alignment; - signal(setHorizontalAlignment, alignment); - return *this; -} - -auto mListViewColumn::setIcon(const image& icon) -> type& { - state.icon = icon; - signal(setIcon, icon); - return *this; -} - -auto mListViewColumn::setResizable(bool resizable) -> type& { - state.resizable = resizable; - signal(setResizable, resizable); - return *this; -} - -auto mListViewColumn::setSortable(bool sortable) -> type& { - state.sortable = sortable; - signal(setSortable, sortable); - return *this; -} - -auto mListViewColumn::setText(const string& text) -> type& { - state.text = text; - signal(setText, text); - return *this; -} - -auto mListViewColumn::setVerticalAlignment(double alignment) -> type& { - alignment = max(0.0, min(1.0, alignment)); - state.verticalAlignment = alignment; - signal(setVerticalAlignment, alignment); - return *this; -} - -auto mListViewColumn::setVisible(bool visible) -> type& { - state.visible = visible; - signal(setVisible, visible); - return *this; -} - -auto mListViewColumn::setWidth(signed width) -> type& { - state.width = max(0, width); - signal(setWidth, width); - return *this; -} - -auto mListViewColumn::sortable() const -> bool { - return state.sortable; -} - -auto mListViewColumn::text() const -> string { - return state.text; -} - -auto mListViewColumn::verticalAlignment() const -> double { - return state.verticalAlignment; -} - -auto mListViewColumn::width() const -> signed { - return state.width; -} - -#endif diff --git a/hiro/core/widget/list-view-header.cpp b/hiro/core/widget/list-view-header.cpp deleted file mode 100644 index 9469ef37..00000000 --- a/hiro/core/widget/list-view-header.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#if defined(Hiro_ListView) - -auto mListViewHeader::allocate() -> pObject* { - return new pListViewHeader(*this); -} - -// - -auto mListViewHeader::append(sListViewColumn column) -> type& { - state.columns.append(column); - column->setParent(this, columnCount() - 1); - signal(append, column); - return *this; -} - -auto mListViewHeader::column(unsigned position) const -> ListViewColumn { - if(position < columnCount()) return state.columns[position]; - return {}; -} - -auto mListViewHeader::columnCount() const -> unsigned { - return state.columns.size(); -} - -auto mListViewHeader::columns() const -> vector { - vector columns; - for(auto& column : state.columns) columns.append(column); - return columns; -} - -auto mListViewHeader::remove() -> type& { - if(auto listView = parentListView()) listView->remove(*this); - return *this; -} - -auto mListViewHeader::remove(sListViewColumn column) -> type& { - signal(remove, column); - state.columns.remove(column->offset()); - for(auto n : range(column->offset(), columnCount())) { - state.columns[n]->adjustOffset(-1); - } - column->setParent(); - return *this; -} - -auto mListViewHeader::setParent(mObject* parent, signed offset) -> type& { - for(auto& column : state.columns) column->destruct(); - mObject::setParent(parent, offset); - for(auto& column : state.columns) column->setParent(this, column->offset()); - return *this; -} - -#endif diff --git a/hiro/core/widget/list-view-item.cpp b/hiro/core/widget/list-view-item.cpp deleted file mode 100644 index 4b9a0d3e..00000000 --- a/hiro/core/widget/list-view-item.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#if defined(Hiro_ListView) - -auto mListViewItem::allocate() -> pObject* { - return new pListViewItem(*this); -} - -// - -auto mListViewItem::alignment() const -> Alignment { - return state.alignment; -} - -auto mListViewItem::append(sListViewCell cell) -> type& { - state.cells.append(cell); - cell->setParent(this, cellCount() - 1); - signal(append, cell); - return *this; -} - -auto mListViewItem::backgroundColor() const -> Color { - return state.backgroundColor; -} - -auto mListViewItem::cell(unsigned position) const -> ListViewCell { - if(position < cellCount()) return state.cells[position]; - return {}; -} - -auto mListViewItem::cellCount() const -> unsigned { - return state.cells.size(); -} - -auto mListViewItem::cells() const -> vector { - vector cells; - for(auto& cell : state.cells) cells.append(cell); - return cells; -} - -auto mListViewItem::foregroundColor() const -> Color { - return state.foregroundColor; -} - -auto mListViewItem::remove() -> type& { - if(auto listView = parentListView()) listView->remove(*this); - return *this; -} - -auto mListViewItem::remove(sListViewCell cell) -> type& { - signal(remove, cell); - state.cells.remove(cell->offset()); - for(auto n : range(cell->offset(), cellCount())) { - state.cells[n]->adjustOffset(-1); - } - cell->setParent(); - return *this; -} - -auto mListViewItem::selected() const -> bool { - return state.selected; -} - -auto mListViewItem::setAlignment(Alignment alignment) -> type& { - state.alignment = alignment; - signal(setAlignment, alignment); - return *this; -} - -auto mListViewItem::setBackgroundColor(Color color) -> type& { - state.backgroundColor = color; - signal(setBackgroundColor, color); - return *this; -} - -auto mListViewItem::setFocused() -> type& { - signal(setFocused); - return *this; -} - -auto mListViewItem::setForegroundColor(Color color) -> type& { - state.foregroundColor = color; - signal(setForegroundColor, color); - return *this; -} - -auto mListViewItem::setParent(mObject* parent, signed offset) -> type& { - for(auto& cell : state.cells) cell->destruct(); - mObject::setParent(parent, offset); - for(auto& cell : state.cells) cell->setParent(this, cell->offset()); - return *this; -} - -auto mListViewItem::setSelected(bool selected) -> type& { - state.selected = selected; - signal(setSelected, selected); - return *this; -} - -#endif diff --git a/hiro/core/widget/list-view-cell.cpp b/hiro/core/widget/table-view-cell.cpp similarity index 66% rename from hiro/core/widget/list-view-cell.cpp rename to hiro/core/widget/table-view-cell.cpp index f9c4d01b..aee788f3 100644 --- a/hiro/core/widget/list-view-cell.cpp +++ b/hiro/core/widget/table-view-cell.cpp @@ -1,17 +1,17 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -auto mListViewCell::allocate() -> pObject* { - return new pListViewCell(*this); +auto mTableViewCell::allocate() -> pObject* { + return new pTableViewCell(*this); } // -auto mListViewCell::alignment(bool recursive) const -> Alignment { +auto mTableViewCell::alignment(bool recursive) const -> Alignment { if(auto alignment = state.alignment) return alignment; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto alignment = parent->state.alignment) return alignment; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -26,12 +26,12 @@ auto mListViewCell::alignment(bool recursive) const -> Alignment { return {}; } -auto mListViewCell::backgroundColor(bool recursive) const -> Color { +auto mTableViewCell::backgroundColor(bool recursive) const -> Color { if(auto color = state.backgroundColor) return color; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto color = parent->state.backgroundColor) return color; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -46,20 +46,20 @@ auto mListViewCell::backgroundColor(bool recursive) const -> Color { return {}; } -auto mListViewCell::checkable() const -> bool { +auto mTableViewCell::checkable() const -> bool { return state.checkable; } -auto mListViewCell::checked() const -> bool { +auto mTableViewCell::checked() const -> bool { return state.checkable && state.checked; } -auto mListViewCell::font(bool recursive) const -> Font { +auto mTableViewCell::font(bool recursive) const -> Font { if(auto font = mObject::font()) return font; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto font = parent->font()) return font; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -74,12 +74,12 @@ auto mListViewCell::font(bool recursive) const -> Font { return {}; } -auto mListViewCell::foregroundColor(bool recursive) const -> Color { +auto mTableViewCell::foregroundColor(bool recursive) const -> Color { if(auto color = state.foregroundColor) return color; if(recursive) { - if(auto parent = parentListViewItem()) { + if(auto parent = parentTableViewItem()) { if(auto color = parent->state.foregroundColor) return color; - if(auto grandparent = parent->parentListView()) { + if(auto grandparent = parent->parentTableView()) { if(auto header = grandparent->state.header) { if(offset() < header->columnCount()) { if(auto column = header->state.columns[offset()]) { @@ -94,54 +94,54 @@ auto mListViewCell::foregroundColor(bool recursive) const -> Color { return state.foregroundColor; } -auto mListViewCell::icon() const -> image { +auto mTableViewCell::icon() const -> image { return state.icon; } -auto mListViewCell::setAlignment(Alignment alignment) -> type& { +auto mTableViewCell::setAlignment(Alignment alignment) -> type& { state.alignment = alignment; signal(setAlignment, alignment); return *this; } -auto mListViewCell::setBackgroundColor(Color color) -> type& { +auto mTableViewCell::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); return *this; } -auto mListViewCell::setCheckable(bool checkable) -> type& { +auto mTableViewCell::setCheckable(bool checkable) -> type& { state.checkable = checkable; signal(setCheckable, checkable); return *this; } -auto mListViewCell::setChecked(bool checked) -> type& { +auto mTableViewCell::setChecked(bool checked) -> type& { setCheckable(true); state.checked = checked; signal(setChecked, checked); return *this; } -auto mListViewCell::setForegroundColor(Color color) -> type& { +auto mTableViewCell::setForegroundColor(Color color) -> type& { state.foregroundColor = color; signal(setForegroundColor, color); return *this; } -auto mListViewCell::setIcon(const image& icon) -> type& { +auto mTableViewCell::setIcon(const image& icon) -> type& { state.icon = icon; signal(setIcon, icon); return *this; } -auto mListViewCell::setText(const string& text) -> type& { +auto mTableViewCell::setText(const string& text) -> type& { state.text = text; signal(setText, text); return *this; } -auto mListViewCell::text() const -> string { +auto mTableViewCell::text() const -> string { return state.text; } diff --git a/hiro/core/widget/table-view-column.cpp b/hiro/core/widget/table-view-column.cpp new file mode 100644 index 00000000..cee2f8ad --- /dev/null +++ b/hiro/core/widget/table-view-column.cpp @@ -0,0 +1,153 @@ +#if defined(Hiro_TableView) + +auto mTableViewColumn::allocate() -> pObject* { + return new pTableViewColumn(*this); +} + +// + +auto mTableViewColumn::active() const -> bool { + if(auto tableView = parentTableView()) return tableView->state.activeColumn == offset(); + return false; +} + +auto mTableViewColumn::alignment() const -> Alignment { + return state.alignment; +} + +auto mTableViewColumn::backgroundColor() const -> Color { + return state.backgroundColor; +} + +auto mTableViewColumn::editable() const -> bool { + return state.editable; +} + +auto mTableViewColumn::expandable() const -> bool { + return state.expandable; +} + +auto mTableViewColumn::foregroundColor() const -> Color { + return state.foregroundColor; +} + +auto mTableViewColumn::horizontalAlignment() const -> double { + return state.horizontalAlignment; +} + +auto mTableViewColumn::icon() const -> image { + return state.icon; +} + +auto mTableViewColumn::remove() -> type& { + if(auto tableView = parentTableViewHeader()) tableView->remove(*this); + return *this; +} + +auto mTableViewColumn::resizable() const -> bool { + return state.resizable; +} + +auto mTableViewColumn::setActive() -> type& { + if(auto tableView = parentTableView()) tableView->state.activeColumn = offset(); + signal(setActive); + return *this; +} + +auto mTableViewColumn::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); + return *this; +} + +auto mTableViewColumn::setBackgroundColor(Color color) -> type& { + state.backgroundColor = color; + signal(setBackgroundColor, color); + return *this; +} + +auto mTableViewColumn::setEditable(bool editable) -> type& { + state.editable = editable; + signal(setEditable, editable); + return *this; +} + +auto mTableViewColumn::setExpandable(bool expandable) -> type& { + state.expandable = expandable; + signal(setExpandable, expandable); + return *this; +} + +auto mTableViewColumn::setForegroundColor(Color color) -> type& { + state.foregroundColor = color; + signal(setForegroundColor, color); + return *this; +} + +auto mTableViewColumn::setHorizontalAlignment(double alignment) -> type& { + alignment = max(0.0, min(1.0, alignment)); + state.horizontalAlignment = alignment; + signal(setHorizontalAlignment, alignment); + return *this; +} + +auto mTableViewColumn::setIcon(const image& icon) -> type& { + state.icon = icon; + signal(setIcon, icon); + return *this; +} + +auto mTableViewColumn::setResizable(bool resizable) -> type& { + state.resizable = resizable; + signal(setResizable, resizable); + return *this; +} + +auto mTableViewColumn::setSortable(bool sortable) -> type& { + state.sortable = sortable; + signal(setSortable, sortable); + return *this; +} + +auto mTableViewColumn::setText(const string& text) -> type& { + state.text = text; + signal(setText, text); + return *this; +} + +auto mTableViewColumn::setVerticalAlignment(double alignment) -> type& { + alignment = max(0.0, min(1.0, alignment)); + state.verticalAlignment = alignment; + signal(setVerticalAlignment, alignment); + return *this; +} + +auto mTableViewColumn::setVisible(bool visible) -> type& { + state.visible = visible; + signal(setVisible, visible); + return *this; +} + +auto mTableViewColumn::setWidth(signed width) -> type& { + state.width = max(0, width); + signal(setWidth, width); + return *this; +} + +auto mTableViewColumn::sortable() const -> bool { + return state.sortable; +} + +auto mTableViewColumn::text() const -> string { + return state.text; +} + +auto mTableViewColumn::verticalAlignment() const -> double { + return state.verticalAlignment; +} + +auto mTableViewColumn::width() const -> signed { + return state.width; +} + +#endif diff --git a/hiro/core/widget/table-view-header.cpp b/hiro/core/widget/table-view-header.cpp new file mode 100644 index 00000000..cfc0dded --- /dev/null +++ b/hiro/core/widget/table-view-header.cpp @@ -0,0 +1,58 @@ +#if defined(Hiro_TableView) + +auto mTableViewHeader::allocate() -> pObject* { + return new pTableViewHeader(*this); +} + +// + +auto mTableViewHeader::append(sTableViewColumn column) -> type& { + state.columns.append(column); + column->setParent(this, columnCount() - 1); + signal(append, column); + return *this; +} + +auto mTableViewHeader::column(unsigned position) const -> TableViewColumn { + if(position < columnCount()) return state.columns[position]; + return {}; +} + +auto mTableViewHeader::columnCount() const -> unsigned { + return state.columns.size(); +} + +auto mTableViewHeader::columns() const -> vector { + vector columns; + for(auto& column : state.columns) columns.append(column); + return columns; +} + +auto mTableViewHeader::remove() -> type& { + if(auto tableView = parentTableView()) tableView->remove(*this); + return *this; +} + +auto mTableViewHeader::remove(sTableViewColumn column) -> type& { + signal(remove, column); + state.columns.remove(column->offset()); + for(auto n : range(column->offset(), columnCount())) { + state.columns[n]->adjustOffset(-1); + } + column->setParent(); + return *this; +} + +auto mTableViewHeader::reset() -> type& { + for(auto n : rrange(state.columns)) remove(state.columns[n]); + return *this; +} + +auto mTableViewHeader::setParent(mObject* parent, signed offset) -> type& { + for(auto& column : state.columns) column->destruct(); + mObject::setParent(parent, offset); + for(auto& column : state.columns) column->setParent(this, column->offset()); + return *this; +} + +#endif diff --git a/hiro/core/widget/table-view-item.cpp b/hiro/core/widget/table-view-item.cpp new file mode 100644 index 00000000..2fc8e2a6 --- /dev/null +++ b/hiro/core/widget/table-view-item.cpp @@ -0,0 +1,103 @@ +#if defined(Hiro_TableView) + +auto mTableViewItem::allocate() -> pObject* { + return new pTableViewItem(*this); +} + +// + +auto mTableViewItem::alignment() const -> Alignment { + return state.alignment; +} + +auto mTableViewItem::append(sTableViewCell cell) -> type& { + state.cells.append(cell); + cell->setParent(this, cellCount() - 1); + signal(append, cell); + return *this; +} + +auto mTableViewItem::backgroundColor() const -> Color { + return state.backgroundColor; +} + +auto mTableViewItem::cell(unsigned position) const -> TableViewCell { + if(position < cellCount()) return state.cells[position]; + return {}; +} + +auto mTableViewItem::cellCount() const -> unsigned { + return state.cells.size(); +} + +auto mTableViewItem::cells() const -> vector { + vector cells; + for(auto& cell : state.cells) cells.append(cell); + return cells; +} + +auto mTableViewItem::foregroundColor() const -> Color { + return state.foregroundColor; +} + +auto mTableViewItem::remove() -> type& { + if(auto tableView = parentTableView()) tableView->remove(*this); + return *this; +} + +auto mTableViewItem::remove(sTableViewCell cell) -> type& { + signal(remove, cell); + state.cells.remove(cell->offset()); + for(auto n : range(cell->offset(), cellCount())) { + state.cells[n]->adjustOffset(-1); + } + cell->setParent(); + return *this; +} + +auto mTableViewItem::reset() -> type& { + for(auto n : rrange(state.cells)) remove(state.cells[n]); + return *this; +} + +auto mTableViewItem::selected() const -> bool { + return state.selected; +} + +auto mTableViewItem::setAlignment(Alignment alignment) -> type& { + state.alignment = alignment; + signal(setAlignment, alignment); + return *this; +} + +auto mTableViewItem::setBackgroundColor(Color color) -> type& { + state.backgroundColor = color; + signal(setBackgroundColor, color); + return *this; +} + +auto mTableViewItem::setFocused() -> type& { + signal(setFocused); + return *this; +} + +auto mTableViewItem::setForegroundColor(Color color) -> type& { + state.foregroundColor = color; + signal(setForegroundColor, color); + return *this; +} + +auto mTableViewItem::setParent(mObject* parent, signed offset) -> type& { + for(auto& cell : state.cells) cell->destruct(); + mObject::setParent(parent, offset); + for(auto& cell : state.cells) cell->setParent(this, cell->offset()); + return *this; +} + +auto mTableViewItem::setSelected(bool selected) -> type& { + state.selected = selected; + signal(setSelected, selected); + return *this; +} + +#endif diff --git a/hiro/core/widget/list-view.cpp b/hiro/core/widget/table-view.cpp similarity index 55% rename from hiro/core/widget/list-view.cpp rename to hiro/core/widget/table-view.cpp index 14a8ccb3..8390b625 100644 --- a/hiro/core/widget/list-view.cpp +++ b/hiro/core/widget/table-view.cpp @@ -1,10 +1,10 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) -auto mListView::allocate() -> pObject* { - return new pListView(*this); +auto mTableView::allocate() -> pObject* { + return new pTableView(*this); } -auto mListView::destruct() -> void { +auto mTableView::destruct() -> void { for(auto& item : state.items) item->destruct(); if(auto& header = state.header) header->destruct(); mWidget::destruct(); @@ -12,11 +12,11 @@ auto mListView::destruct() -> void { // -auto mListView::alignment() const -> Alignment { +auto mTableView::alignment() const -> Alignment { return state.alignment; } -auto mListView::append(sListViewHeader header) -> type& { +auto mTableView::append(sTableViewHeader header) -> type& { if(auto& header = state.header) remove(header); state.header = header; header->setParent(this, 0); @@ -24,118 +24,118 @@ auto mListView::append(sListViewHeader header) -> type& { return *this; } -auto mListView::append(sListViewItem item) -> type& { +auto mTableView::append(sTableViewItem item) -> type& { state.items.append(item); item->setParent(this, itemCount() - 1); signal(append, item); return *this; } -auto mListView::backgroundColor() const -> Color { +auto mTableView::backgroundColor() const -> Color { return state.backgroundColor; } -auto mListView::batchable() const -> bool { +auto mTableView::batchable() const -> bool { return state.batchable; } -auto mListView::batched() const -> vector { - vector items; +auto mTableView::batched() const -> vector { + vector items; for(auto& item : state.items) { if(item->selected()) items.append(item); } return items; } -auto mListView::bordered() const -> bool { +auto mTableView::bordered() const -> bool { return state.bordered; } -auto mListView::doActivate() const -> void { +auto mTableView::doActivate() const -> void { if(state.onActivate) return state.onActivate(); } -auto mListView::doChange() const -> void { +auto mTableView::doChange() const -> void { if(state.onChange) return state.onChange(); } -auto mListView::doContext() const -> void { +auto mTableView::doContext() const -> void { if(state.onContext) return state.onContext(); } -auto mListView::doEdit(sListViewCell cell) const -> void { +auto mTableView::doEdit(sTableViewCell cell) const -> void { if(state.onEdit) return state.onEdit(cell); } -auto mListView::doSort(sListViewColumn column) const -> void { +auto mTableView::doSort(sTableViewColumn column) const -> void { if(state.onSort) return state.onSort(column); } -auto mListView::doToggle(sListViewCell cell) const -> void { +auto mTableView::doToggle(sTableViewCell cell) const -> void { if(state.onToggle) return state.onToggle(cell); } -auto mListView::foregroundColor() const -> Color { +auto mTableView::foregroundColor() const -> Color { return state.foregroundColor; } -auto mListView::header() const -> ListViewHeader { +auto mTableView::header() const -> TableViewHeader { return state.header; } -auto mListView::item(unsigned position) const -> ListViewItem { +auto mTableView::item(unsigned position) const -> TableViewItem { if(position < itemCount()) return state.items[position]; return {}; } -auto mListView::itemCount() const -> unsigned { +auto mTableView::itemCount() const -> unsigned { return state.items.size(); } -auto mListView::items() const -> vector { - vector items; +auto mTableView::items() const -> vector { + vector items; for(auto& item : state.items) items.append(item); return items; } -auto mListView::onActivate(const function& callback) -> type& { +auto mTableView::onActivate(const function& callback) -> type& { state.onActivate = callback; return *this; } -auto mListView::onChange(const function& callback) -> type& { +auto mTableView::onChange(const function& callback) -> type& { state.onChange = callback; return *this; } -auto mListView::onContext(const function& callback) -> type& { +auto mTableView::onContext(const function& callback) -> type& { state.onContext = callback; return *this; } -auto mListView::onEdit(const function& callback) -> type& { +auto mTableView::onEdit(const function& callback) -> type& { state.onEdit = callback; return *this; } -auto mListView::onSort(const function& callback) -> type& { +auto mTableView::onSort(const function& callback) -> type& { state.onSort = callback; return *this; } -auto mListView::onToggle(const function& callback) -> type& { +auto mTableView::onToggle(const function& callback) -> type& { state.onToggle = callback; return *this; } -auto mListView::remove(sListViewHeader header) -> type& { +auto mTableView::remove(sTableViewHeader header) -> type& { signal(remove, header); header->setParent(); state.header.reset(); return *this; } -auto mListView::remove(sListViewItem item) -> type& { +auto mTableView::remove(sTableViewItem item) -> type& { signal(remove, item); state.items.remove(item->offset()); for(auto n : range(item->offset(), itemCount())) { @@ -145,55 +145,55 @@ auto mListView::remove(sListViewItem item) -> type& { return *this; } -auto mListView::reset() -> type& { +auto mTableView::reset() -> type& { for(auto n : rrange(state.items)) remove(state.items[n]); if(auto& header = state.header) remove(header); return *this; } -auto mListView::resizeColumns() -> type& { +auto mTableView::resizeColumns() -> type& { signal(resizeColumns); return *this; } -auto mListView::selected() const -> ListViewItem { +auto mTableView::selected() const -> TableViewItem { for(auto& item : state.items) { if(item->selected()) return item; } return {}; } -auto mListView::setAlignment(Alignment alignment) -> type& { +auto mTableView::setAlignment(Alignment alignment) -> type& { state.alignment = alignment; signal(setAlignment, alignment); return *this; } -auto mListView::setBackgroundColor(Color color) -> type& { +auto mTableView::setBackgroundColor(Color color) -> type& { state.backgroundColor = color; signal(setBackgroundColor, color); return *this; } -auto mListView::setBatchable(bool batchable) -> type& { +auto mTableView::setBatchable(bool batchable) -> type& { state.batchable = batchable; signal(setBatchable, batchable); return *this; } -auto mListView::setBordered(bool bordered) -> type& { +auto mTableView::setBordered(bool bordered) -> type& { state.bordered = bordered; signal(setBordered, bordered); return *this; } -auto mListView::setForegroundColor(Color color) -> type& { +auto mTableView::setForegroundColor(Color color) -> type& { state.foregroundColor = color; signal(setForegroundColor, color); return *this; } -auto mListView::setParent(mObject* parent, signed offset) -> type& { +auto mTableView::setParent(mObject* parent, signed offset) -> type& { for(auto n : rrange(state.items)) state.items[n]->destruct(); if(auto& header = state.header) header->destruct(); mObject::setParent(parent, offset); diff --git a/hiro/extension/browser-dialog.cpp b/hiro/extension/browser-dialog.cpp index 57aa22ae..4e217cf5 100644 --- a/hiro/extension/browser-dialog.cpp +++ b/hiro/extension/browser-dialog.cpp @@ -18,7 +18,7 @@ private: Button pathRefresh{&pathLayout, Size{0, 0}, 0}; Button pathHome{&pathLayout, Size{0, 0}, 0}; Button pathUp{&pathLayout, Size{0, 0}, 0}; - ListView view{&layout, Size{~0, ~0}, 5}; + TableView view{&layout, Size{~0, ~0}, 5}; HorizontalLayout controlLayout{&layout, Size{~0, 0}}; ComboButton filterList{&controlLayout, Size{120, 0}, 5}; LineEdit fileName{&controlLayout, Size{~0, 0}, 5}; @@ -30,7 +30,7 @@ private: }; //accept button clicked, or enter pressed on file name line edit -//also called by list view activate after special case handling +//also called by table view activate after special case handling auto BrowserDialogWindow::accept() -> void { auto batched = view.batched(); @@ -71,7 +71,7 @@ auto BrowserDialogWindow::accept() -> void { if(state.response) window.setModal(false); } -//list view item double-clicked, or enter pressed on selected list view item +//table view item double-clicked, or enter pressed on selected table view item auto BrowserDialogWindow::activate() -> void { auto selectedItem = view.selected(); @@ -89,7 +89,7 @@ auto BrowserDialogWindow::activate() -> void { accept(); } -//list view item changed +//table view item changed auto BrowserDialogWindow::change() -> void { fileName.setText(""); if(state.action == "saveFile") { @@ -162,8 +162,8 @@ auto BrowserDialogWindow::setPath(string path) -> void { pathName.setText(state.path = path); view.reset(); - view.append(ListViewHeader().setVisible(false) - .append(ListViewColumn().setExpandable()) + view.append(TableViewHeader().setVisible(false) + .append(TableViewColumn().setExpandable()) ); auto contents = directory::icontents(path); @@ -174,8 +174,8 @@ auto BrowserDialogWindow::setPath(string path) -> void { content.rtrim("/"); if(folderMode && isMatch(content)) continue; - view.append(ListViewItem() - .append(ListViewCell().setText(content).setIcon(Icon::Emblem::Folder)) + view.append(TableViewItem() + .append(TableViewCell().setText(content).setIcon(Icon::Emblem::Folder)) ); } @@ -184,8 +184,8 @@ auto BrowserDialogWindow::setPath(string path) -> void { content.rtrim("/"); if(!isMatch(content)) continue; - view.append(ListViewItem() - .append(ListViewCell().setText(content).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File)) + view.append(TableViewItem() + .append(TableViewCell().setText(content).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File)) ); } diff --git a/hiro/extension/extension.cpp b/hiro/extension/extension.cpp index aa46d451..a18e44c6 100644 --- a/hiro/extension/extension.cpp +++ b/hiro/extension/extension.cpp @@ -6,6 +6,8 @@ namespace hiro { #include "fixed-layout.cpp" #include "horizontal-layout.cpp" #include "vertical-layout.cpp" + #include "list-view-item.cpp" + #include "list-view.cpp" #include "browser-dialog.cpp" #include "message-dialog.cpp" } diff --git a/hiro/extension/extension.hpp b/hiro/extension/extension.hpp index f3655abe..3f20bf8e 100644 --- a/hiro/extension/extension.hpp +++ b/hiro/extension/extension.hpp @@ -3,6 +3,8 @@ namespace hiro { #include "fixed-layout.hpp" #include "horizontal-layout.hpp" #include "vertical-layout.hpp" + #include "list-view-item.hpp" + #include "list-view.hpp" #include "shared.hpp" #include "browser-dialog.hpp" #include "message-dialog.hpp" diff --git a/hiro/extension/list-view-item.cpp b/hiro/extension/list-view-item.cpp new file mode 100644 index 00000000..51b09e79 --- /dev/null +++ b/hiro/extension/list-view-item.cpp @@ -0,0 +1,49 @@ +#if defined(Hiro_ListView) + +mListViewItem::mListViewItem() { + append(TableViewCell()); +} + +auto mListViewItem::checkable() const -> bool { + return cell(0).checkable(); +} + +auto mListViewItem::checked() const -> bool { + return cell(0).checked(); +} + +auto mListViewItem::icon() const -> image { + return cell(0).icon(); +} + +auto mListViewItem::reset() -> type& { + mTableViewItem::reset(); + append(TableViewCell()); + return *this; +} + +auto mListViewItem::setCheckable(bool checkable) -> type& { + cell(0).setCheckable(checkable); + return *this; +} + +auto mListViewItem::setChecked(bool checked) -> type& { + cell(0).setChecked(checked); + return *this; +} + +auto mListViewItem::setIcon(const image& icon) -> type& { + cell(0).setIcon(icon); + return *this; +} + +auto mListViewItem::setText(const string& text) -> type& { + cell(0).setText(text); + return *this; +} + +auto mListViewItem::text() const -> string { + return cell(0).text(); +} + +#endif diff --git a/hiro/extension/list-view-item.hpp b/hiro/extension/list-view-item.hpp new file mode 100644 index 00000000..cc26c933 --- /dev/null +++ b/hiro/extension/list-view-item.hpp @@ -0,0 +1,24 @@ +#if defined(Hiro_ListView) + +struct ListViewItem; +struct mListViewItem; +using sListViewItem = shared_pointer; + +struct mListViewItem : mTableViewItem { + using type = mListViewItem; + using mTableViewItem::append; + using mTableViewItem::remove; + + mListViewItem(); + auto checkable() const -> bool; + auto checked() const -> bool; + auto icon() const -> image; + auto reset() -> type&; + auto setCheckable(bool checkable) -> type&; + auto setChecked(bool checked) -> type&; + auto setIcon(const image& icon = {}) -> type&; + auto setText(const string& text) -> type&; + auto text() const -> string; +}; + +#endif diff --git a/hiro/extension/list-view.cpp b/hiro/extension/list-view.cpp new file mode 100644 index 00000000..07d51152 --- /dev/null +++ b/hiro/extension/list-view.cpp @@ -0,0 +1,51 @@ +#if defined(Hiro_ListView) + +mListView::mListView() { + mTableView::onToggle([&](TableViewCell cell) { + if(auto item = cell->parentTableViewItem()) { + if(auto shared = item->instance.acquire()) { + doToggle(ListViewItem{shared}); + } + } + }); + append(TableViewHeader().setVisible(false).append(TableViewColumn().setExpandable())); +} + +auto mListView::batched() const -> vector { + auto batched = mTableView::batched(); + vector result; + for(auto item : batched) result.append(ListViewItem{item}); + return result; +} + +auto mListView::doToggle(ListViewItem item) const -> void { + if(state.onToggle) state.onToggle(item); +} + +auto mListView::item(uint position) const -> ListViewItem { + return ListViewItem{mTableView::item(position)}; +} + +auto mListView::items() const -> vector { + auto items = mTableView::items(); + vector result; + for(auto item : items) result.append(ListViewItem{item}); + return result; +} + +auto mListView::onToggle(const function& callback) -> type& { + state.onToggle = callback; + return *this; +} + +auto mListView::reset() -> type& { + mTableView::reset(); + append(TableViewHeader().setVisible(false).append(TableViewColumn().setExpandable())); + return *this; +} + +auto mListView::selected() const -> ListViewItem { + return ListViewItem{mTableView::selected()}; +} + +#endif diff --git a/hiro/extension/list-view.hpp b/hiro/extension/list-view.hpp new file mode 100644 index 00000000..3650983d --- /dev/null +++ b/hiro/extension/list-view.hpp @@ -0,0 +1,27 @@ +#if defined(Hiro_ListView) + +struct ListView; +struct mListView; +using sListView = shared_pointer; + +struct mListView : mTableView { + using type = mListView; + using mTableView::append; + using mTableView::remove; + + mListView(); + auto batched() const -> vector; + auto doToggle(ListViewItem) const -> void; + auto item(uint position) const -> ListViewItem; + auto items() const -> vector; + auto onToggle(const function& callback) -> type&; + auto reset() -> type& override; + auto selected() const -> ListViewItem; + +//private: + struct State { + function onToggle; + } state; +}; + +#endif diff --git a/hiro/extension/shared.hpp b/hiro/extension/shared.hpp index de05c1c9..318355d6 100644 --- a/hiro/extension/shared.hpp +++ b/hiro/extension/shared.hpp @@ -33,3 +33,56 @@ struct VerticalLayout : sVerticalLayout { auto setSpacing(signed spacing = 5) { return self().setSpacing(spacing), *this; } }; #endif + +#if defined(Hiro_ListView) +struct ListViewItem : sListViewItem { + DeclareSharedObject(ListViewItem) + + auto alignment() const { return self().alignment(); } + auto backgroundColor() const { return self().backgroundColor(); } + auto checkable() const { return self().checkable(); } + auto checked() const { return self().checked(); } + auto foregroundColor() const { return self().foregroundColor(); } + auto icon() const { return self().icon(); } + auto reset() { return self().reset(), *this; } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setCheckable(bool checkable = true) { return self().setCheckable(checkable), *this; } + auto setChecked(bool checked = true) { return self().setChecked(checked), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } + auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; } + auto setText(const string& text = "") { return self().setText(text), *this; } + auto text() const { return self().text(); } +}; +#endif + +#if defined(Hiro_ListView) +struct ListView : sListView { + DeclareSharedWidget(ListView) + + auto alignment() const { return self().alignment(); } + auto append(sListViewItem item) { return self().append(item), *this; } + auto backgroundColor() const { return self().backgroundColor(); } + auto batchable() const { return self().batchable(); } + auto batched() const { return self().batched(); } + auto doActivate() const { return self().doActivate(); } + auto doChange() const { return self().doChange(); } + auto doContext() const { return self().doContext(); } + auto doToggle(ListViewItem item) const { return self().doToggle(item); } + auto foregroundColor() const { return self().foregroundColor(); } + auto item(uint position) const { return self().item(position); } + auto itemCount() const { return self().itemCount(); } + auto items() const { return self().items(); } + auto onActivate(const function& callback = {}) { return self().onActivate(callback), *this; } + auto onChange(const function& callback = {}) { return self().onChange(callback), *this; } + auto onContext(const function& callback = {}) { return self().onContext(callback), *this; } + auto onToggle(const function& callback = {}) { return self().onToggle(callback), *this; } + auto remove(sListViewItem item) { return self().remove(item), *this; } + auto reset() { return self().reset(), *this; } + auto selected() { return self().selected(); } + auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; } + auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; } + auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; } + auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; } +}; +#endif diff --git a/hiro/gtk/platform.cpp b/hiro/gtk/platform.cpp index 72a42b4a..912ebd6b 100644 --- a/hiro/gtk/platform.cpp +++ b/hiro/gtk/platform.cpp @@ -44,17 +44,17 @@ #include "widget/icon-view-item.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/source-edit.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/tree-view.cpp" #include "widget/tree-view-item.cpp" diff --git a/hiro/gtk/platform.hpp b/hiro/gtk/platform.hpp index 828959ed..47a2c2d5 100644 --- a/hiro/gtk/platform.hpp +++ b/hiro/gtk/platform.hpp @@ -55,17 +55,17 @@ namespace hiro { #include "widget/icon-view-item.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/source-edit.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/tree-view.hpp" #include "widget/tree-view-item.hpp" diff --git a/hiro/gtk/widget/list-view-header.cpp b/hiro/gtk/widget/list-view-header.cpp deleted file mode 100644 index 569a753d..00000000 --- a/hiro/gtk/widget/list-view-header.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewHeader::construct() -> void { - _setState(); -} - -auto pListViewHeader::destruct() -> void { -} - -auto pListViewHeader::append(sListViewColumn column) -> void { - _setState(); -} - -auto pListViewHeader::remove(sListViewColumn column) -> void { -} - -auto pListViewHeader::setVisible(bool visible) -> void { - _setState(); -} - -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -auto pListViewHeader::_setState() -> void { - if(auto parent = _parent()) { - gtk_tree_view_set_headers_visible(parent->gtkTreeView, self().visible()); - for(auto& column : state().columns) { - if(auto self = column->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/hiro/gtk/widget/list-view-header.hpp b/hiro/gtk/widget/list-view-header.hpp deleted file mode 100644 index a46855bb..00000000 --- a/hiro/gtk/widget/list-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/hiro/gtk/widget/list-view-cell.cpp b/hiro/gtk/widget/table-view-cell.cpp similarity index 50% rename from hiro/gtk/widget/list-view-cell.cpp rename to hiro/gtk/widget/table-view-cell.cpp index 94e22bcc..33167750 100644 --- a/hiro/gtk/widget/list-view-cell.cpp +++ b/hiro/gtk/widget/table-view-cell.cpp @@ -1,51 +1,51 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewCell::construct() -> void { +auto pTableViewCell::construct() -> void { _setState(); } -auto pListViewCell::destruct() -> void { +auto pTableViewCell::destruct() -> void { } -auto pListViewCell::setAlignment(Alignment alignment) -> void { +auto pTableViewCell::setAlignment(Alignment alignment) -> void { } -auto pListViewCell::setBackgroundColor(Color color) -> void { +auto pTableViewCell::setBackgroundColor(Color color) -> void { } -auto pListViewCell::setCheckable(bool checkable) -> void { +auto pTableViewCell::setCheckable(bool checkable) -> void { } -auto pListViewCell::setChecked(bool checked) -> void { +auto pTableViewCell::setChecked(bool checked) -> void { _setState(); } -auto pListViewCell::setForegroundColor(Color color) -> void { +auto pTableViewCell::setForegroundColor(Color color) -> void { } -auto pListViewCell::setIcon(const image& icon) -> void { +auto pTableViewCell::setIcon(const image& icon) -> void { _setState(); } -auto pListViewCell::setText(const string& text) -> void { +auto pTableViewCell::setText(const string& text) -> void { _setState(); } -auto pListViewCell::_grandparent() -> maybe { +auto pTableViewCell::_grandparent() -> maybe { if(auto parent = _parent()) return parent->_parent(); return nothing; } -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewCell::_setState() -> void { +auto pTableViewCell::_setState() -> void { if(auto parent = _parent()) { if(auto grandparent = _grandparent()) { grandparent->lock(); diff --git a/hiro/gtk/widget/list-view-cell.hpp b/hiro/gtk/widget/table-view-cell.hpp similarity index 67% rename from hiro/gtk/widget/list-view-cell.hpp rename to hiro/gtk/widget/table-view-cell.hpp index 2fd00821..d8c7bae5 100644 --- a/hiro/gtk/widget/list-view-cell.hpp +++ b/hiro/gtk/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -13,8 +13,8 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/hiro/gtk/widget/list-view-column.cpp b/hiro/gtk/widget/table-view-column.cpp similarity index 67% rename from hiro/gtk/widget/list-view-column.cpp rename to hiro/gtk/widget/table-view-column.cpp index 05842074..f9e966b6 100644 --- a/hiro/gtk/widget/list-view-column.cpp +++ b/hiro/gtk/widget/table-view-column.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewColumn::construct() -> void { +auto pTableViewColumn::construct() -> void { if(auto grandparent = _grandparent()) { auto handle = grandparent.data(); unsigned offset = self().offset(); @@ -23,21 +23,21 @@ auto pListViewColumn::construct() -> void { gtkCellToggle = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellToggle, false); gtk_tree_view_column_set_attributes(gtkColumn, gtkCellToggle, "active", 3 * offset + 0, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellToggle), (GtkTreeCellDataFunc)ListView_dataFunc, (gpointer)handle, nullptr); + gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellToggle), (GtkTreeCellDataFunc)TableView_dataFunc, (gpointer)handle, nullptr); gtkCellIcon = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellIcon, false); gtk_tree_view_column_set_attributes(gtkColumn, gtkCellIcon, "pixbuf", 3 * offset + 1, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellIcon), (GtkTreeCellDataFunc)ListView_dataFunc, (gpointer)handle, nullptr); + gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellIcon), (GtkTreeCellDataFunc)TableView_dataFunc, (gpointer)handle, nullptr); gtkCellText = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(gtkColumn, gtkCellText, true); //text must expand to cell width for horizontal alignment to work gtk_tree_view_column_set_attributes(gtkColumn, gtkCellText, "text", 3 * offset + 2, nullptr); - gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellText), (GtkTreeCellDataFunc)ListView_dataFunc, (gpointer)handle, nullptr); + gtk_tree_view_column_set_cell_data_func(gtkColumn, GTK_CELL_RENDERER(gtkCellText), (GtkTreeCellDataFunc)TableView_dataFunc, (gpointer)handle, nullptr); - g_signal_connect(G_OBJECT(gtkColumn), "clicked", G_CALLBACK(ListView_headerActivate), (gpointer)handle); - g_signal_connect(G_OBJECT(gtkCellText), "edited", G_CALLBACK(ListView_edit), (gpointer)handle); - g_signal_connect(G_OBJECT(gtkCellToggle), "toggled", G_CALLBACK(ListView_toggle), (gpointer)handle); + g_signal_connect(G_OBJECT(gtkColumn), "clicked", G_CALLBACK(TableView_headerActivate), (gpointer)handle); + g_signal_connect(G_OBJECT(gtkCellText), "edited", G_CALLBACK(TableView_edit), (gpointer)handle); + g_signal_connect(G_OBJECT(gtkCellToggle), "toggled", G_CALLBACK(TableView_toggle), (gpointer)handle); gtk_tree_view_append_column(grandparent->gtkTreeView, gtkColumn); gtk_widget_show_all(gtkHeader); @@ -47,7 +47,7 @@ auto pListViewColumn::construct() -> void { } } -auto pListViewColumn::destruct() -> void { +auto pTableViewColumn::destruct() -> void { if(auto grandparent = _grandparent()) { gtk_tree_view_remove_column(grandparent->gtkTreeView, gtkColumn); gtkColumn = nullptr; @@ -55,33 +55,33 @@ auto pListViewColumn::destruct() -> void { } } -auto pListViewColumn::setActive() -> void { +auto pTableViewColumn::setActive() -> void { _setState(); } -auto pListViewColumn::setAlignment(Alignment alignment) -> void { +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { } -auto pListViewColumn::setBackgroundColor(Color color) -> void { +auto pTableViewColumn::setBackgroundColor(Color color) -> void { } -auto pListViewColumn::setEditable(bool editable) -> void { +auto pTableViewColumn::setEditable(bool editable) -> void { g_object_set(G_OBJECT(gtkCellText), "editable", editable ? true : false, nullptr); } -auto pListViewColumn::setExpandable(bool expandable) -> void { +auto pTableViewColumn::setExpandable(bool expandable) -> void { if(auto grandparent = _grandparent()) { grandparent->resizeColumns(); } } -auto pListViewColumn::setFont(const Font& font) -> void { +auto pTableViewColumn::setFont(const Font& font) -> void { } -auto pListViewColumn::setForegroundColor(Color color) -> void { +auto pTableViewColumn::setForegroundColor(Color color) -> void { } -auto pListViewColumn::setIcon(const image& icon) -> void { +auto pTableViewColumn::setIcon(const image& icon) -> void { if(icon) { gtk_image_set_from_pixbuf(GTK_IMAGE(gtkHeaderIcon), CreatePixbuf(icon)); } else { @@ -89,41 +89,41 @@ auto pListViewColumn::setIcon(const image& icon) -> void { } } -auto pListViewColumn::setResizable(bool resizable) -> void { +auto pTableViewColumn::setResizable(bool resizable) -> void { _setState(); } -auto pListViewColumn::setSortable(bool sortable) -> void { +auto pTableViewColumn::setSortable(bool sortable) -> void { _setState(); } -auto pListViewColumn::setText(const string& text) -> void { +auto pTableViewColumn::setText(const string& text) -> void { _setState(); } -auto pListViewColumn::setVisible(bool visible) -> void { +auto pTableViewColumn::setVisible(bool visible) -> void { _setState(); } -auto pListViewColumn::setWidth(signed width) -> void { +auto pTableViewColumn::setWidth(signed width) -> void { if(auto grandparent = _grandparent()) { grandparent->resizeColumns(); } } -auto pListViewColumn::_grandparent() -> maybe { +auto pTableViewColumn::_grandparent() -> maybe { if(auto parent = _parent()) return parent->_parent(); return nothing; } -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewColumn::_setState() -> void { +auto pTableViewColumn::_setState() -> void { if(auto grandparent = _grandparent()) { gtk_tree_view_set_search_column(grandparent->gtkTreeView, 3 * self().offset() + 2); gtk_tree_view_column_set_resizable(gtkColumn, state().resizable); diff --git a/hiro/gtk/widget/list-view-column.hpp b/hiro/gtk/widget/table-view-column.hpp similarity index 84% rename from hiro/gtk/widget/list-view-column.hpp rename to hiro/gtk/widget/table-view-column.hpp index 1cc4b182..882f7a19 100644 --- a/hiro/gtk/widget/list-view-column.hpp +++ b/hiro/gtk/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -21,8 +21,8 @@ struct pListViewColumn : pObject { auto setVisible(bool visible) -> void override; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; GtkTreeViewColumn* gtkColumn = nullptr; diff --git a/hiro/gtk/widget/table-view-header.cpp b/hiro/gtk/widget/table-view-header.cpp new file mode 100644 index 00000000..f8488fec --- /dev/null +++ b/hiro/gtk/widget/table-view-header.cpp @@ -0,0 +1,41 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewHeader::construct() -> void { + _setState(); +} + +auto pTableViewHeader::destruct() -> void { +} + +auto pTableViewHeader::append(sTableViewColumn column) -> void { + _setState(); +} + +auto pTableViewHeader::remove(sTableViewColumn column) -> void { +} + +auto pTableViewHeader::setVisible(bool visible) -> void { + _setState(); +} + +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pTableViewHeader::_setState() -> void { + if(auto parent = _parent()) { + gtk_tree_view_set_headers_visible(parent->gtkTreeView, self().visible()); + for(auto& column : state().columns) { + if(auto self = column->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/hiro/gtk/widget/table-view-header.hpp b/hiro/gtk/widget/table-view-header.hpp new file mode 100644 index 00000000..814f3ac8 --- /dev/null +++ b/hiro/gtk/widget/table-view-header.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/gtk/widget/list-view-item.cpp b/hiro/gtk/widget/table-view-item.cpp similarity index 63% rename from hiro/gtk/widget/list-view-item.cpp rename to hiro/gtk/widget/table-view-item.cpp index c70aad51..56b628cc 100644 --- a/hiro/gtk/widget/list-view-item.cpp +++ b/hiro/gtk/widget/table-view-item.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewItem::construct() -> void { +auto pTableViewItem::construct() -> void { if(auto parent = _parent()) { parent->lock(); gtk_list_store_append(parent->gtkListStore, >kIter); @@ -11,7 +11,7 @@ auto pListViewItem::construct() -> void { } } -auto pListViewItem::destruct() -> void { +auto pTableViewItem::destruct() -> void { if(auto parent = _parent()) { parent->lock(); gtk_list_store_remove(parent->gtkListStore, >kIter); @@ -20,19 +20,19 @@ auto pListViewItem::destruct() -> void { } } -auto pListViewItem::append(sListViewCell cell) -> void { +auto pTableViewItem::append(sTableViewCell cell) -> void { } -auto pListViewItem::remove(sListViewCell cell) -> void { +auto pTableViewItem::remove(sTableViewCell cell) -> void { } -auto pListViewItem::setAlignment(Alignment alignment) -> void { +auto pTableViewItem::setAlignment(Alignment alignment) -> void { } -auto pListViewItem::setBackgroundColor(Color color) -> void { +auto pTableViewItem::setBackgroundColor(Color color) -> void { } -auto pListViewItem::setFocused() -> void { +auto pTableViewItem::setFocused() -> void { if(auto parent = _parent()) { GtkTreePath* path = gtk_tree_path_new_from_string(string{self().offset()}); gtk_tree_view_set_cursor(parent->gtkTreeView, path, nullptr, false); @@ -41,21 +41,21 @@ auto pListViewItem::setFocused() -> void { } } -auto pListViewItem::setForegroundColor(Color color) -> void { +auto pTableViewItem::setForegroundColor(Color color) -> void { } -auto pListViewItem::setSelected(bool selected) -> void { +auto pTableViewItem::setSelected(bool selected) -> void { _setState(); } -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewItem::_setState() -> void { +auto pTableViewItem::_setState() -> void { if(auto parent = _parent()) { parent->lock(); if(state().selected) { diff --git a/hiro/gtk/widget/list-view-item.hpp b/hiro/gtk/widget/table-view-item.hpp similarity index 57% rename from hiro/gtk/widget/list-view-item.hpp rename to hiro/gtk/widget/table-view-item.hpp index 21948797..8289d687 100644 --- a/hiro/gtk/widget/list-view-item.hpp +++ b/hiro/gtk/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; GtkTreeIter gtkIter; diff --git a/hiro/gtk/widget/list-view.cpp b/hiro/gtk/widget/table-view.cpp similarity index 78% rename from hiro/gtk/widget/list-view.cpp rename to hiro/gtk/widget/table-view.cpp index 5947a37f..aa88fd7a 100644 --- a/hiro/gtk/widget/list-view.cpp +++ b/hiro/gtk/widget/table-view.cpp @@ -1,21 +1,21 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -static auto ListView_activate(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, pListView* p) -> void { return p->_doActivate(); } -static auto ListView_buttonEvent(GtkTreeView* treeView, GdkEventButton* event, pListView* p) -> signed { return p->_doEvent(event); } -static auto ListView_change(GtkTreeSelection*, pListView* p) -> void { return p->_doChange(); } -static auto ListView_edit(GtkCellRendererText* renderer, const char* path, const char* text, pListView* p) -> void { return p->_doEdit(renderer, path, text); } -static auto ListView_headerActivate(GtkTreeViewColumn* column, pListView* p) -> void { return p->_doHeaderActivate(column); } -static auto ListView_mouseMoveEvent(GtkWidget*, GdkEvent*, pListView* p) -> signed { return p->_doMouseMove(); } -static auto ListView_popup(GtkTreeView*, pListView* p) -> void { return p->_doContext(); } +static auto TableView_activate(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, pTableView* p) -> void { return p->_doActivate(); } +static auto TableView_buttonEvent(GtkTreeView* treeView, GdkEventButton* event, pTableView* p) -> signed { return p->_doEvent(event); } +static auto TableView_change(GtkTreeSelection*, pTableView* p) -> void { return p->_doChange(); } +static auto TableView_edit(GtkCellRendererText* renderer, const char* path, const char* text, pTableView* p) -> void { return p->_doEdit(renderer, path, text); } +static auto TableView_headerActivate(GtkTreeViewColumn* column, pTableView* p) -> void { return p->_doHeaderActivate(column); } +static auto TableView_mouseMoveEvent(GtkWidget*, GdkEvent*, pTableView* p) -> signed { return p->_doMouseMove(); } +static auto TableView_popup(GtkTreeView*, pTableView* p) -> void { return p->_doContext(); } -static auto ListView_dataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, pListView* p) -> void { return p->_doDataFunc(column, renderer, iter); } -static auto ListView_toggle(GtkCellRendererToggle* toggle, const char* path, pListView* p) -> void { return p->_doToggle(toggle, path); } +static auto TableView_dataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, pTableView* p) -> void { return p->_doDataFunc(column, renderer, iter); } +static auto TableView_toggle(GtkCellRendererToggle* toggle, const char* path, pTableView* p) -> void { return p->_doToggle(toggle, path); } //gtk_tree_view_set_rules_hint(gtkTreeView, true); -auto pListView::construct() -> void { +auto pTableView::construct() -> void { gtkWidget = gtk_scrolled_window_new(0, 0); gtkScrolledWindow = GTK_SCROLLED_WINDOW(gtkWidget); gtk_scrolled_window_set_policy(gtkScrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); @@ -35,38 +35,38 @@ auto pListView::construct() -> void { setFont(self().font(true)); setForegroundColor(state().foregroundColor); - g_signal_connect(G_OBJECT(gtkTreeView), "button-press-event", G_CALLBACK(ListView_buttonEvent), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "button-release-event", G_CALLBACK(ListView_buttonEvent), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "motion-notify-event", G_CALLBACK(ListView_mouseMoveEvent), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "popup-menu", G_CALLBACK(ListView_popup), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeView), "row-activated", G_CALLBACK(ListView_activate), (gpointer)this); - g_signal_connect(G_OBJECT(gtkTreeSelection), "changed", G_CALLBACK(ListView_change), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "button-press-event", G_CALLBACK(TableView_buttonEvent), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "button-release-event", G_CALLBACK(TableView_buttonEvent), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "motion-notify-event", G_CALLBACK(TableView_mouseMoveEvent), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "popup-menu", G_CALLBACK(TableView_popup), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeView), "row-activated", G_CALLBACK(TableView_activate), (gpointer)this); + g_signal_connect(G_OBJECT(gtkTreeSelection), "changed", G_CALLBACK(TableView_change), (gpointer)this); pWidget::construct(); } -auto pListView::destruct() -> void { +auto pTableView::destruct() -> void { gtk_widget_destroy(gtkWidgetChild); gtk_widget_destroy(gtkWidget); } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { } -auto pListView::focused() const -> bool { +auto pTableView::focused() const -> bool { return GTK_WIDGET_HAS_FOCUS(gtkTreeView); } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { lock(); if(auto& header = state().header) { @@ -102,23 +102,23 @@ auto pListView::resizeColumns() -> void { unlock(); } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { GdkColor gdkColor = CreateColor(color); gtk_widget_modify_base(gtkWidgetChild, GTK_STATE_NORMAL, color ? &gdkColor : nullptr); } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { gtk_tree_selection_set_mode(gtkTreeSelection, batchable ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE); } -auto pListView::setBordered(bool bordered) -> void { +auto pTableView::setBordered(bool bordered) -> void { gtk_tree_view_set_grid_lines(gtkTreeView, bordered ? GTK_TREE_VIEW_GRID_LINES_BOTH : GTK_TREE_VIEW_GRID_LINES_NONE); } -auto pListView::setFocused() -> void { +auto pTableView::setFocused() -> void { //gtk_widget_grab_focus() will select the first item if nothing is currently selected //this behavior is undesirable. detect selection state first, and restore if required lock(); @@ -128,18 +128,18 @@ auto pListView::setFocused() -> void { unlock(); } -auto pListView::setFont(const Font& font) -> void { +auto pTableView::setFont(const Font& font) -> void { if(auto& header = state().header) { if(auto self = header->self()) self->_setState(); } } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { GdkColor gdkColor = CreateColor(color); gtk_widget_modify_text(gtkWidgetChild, GTK_STATE_NORMAL, color ? &gdkColor : nullptr); } -auto pListView::setGeometry(Geometry geometry) -> void { +auto pTableView::setGeometry(Geometry geometry) -> void { pWidget::setGeometry(geometry); if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -148,7 +148,7 @@ auto pListView::setGeometry(Geometry geometry) -> void { } } -auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { +auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { unsigned width = 8; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { @@ -166,7 +166,7 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { return width; } -auto pListView::_columnWidth(unsigned _column) -> unsigned { +auto pTableView::_columnWidth(unsigned _column) -> unsigned { unsigned width = 8; if(auto& header = state().header) { if(auto column = header->column(_column)) { @@ -181,7 +181,7 @@ auto pListView::_columnWidth(unsigned _column) -> unsigned { return width; } -auto pListView::_createModel() -> void { +auto pTableView::_createModel() -> void { gtk_tree_view_set_model(gtkTreeView, nullptr); gtkListStore = nullptr; gtkTreeModel = nullptr; @@ -204,19 +204,19 @@ auto pListView::_createModel() -> void { gtk_tree_view_set_model(gtkTreeView, gtkTreeModel); } -auto pListView::_doActivate() -> void { +auto pTableView::_doActivate() -> void { if(!locked()) self().doActivate(); } -auto pListView::_doChange() -> void { +auto pTableView::_doChange() -> void { if(!locked()) _updateSelected(); } -auto pListView::_doContext() -> void { +auto pTableView::_doContext() -> void { if(!locked()) self().doContext(); } -auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { +auto pTableView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter); auto row = natural(path); g_free(path); @@ -266,7 +266,7 @@ auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* rende } } -auto pListView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* path, const char* text) -> void { +auto pTableView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* path, const char* text) -> void { if(auto& header = state().header) { for(auto& column : header->state.columns) { if(auto delegate = column->self()) { @@ -287,12 +287,12 @@ auto pListView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* pa } } -auto pListView::_doEvent(GdkEventButton* event) -> signed { +auto pTableView::_doEvent(GdkEventButton* event) -> signed { GtkTreePath* path = nullptr; gtk_tree_view_get_path_at_pos(gtkTreeView, event->x, event->y, &path, nullptr, nullptr, nullptr); if(event->type == GDK_BUTTON_PRESS) { - //when clicking in empty space below the last list view item; GTK+ does not deselect all items; + //when clicking in empty space below the last table view item; GTK+ does not deselect all items; //below code enables this functionality, to match behavior with all other UI toolkits (and because it's very convenient to have) if(path == nullptr && gtk_tree_selection_count_selected_rows(gtkTreeSelection) > 0) { for(auto& item : state().items) item->setSelected(false); @@ -316,7 +316,7 @@ auto pListView::_doEvent(GdkEventButton* event) -> signed { return false; } -auto pListView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void { +auto pTableView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void { if(auto& header = state().header) { for(auto& column : header->state.columns) { if(auto delegate = column->self()) { @@ -330,15 +330,15 @@ auto pListView::_doHeaderActivate(GtkTreeViewColumn* gtkTreeViewColumn) -> void } //GtkTreeView::cursor-changed and GtkTreeSelection::changed do not send signals for changes during rubber-banding selection -//so here we capture motion-notify-event, and if the selections have changed, invoke ListView::onChange -auto pListView::_doMouseMove() -> signed { +//so here we capture motion-notify-event, and if the selections have changed, invoke TableView::onChange +auto pTableView::_doMouseMove() -> signed { if(gtk_tree_view_is_rubber_banding_active(gtkTreeView)) { if(!locked()) _updateSelected(); } return false; } -auto pListView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const char* path) -> void { +auto pTableView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const char* path) -> void { if(auto& header = state().header) { for(auto& column : header->state.columns) { if(auto delegate = column->self()) { @@ -361,7 +361,7 @@ auto pListView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const ch //if different, invoke the onChange callback unless locked, and cache current selection //this prevents firing an onChange event when the actual selection has not changed //this is particularly important for the motion-notify-event binding -auto pListView::_updateSelected() -> void { +auto pTableView::_updateSelected() -> void { vector selected; GList* list = gtk_tree_selection_get_selected_rows(gtkTreeSelection, >kTreeModel); @@ -402,7 +402,7 @@ auto pListView::_updateSelected() -> void { if(!locked()) self().doChange(); } -auto pListView::_width(unsigned column) -> unsigned { +auto pTableView::_width(unsigned column) -> unsigned { if(auto& header = state().header) { if(auto width = header->column(column).width()) return width; unsigned width = 1; diff --git a/hiro/gtk/widget/list-view.hpp b/hiro/gtk/widget/table-view.hpp similarity index 84% rename from hiro/gtk/widget/list-view.hpp rename to hiro/gtk/widget/table-view.hpp index 1df15dfb..71a482e7 100644 --- a/hiro/gtk/widget/list-view.hpp +++ b/hiro/gtk/widget/table-view.hpp @@ -1,15 +1,15 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader column) -> void; - auto append(sListViewItem item) -> void; + auto append(sTableViewHeader column) -> void; + auto append(sTableViewItem item) -> void; auto focused() const -> bool override; - auto remove(sListViewHeader column) -> void; - auto remove(sListViewItem item) -> void; + auto remove(sTableViewHeader column) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; diff --git a/hiro/qt/platform.cpp b/hiro/qt/platform.cpp index e529b916..d062a0a7 100644 --- a/hiro/qt/platform.cpp +++ b/hiro/qt/platform.cpp @@ -47,16 +47,16 @@ #include "widget/icon-view.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/text-edit.cpp" #include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" diff --git a/hiro/qt/platform.hpp b/hiro/qt/platform.hpp index 2f223cdf..c54b5634 100644 --- a/hiro/qt/platform.hpp +++ b/hiro/qt/platform.hpp @@ -48,16 +48,16 @@ #include "widget/horizontal-slider.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/vertical-scroll-bar.hpp" #include "widget/vertical-slider.hpp" diff --git a/hiro/qt/qt.hpp b/hiro/qt/qt.hpp index df41bdab..15e7c7d3 100644 --- a/hiro/qt/qt.hpp +++ b/hiro/qt/qt.hpp @@ -1,3 +1,5 @@ +//moc-qt4 -i -o qt.moc qt.hpp + /* Qt requires moc in order to bind callbacks, which causes many complications. @@ -194,30 +196,6 @@ public slots: }; #endif -#if defined(Hiro_ListView) -struct QtListView : public QTreeWidget { - Q_OBJECT -public: - QtListView(pListView& p) : p(p) {} - auto mousePressEvent(QMouseEvent*) -> void override; - auto resizeEvent(QResizeEvent*) -> void override; - auto showEvent(QShowEvent*) -> void override; - pListView& p; -public slots: - void onActivate(); - void onChange(); - void onContext(); - void onSort(int column); - void onToggle(QTreeWidgetItem* item, int column); -}; - -struct QtListViewDelegate : public QStyledItemDelegate { - QtListViewDelegate(pListView& p); - auto paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void; - pListView& p; -}; -#endif - #if defined(Hiro_RadioLabel) struct QtRadioLabel : public QRadioButton { Q_OBJECT @@ -252,6 +230,30 @@ public slots: }; #endif +#if defined(Hiro_TableView) +struct QtTableView : public QTreeWidget { + Q_OBJECT +public: + QtTableView(pTableView& p) : p(p) {} + auto mousePressEvent(QMouseEvent*) -> void override; + auto resizeEvent(QResizeEvent*) -> void override; + auto showEvent(QShowEvent*) -> void override; + pTableView& p; +public slots: + void onActivate(); + void onChange(); + void onContext(); + void onSort(int column); + void onToggle(QTreeWidgetItem* item, int column); +}; + +struct QtTableViewDelegate : public QStyledItemDelegate { + QtTableViewDelegate(pTableView& p); + auto paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void; + pTableView& p; +}; +#endif + #if defined(Hiro_TextEdit) struct QtTextEdit : public QTextEdit { Q_OBJECT diff --git a/hiro/qt/qt.moc b/hiro/qt/qt.moc index c3014c88..4cfb678f 100644 --- a/hiro/qt/qt.moc +++ b/hiro/qt/qt.moc @@ -1031,90 +1031,6 @@ int hiro::QtLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) } return _id; } -static const uint qt_meta_data_hiro__QtListView[] = { - - // content: - 6, // revision - 0, // classname - 0, 0, // classinfo - 5, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: signature, parameters, type, tag, flags - 17, 30, 30, 30, 0x0a, - 31, 30, 30, 30, 0x0a, - 42, 30, 30, 30, 0x0a, - 54, 66, 30, 30, 0x0a, - 73, 104, 30, 30, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_hiro__QtListView[] = { - "hiro::QtListView\0onActivate()\0\0" - "onChange()\0onContext()\0onSort(int)\0" - "column\0onToggle(QTreeWidgetItem*,int)\0" - "item,column\0" -}; - -void hiro::QtListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - Q_ASSERT(staticMetaObject.cast(_o)); - QtListView *_t = static_cast(_o); - switch (_id) { - case 0: _t->onActivate(); break; - case 1: _t->onChange(); break; - case 2: _t->onContext(); break; - case 3: _t->onSort((*reinterpret_cast< int(*)>(_a[1]))); break; - case 4: _t->onToggle((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; - default: ; - } - } -} - -const QMetaObjectExtraData hiro::QtListView::staticMetaObjectExtraData = { - 0, qt_static_metacall -}; - -const QMetaObject hiro::QtListView::staticMetaObject = { - { &QTreeWidget::staticMetaObject, qt_meta_stringdata_hiro__QtListView, - qt_meta_data_hiro__QtListView, &staticMetaObjectExtraData } -}; - -#ifdef Q_NO_DATA_RELOCATION -const QMetaObject &hiro::QtListView::getStaticMetaObject() { return staticMetaObject; } -#endif //Q_NO_DATA_RELOCATION - -const QMetaObject *hiro::QtListView::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; -} - -void *hiro::QtListView::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_hiro__QtListView)) - return static_cast(const_cast< QtListView*>(this)); - return QTreeWidget::qt_metacast(_clname); -} - -int hiro::QtListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QTreeWidget::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 5) - qt_static_metacall(this, _c, _id, _a); - _id -= 5; - } - return _id; -} static const uint qt_meta_data_hiro__QtRadioLabel[] = { // content: @@ -1337,6 +1253,90 @@ int hiro::QtTabFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a) } return _id; } +static const uint qt_meta_data_hiro__QtTableView[] = { + + // content: + 6, // revision + 0, // classname + 0, 0, // classinfo + 5, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 18, 31, 31, 31, 0x0a, + 32, 31, 31, 31, 0x0a, + 43, 31, 31, 31, 0x0a, + 55, 67, 31, 31, 0x0a, + 74, 105, 31, 31, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_hiro__QtTableView[] = { + "hiro::QtTableView\0onActivate()\0\0" + "onChange()\0onContext()\0onSort(int)\0" + "column\0onToggle(QTreeWidgetItem*,int)\0" + "item,column\0" +}; + +void hiro::QtTableView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Q_ASSERT(staticMetaObject.cast(_o)); + QtTableView *_t = static_cast(_o); + switch (_id) { + case 0: _t->onActivate(); break; + case 1: _t->onChange(); break; + case 2: _t->onContext(); break; + case 3: _t->onSort((*reinterpret_cast< int(*)>(_a[1]))); break; + case 4: _t->onToggle((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + default: ; + } + } +} + +const QMetaObjectExtraData hiro::QtTableView::staticMetaObjectExtraData = { + 0, qt_static_metacall +}; + +const QMetaObject hiro::QtTableView::staticMetaObject = { + { &QTreeWidget::staticMetaObject, qt_meta_stringdata_hiro__QtTableView, + qt_meta_data_hiro__QtTableView, &staticMetaObjectExtraData } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &hiro::QtTableView::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *hiro::QtTableView::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *hiro::QtTableView::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_hiro__QtTableView)) + return static_cast(const_cast< QtTableView*>(this)); + return QTreeWidget::qt_metacast(_clname); +} + +int hiro::QtTableView::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QTreeWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 5) + qt_static_metacall(this, _c, _id, _a); + _id -= 5; + } + return _id; +} static const uint qt_meta_data_hiro__QtTextEdit[] = { // content: diff --git a/hiro/qt/widget/list-view-column.cpp b/hiro/qt/widget/list-view-column.cpp deleted file mode 100644 index 1ba29f20..00000000 --- a/hiro/qt/widget/list-view-column.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewColumn::construct() -> void { -} - -auto pListViewColumn::destruct() -> void { -} - -auto pListViewColumn::setActive() -> void { - //unsupported -} - -auto pListViewColumn::setAlignment(Alignment alignment) -> void { - _setState(); -} - -auto pListViewColumn::setBackgroundColor(Color color) -> void { - _setState(); -} - -auto pListViewColumn::setEditable(bool editable) -> void { - //unsupported -} - -auto pListViewColumn::setExpandable(bool expandable) -> void { - _setState(); -} - -auto pListViewColumn::setFont(const Font& font) -> void { - _setState(); -} - -auto pListViewColumn::setForegroundColor(Color color) -> void { - _setState(); -} - -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { - _setState(); -} - -auto pListViewColumn::setIcon(const image& icon) -> void { - //unsupported -} - -auto pListViewColumn::setResizable(bool resizable) -> void { - _setState(); -} - -auto pListViewColumn::setSortable(bool sortable) -> void { - _setState(); -} - -auto pListViewColumn::setText(const string& text) -> void { - _setState(); -} - -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { - _setState(); -} - -auto pListViewColumn::setVisible(bool visible) -> void { - _setState(); -} - -auto pListViewColumn::setWidth(signed width) -> void { - _setState(); -} - -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pListViewColumn::_setState() -> void { - if(auto header = _parent()) { - if(auto parent = header->_parent()) { - parent->qtListView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); - bool clickable = false; - for(auto& column : header->state().columns) clickable |= column->state.sortable; - parent->qtListView->header()->setClickable(clickable); - parent->qtListView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text)); - parent->qtListView->setColumnHidden(self().offset(), !self().visible()); - - for(auto& item : parent->state().items) { - if(auto cell = item->cell(self().offset())) { - if(auto self = cell->self()) self->_setState(); - } - } - } - } -} - -} - -#endif diff --git a/hiro/qt/widget/list-view-header.cpp b/hiro/qt/widget/list-view-header.cpp deleted file mode 100644 index ead448a4..00000000 --- a/hiro/qt/widget/list-view-header.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewHeader::construct() -> void { -} - -auto pListViewHeader::destruct() -> void { -} - -auto pListViewHeader::append(sListViewColumn column) -> void { - _setState(); -} - -auto pListViewHeader::remove(sListViewColumn column) -> void { - _setState(); -} - -auto pListViewHeader::setVisible(bool visible) -> void { - _setState(); -} - -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pListViewHeader::_setState() -> void { - if(auto parent = _parent()) { - //parent->qtListView->setAlternatingRowColors(self().columnCount() >= 2); - parent->qtListView->setColumnCount(self().columnCount()); - parent->qtListView->setHeaderHidden(!self().visible()); - for(auto& column : state().columns) { - if(auto self = column->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/hiro/qt/widget/list-view-header.hpp b/hiro/qt/widget/list-view-header.hpp deleted file mode 100644 index a46855bb..00000000 --- a/hiro/qt/widget/list-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/hiro/qt/widget/list-view-item.cpp b/hiro/qt/widget/list-view-item.cpp deleted file mode 100644 index b3e71064..00000000 --- a/hiro/qt/widget/list-view-item.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewItem::construct() -> void { -} - -auto pListViewItem::destruct() -> void { - if(auto parent = _parent()) parent->lock(); - if(qtItem) { - delete qtItem; - qtItem = nullptr; - } - if(auto parent = _parent()) parent->unlock(); -} - -auto pListViewItem::append(sListViewCell cell) -> void { -} - -auto pListViewItem::remove(sListViewCell cell) -> void { -} - -auto pListViewItem::setAlignment(Alignment alignment) -> void { - _setState(); -} - -auto pListViewItem::setBackgroundColor(Color color) -> void { - _setState(); -} - -auto pListViewItem::setFont(const Font& font) -> void { - _setState(); -} - -auto pListViewItem::setForegroundColor(Color color) -> void { - _setState(); -} - -auto pListViewItem::setSelected(bool selected) -> void { - _setState(); -} - -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pListViewItem::_setState() -> void { - if(auto parent = _parent()) { - qtItem->setSelected(state().selected); - if(state().selected) { - parent->qtListView->setCurrentItem(qtItem); - } - for(auto& cell : state().cells) { - if(auto self = cell->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/hiro/qt/widget/list-view-cell.cpp b/hiro/qt/widget/table-view-cell.cpp similarity index 63% rename from hiro/qt/widget/list-view-cell.cpp rename to hiro/qt/widget/table-view-cell.cpp index 6469ca64..29138a77 100644 --- a/hiro/qt/widget/list-view-cell.cpp +++ b/hiro/qt/widget/table-view-cell.cpp @@ -1,53 +1,53 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewCell::construct() -> void { +auto pTableViewCell::construct() -> void { } -auto pListViewCell::destruct() -> void { +auto pTableViewCell::destruct() -> void { } -auto pListViewCell::setAlignment(Alignment alignment) -> void { +auto pTableViewCell::setAlignment(Alignment alignment) -> void { _setState(); } -auto pListViewCell::setBackgroundColor(Color color) -> void { +auto pTableViewCell::setBackgroundColor(Color color) -> void { _setState(); } -auto pListViewCell::setCheckable(bool checkable) -> void { +auto pTableViewCell::setCheckable(bool checkable) -> void { _setState(); } -auto pListViewCell::setChecked(bool checked) -> void { +auto pTableViewCell::setChecked(bool checked) -> void { _setState(); } -auto pListViewCell::setFont(const string& font) -> void { +auto pTableViewCell::setFont(const string& font) -> void { _setState(); } -auto pListViewCell::setForegroundColor(Color color) -> void { +auto pTableViewCell::setForegroundColor(Color color) -> void { _setState(); } -auto pListViewCell::setIcon(const image& icon) -> void { +auto pTableViewCell::setIcon(const image& icon) -> void { _setState(); } -auto pListViewCell::setText(const string& text) -> void { +auto pTableViewCell::setText(const string& text) -> void { _setState(); } -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { if(auto delegate = parent->self()) return *delegate; } return nothing; } -auto pListViewCell::_setState() -> void { +auto pTableViewCell::_setState() -> void { if(auto parent = _parent()) { if(auto grandparent = parent->_parent()) { grandparent->lock(); diff --git a/hiro/qt/widget/list-view-cell.hpp b/hiro/qt/widget/table-view-cell.hpp similarity index 75% rename from hiro/qt/widget/list-view-cell.hpp rename to hiro/qt/widget/table-view-cell.hpp index 4eddcc5e..14ffec79 100644 --- a/hiro/qt/widget/list-view-cell.hpp +++ b/hiro/qt/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -14,7 +14,7 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/hiro/qt/widget/table-view-column.cpp b/hiro/qt/widget/table-view-column.cpp new file mode 100644 index 00000000..a05a25ca --- /dev/null +++ b/hiro/qt/widget/table-view-column.cpp @@ -0,0 +1,99 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewColumn::construct() -> void { +} + +auto pTableViewColumn::destruct() -> void { +} + +auto pTableViewColumn::setActive() -> void { + //unsupported +} + +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { + _setState(); +} + +auto pTableViewColumn::setBackgroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewColumn::setEditable(bool editable) -> void { + //unsupported +} + +auto pTableViewColumn::setExpandable(bool expandable) -> void { + _setState(); +} + +auto pTableViewColumn::setFont(const Font& font) -> void { + _setState(); +} + +auto pTableViewColumn::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { + _setState(); +} + +auto pTableViewColumn::setIcon(const image& icon) -> void { + //unsupported +} + +auto pTableViewColumn::setResizable(bool resizable) -> void { + _setState(); +} + +auto pTableViewColumn::setSortable(bool sortable) -> void { + _setState(); +} + +auto pTableViewColumn::setText(const string& text) -> void { + _setState(); +} + +auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { + _setState(); +} + +auto pTableViewColumn::setVisible(bool visible) -> void { + _setState(); +} + +auto pTableViewColumn::setWidth(signed width) -> void { + _setState(); +} + +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pTableViewColumn::_setState() -> void { + if(auto header = _parent()) { + if(auto parent = header->_parent()) { + parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); + bool clickable = false; + for(auto& column : header->state().columns) clickable |= column->state.sortable; + parent->qtTableView->header()->setClickable(clickable); + parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text)); + parent->qtTableView->setColumnHidden(self().offset(), !self().visible()); + + for(auto& item : parent->state().items) { + if(auto cell = item->cell(self().offset())) { + if(auto self = cell->self()) self->_setState(); + } + } + } + } +} + +} + +#endif diff --git a/hiro/qt/widget/list-view-column.hpp b/hiro/qt/widget/table-view-column.hpp similarity index 83% rename from hiro/qt/widget/list-view-column.hpp rename to hiro/qt/widget/table-view-column.hpp index f130ea41..f3933e11 100644 --- a/hiro/qt/widget/list-view-column.hpp +++ b/hiro/qt/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -21,7 +21,7 @@ struct pListViewColumn : pObject { auto setVisible(bool visible) -> void; auto setWidth(signed width) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/hiro/qt/widget/table-view-header.cpp b/hiro/qt/widget/table-view-header.cpp new file mode 100644 index 00000000..2a835c1f --- /dev/null +++ b/hiro/qt/widget/table-view-header.cpp @@ -0,0 +1,43 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewHeader::construct() -> void { +} + +auto pTableViewHeader::destruct() -> void { +} + +auto pTableViewHeader::append(sTableViewColumn column) -> void { + _setState(); +} + +auto pTableViewHeader::remove(sTableViewColumn column) -> void { + _setState(); +} + +auto pTableViewHeader::setVisible(bool visible) -> void { + _setState(); +} + +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pTableViewHeader::_setState() -> void { + if(auto parent = _parent()) { + //parent->qtTableView->setAlternatingRowColors(self().columnCount() >= 2); + parent->qtTableView->setColumnCount(self().columnCount()); + parent->qtTableView->setHeaderHidden(!self().visible()); + for(auto& column : state().columns) { + if(auto self = column->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/hiro/qt/widget/table-view-header.hpp b/hiro/qt/widget/table-view-header.hpp new file mode 100644 index 00000000..814f3ac8 --- /dev/null +++ b/hiro/qt/widget/table-view-header.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/qt/widget/table-view-item.cpp b/hiro/qt/widget/table-view-item.cpp new file mode 100644 index 00000000..8635b0f9 --- /dev/null +++ b/hiro/qt/widget/table-view-item.cpp @@ -0,0 +1,66 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewItem::construct() -> void { +} + +auto pTableViewItem::destruct() -> void { + if(auto parent = _parent()) parent->lock(); + if(qtItem) { + delete qtItem; + qtItem = nullptr; + } + if(auto parent = _parent()) parent->unlock(); +} + +auto pTableViewItem::append(sTableViewCell cell) -> void { + _setState(); +} + +auto pTableViewItem::remove(sTableViewCell cell) -> void { + _setState(); +} + +auto pTableViewItem::setAlignment(Alignment alignment) -> void { + _setState(); +} + +auto pTableViewItem::setBackgroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewItem::setFont(const Font& font) -> void { + _setState(); +} + +auto pTableViewItem::setForegroundColor(Color color) -> void { + _setState(); +} + +auto pTableViewItem::setSelected(bool selected) -> void { + _setState(); +} + +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { + if(auto delegate = parent->self()) return *delegate; + } + return nothing; +} + +auto pTableViewItem::_setState() -> void { + if(auto parent = _parent()) { + qtItem->setSelected(state().selected); + if(state().selected) { + parent->qtTableView->setCurrentItem(qtItem); + } + for(auto& cell : state().cells) { + if(auto self = cell->self()) self->_setState(); + } + } +} + +} + +#endif diff --git a/hiro/qt/widget/list-view-item.hpp b/hiro/qt/widget/table-view-item.hpp similarity index 60% rename from hiro/qt/widget/list-view-item.hpp rename to hiro/qt/widget/table-view-item.hpp index eb51d302..a05509a6 100644 --- a/hiro/qt/widget/list-view-item.hpp +++ b/hiro/qt/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFont(const Font& font) -> void override; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; QTreeWidgetItem* qtItem = nullptr; diff --git a/hiro/qt/widget/list-view.cpp b/hiro/qt/widget/table-view.cpp similarity index 56% rename from hiro/qt/widget/list-view.cpp rename to hiro/qt/widget/table-view.cpp index 3bd27a34..36532b32 100644 --- a/hiro/qt/widget/list-view.cpp +++ b/hiro/qt/widget/table-view.cpp @@ -1,23 +1,23 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListView::construct() -> void { - qtWidget = qtListView = new QtListView(*this); - qtListView->setAllColumnsShowFocus(true); - qtListView->setContextMenuPolicy(Qt::CustomContextMenu); - qtListView->setRootIsDecorated(false); - qtListView->setHeaderHidden(true); - qtListView->header()->setMovable(false); +auto pTableView::construct() -> void { + qtWidget = qtTableView = new QtTableView(*this); + qtTableView->setAllColumnsShowFocus(true); + qtTableView->setContextMenuPolicy(Qt::CustomContextMenu); + qtTableView->setRootIsDecorated(false); + qtTableView->setHeaderHidden(true); + qtTableView->header()->setMovable(false); - qtListViewDelegate = new QtListViewDelegate(*this); - qtListView->setItemDelegate(qtListViewDelegate); + qtTableViewDelegate = new QtTableViewDelegate(*this); + qtTableView->setItemDelegate(qtTableViewDelegate); - qtListView->connect(qtListView, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(onActivate())); - qtListView->connect(qtListView, SIGNAL(itemSelectionChanged()), SLOT(onChange())); - qtListView->connect(qtListView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onContext())); - qtListView->connect(qtListView->header(), SIGNAL(sectionClicked(int)), SLOT(onSort(int))); - qtListView->connect(qtListView, SIGNAL(itemChanged(QTreeWidgetItem*, int)), SLOT(onToggle(QTreeWidgetItem*, int))); + qtTableView->connect(qtTableView, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(onActivate())); + qtTableView->connect(qtTableView, SIGNAL(itemSelectionChanged()), SLOT(onChange())); + qtTableView->connect(qtTableView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onContext())); + qtTableView->connect(qtTableView->header(), SIGNAL(sectionClicked(int)), SLOT(onSort(int))); + qtTableView->connect(qtTableView, SIGNAL(itemChanged(QTreeWidgetItem*, int)), SLOT(onToggle(QTreeWidgetItem*, int))); setBackgroundColor(state().backgroundColor); setBatchable(state().batchable); @@ -27,14 +27,14 @@ auto pListView::construct() -> void { pWidget::construct(); } -auto pListView::destruct() -> void { - delete qtListViewDelegate; - delete qtListView; - qtWidget = qtListView = nullptr; - qtListViewDelegate = nullptr; +auto pTableView::destruct() -> void { + delete qtTableViewDelegate; + delete qtTableView; + qtWidget = qtTableView = nullptr; + qtTableViewDelegate = nullptr; } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { lock(); if(auto self = header->self()) { self->_setState(); @@ -42,22 +42,22 @@ auto pListView::append(sListViewHeader header) -> void { unlock(); } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { lock(); if(auto self = item->self()) { - self->qtItem = new QTreeWidgetItem(qtListView); + self->qtItem = new QTreeWidgetItem(qtTableView); self->_setState(); } unlock(); } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { lock(); if(auto& header = state().header) { @@ -72,7 +72,7 @@ auto pListView::resizeColumns() -> void { } signed maximumWidth = self().geometry().width() - 6; - if(auto scrollBar = qtListView->verticalScrollBar()) { + if(auto scrollBar = qtTableView->verticalScrollBar()) { if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width(); } @@ -84,50 +84,50 @@ auto pListView::resizeColumns() -> void { for(auto column : range(header->columnCount())) { signed width = widths[column]; if(header->column(column).expandable()) width += expandWidth; - qtListView->setColumnWidth(column, width); + qtTableView->setColumnWidth(column, width); } } unlock(); } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { if(color) { - QPalette palette = qtListView->palette(); + QPalette palette = qtTableView->palette(); palette.setColor(QPalette::Base, QColor(color.red(), color.green(), color.blue())); palette.setColor(QPalette::AlternateBase, QColor(max(0, (signed)color.red() - 17), max(0, (signed)color.green() - 17), max(0, (signed)color.blue() - 17))); - qtListView->setPalette(palette); - qtListView->setAutoFillBackground(true); + qtTableView->setPalette(palette); + qtTableView->setAutoFillBackground(true); } else { //todo: set default color } } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { lock(); - qtListView->setSelectionMode(batchable ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection); + qtTableView->setSelectionMode(batchable ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection); unlock(); } -auto pListView::setBordered(bool bordered) -> void { - qtListView->repaint(); +auto pTableView::setBordered(bool bordered) -> void { + qtTableView->repaint(); } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { if(color) { - QPalette palette = qtListView->palette(); + QPalette palette = qtTableView->palette(); palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue())); - qtListView->setPalette(palette); + qtTableView->setPalette(palette); } else { //todo: set default color } } //called on resize/show events -auto pListView::_onSize() -> void { +auto pTableView::_onSize() -> void { //resize columns only if at least one column is expandable if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -136,7 +136,7 @@ auto pListView::_onSize() -> void { } } -auto pListView::_width(unsigned column) -> unsigned { +auto pTableView::_width(unsigned column) -> unsigned { if(auto& header = state().header) { if(auto width = header->column(column).width()) return width; unsigned width = 1; @@ -150,12 +150,12 @@ auto pListView::_width(unsigned column) -> unsigned { return 1; } -auto pListView::_widthOfColumn(unsigned _column) -> unsigned { +auto pTableView::_widthOfColumn(unsigned _column) -> unsigned { unsigned width = 8; if(auto& header = state().header) { if(auto column = header->column(_column)) { if(auto& icon = column->state.icon) { - width += icon.width() + 2; + width += icon.width() + 4; } if(auto& text = column->state.text) { width += pFont::size(column->font(true), text).width(); @@ -165,15 +165,15 @@ auto pListView::_widthOfColumn(unsigned _column) -> unsigned { return width; } -auto pListView::_widthOfCell(unsigned _row, unsigned _column) -> unsigned { +auto pTableView::_widthOfCell(unsigned _row, unsigned _column) -> unsigned { unsigned width = 8; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(cell->state.checkable) { - width += 16 + 2; + width += 16 + 4; } if(auto& icon = cell->state.icon) { - width += icon.width() + 2; + width += icon.width() + 4; } if(auto& text = cell->state.text) { width += pFont::size(cell->font(true), text).width(); @@ -183,11 +183,11 @@ auto pListView::_widthOfCell(unsigned _row, unsigned _column) -> unsigned { return width; } -auto QtListView::onActivate() -> void { +auto QtTableView::onActivate() -> void { if(!p.locked()) p.self().doActivate(); } -auto QtListView::onChange() -> void { +auto QtTableView::onChange() -> void { for(auto& item : p.state().items) { item->state.selected = false; if(auto self = item->self()) { @@ -197,11 +197,11 @@ auto QtListView::onChange() -> void { if(!p.locked()) p.self().doChange(); } -auto QtListView::onContext() -> void { +auto QtTableView::onContext() -> void { if(!p.locked()) p.self().doContext(); } -auto QtListView::onSort(int columnNumber) -> void { +auto QtTableView::onSort(int columnNumber) -> void { if(auto& header = p.state().header) { if(auto column = header->column(columnNumber)) { if(!p.locked() && column.sortable()) p.self().doSort(column); @@ -209,7 +209,7 @@ auto QtListView::onSort(int columnNumber) -> void { } } -auto QtListView::onToggle(QTreeWidgetItem* qtItem, int column) -> void { +auto QtTableView::onToggle(QTreeWidgetItem* qtItem, int column) -> void { for(auto& item : p.state().items) { if(auto self = item->self()) { if(qtItem == self->qtItem) { @@ -222,25 +222,25 @@ auto QtListView::onToggle(QTreeWidgetItem* qtItem, int column) -> void { } } -auto QtListView::mousePressEvent(QMouseEvent* event) -> void { +auto QtTableView::mousePressEvent(QMouseEvent* event) -> void { QTreeWidget::mousePressEvent(event); if(event->button() == Qt::RightButton) onContext(); } -auto QtListView::resizeEvent(QResizeEvent* event) -> void { +auto QtTableView::resizeEvent(QResizeEvent* event) -> void { QTreeWidget::resizeEvent(event); p._onSize(); } -auto QtListView::showEvent(QShowEvent* event) -> void { +auto QtTableView::showEvent(QShowEvent* event) -> void { QTreeWidget::showEvent(event); p._onSize(); } -QtListViewDelegate::QtListViewDelegate(pListView& p) : QStyledItemDelegate(p.qtListView), p(p) { +QtTableViewDelegate::QtTableViewDelegate(pTableView& p) : QStyledItemDelegate(p.qtTableView), p(p) { } -auto QtListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void { +auto QtTableViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -> void { QStyledItemDelegate::paint(painter, option, index); if(p.state().bordered) { QPen pen; diff --git a/hiro/qt/widget/list-view.hpp b/hiro/qt/widget/table-view.hpp similarity index 57% rename from hiro/qt/widget/list-view.hpp rename to hiro/qt/widget/table-view.hpp index 20bac6bc..f36f6403 100644 --- a/hiro/qt/widget/list-view.hpp +++ b/hiro/qt/widget/table-view.hpp @@ -1,14 +1,14 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader header) -> void; - auto append(sListViewItem item) -> void; - auto remove(sListViewHeader header) -> void; - auto remove(sListViewItem item) -> void; + auto append(sTableViewHeader header) -> void; + auto append(sTableViewItem item) -> void; + auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -21,8 +21,8 @@ struct pListView : pWidget { auto _widthOfColumn(unsigned column) -> unsigned; auto _widthOfCell(unsigned row, unsigned column) -> unsigned; - QtListView* qtListView = nullptr; - QtListViewDelegate* qtListViewDelegate = nullptr; + QtTableView* qtTableView = nullptr; + QtTableViewDelegate* qtTableViewDelegate = nullptr; }; } diff --git a/hiro/windows/application.cpp b/hiro/windows/application.cpp index 67d29081..9b80eba4 100644 --- a/hiro/windows/application.cpp +++ b/hiro/windows/application.cpp @@ -163,10 +163,10 @@ static auto Application_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM if(msg == WM_KEYDOWN) { if(0); - #if defined(Hiro_ListView) - else if(auto listView = dynamic_cast(object)) { + #if defined(Hiro_TableView) + else if(auto tableView = dynamic_cast(object)) { if(wparam == VK_RETURN) { - if(listView->selected()) return true; //returning true generates LVN_ITEMACTIVATE message + if(tableView->selected()) return true; //returning true generates LVN_ITEMACTIVATE message } } #endif diff --git a/hiro/windows/platform.cpp b/hiro/windows/platform.cpp index 42dac191..799c8a43 100644 --- a/hiro/windows/platform.cpp +++ b/hiro/windows/platform.cpp @@ -41,11 +41,11 @@ #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" -#include "widget/list-view.cpp" -#include "widget/list-view-header.cpp" -#include "widget/list-view-column.cpp" -#include "widget/list-view-item.cpp" -#include "widget/list-view-cell.cpp" +#include "widget/table-view.cpp" +#include "widget/table-view-header.cpp" +#include "widget/table-view-column.cpp" +#include "widget/table-view-item.cpp" +#include "widget/table-view-cell.cpp" #include "widget/progress-bar.cpp" #include "widget/radio-button.cpp" #include "widget/radio-label.cpp" diff --git a/hiro/windows/platform.hpp b/hiro/windows/platform.hpp index 7c6be74c..36a4e1ed 100644 --- a/hiro/windows/platform.hpp +++ b/hiro/windows/platform.hpp @@ -10,9 +10,9 @@ struct pWidget; struct AppMessage { enum : unsigned { None = WM_APP, - ListView_doPaint, - ListView_onActivate, - ListView_onChange, + TableView_doPaint, + TableView_onActivate, + TableView_onChange, }; }; @@ -70,16 +70,16 @@ static vector windows; #include "widget/horizontal-slider.hpp" #include "widget/label.hpp" #include "widget/line-edit.hpp" -#include "widget/list-view.hpp" -#include "widget/list-view-header.hpp" -#include "widget/list-view-column.hpp" -#include "widget/list-view-item.hpp" -#include "widget/list-view-cell.hpp" #include "widget/progress-bar.hpp" #include "widget/radio-button.hpp" #include "widget/radio-label.hpp" #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" +#include "widget/table-view.hpp" +#include "widget/table-view-header.hpp" +#include "widget/table-view-column.hpp" +#include "widget/table-view-item.hpp" +#include "widget/table-view-cell.hpp" #include "widget/text-edit.hpp" #include "widget/vertical-scroll-bar.hpp" #include "widget/vertical-slider.hpp" diff --git a/hiro/windows/utility.cpp b/hiro/windows/utility.cpp index ff1b77e8..31ca0f60 100644 --- a/hiro/windows/utility.cpp +++ b/hiro/windows/utility.cpp @@ -298,31 +298,31 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms auto object = (mObject*)GetWindowLongPtr((HWND)header->hwndFrom, GWLP_USERDATA); if(!object) break; - #if defined(Hiro_ListView) - if(auto listView = dynamic_cast(object)) { + #if defined(Hiro_TableView) + if(auto tableView = dynamic_cast(object)) { if(header->code == LVN_ITEMACTIVATE) { - listView->self()->onActivate(lparam); + tableView->self()->onActivate(lparam); break; } if(header->code == LVN_ITEMCHANGED) { - listView->self()->onChange(lparam); + tableView->self()->onChange(lparam); break; } if(header->code == LVN_COLUMNCLICK) { - if(isWindowCallback) listView->self()->onSort(lparam); + if(isWindowCallback) tableView->self()->onSort(lparam); break; } if(header->code == NM_CLICK || header->code == NM_DBLCLK) { - //onToggle performs the test to ensure the ListViewItem clicked was checkable - if(isWindowCallback) listView->self()->onToggle(lparam); + //onToggle performs the test to ensure the TableViewItem clicked was checkable + if(isWindowCallback) tableView->self()->onToggle(lparam); break; } if(header->code == NM_RCLICK) { - if(isWindowCallback) listView->self()->onContext(lparam); + if(isWindowCallback) tableView->self()->onContext(lparam); break; } if(header->code == NM_CUSTOMDRAW) { - return listView->self()->onCustomDraw(lparam); + return tableView->self()->onCustomDraw(lparam); } } #endif @@ -339,21 +339,21 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms break; } - #if defined(Hiro_ListView) - case AppMessage::ListView_doPaint: { - if(auto listView = (mListView*)lparam) { - if(auto self = listView->self()) InvalidateRect(self->hwnd, nullptr, true); + #if defined(Hiro_TableView) + case AppMessage::TableView_doPaint: { + if(auto tableView = (mTableView*)lparam) { + if(auto self = tableView->self()) InvalidateRect(self->hwnd, nullptr, true); } break; } - case AppMessage::ListView_onActivate: { - if(auto listView = (mListView*)lparam) listView->doActivate(); + case AppMessage::TableView_onActivate: { + if(auto tableView = (mTableView*)lparam) tableView->doActivate(); break; } - case AppMessage::ListView_onChange: { - if(auto listView = (mListView*)lparam) listView->doChange(); + case AppMessage::TableView_onChange: { + if(auto tableView = (mTableView*)lparam) tableView->doChange(); } #endif diff --git a/hiro/windows/widget/canvas.cpp b/hiro/windows/widget/canvas.cpp index f4f23127..72278cb1 100644 --- a/hiro/windows/widget/canvas.cpp +++ b/hiro/windows/widget/canvas.cpp @@ -151,7 +151,8 @@ auto pCanvas::_rasterize() -> void { } if(width <= 0 || height <= 0) return; - pixels.reallocate(width * height); + pixels.reset(); + pixels.resize(width * height); if(auto& icon = state().icon) { memory::copy(pixels.data(), icon.data(), width * height * sizeof(uint32)); diff --git a/hiro/windows/widget/list-view-cell.cpp b/hiro/windows/widget/list-view-cell.cpp deleted file mode 100644 index 0b912aae..00000000 --- a/hiro/windows/widget/list-view-cell.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -auto pListViewCell::construct() -> void { -} - -auto pListViewCell::destruct() -> void { -} - -auto pListViewCell::setAlignment(Alignment alignment) -> void { -} - -auto pListViewCell::setBackgroundColor(Color color) -> void { - _repaint(); -} - -auto pListViewCell::setCheckable(bool checkable) -> void { - _repaint(); -} - -auto pListViewCell::setChecked(bool checked) -> void { - _repaint(); -} - -auto pListViewCell::setForegroundColor(Color color) -> void { - _repaint(); -} - -auto pListViewCell::setIcon(const image& icon) -> void { - _repaint(); -} - -auto pListViewCell::setText(const string& text) -> void { - _repaint(); -} - -auto pListViewCell::_parent() -> maybe { - if(auto parent = self().parentListViewItem()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -auto pListViewCell::_repaint() -> void { - if(auto parent = _parent()) { - if(auto listView = parent->_parent()) { - //ListView uses a custom drawing routine; so we need to tell the control to repaint itself manually - PostMessageOnce(listView->_parentHandle(), AppMessage::ListView_doPaint, 0, (LPARAM)&listView->reference); - } - } -} - -auto pListViewCell::_setState() -> void { - if(auto item = _parent()) { - if(auto parent = item->_parent()) { - parent->lock(); - wchar_t text[] = L""; - LVITEM lvItem; - lvItem.mask = LVIF_TEXT; - lvItem.iItem = item->self().offset(); - lvItem.iSubItem = self().offset(); - lvItem.pszText = text; - ListView_SetItem(parent->hwnd, &lvItem); - parent->unlock(); - } - } -} - -} - -#endif diff --git a/hiro/windows/widget/list-view-header.hpp b/hiro/windows/widget/list-view-header.hpp deleted file mode 100644 index a46855bb..00000000 --- a/hiro/windows/widget/list-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_ListView) - -namespace hiro { - -struct pListViewHeader : pObject { - Declare(ListViewHeader, Object) - - auto append(sListViewColumn column) -> void; - auto remove(sListViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/hiro/windows/widget/table-view-cell.cpp b/hiro/windows/widget/table-view-cell.cpp new file mode 100644 index 00000000..3d373caf --- /dev/null +++ b/hiro/windows/widget/table-view-cell.cpp @@ -0,0 +1,72 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +auto pTableViewCell::construct() -> void { +} + +auto pTableViewCell::destruct() -> void { +} + +auto pTableViewCell::setAlignment(Alignment alignment) -> void { +} + +auto pTableViewCell::setBackgroundColor(Color color) -> void { + _repaint(); +} + +auto pTableViewCell::setCheckable(bool checkable) -> void { + _repaint(); +} + +auto pTableViewCell::setChecked(bool checked) -> void { + _repaint(); +} + +auto pTableViewCell::setForegroundColor(Color color) -> void { + _repaint(); +} + +auto pTableViewCell::setIcon(const image& icon) -> void { + _repaint(); +} + +auto pTableViewCell::setText(const string& text) -> void { + _repaint(); +} + +auto pTableViewCell::_parent() -> maybe { + if(auto parent = self().parentTableViewItem()) { + if(auto self = parent->self()) return *self; + } + return nothing; +} + +auto pTableViewCell::_repaint() -> void { + if(auto parent = _parent()) { + if(auto tableView = parent->_parent()) { + //TableView uses a custom drawing routine; so we need to tell the control to repaint itself manually + PostMessageOnce(tableView->_parentHandle(), AppMessage::TableView_doPaint, 0, (LPARAM)&tableView->reference); + } + } +} + +auto pTableViewCell::_setState() -> void { + if(auto item = _parent()) { + if(auto parent = item->_parent()) { + parent->lock(); + wchar_t text[] = L""; + LVITEM lvItem; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = item->self().offset(); + lvItem.iSubItem = self().offset(); + lvItem.pszText = text; + ListView_SetItem(parent->hwnd, &lvItem); + parent->unlock(); + } + } +} + +} + +#endif diff --git a/hiro/windows/widget/list-view-cell.hpp b/hiro/windows/widget/table-view-cell.hpp similarity index 74% rename from hiro/windows/widget/list-view-cell.hpp rename to hiro/windows/widget/table-view-cell.hpp index d5c62923..229dc43b 100644 --- a/hiro/windows/widget/list-view-cell.hpp +++ b/hiro/windows/widget/table-view-cell.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewCell : pObject { - Declare(ListViewCell, Object) +struct pTableViewCell : pObject { + Declare(TableViewCell, Object) auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; @@ -13,7 +13,7 @@ struct pListViewCell : pObject { auto setIcon(const image& icon) -> void; auto setText(const string& text) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _repaint() -> void; auto _setState() -> void; }; diff --git a/hiro/windows/widget/list-view-column.cpp b/hiro/windows/widget/table-view-column.cpp similarity index 58% rename from hiro/windows/widget/list-view-column.cpp rename to hiro/windows/widget/table-view-column.cpp index ef2871b3..76fb61d3 100644 --- a/hiro/windows/widget/list-view-column.cpp +++ b/hiro/windows/widget/table-view-column.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewColumn::construct() -> void { +auto pTableViewColumn::construct() -> void { if(auto grandparent = _grandparent()) { grandparent->lock(); wchar_t text[] = L""; @@ -17,7 +17,7 @@ auto pListViewColumn::construct() -> void { } } -auto pListViewColumn::destruct() -> void { +auto pTableViewColumn::destruct() -> void { if(auto grandparent = _grandparent()) { grandparent->lock(); ListView_DeleteColumn(grandparent->hwnd, self().offset()); @@ -25,65 +25,65 @@ auto pListViewColumn::destruct() -> void { } } -auto pListViewColumn::setActive() -> void { +auto pTableViewColumn::setActive() -> void { //unsupported } -auto pListViewColumn::setAlignment(Alignment alignment) -> void { +auto pTableViewColumn::setAlignment(Alignment alignment) -> void { } -auto pListViewColumn::setBackgroundColor(Color color) -> void { +auto pTableViewColumn::setBackgroundColor(Color color) -> void { } -auto pListViewColumn::setEditable(bool editable) -> void { +auto pTableViewColumn::setEditable(bool editable) -> void { //unsupported } -auto pListViewColumn::setExpandable(bool expandable) -> void { +auto pTableViewColumn::setExpandable(bool expandable) -> void { } -auto pListViewColumn::setForegroundColor(Color color) -> void { +auto pTableViewColumn::setForegroundColor(Color color) -> void { } -auto pListViewColumn::setHorizontalAlignment(double alignment) -> void { +auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { _setState(); } -auto pListViewColumn::setIcon(const image& icon) -> void { +auto pTableViewColumn::setIcon(const image& icon) -> void { _setState(); } -auto pListViewColumn::setResizable(bool resizable) -> void { +auto pTableViewColumn::setResizable(bool resizable) -> void { _setState(); } -auto pListViewColumn::setSortable(bool sortable) -> void { +auto pTableViewColumn::setSortable(bool sortable) -> void { } -auto pListViewColumn::setText(const string& text) -> void { +auto pTableViewColumn::setText(const string& text) -> void { _setState(); } -auto pListViewColumn::setVerticalAlignment(double alignment) -> void { +auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { } -auto pListViewColumn::setWidth(signed width) -> void { +auto pTableViewColumn::setWidth(signed width) -> void { _setState(); } -auto pListViewColumn::_grandparent() -> maybe { +auto pTableViewColumn::_grandparent() -> maybe { if(auto parent = _parent()) return parent->_parent(); return nothing; } -auto pListViewColumn::_parent() -> maybe { - if(auto parent = self().parentListViewHeader()) { +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableViewHeader()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewColumn::_setState() -> void { +auto pTableViewColumn::_setState() -> void { if(auto grandparent = _grandparent()) { grandparent->lock(); grandparent->_setIcons(); diff --git a/hiro/windows/widget/list-view-column.hpp b/hiro/windows/widget/table-view-column.hpp similarity index 71% rename from hiro/windows/widget/list-view-column.hpp rename to hiro/windows/widget/table-view-column.hpp index 2c00c654..91c503f7 100644 --- a/hiro/windows/widget/list-view-column.hpp +++ b/hiro/windows/widget/table-view-column.hpp @@ -1,9 +1,9 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewColumn : pObject { - Declare(ListViewColumn, Object) +struct pTableViewColumn : pObject { + Declare(TableViewColumn, Object) auto setActive() -> void; auto setAlignment(Alignment alignment) -> void; @@ -19,11 +19,11 @@ struct pListViewColumn : pObject { auto setVerticalAlignment(double alignment) -> void; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _grandparent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; - signed _width = 128; //computed width (via ListView::resizeColumns) + signed _width = 128; //computed width (via TableView::resizeColumns) }; } diff --git a/hiro/windows/widget/list-view-header.cpp b/hiro/windows/widget/table-view-header.cpp similarity index 51% rename from hiro/windows/widget/list-view-header.cpp rename to hiro/windows/widget/table-view-header.cpp index fbce80c5..71f02a47 100644 --- a/hiro/windows/widget/list-view-header.cpp +++ b/hiro/windows/widget/table-view-header.cpp @@ -1,32 +1,32 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewHeader::construct() -> void { +auto pTableViewHeader::construct() -> void { _setState(); } -auto pListViewHeader::destruct() -> void { +auto pTableViewHeader::destruct() -> void { } -auto pListViewHeader::append(sListViewColumn column) -> void { +auto pTableViewHeader::append(sTableViewColumn column) -> void { } -auto pListViewHeader::remove(sListViewColumn column) -> void { +auto pTableViewHeader::remove(sTableViewColumn column) -> void { } -auto pListViewHeader::setVisible(bool visible) -> void { +auto pTableViewHeader::setVisible(bool visible) -> void { _setState(); } -auto pListViewHeader::_parent() -> maybe { - if(auto parent = self().parentListView()) { +auto pTableViewHeader::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewHeader::_setState() -> void { +auto pTableViewHeader::_setState() -> void { if(auto parent = _parent()) { auto style = GetWindowLong(parent->hwnd, GWL_STYLE); self().visible() ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER; diff --git a/hiro/windows/widget/table-view-header.hpp b/hiro/windows/widget/table-view-header.hpp new file mode 100644 index 00000000..814f3ac8 --- /dev/null +++ b/hiro/windows/widget/table-view-header.hpp @@ -0,0 +1,18 @@ +#if defined(Hiro_TableView) + +namespace hiro { + +struct pTableViewHeader : pObject { + Declare(TableViewHeader, Object) + + auto append(sTableViewColumn column) -> void; + auto remove(sTableViewColumn column) -> void; + auto setVisible(bool visible) -> void override; + + auto _parent() -> maybe; + auto _setState() -> void; +}; + +} + +#endif diff --git a/hiro/windows/widget/list-view-item.cpp b/hiro/windows/widget/table-view-item.cpp similarity index 60% rename from hiro/windows/widget/list-view-item.cpp rename to hiro/windows/widget/table-view-item.cpp index b9562862..be42bfe8 100644 --- a/hiro/windows/widget/list-view-item.cpp +++ b/hiro/windows/widget/table-view-item.cpp @@ -1,8 +1,8 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -auto pListViewItem::construct() -> void { +auto pTableViewItem::construct() -> void { if(auto parent = _parent()) { parent->lock(); wchar_t text[] = L""; @@ -17,7 +17,7 @@ auto pListViewItem::construct() -> void { } } -auto pListViewItem::destruct() -> void { +auto pTableViewItem::destruct() -> void { if(auto parent = _parent()) { parent->lock(); ListView_DeleteItem(parent->hwnd, self().offset()); @@ -25,19 +25,19 @@ auto pListViewItem::destruct() -> void { } } -auto pListViewItem::append(sListViewCell cell) -> void { +auto pTableViewItem::append(sTableViewCell cell) -> void { } -auto pListViewItem::remove(sListViewCell cell) -> void { +auto pTableViewItem::remove(sTableViewCell cell) -> void { } -auto pListViewItem::setAlignment(Alignment alignment) -> void { +auto pTableViewItem::setAlignment(Alignment alignment) -> void { } -auto pListViewItem::setBackgroundColor(Color color) -> void { +auto pTableViewItem::setBackgroundColor(Color color) -> void { } -auto pListViewItem::setFocused() -> void { +auto pTableViewItem::setFocused() -> void { if(auto parent = _parent()) { parent->lock(); ListView_SetItemState(parent->hwnd, self().offset(), LVIS_FOCUSED, LVIS_FOCUSED); @@ -45,21 +45,21 @@ auto pListViewItem::setFocused() -> void { } } -auto pListViewItem::setForegroundColor(Color color) -> void { +auto pTableViewItem::setForegroundColor(Color color) -> void { } -auto pListViewItem::setSelected(bool selected) -> void { +auto pTableViewItem::setSelected(bool selected) -> void { _setState(); } -auto pListViewItem::_parent() -> maybe { - if(auto parent = self().parentListView()) { +auto pTableViewItem::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } return nothing; } -auto pListViewItem::_setState() -> void { +auto pTableViewItem::_setState() -> void { if(auto parent = _parent()) { parent->lock(); ListView_SetItemState(parent->hwnd, self().offset(), state().selected ? LVIS_SELECTED : 0, LVIS_SELECTED); diff --git a/hiro/windows/widget/list-view-item.hpp b/hiro/windows/widget/table-view-item.hpp similarity index 55% rename from hiro/windows/widget/list-view-item.hpp rename to hiro/windows/widget/table-view-item.hpp index bc0d3c26..00b5a97b 100644 --- a/hiro/windows/widget/list-view-item.hpp +++ b/hiro/windows/widget/table-view-item.hpp @@ -1,19 +1,19 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListViewItem : pObject { - Declare(ListViewItem, Object) +struct pTableViewItem : pObject { + Declare(TableViewItem, Object) - auto append(sListViewCell cell) -> void; - auto remove(sListViewCell cell) -> void; + auto append(sTableViewCell cell) -> void; + auto remove(sTableViewCell cell) -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; auto setFocused() -> void; auto setForegroundColor(Color color) -> void; auto setSelected(bool selected) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/hiro/windows/widget/list-view.cpp b/hiro/windows/widget/table-view.cpp similarity index 85% rename from hiro/windows/widget/list-view.cpp rename to hiro/windows/widget/table-view.cpp index fa561b20..fb0c3040 100644 --- a/hiro/windows/widget/list-view.cpp +++ b/hiro/windows/widget/table-view.cpp @@ -1,12 +1,12 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -static auto CALLBACK ListView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { +static auto CALLBACK TableView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { if(auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA)) { - if(auto listView = dynamic_cast(object)) { - if(auto self = listView->self()) { - if(!listView->enabled(true)) { + if(auto tableView = dynamic_cast(object)) { + if(auto self = tableView->self()) { + if(!tableView->enabled(true)) { if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) { //WC_LISTVIEW responds to key messages even when its HWND is disabled //the control should be inactive when disabled; so we intercept the messages here @@ -21,7 +21,7 @@ static auto CALLBACK ListView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPA return DefWindowProc(hwnd, msg, wparam, lparam); } -auto pListView::construct() -> void { +auto pTableView::construct() -> void { hwnd = CreateWindowEx( WS_EX_CLIENTEDGE | LVS_EX_DOUBLEBUFFER, WC_LISTVIEW, L"", WS_CHILD | WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS, @@ -29,7 +29,7 @@ auto pListView::construct() -> void { ); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&reference); windowProc = (WindowProc)GetWindowLongPtr(hwnd, GWLP_WNDPROC); - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)&ListView_windowProc); + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)&TableView_windowProc); ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES); pWidget::_setState(); setBackgroundColor(state().backgroundColor); @@ -40,28 +40,28 @@ auto pListView::construct() -> void { resizeColumns(); } -auto pListView::destruct() -> void { +auto pTableView::destruct() -> void { if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; } DestroyWindow(hwnd); } -auto pListView::append(sListViewHeader header) -> void { +auto pTableView::append(sTableViewHeader header) -> void { } -auto pListView::append(sListViewItem item) -> void { +auto pTableView::append(sTableViewItem item) -> void { } -auto pListView::remove(sListViewHeader header) -> void { +auto pTableView::remove(sTableViewHeader header) -> void { LVCOLUMN lvColumn{LVCF_WIDTH}; while(ListView_GetColumn(hwnd, 0, &lvColumn)) { ListView_DeleteColumn(hwnd, 0); } } -auto pListView::remove(sListViewItem item) -> void { +auto pTableView::remove(sTableViewItem item) -> void { } -auto pListView::resizeColumns() -> void { +auto pTableView::resizeColumns() -> void { lock(); if(auto& header = state().header) { @@ -101,28 +101,28 @@ auto pListView::resizeColumns() -> void { unlock(); } -auto pListView::setAlignment(Alignment alignment) -> void { +auto pTableView::setAlignment(Alignment alignment) -> void { } -auto pListView::setBackgroundColor(Color color) -> void { +auto pTableView::setBackgroundColor(Color color) -> void { if(!color) color = {255, 255, 255}; ListView_SetBkColor(hwnd, RGB(color.red(), color.green(), color.blue())); } -auto pListView::setBatchable(bool batchable) -> void { +auto pTableView::setBatchable(bool batchable) -> void { auto style = GetWindowLong(hwnd, GWL_STYLE); !batchable ? style |= LVS_SINGLESEL : style &=~ LVS_SINGLESEL; SetWindowLong(hwnd, GWL_STYLE, style); } -auto pListView::setBordered(bool bordered) -> void { +auto pTableView::setBordered(bool bordered) -> void { //rendered via onCustomDraw } -auto pListView::setForegroundColor(Color color) -> void { +auto pTableView::setForegroundColor(Color color) -> void { } -auto pListView::setGeometry(Geometry geometry) -> void { +auto pTableView::setGeometry(Geometry geometry) -> void { pWidget::setGeometry(geometry); if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -131,17 +131,17 @@ auto pListView::setGeometry(Geometry geometry) -> void { } } -auto pListView::onActivate(LPARAM lparam) -> void { +auto pTableView::onActivate(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; if(ListView_GetSelectedCount(hwnd) == 0) return; if(!locked()) { //LVN_ITEMACTIVATE is not re-entrant until DispatchMessage() completes //thus, we don't call self().doActivate() here - PostMessageOnce(_parentHandle(), AppMessage::ListView_onActivate, 0, (LPARAM)&reference); + PostMessageOnce(_parentHandle(), AppMessage::TableView_onActivate, 0, (LPARAM)&reference); } } -auto pListView::onChange(LPARAM lparam) -> void { +auto pTableView::onChange(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; if(!(nmlistview->uChanged & LVIF_STATE)) return; @@ -157,16 +157,16 @@ auto pListView::onChange(LPARAM lparam) -> void { //state event change messages are sent for every item //so when doing a batch select/deselect; this can generate several messages //we use a delayed AppMessage so that only one callback event is fired off - PostMessageOnce(_parentHandle(), AppMessage::ListView_onChange, 0, (LPARAM)&reference); + PostMessageOnce(_parentHandle(), AppMessage::TableView_onChange, 0, (LPARAM)&reference); } } -auto pListView::onContext(LPARAM lparam) -> void { +auto pTableView::onContext(LPARAM lparam) -> void { auto nmitemactivate = (LPNMITEMACTIVATE)lparam; return self().doContext(); } -auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { +auto pTableView::onCustomDraw(LPARAM lparam) -> LRESULT { auto lvcd = (LPNMLVCUSTOMDRAW)lparam; switch(lvcd->nmcd.dwDrawStage) { @@ -275,7 +275,7 @@ auto pListView::onCustomDraw(LPARAM lparam) -> LRESULT { return CDRF_SKIPDEFAULT; } -auto pListView::onSort(LPARAM lparam) -> void { +auto pTableView::onSort(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; if(auto& header = state().header) { if(auto column = header->column(nmlistview->iSubItem)) { @@ -284,7 +284,7 @@ auto pListView::onSort(LPARAM lparam) -> void { } } -auto pListView::onToggle(LPARAM lparam) -> void { +auto pTableView::onToggle(LPARAM lparam) -> void { auto itemActivate = (LPNMITEMACTIVATE)lparam; LVHITTESTINFO hitTestInfo{0}; hitTestInfo.pt = itemActivate->ptAction; @@ -295,12 +295,12 @@ auto pListView::onToggle(LPARAM lparam) -> void { cell->state.checked = !cell->state.checked; if(!locked()) self().doToggle(cell); //todo: try to find a way to only repaint this cell instead of the entire control to reduce flickering - PostMessageOnce(_parentHandle(), AppMessage::ListView_doPaint, 0, (LPARAM)&reference); + PostMessageOnce(_parentHandle(), AppMessage::TableView_doPaint, 0, (LPARAM)&reference); } } } -auto pListView::_backgroundColor(unsigned _row, unsigned _column) -> Color { +auto pTableView::_backgroundColor(unsigned _row, unsigned _column) -> Color { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(auto color = cell->backgroundColor()) return color; @@ -315,7 +315,7 @@ auto pListView::_backgroundColor(unsigned _row, unsigned _column) -> Color { return {255, 255, 255}; } -auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { +auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { unsigned width = 6; if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { @@ -333,7 +333,7 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { return width; } -auto pListView::_columnWidth(unsigned _column) -> unsigned { +auto pTableView::_columnWidth(unsigned _column) -> unsigned { unsigned width = 12; if(auto header = state().header) { if(auto column = header->column(_column)) { @@ -348,7 +348,7 @@ auto pListView::_columnWidth(unsigned _column) -> unsigned { return width; } -auto pListView::_font(unsigned _row, unsigned _column) -> Font { +auto pTableView::_font(unsigned _row, unsigned _column) -> Font { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(auto font = cell->font()) return font; @@ -362,7 +362,7 @@ auto pListView::_font(unsigned _row, unsigned _column) -> Font { return {}; } -auto pListView::_foregroundColor(unsigned _row, unsigned _column) -> Color { +auto pTableView::_foregroundColor(unsigned _row, unsigned _column) -> Color { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(auto color = cell->foregroundColor()) return color; @@ -376,7 +376,7 @@ auto pListView::_foregroundColor(unsigned _row, unsigned _column) -> Color { return {0, 0, 0}; } -auto pListView::_setIcons() -> void { +auto pTableView::_setIcons() -> void { ListView_SetImageList(hwnd, nullptr, LVSIL_SMALL); if(imageList) ImageList_Destroy(imageList); imageList = ImageList_Create(16, 16, ILC_COLOR32, 1, 0); @@ -408,7 +408,7 @@ auto pListView::_setIcons() -> void { DeleteObject(bitmap); } -auto pListView::_setSortable() -> void { +auto pTableView::_setSortable() -> void { bool sortable = false; if(auto& header = state().header) { for(auto& column : header->state.columns) { @@ -422,7 +422,7 @@ auto pListView::_setSortable() -> void { SetWindowLong(hwnd, GWL_STYLE, style); } -auto pListView::_width(unsigned column) -> unsigned { +auto pTableView::_width(unsigned column) -> unsigned { if(auto& header = state().header) { if(auto width = header->state.columns[column]->width()) return width; unsigned width = 1; diff --git a/hiro/windows/widget/list-view.hpp b/hiro/windows/widget/table-view.hpp similarity index 80% rename from hiro/windows/widget/list-view.hpp rename to hiro/windows/widget/table-view.hpp index 3e3af014..65fa610d 100644 --- a/hiro/windows/widget/list-view.hpp +++ b/hiro/windows/widget/table-view.hpp @@ -1,14 +1,14 @@ -#if defined(Hiro_ListView) +#if defined(Hiro_TableView) namespace hiro { -struct pListView : pWidget { - Declare(ListView, Widget) +struct pTableView : pWidget { + Declare(TableView, Widget) - auto append(sListViewHeader header) -> void; - auto append(sListViewItem item) -> void; - auto remove(sListViewHeader header) -> void; - auto remove(sListViewItem item) -> void; + auto append(sTableViewHeader header) -> void; + auto append(sTableViewItem item) -> void; + auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; auto setBackgroundColor(Color color) -> void; diff --git a/hiro/windows/window.cpp b/hiro/windows/window.cpp index 393020f4..77f53ee4 100644 --- a/hiro/windows/window.cpp +++ b/hiro/windows/window.cpp @@ -177,8 +177,7 @@ auto pWindow::onClose() -> void { auto pWindow::onDrop(WPARAM wparam) -> void { lstring paths = DropPaths(wparam); - if(paths.empty()) return; - self().doDrop(paths); + if(paths) self().doDrop(paths); } auto pWindow::onEraseBackground() -> bool { diff --git a/icarus/ui/scan-dialog.cpp b/icarus/ui/scan-dialog.cpp index 342be290..e45d2718 100644 --- a/icarus/ui/scan-dialog.cpp +++ b/icarus/ui/scan-dialog.cpp @@ -19,12 +19,12 @@ ScanDialog::ScanDialog() { scanList.onActivate([&] { activate(); }); selectAllButton.setText("Select All").onActivate([&] { for(auto& item : scanList.items()) { - if(item.cell(0).checkable()) item.cell(0).setChecked(true); + if(item.checkable()) item.setChecked(true); } }); unselectAllButton.setText("Unselect All").onActivate([&] { for(auto& item : scanList.items()) { - if(item.cell(0).checkable()) item.cell(0).setChecked(false); + if(item.checkable()) item.setChecked(false); } }); settingsButton.setText("Settings ...").onActivate([&] { @@ -47,7 +47,6 @@ auto ScanDialog::show() -> void { auto ScanDialog::refresh() -> void { scanList.reset(); - scanList.append(ListViewHeader().setVisible(false).append(ListViewColumn().setExpandable())); auto pathname = pathEdit.text().transform("\\", "/").rtrim("/").append("/"); if(!directory::exists(pathname)) return; @@ -59,23 +58,22 @@ auto ScanDialog::refresh() -> void { for(auto& name : contents) { if(!name.endsWith("/")) continue; if(gamePakType(suffixname(name))) continue; - scanList.append(ListViewItem().append(ListViewCell().setIcon(Icon::Emblem::Folder).setText(name.rtrim("/")))); + scanList.append(ListViewItem().setIcon(Icon::Emblem::Folder).setText(name.rtrim("/"))); } for(auto& name : contents) { if(name.endsWith("/")) continue; if(!gameRomType(suffixname(name).downcase())) continue; - scanList.append(ListViewItem().append(ListViewCell().setCheckable().setIcon(Icon::Emblem::File).setText(name))); + scanList.append(ListViewItem().setCheckable().setIcon(Icon::Emblem::File).setText(name)); } Application::processEvents(); - scanList.resizeColumns(); scanList.setFocused(); } auto ScanDialog::activate() -> void { if(auto item = scanList.selected()) { - string location{settings["icarus/Path"].text(), item.cell(0).text()}; + string location{settings["icarus/Path"].text(), item.text()}; if(directory::exists(location) && !gamePakType(suffixname(location))) { pathEdit.setText(location); refresh(); @@ -86,8 +84,8 @@ auto ScanDialog::activate() -> void { auto ScanDialog::import() -> void { lstring filenames; for(auto& item : scanList.items()) { - if(item.cell(0).checked()) { - filenames.append(string{settings["icarus/Path"].text(), item.cell(0).text()}); + if(item.checked()) { + filenames.append(string{settings["icarus/Path"].text(), item.text()}); } } diff --git a/nall/vector/memory.hpp b/nall/vector/memory.hpp index fe4ca118..e1777870 100644 --- a/nall/vector/memory.hpp +++ b/nall/vector/memory.hpp @@ -27,7 +27,7 @@ template auto vector::reserveLeft(uint capacity) -> bool { if(_size + _left >= capacity) return false; uint left = bit::round(capacity); - auto pool = (T*)memory::allocate(sizeof(T) * (left + _right)) + left; + auto pool = (T*)memory::allocate(sizeof(T) * (left + _right)) + (left - _size); for(uint n : range(_size)) new(pool + n) T(move(_pool[n])); memory::free(_pool - _left); @@ -72,14 +72,14 @@ template auto vector::resizeLeft(uint size, const T& value) -> bo template auto vector::resizeRight(uint size, const T& value) -> bool { if(size < _size) { //shrink - for(uint n = size; n < _size; n++) _pool[n].~T(); + for(uint n : range(size, _size)) _pool[n].~T(); _right += _size - size; _size = size; return true; } if(size > _size) { //grow reserveRight(size); - for(uint n = _size; n < size; n++) new(_pool + n) T(value); + for(uint n : range(_size, size)) new(_pool + n) T(value); _right -= size - _size; _size = size; return true; diff --git a/nall/windows/registry.hpp b/nall/windows/registry.hpp index cd5767d8..e9a50559 100644 --- a/nall/windows/registry.hpp +++ b/nall/windows/registry.hpp @@ -25,8 +25,8 @@ namespace nall { struct registry { static auto exists(const string& name) -> bool { lstring part = name.split("/"); - HKEY handle, rootKey = root(part.take(0)); - string node = part.take(); + HKEY handle, rootKey = root(part.takeLeft()); + string node = part.takeRight(); string path = part.merge("\\"); if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { wchar_t data[NWR_SIZE] = L""; @@ -40,8 +40,8 @@ struct registry { static auto read(const string& name) -> string { lstring part = name.split("/"); - HKEY handle, rootKey = root(part.take(0)); - string node = part.take(); + HKEY handle, rootKey = root(part.takeLeft()); + string node = part.takeRight(); string path = part.merge("\\"); if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { wchar_t data[NWR_SIZE] = L""; @@ -55,8 +55,8 @@ struct registry { static auto write(const string& name, const string& data = "") -> void { lstring part = name.split("/"); - HKEY handle, rootKey = root(part.take(0)); - string node = part.take(), path; + HKEY handle, rootKey = root(part.takeLeft()); + string node = part.takeRight(), path; DWORD disposition; for(uint n = 0; n < part.size(); n++) { path.append(part[n]); @@ -72,8 +72,8 @@ struct registry { static auto remove(const string& name) -> bool { lstring part = name.split("/"); - HKEY rootKey = root(part.take(0)); - string node = part.take(); + HKEY rootKey = root(part.takeLeft()); + string node = part.takeRight(); string path = part.merge("\\"); if(node.empty()) return SHDeleteKeyW(rootKey, utf16_t(path)) == ERROR_SUCCESS; return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS; @@ -81,8 +81,8 @@ struct registry { static auto contents(const string& name) -> lstring { lstring part = name.split("/"), result; - HKEY handle, rootKey = root(part.take(0)); - part.remove(); + HKEY handle, rootKey = root(part.takeLeft()); + part.removeRight(); string path = part.merge("\\"); if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { DWORD folders, nodes; diff --git a/ruby/audio/wasapi.cpp b/ruby/audio/wasapi.cpp index c9d94a84..a7b9c895 100644 --- a/ruby/audio/wasapi.cpp +++ b/ruby/audio/wasapi.cpp @@ -63,12 +63,12 @@ struct AudioWASAPI : Audio { if(!available() && queuedFrames.size() >= bufferSize) { if(settings.synchronize) while(!available()); //wait for free sample slot - else queuedFrames.takeFirst(); //drop sample (run ahead) + else queuedFrames.takeLeft(); //drop sample (run ahead) } uint32_t cachedFrame = 0; for(auto n : range(available())) { - if(queuedFrames) cachedFrame = queuedFrames.takeFirst(); + if(queuedFrames) cachedFrame = queuedFrames.takeLeft(); write(cachedFrame >> 0, cachedFrame >> 16); } }