diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index fb166825..3aea4054 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "106.15"; + static const string Version = "106.16"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org/"; diff --git a/higan/target-tomoko/presentation/presentation.cpp b/higan/target-tomoko/presentation/presentation.cpp index f89a1183..dedc6458 100644 --- a/higan/target-tomoko/presentation/presentation.cpp +++ b/higan/target-tomoko/presentation/presentation.cpp @@ -6,7 +6,7 @@ unique_pointer presentation; Presentation::Presentation() { presentation = this; - libraryMenu.setText("System"); + libraryMenu.setText("Systems"); systemMenu.setVisible(false); resetSystem.setText("Soft Reset").onActivate([&] { program->softReset(); }); @@ -306,7 +306,7 @@ auto Presentation::toggleFullScreen() -> void { auto Presentation::loadSystems() -> void { libraryMenu.reset(); for(auto system : settings.find("Systems/System")) { - if(system["Hidden"].boolean()) continue; + if(!system["Show"].boolean()) continue; MenuItem item; string boot = system["Boot"].text(); item.setText({system["Name"].text(), " ..."}).onActivate([=] { @@ -328,7 +328,7 @@ auto Presentation::loadSystems() -> void { //add icarus menu option -- but only if icarus binary is present if(execute("icarus", "--name").output.strip() == "icarus") { - libraryMenu.append(MenuSeparator()); + if(libraryMenu.actionCount()) libraryMenu.append(MenuSeparator()); libraryMenu.append(MenuItem().setText("Load ROM File ...").onActivate([&] { audio->clear(); if(auto location = execute("icarus", "--import")) { diff --git a/higan/target-tomoko/settings/settings.hpp b/higan/target-tomoko/settings/settings.hpp index e3092186..505ccfd0 100644 --- a/higan/target-tomoko/settings/settings.hpp +++ b/higan/target-tomoko/settings/settings.hpp @@ -12,8 +12,7 @@ struct SystemProperties : Window { ComboEdit bootEdit{&bootLayout, Size{~0, 0}}; Button bootBrowse{&bootLayout, Size{80, 0}}; HorizontalLayout controlLayout{&layout, Size{~0, 0}}; - Widget spacer{&controlLayout, Size{40, 0}}; - CheckLabel hiddenOption{&controlLayout, Size{~0, 0}}; + Widget spacer{&controlLayout, Size{~0, 0}}; Button acceptButton{&controlLayout, Size{80, 0}}; Button cancelButton{&controlLayout, Size{80, 0}}; }; @@ -21,7 +20,12 @@ struct SystemProperties : Window { struct SystemSettings : TabFrameItem { SystemSettings(TabFrame*); auto reload() -> void; - auto acceptProperties() -> void; + auto toggle(TableViewCell) -> void; + auto moveUp() -> void; + auto moveDown() -> void; + auto modify() -> void; + auto remove() -> void; + auto accept() -> void; VerticalLayout layout{this}; TableView systemList{&layout, Size{~0, ~0}}; diff --git a/higan/target-tomoko/settings/system-properties.cpp b/higan/target-tomoko/settings/system-properties.cpp index b6fa54dc..1533ab43 100644 --- a/higan/target-tomoko/settings/system-properties.cpp +++ b/higan/target-tomoko/settings/system-properties.cpp @@ -9,14 +9,24 @@ SystemProperties::SystemProperties() { bootEdit.append(ComboEditItem().setText(emulator->information.name)); } bootBrowse.setText("Browse ...").onActivate([&] { - if(auto location = BrowserDialog().setTitle("Select Boot Game").setPath(settings["Library/Location"].text()).selectFolder()) { + string filters = "Games|"; + for(auto& emulator : program->emulators) { + for(auto& media : emulator->media) { + filters.append("*.", media.type, ":"); + } + } + filters.trimRight(":", 1L); + if(auto location = BrowserDialog() + .setTitle("Select Boot Game") + .setPath(settings["Library/Location"].text()) + .setFilters(filters) + .openFolder()) { bootEdit.setText(location); } }); - hiddenOption.setText("Hidden"); acceptButton.onActivate([&] { setVisible(false); - settingsManager->systems.acceptProperties(); + settingsManager->systems.accept(); }); cancelButton.setText("Cancel").onActivate([&] { setVisible(false); @@ -31,7 +41,6 @@ auto SystemProperties::append() -> void { setCentered(*settingsManager); nameEdit.setText(""); bootEdit.setText(""); - hiddenOption.setChecked(false); acceptButton.setText("Append"); setFocused(); setVisible(); @@ -42,7 +51,6 @@ auto SystemProperties::modify(Markup::Node system) -> void { setCentered(*settingsManager); nameEdit.setText(system["Name"].text()); bootEdit.setText(system["Boot"].text()); - hiddenOption.setChecked(system["Hidden"].boolean()); acceptButton.setText("Modify"); setFocused(); setVisible(); diff --git a/higan/target-tomoko/settings/systems.cpp b/higan/target-tomoko/settings/systems.cpp index 278fe597..1bba928d 100644 --- a/higan/target-tomoko/settings/systems.cpp +++ b/higan/target-tomoko/settings/systems.cpp @@ -9,41 +9,23 @@ SystemSettings::SystemSettings(TabFrame* parent) : TabFrameItem(parent) { }); systemList.onChange([&] { - auto selected = (bool)systemList.selected(); - upButton.setEnabled(selected); - downButton.setEnabled(selected); - modifyButton.setEnabled(selected); - removeButton.setEnabled(selected); + auto selected = systemList.selected(); + upButton.setEnabled((bool)selected && selected.offset() != 0); + downButton.setEnabled((bool)selected && selected.offset() != systemList.itemCount() - 1); + modifyButton.setEnabled((bool)selected); + removeButton.setEnabled((bool)selected); }); - upButton.setIcon(Icon::Go::Up); - downButton.setIcon(Icon::Go::Down); - - appendButton.setText("Append").onActivate([&] { - systemProperties->append(); + systemList.onToggle([&](TableViewCell cell) { + toggle(cell); }); - modifyButton.setText("Modify").onActivate([&] { - if(auto item = systemList.selected()) { - if(auto system = settings.find("Systems/System")[item.offset()]) { - systemProperties->modify(system); - } - } - }); + upButton.setIcon(Icon::Go::Up).onActivate([&] { moveUp(); }); + downButton.setIcon(Icon::Go::Down).onActivate([&] { moveDown(); }); - removeButton.setText("Remove").onActivate([&] { - if(auto item = systemList.selected()) { - if(auto system = settings.find("Systems/System")[item.offset()]) { - if(MessageDialog().setParent(*settingsManager).setText({ - "Are you sure you want to delete this system?\n\n" - "Name: ", system["Name"].text() - }).question() == "Yes") { - settings["Systems"].remove(system); - reload(); - } - } - } - }); + appendButton.setText("Append").onActivate([&] { systemProperties->append(); }); + modifyButton.setText("Modify").onActivate([&] { modify(); }); + removeButton.setText("Remove").onActivate([&] { remove(); }); reload(); } @@ -51,33 +33,88 @@ SystemSettings::SystemSettings(TabFrame* parent) : TabFrameItem(parent) { auto SystemSettings::reload() -> void { systemList.reset(); systemList.append(TableViewHeader().setVisible() + .append(TableViewColumn()) .append(TableViewColumn().setText("Name")) .append(TableViewColumn().setText("Boot").setExpandable()) ); for(auto system : settings.find("Systems/System")) { + string boot = Location::base(system["Boot"].text()); systemList.append(TableViewItem() + .append(TableViewCell().setCheckable().setChecked(system["Show"].boolean())) .append(TableViewCell().setText(system["Name"].text())) - .append(TableViewCell().setText(Location::base(system["Boot"].text()).trimRight("/", 1L))) - .setForegroundColor(system["Hidden"].boolean() ? Color{160, 160, 160} : Color{}) + .append(TableViewCell() + .setIcon(boot.endsWith("/") ? Icon::Emblem::Folder : Icon::Device::Storage) + .setText(string{boot}.trimRight("/", 1L)) + ) ); } systemList.resizeColumns().doChange(); presentation->loadSystems(); } -auto SystemSettings::acceptProperties() -> void { +auto SystemSettings::toggle(TableViewCell cell) -> void { + if(auto item = cell->parentTableViewItem()) { + if(auto system = settings.find("Systems/System")[item->offset()]) { + system("Show").setValue(item->cell(0).checked()); + presentation->loadSystems(); + } + } +} + +auto SystemSettings::moveUp() -> void { + if(auto item = systemList.selected()) { + auto offset = item.offset(); + settings["Systems"].swap(offset, offset - 1); + reload(); + systemList.item(offset - 1).setSelected(); + systemList.doChange(); + } +} + +auto SystemSettings::moveDown() -> void { + if(auto item = systemList.selected()) { + auto offset = item.offset(); + settings["Systems"].swap(offset, offset + 1); + reload(); + systemList.item(offset + 1).setSelected(); + systemList.doChange(); + } +} + +auto SystemSettings::modify() -> void { + if(auto item = systemList.selected()) { + if(auto system = settings.find("Systems/System")[item.offset()]) { + systemProperties->modify(system); + } + } +} + +auto SystemSettings::remove() -> void { + if(auto item = systemList.selected()) { + if(auto system = settings.find("Systems/System")[item.offset()]) { + if(MessageDialog().setParent(*settingsManager).setText({ + "Are you sure you want to delete this system?\n\n" + "Name: ", system["Name"].text() + }).question() == "Yes") { + settings["Systems"].remove(system); + reload(); + } + } + } +} + +auto SystemSettings::accept() -> void { if(systemProperties->acceptButton.text() == "Append") { Markup::Node system{"System"}; system.append({"Name", systemProperties->nameEdit.text()}); system.append({"Boot", systemProperties->bootEdit.text()}); - system.append({"Hidden", systemProperties->hiddenOption.checked()}); + system.append({"Show", "true"}); settings["Systems"].append(system); } else if(systemProperties->acceptButton.text() == "Modify") { if(auto item = systemList.selected()) { if(auto system = settings.find("Systems/System")[item.offset()]) { system("Name").setValue(systemProperties->nameEdit.text()); system("Boot").setValue(systemProperties->bootEdit.text()); - system("Hidden").setValue(systemProperties->hiddenOption.checked()); } } } diff --git a/higan/target-tomoko/tools/cheat-editor.cpp b/higan/target-tomoko/tools/cheat-editor.cpp index f81c5ba3..89fdad55 100644 --- a/higan/target-tomoko/tools/cheat-editor.cpp +++ b/higan/target-tomoko/tools/cheat-editor.cpp @@ -4,13 +4,15 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) { layout.setMargin(5); cheatList.append(TableViewHeader().setVisible() + .append(TableViewColumn()) .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(TableViewItem() - .append(TableViewCell().setCheckable().setText(1 + slot)) + .append(TableViewCell().setCheckable()) + .append(TableViewCell().setText(1 + slot)) .append(TableViewCell()) .append(TableViewCell()) ); @@ -62,12 +64,12 @@ auto CheatEditor::doRefresh() -> void { auto codes = cheat.code.split("+"); if(codes.size() > 1) codes[0].append("+..."); cheatList.item(slot).cell(0).setChecked(cheat.enabled); - cheatList.item(slot).cell(1).setText(codes[0]); - cheatList.item(slot).cell(2).setText(cheat.description).setForegroundColor({0, 0, 0}); + cheatList.item(slot).cell(2).setText(codes[0]); + cheatList.item(slot).cell(3).setText(cheat.description).setForegroundColor({0, 0, 0}); } else { cheatList.item(slot).cell(0).setChecked(false); - cheatList.item(slot).cell(1).setText(""); - cheatList.item(slot).cell(2).setText("(empty)").setForegroundColor({128, 128, 128}); + cheatList.item(slot).cell(2).setText(""); + cheatList.item(slot).cell(3).setText("(empty)").setForegroundColor({128, 128, 128}); } } diff --git a/hiro/gtk/widget/table-view.cpp b/hiro/gtk/widget/table-view.cpp index 315b4a89..df8f562a 100644 --- a/hiro/gtk/widget/table-view.cpp +++ b/hiro/gtk/widget/table-view.cpp @@ -153,7 +153,7 @@ auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { if(cell->state.checkable) { - width += 24; + width += 16 + (cell->state.icon || cell->state.text ? 4 : 0); } if(auto& icon = cell->state.icon) { width += icon.width() + 2;