Update to v106r47 release.

byuu says:

This is probably the largest code-change diff I've done in years.

I spent four days working 10-16 hours a day reworking layouts in hiro
completely.

The result is we now have TableLayout, which will allow for better
horizontal+vertical combined alignment.

Windows, GTK2, and now GTK3 are fully supported.

Windows is getting the initial window geometry wrong by a bit.

GTK2 and GTK3 work perfectly. I basically abandoned trying to detect
resize signals, and instead keep a list of all hiro windows that are
allocated, and every time the main loop runs, it will query all of them
to see if they've been resized. I'm disgusted that I have to do this,
but after fighting with GTK for years, I'm about sick of it. GTK was
doing this crazy thing where it would trigger another size-allocate
inside of a previous size-allocate, and so my layouts would be halfway
through resizing all the widgets, and then the size-allocate would kick
off another one. That would end up leaving the rest of the first layout
loop with bad widget sizes. And if I detected a second re-entry and
blocked it, then the entire window would end up with the older geometry.
I started trying to build a message queue system to allow the second
layout resize to occur after the first one completed, but this was just
too much madness, so I went with the simpler solution.

Qt4 has some geometry problems, and doesn't show tab frame layouts
properly yet.

Qt5 causes an ICE error and tanks my entire Xorg display server, so ...
something is seriously wrong there, and it's not hiro's fault. Creating
a dummy Qt5 application without even using hiro, just int main() {
TestObject object; } with object performing a dynamic\_cast to a derived
type segfaults. Memory is getting corrupted where GCC allocates the
vtables for classes, just by linking in Qt. Could be somehow related to
the -fPIC requirement that only Qt5 has ... could just be that FreeBSD
10.1 has a buggy implementation of Qt5. I don't know. It's beyond my
ability to debug, so this one's going to stay broken.

The Cocoa port is busted. I'll fix it up to compile again, but that's
about all I'm going to do.

Many optimizations mean bsnes and higan open faster. GTK2 and GTK3 both
resize windows very quickly now.

higan crashes when you load a game, so that's not good. bsnes works
though.

bsnes also has the start of a localization engine now. Still a long way
to go.

The makefiles received a rather substantial restructuring. Including the
ruby and hiro makefiles will add the necessary compilation rules for
you, which also means that moc will run for the qt4 and qt5 targets, and
windres will run for the Windows targets.
This commit is contained in:
Tim Allen 2018-07-14 13:59:29 +10:00
parent 0c55796060
commit 6090c63958
207 changed files with 2864 additions and 1667 deletions

View File

@ -1,17 +1,22 @@
build := stable
include ../nall/GNUmakefile
include ../hiro/GNUmakefile
name := genius name := genius
build := stable
nall.path := ../nall
include $(nall.path)/GNUmakefile
object.path := obj
flags += -I.. flags += -I..
objects := obj/hiro.o hiro.path := ../hiro
objects += obj/genius.o hiro.resource := data/$(name).rc
objects += $(if $(call streq,$(platform),windows),obj/resource.o) include $(hiro.path)/GNUmakefile
default: information $(objects) objects := obj/hiro.o $(if $(call streq,$(platform),windows),obj/hiro-resource.o)
objects += obj/genius.o
all: $(objects)
$(info Linking out/$(name) ...) $(info Linking out/$(name) ...)
+@$(strip $(compiler) -o out/$(name) $(objects) $(link) $(hirolink)) +@$(strip $(compiler) -o out/$(name) $(objects) $(options) $(hiro.options))
ifeq ($(platform),macos) ifeq ($(platform),macos)
rm -rf out/$(name).app rm -rf out/$(name).app
mkdir -p out/$(name).app/Contents/MacOS/ mkdir -p out/$(name).app/Contents/MacOS/
@ -21,17 +26,9 @@ ifeq ($(platform),macos)
sips -s format icns data/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns sips -s format icns data/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
endif endif
obj/hiro.o: ../hiro/hiro.cpp
$(info Compiling $< ...)
@$(compiler) $(hiroflags) -o obj/hiro.o -c ../hiro/hiro.cpp
obj/genius.o: genius.cpp genius.hpp obj/genius.o: genius.cpp genius.hpp
$(info Compiling $< ...) $(info Compiling $< ...)
@$(compiler) $(cppflags) $(flags) -o obj/genius.o -c genius.cpp @$(compiler) $(flags.cpp) $(flags) -o obj/genius.o -c genius.cpp
obj/resource.o: data/$(name).rc
$(info Compiling $< ...)
@$(windres) data/$(name).rc obj/resource.o
clean: clean:
ifeq ($(platform),macos) ifeq ($(platform),macos)

View File

@ -42,7 +42,7 @@ ListWindow::ListWindow() {
}).information(); }).information();
}); });
layout.setMargin(5); layout.setPadding(5);
gameList.onActivate([&] { modifyButton.doActivate(); }); gameList.onActivate([&] { modifyButton.doActivate(); });
gameList.onChange([&] { updateWindow(); }); gameList.onChange([&] { updateWindow(); });
appendButton.setText("Append").onActivate([&] { appendButton.setText("Append").onActivate([&] {
@ -249,7 +249,7 @@ auto ListWindow::removeGame() -> void {
GameWindow::GameWindow() { GameWindow::GameWindow() {
gameWindow = this; gameWindow = this;
layout.setMargin(5); layout.setPadding(5);
hashLabel.setText("SHA256:").setAlignment(1.0); hashLabel.setText("SHA256:").setAlignment(1.0);
hashEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); }); hashEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
regionLabel.setText("Region:").setAlignment(1.0); regionLabel.setText("Region:").setAlignment(1.0);
@ -451,7 +451,7 @@ auto GameWindow::removeComponent() -> void {
MemoryWindow::MemoryWindow() { MemoryWindow::MemoryWindow() {
memoryWindow = this; memoryWindow = this;
layout.setMargin(5); layout.setPadding(5);
typeLabel.setText("Type:").setAlignment(1.0); typeLabel.setText("Type:").setAlignment(1.0);
typeEdit.append(ComboEditItem().setText("ROM")); typeEdit.append(ComboEditItem().setText("ROM"));
typeEdit.append(ComboEditItem().setText("EEPROM")); typeEdit.append(ComboEditItem().setText("EEPROM"));
@ -554,7 +554,7 @@ auto MemoryWindow::updateWindow() -> void {
OscillatorWindow::OscillatorWindow() { OscillatorWindow::OscillatorWindow() {
oscillatorWindow = this; oscillatorWindow = this;
layout.setMargin(5); layout.setPadding(5);
frequencyLabel.setText("Frequency:").setAlignment(1.0); frequencyLabel.setText("Frequency:").setAlignment(1.0);
frequencyEdit.onChange([&] { modified = true, updateWindow(); }); frequencyEdit.onChange([&] { modified = true, updateWindow(); });
acceptButton.setText("Accept").onActivate([&] { accept(); }); acceptButton.setText("Accept").onActivate([&] { accept(); });

View File

@ -1,11 +1,13 @@
build := performance build := performance
openmp := true openmp := true
include ../nall/GNUmakefile
nall.path := ../nall
include $(nall.path)/GNUmakefile
binary := application binary := application
target := bsnes target := bsnes
objects := libco emulator audio video resource objects := libco emulator audio video resource
object.path := obj
flags += -I. -I.. flags += -I. -I..
ifeq ($(platform),windows) ifeq ($(platform),windows)
@ -38,9 +40,9 @@ endif
compile = \ compile = \
$(strip \ $(strip \
$(if $(filter %.c,$<), \ $(if $(filter %.c,$<), \
$(compiler) $(cflags) $(flags) $1 -c $< -o $@ -MMD -MP -MF $(@:.o=.d), \ $(compiler) $(flags.c) $(flags) $1 -c $< -o $@ -MMD -MP -MF $(@:.o=.d), \
$(if $(filter %.cpp,$<), \ $(if $(filter %.cpp,$<), \
$(compiler) $(cppflags) $(flags) $1 -c $< -o $@ -MMD -MP -MF $(@:.o=.d) \ $(compiler) $(flags.cpp) $(flags) $1 -c $< -o $@ -MMD -MP -MF $(@:.o=.d) \
)) \ )) \
) )

View File

@ -50,12 +50,12 @@ auto Stream::pending() const -> bool {
} }
auto Stream::read(double samples[]) -> uint { auto Stream::read(double samples[]) -> uint {
for(auto c : range(channels)) samples[c] = channels[c].resampler.read(); for(auto c : range(channels.size())) samples[c] = channels[c].resampler.read();
return channels.size(); return channels.size();
} }
auto Stream::write(const double samples[]) -> void { auto Stream::write(const double samples[]) -> void {
for(auto c : range(channels)) { for(auto c : range(channels.size())) {
double sample = samples[c] + 1e-25; //constant offset used to suppress denormals double sample = samples[c] + 1e-25; //constant offset used to suppress denormals
for(auto& filter : channels[c].filters) { for(auto& filter : channels[c].filters) {
switch(filter.order) { switch(filter.order) {

View File

@ -13,7 +13,7 @@ using namespace nall;
namespace Emulator { namespace Emulator {
static const string Name = "higan"; static const string Name = "higan";
static const string Version = "106.46"; static const string Version = "106.47";
static const string Author = "byuu"; static const string Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "https://byuu.org/"; static const string Website = "https://byuu.org/";

View File

@ -7,7 +7,7 @@ auto V30MZ::serialize(serializer& s) -> void {
if(s.mode() == serializer::Save) { if(s.mode() == serializer::Save) {
uint8 _prefixes[7] = {0}; uint8 _prefixes[7] = {0};
uint8 _prefixCount = prefixes.size(); uint8 _prefixCount = prefixes.size();
for(auto n : range(prefixes)) _prefixes[n] = prefixes[n]; for(auto n : range(_prefixCount)) _prefixes[n] = prefixes[n];
s.integer(_prefixCount); s.integer(_prefixCount);
s.array(_prefixes); s.array(_prefixes);
} else { } else {
@ -16,7 +16,7 @@ auto V30MZ::serialize(serializer& s) -> void {
s.integer(_prefixCount); s.integer(_prefixCount);
s.array(_prefixes); s.array(_prefixes);
prefixes.resize(_prefixCount); prefixes.resize(_prefixCount);
for(auto n : range(prefixes)) prefixes[n] = _prefixes[n]; for(auto n : range(_prefixCount)) prefixes[n] = _prefixes[n];
} }
s.integer(modrm.mod); s.integer(modrm.mod);

View File

@ -38,7 +38,7 @@ auto PPU::Line::renderObject(PPU::IO::Object& self) -> void {
} }
} }
for(int n : rrange(ppu.ItemLimit)) { for(int n : reverse(range(ppu.ItemLimit))) {
const auto& item = items[n]; const auto& item = items[n];
if(!item.valid) continue; if(!item.valid) continue;

View File

@ -5,13 +5,11 @@ include sfc/GNUmakefile
include gb/GNUmakefile include gb/GNUmakefile
include processor/GNUmakefile include processor/GNUmakefile
objects := ruby hiro $(objects) objects := ruby hiro $(if $(call streq,$(platform),windows),hiro-resource) $(objects)
objects += ui-bsnes ui-program ui-input ui-presentation objects += ui-bsnes ui-program ui-input ui-presentation
objects += ui-settings ui-tools ui-resource objects += ui-settings ui-tools ui-resource
objects += $(if $(call streq,$(platform),windows),ui-windows)
objects := $(objects:%=obj/%.o) objects := $(objects:%=obj/%.o)
# platform
ifeq ($(platform),windows) ifeq ($(platform),windows)
ruby += video.wgl video.direct3d video.directdraw video.gdi ruby += video.wgl video.direct3d video.directdraw video.gdi
ruby += audio.asio audio.wasapi audio.xaudio2 audio.directsound ruby += audio.asio audio.wasapi audio.xaudio2 audio.directsound
@ -30,23 +28,13 @@ else ifeq ($(platform),bsd)
ruby += input.sdl input.xlib ruby += input.sdl input.xlib
endif endif
# ruby ruby.path := ../ruby
include ../ruby/GNUmakefile include $(ruby.path)/GNUmakefile
link += $(rubylink)
obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/) hiro.path := ../hiro
$(info Compiling $< ...) hiro.resource := $(ui)/resource/bsnes.rc
@$(compiler) $(rubyflags) -c $< -o $@ include $(hiro.path)/GNUmakefile
# hiro
include ../hiro/GNUmakefile
link += $(hirolink)
obj/hiro.o: ../hiro/hiro.cpp $(call rwildcard,../hiro/)
$(info Compiling $< ...)
@$(compiler) $(hiroflags) -c $< -o $@
# rules
obj/ui-bsnes.o: $(ui)/bsnes.cpp obj/ui-bsnes.o: $(ui)/bsnes.cpp
obj/ui-program.o: $(ui)/program/program.cpp obj/ui-program.o: $(ui)/program/program.cpp
obj/ui-input.o: $(ui)/input/input.cpp obj/ui-input.o: $(ui)/input/input.cpp
@ -55,14 +43,10 @@ obj/ui-settings.o: $(ui)/settings/settings.cpp
obj/ui-tools.o: $(ui)/tools/tools.cpp obj/ui-tools.o: $(ui)/tools/tools.cpp
obj/ui-resource.o: $(ui)/resource/resource.cpp obj/ui-resource.o: $(ui)/resource/resource.cpp
obj/ui-windows.o: $(ui)/resource/bsnes.rc
$(info Compiling $< ...)
@$(windres) $(ui)/resource/bsnes.rc obj/ui-windows.o
# targets # targets
default: information $(objects) all: $(objects)
$(info Linking out/$(name) ...) $(info Linking out/$(name) ...)
+@$(strip $(compiler) -o out/$(name) $(objects) $(link)) +@$(strip $(compiler) -o out/$(name) $(objects) $(options) $(ruby.options) $(hiro.options))
ifeq ($(platform),macos) ifeq ($(platform),macos)
rm -rf out/$(name).app rm -rf out/$(name).app
mkdir -p out/$(name).app/Contents/MacOS/ mkdir -p out/$(name).app/Contents/MacOS/
@ -84,7 +68,9 @@ else ifneq ($(filter $(platform),linux bsd),)
mkdir -p $(prefix)/share/applications/ mkdir -p $(prefix)/share/applications/
mkdir -p $(prefix)/share/icons/ mkdir -p $(prefix)/share/icons/
mkdir -p $(prefix)/share/$(name)/ mkdir -p $(prefix)/share/$(name)/
mkdir -p $(prefix)/share/$(name)/locales/
cp out/$(name) $(prefix)/bin/$(name) cp out/$(name) $(prefix)/bin/$(name)
cp $(ui)/resource/locales/* $(prefix)/share/$(name)/locales/
cp $(ui)/resource/$(name).desktop $(prefix)/share/applications/$(name).desktop cp $(ui)/resource/$(name).desktop $(prefix)/share/applications/$(name).desktop
cp $(ui)/resource/$(name).png $(prefix)/share/icons/$(name).png cp $(ui)/resource/$(name).png $(prefix)/share/icons/$(name).png
endif endif

View File

@ -4,6 +4,7 @@ unique_pointer<Video> video;
unique_pointer<Audio> audio; unique_pointer<Audio> audio;
unique_pointer<Input> input; unique_pointer<Input> input;
unique_pointer<Emulator::Interface> emulator; unique_pointer<Emulator::Interface> emulator;
Locale ns;
auto locate(string name) -> string { auto locate(string name) -> string {
string location = {Path::program(), name}; string location = {Path::program(), name};
@ -19,9 +20,16 @@ auto locate(string name) -> string {
} }
#include <nall/main.hpp> #include <nall/main.hpp>
auto nall::main(string_vector args) -> void { auto nall::main(string_vector arguments) -> void {
ns.scan(locate("locales/"));
ns.select("日本語");
for(auto argument : arguments) {
if(argument.beginsWith("--locale=")) {
ns.select(argument.trimLeft("--locale=", 1L));
}
}
Application::setName("bsnes"); Application::setName("bsnes");
emulator = new SuperFamicom::Interface; emulator = new SuperFamicom::Interface;
new Program(args); new Program(arguments);
Application::run(); Application::run();
} }

View File

@ -11,6 +11,7 @@ extern unique_pointer<Input> input;
#include <emulator/emulator.hpp> #include <emulator/emulator.hpp>
extern unique_pointer<Emulator::Interface> emulator; extern unique_pointer<Emulator::Interface> emulator;
extern Locale ns;
#include "program/program.hpp" #include "program/program.hpp"
#include "input/input.hpp" #include "input/input.hpp"
#include "presentation/presentation.hpp" #include "presentation/presentation.hpp"

View File

@ -231,7 +231,7 @@ auto InputManager::poll() -> void {
auto devices = input->poll(); auto devices = input->poll();
bool changed = devices.size() != this->devices.size(); bool changed = devices.size() != this->devices.size();
if(!changed) { if(!changed) {
for(auto n : range(devices)) { for(auto n : range(devices.size())) {
changed = devices[n] != this->devices[n]; changed = devices[n] != this->devices[n];
if(changed) break; if(changed) break;
} }

View File

@ -1,24 +1,23 @@
AboutWindow::AboutWindow() { AboutWindow::AboutWindow() : Locale::Namespace(ns, "About") {
aboutWindow = this; aboutWindow = this;
setTitle("About bsnes ..."); setTitle(tr("About {0} ...", "bsnes"));
setBackgroundColor({255, 255, 240}); setBackgroundColor({255, 255, 240});
layout.setMargin(10); layout.setPadding(10);
auto logo = image{Resource::Logo}; auto logo = image{Resource::Logo};
logo.alphaBlend(0xfffff0); logo.alphaBlend(0xfffff0);
canvas.setIcon(logo); canvas.setIcon(logo);
informationLeft.setFont(Font().setBold()).setAlignment(1.0).setText({ tableLayout.setFont(Font().setBold());
"Version:\n", tableLayout.setSize({2, 4});
"Author:\n", tableLayout.column(0).setSpacing(3);
"License:\n", versionLabel.setText(tr("Version:")).setAlignment(1.0);
"Website:" versionValue.setText(Emulator::Version);
}); authorLabel.setText(tr("Author:")).setAlignment(1.0);
informationRight.setFont(Font().setBold()).setAlignment(0.0).setText({ authorValue.setText(Emulator::Author);
Emulator::Version, "\n", licenseLabel.setText(tr("License:")).setAlignment(1.0);
Emulator::Author, "\n", licenseValue.setText(Emulator::License);
Emulator::License, "\n", websiteLabel.setText(tr("Website:")).setAlignment(1.0);
Emulator::Website websiteValue.setText(Emulator::Website);
});
setResizable(false); setResizable(false);
setSize(layout.minimumSize()); setSize(layout.minimumSize());

View File

@ -3,10 +3,10 @@
unique_pointer<AboutWindow> aboutWindow; unique_pointer<AboutWindow> aboutWindow;
unique_pointer<Presentation> presentation; unique_pointer<Presentation> presentation;
Presentation::Presentation() { Presentation::Presentation() : Locale::Namespace(ns, "Presentation") {
presentation = this; presentation = this;
systemMenu.setText("System"); systemMenu.setText(tr("System"));
loadGame.setIcon(Icon::Action::Open).setText("Load Game ...").onActivate([&] { loadGame.setIcon(Icon::Action::Open).setText("Load Game ...").onActivate([&] {
program->load(); program->load();
}); });
@ -55,7 +55,7 @@ Presentation::Presentation() {
} }
quit.setIcon(Icon::Action::Quit).setText("Quit").onActivate([&] { program->quit(); }); quit.setIcon(Icon::Action::Quit).setText("Quit").onActivate([&] { program->quit(); });
settingsMenu.setText("Settings"); settingsMenu.setText(tr("Settings"));
sizeMenu.setIcon(Icon::Emblem::Image).setText("Size"); sizeMenu.setIcon(Icon::Emblem::Image).setText("Size");
updateSizeMenu(); updateSizeMenu();
outputMenu.setIcon(Icon::Emblem::Image).setText("Output"); outputMenu.setIcon(Icon::Emblem::Image).setText("Output");
@ -115,7 +115,7 @@ Presentation::Presentation() {
pathSettings.setIcon(Icon::Emblem::Folder).setText("Paths ...").onActivate([&] { settingsWindow->show(4); }); pathSettings.setIcon(Icon::Emblem::Folder).setText("Paths ...").onActivate([&] { settingsWindow->show(4); });
advancedSettings.setIcon(Icon::Action::Settings).setText("Advanced ...").onActivate([&] { settingsWindow->show(5); }); advancedSettings.setIcon(Icon::Action::Settings).setText("Advanced ...").onActivate([&] { settingsWindow->show(5); });
toolsMenu.setText("Tools").setVisible(false); toolsMenu.setText(tr("Tools")).setVisible(false);
saveState.setIcon(Icon::Action::Save).setText("Save State"); saveState.setIcon(Icon::Action::Save).setText("Save State");
for(uint index : range(QuickStates)) { for(uint index : range(QuickStates)) {
saveState.append(MenuItem().setText({"Slot ", 1 + index}).onActivate([=] { saveState.append(MenuItem().setText({"Slot ", 1 + index}).onActivate([=] {
@ -152,7 +152,7 @@ Presentation::Presentation() {
stateManager.setIcon(Icon::Application::FileManager).setText("State Manager ...").onActivate([&] { toolsWindow->show(1); }); stateManager.setIcon(Icon::Application::FileManager).setText("State Manager ...").onActivate([&] { toolsWindow->show(1); });
manifestViewer.setIcon(Icon::Emblem::Text).setText("Manifest Viewer ...").onActivate([&] { toolsWindow->show(2); }); manifestViewer.setIcon(Icon::Emblem::Text).setText("Manifest Viewer ...").onActivate([&] { toolsWindow->show(2); });
helpMenu.setText("Help"); helpMenu.setText(tr("Help"));
documentation.setIcon(Icon::Application::Browser).setText("Documentation ...").onActivate([&] { documentation.setIcon(Icon::Application::Browser).setText("Documentation ...").onActivate([&] {
invoke("https://doc.byuu.org/bsnes/"); invoke("https://doc.byuu.org/bsnes/");
}); });
@ -469,7 +469,7 @@ auto Presentation::addRecentGame(string location) -> void {
for(uint index : range(RecentGames + 1)) { for(uint index : range(RecentGames + 1)) {
auto value = settings[{"Game/Recent/", 1 + index}].text(); auto value = settings[{"Game/Recent/", 1 + index}].text();
if(!value || value == location) { if(!value || value == location) {
for(uint n : rrange(index + 1)) { for(uint n : reverse(range(index + 1))) {
if(1 + n > RecentGames) continue; if(1 + n > RecentGames) continue;
settings({"Game/Recent/", 1 + n}).setValue(settings[{"Game/Recent/", n}].text()); settings({"Game/Recent/", 1 + n}).setValue(settings[{"Game/Recent/", n}].text());
} }

View File

@ -1,14 +1,23 @@
struct AboutWindow : Window { struct AboutWindow : Locale::Namespace, Window {
AboutWindow(); AboutWindow();
VerticalLayout layout{this}; VerticalLayout layout{this};
Canvas canvas{&layout, Size{400, 85}, 0}; Canvas canvas{&layout, Size{400, 85}, 0};
HorizontalLayout informationLayout{&layout, Size{~0, ~0}}; TableLayout tableLayout{&layout, Size{~0, 0}};
Label informationLeft{&informationLayout, Size{~0, 0}, 3}; Label versionLabel{&tableLayout, Size{~0, 0}};
Label informationRight{&informationLayout, Size{~0, 0}}; Label versionValue{&tableLayout, Size{~0, 0}};
//
Label authorLabel{&tableLayout, Size{~0, 0}};
Label authorValue{&tableLayout, Size{~0, 0}};
//
Label licenseLabel{&tableLayout, Size{~0, 0}};
Label licenseValue{&tableLayout, Size{~0, 0}};
//
Label websiteLabel{&tableLayout, Size{~0, 0}};
Label websiteValue{&tableLayout, Size{~0, 0}};
}; };
struct Presentation : Window { struct Presentation : Locale::Namespace, Window {
enum : uint { RecentGames = 9, QuickStates = 9 }; enum : uint { RecentGames = 9, QuickStates = 9 };
enum : uint { StatusHeight = 24 }; enum : uint { StatusHeight = 24 };

View File

@ -13,7 +13,7 @@
#include "hacks.cpp" #include "hacks.cpp"
unique_pointer<Program> program; unique_pointer<Program> program;
Program::Program(string_vector arguments) { Program::Program(string_vector arguments) : Locale::Namespace(ns, "Program") {
program = this; program = this;
Emulator::platform = this; Emulator::platform = this;

View File

@ -1,4 +1,4 @@
struct Program : Emulator::Platform { struct Program : Locale::Namespace, Emulator::Platform {
//program.cpp //program.cpp
Program(string_vector arguments); Program(string_vector arguments);
auto main() -> void; auto main() -> void;

View File

@ -18,11 +18,11 @@ auto Program::updateStatus() -> void {
string frameRate; string frameRate;
if(!emulator->loaded()) { if(!emulator->loaded()) {
frameRate = "Unloaded"; frameRate = tr("Unloaded");
} else if(presentation->pauseEmulation.checked()) { } else if(presentation->pauseEmulation.checked()) {
frameRate = "Paused"; frameRate = tr("Paused");
} else if(!focused() && settingsWindow->input.pauseEmulation.checked()) { } else if(!focused() && settingsWindow->input.pauseEmulation.checked()) {
frameRate = "Paused"; frameRate = tr("Paused");
} else { } else {
frameRate = statusFrameRate; frameRate = statusFrameRate;
} }

View File

@ -0,0 +1,40 @@
locale
language: 日本語
namespace: Program
map
input: Paused
value: ポーズ
namespace: Presentation
map
input: System
value: システム
map
input: Settings
value: 設定
map
input: Tools
value: ツール
map
input: Help
value: ヘルプ
namespace: About
map
input: About {0} ...
value: {0}について ...
map
input: Version:
value: バージョン:
map
input: Author:
value: 作者:
map
input: License:
value: ライセンス:
map
input: Website:
value: 公式サイト:

View File

@ -2,7 +2,7 @@ AdvancedSettings::AdvancedSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Action::Settings); setIcon(Icon::Action::Settings);
setText("Advanced"); setText("Advanced");
layout.setMargin(5); layout.setPadding(5);
driversLabel.setText("Drivers").setFont(Font().setBold()); driversLabel.setText("Drivers").setFont(Font().setBold());
videoDriverLabel.setText("Video:"); videoDriverLabel.setText("Video:");

View File

@ -2,7 +2,7 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Speaker); setIcon(Icon::Device::Speaker);
setText("Audio"); setText("Audio");
layout.setMargin(5); layout.setPadding(5);
driverLabel.setFont(Font().setBold()).setText("Driver"); driverLabel.setFont(Font().setBold()).setText("Driver");
deviceLabel.setText("Device:"); deviceLabel.setText("Device:");
@ -26,7 +26,9 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) {
}); });
effectsLabel.setFont(Font().setBold()).setText("Effects"); effectsLabel.setFont(Font().setBold()).setText("Effects");
skewLabel.setAlignment(1.0).setText("Skew:"); effectsLayout.setSize({3, 3});
effectsLayout.column(0).setAlignment(1.0);
skewLabel.setText("Skew:");
skewValue.setAlignment(0.5); skewValue.setAlignment(0.5);
skewSlider.setLength(10001).setPosition(settings["Audio/Skew"].integer() + 5000).onChange([&] { skewSlider.setLength(10001).setPosition(settings["Audio/Skew"].integer() + 5000).onChange([&] {
string value = {skewSlider.position() > 5000 ? "+" : "", (int)skewSlider.position() - 5000}; string value = {skewSlider.position() > 5000 ? "+" : "", (int)skewSlider.position() - 5000};
@ -34,7 +36,7 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) {
skewValue.setText(value); skewValue.setText(value);
program->updateAudioFrequency(); program->updateAudioFrequency();
}).doChange(); }).doChange();
volumeLabel.setAlignment(1.0).setText("Volume:"); volumeLabel.setText("Volume:");
volumeValue.setAlignment(0.5); volumeValue.setAlignment(0.5);
volumeSlider.setLength(201).setPosition(settings["Audio/Volume"].natural()).onChange([&] { volumeSlider.setLength(201).setPosition(settings["Audio/Volume"].natural()).onChange([&] {
string value = {volumeSlider.position(), "%"}; string value = {volumeSlider.position(), "%"};
@ -42,7 +44,7 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) {
volumeValue.setText(value); volumeValue.setText(value);
program->updateAudioEffects(); program->updateAudioEffects();
}).doChange(); }).doChange();
balanceLabel.setAlignment(1.0).setText("Balance:"); balanceLabel.setText("Balance:");
balanceValue.setAlignment(0.5); balanceValue.setAlignment(0.5);
balanceSlider.setLength(101).setPosition(settings["Audio/Balance"].natural()).onChange([&] { balanceSlider.setLength(101).setPosition(settings["Audio/Balance"].natural()).onChange([&] {
string value = {balanceSlider.position(), "%"}; string value = {balanceSlider.position(), "%"};

View File

@ -2,7 +2,7 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Keyboard); setIcon(Icon::Device::Keyboard);
setText("Hotkeys"); setText("Hotkeys");
layout.setMargin(5); layout.setPadding(5);
mappingList.setBatchable(); mappingList.setBatchable();
mappingList.onActivate([&] { mappingList.onActivate([&] {
if(assignButton.enabled()) assignButton.doActivate(); if(assignButton.enabled()) assignButton.doActivate();

View File

@ -2,7 +2,7 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Joypad); setIcon(Icon::Device::Joypad);
setText("Input"); setText("Input");
layout.setMargin(5); layout.setPadding(5);
defocusLabel.setText("When focus is lost:"); defocusLabel.setText("When focus is lost:");
pauseEmulation.setText("Pause emulation").onActivate([&] { pauseEmulation.setText("Pause emulation").onActivate([&] {
settings["Input/Defocus"].setValue("Pause"); settings["Input/Defocus"].setValue("Pause");

View File

@ -2,9 +2,11 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Emblem::Folder); setIcon(Icon::Emblem::Folder);
setText("Paths"); setText("Paths");
layout.setMargin(5); layout.setPadding(5);
layout.setSize({4, 6});
layout.column(0).setAlignment(1.0);
gamesLabel.setAlignment(1.0).setText("Games:"); gamesLabel.setText("Games:");
gamesPath.setEditable(false); gamesPath.setEditable(false);
gamesAssign.setText("Assign ...").onActivate([&] { gamesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) { if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -17,7 +19,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths(); refreshPaths();
}); });
patchesLabel.setAlignment(1.0).setText("Patches:"); patchesLabel.setText("Patches:");
patchesPath.setEditable(false); patchesPath.setEditable(false);
patchesAssign.setText("Assign ...").onActivate([&] { patchesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) { if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -30,7 +32,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths(); refreshPaths();
}); });
savesLabel.setAlignment(1.0).setText("Saves:"); savesLabel.setText("Saves:");
savesPath.setEditable(false); savesPath.setEditable(false);
savesAssign.setText("Assign ...").onActivate([&] { savesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) { if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -43,7 +45,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths(); refreshPaths();
}); });
cheatsLabel.setAlignment(1.0).setText("Cheats:"); cheatsLabel.setText("Cheats:");
cheatsPath.setEditable(false); cheatsPath.setEditable(false);
cheatsAssign.setText("Assign ...").onActivate([&] { cheatsAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) { if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -56,7 +58,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths(); refreshPaths();
}); });
statesLabel.setAlignment(1.0).setText("States:"); statesLabel.setText("States:");
statesPath.setEditable(false); statesPath.setEditable(false);
statesAssign.setText("Assign ...").onActivate([&] { statesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) { if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -69,7 +71,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths(); refreshPaths();
}); });
screenshotsLabel.setAlignment(1.0).setText("Screenshots:"); screenshotsLabel.setText("Screenshots:");
screenshotsPath.setEditable(false); screenshotsPath.setEditable(false);
screenshotsAssign.setText("Assign ...").onActivate([&] { screenshotsAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) { if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {

View File

@ -82,7 +82,7 @@ auto Settings::save() -> void {
SettingsWindow::SettingsWindow() { SettingsWindow::SettingsWindow() {
settingsWindow = this; settingsWindow = this;
layout.setMargin(5); layout.setPadding(5);
statusBar.setFont(Font().setBold()); statusBar.setFont(Font().setBold());
setTitle("Settings"); setTitle("Settings");

View File

@ -9,18 +9,18 @@ struct VideoSettings : TabFrameItem {
public: public:
VerticalLayout layout{this}; VerticalLayout layout{this};
Label colorAdjustmentLabel{&layout, Size{~0, 0}, 2}; Label colorAdjustmentLabel{&layout, Size{~0, 0}, 2};
HorizontalLayout luminanceLayout{&layout, Size{~0, 0}}; TableLayout colorLayout{&layout, Size{~0, 0}};
Label luminanceLabel{&luminanceLayout, Size{65, 0}}; Label luminanceLabel{&colorLayout, Size{0, 0}};
Label luminanceValue{&luminanceLayout, Size{50, 0}}; Label luminanceValue{&colorLayout, Size{50, 0}};
HorizontalSlider luminanceSlider{&luminanceLayout, Size{~0, 0}}; HorizontalSlider luminanceSlider{&colorLayout, Size{~0, 0}};
HorizontalLayout saturationLayout{&layout, Size{~0, 0}}; //
Label saturationLabel{&saturationLayout, Size{65, 0}}; Label saturationLabel{&colorLayout, Size{0, 0}};
Label saturationValue{&saturationLayout, Size{50, 0}}; Label saturationValue{&colorLayout, Size{50, 0}};
HorizontalSlider saturationSlider{&saturationLayout, Size{~0, 0}}; HorizontalSlider saturationSlider{&colorLayout, Size{~0, 0}};
HorizontalLayout gammaLayout{&layout, Size{~0, 0}}; //
Label gammaLabel{&gammaLayout, Size{65, 0}}; Label gammaLabel{&colorLayout, Size{0, 0}};
Label gammaValue{&gammaLayout, Size{50, 0}}; Label gammaValue{&colorLayout, Size{50, 0}};
HorizontalSlider gammaSlider{&gammaLayout, Size{~0, 0}}; HorizontalSlider gammaSlider{&colorLayout, Size{~0, 0}};
Label fullscreenLabel{&layout, Size{~0, 0}, 2}; Label fullscreenLabel{&layout, Size{~0, 0}, 2};
CheckLabel exclusiveMode{&layout, Size{~0, 0}}; CheckLabel exclusiveMode{&layout, Size{~0, 0}};
}; };
@ -43,18 +43,18 @@ public:
ComboButton latencyList{&driverLayout, Size{80, 0}}; ComboButton latencyList{&driverLayout, Size{80, 0}};
CheckLabel exclusiveMode{&layout, Size{~0, 0}}; CheckLabel exclusiveMode{&layout, Size{~0, 0}};
Label effectsLabel{&layout, Size{~0, 0}, 2}; Label effectsLabel{&layout, Size{~0, 0}, 2};
HorizontalLayout skewLayout{&layout, Size{~0, 0}}; TableLayout effectsLayout{&layout, Size{~0, 0}};
Label skewLabel{&skewLayout, Size{65, 0}}; Label skewLabel{&effectsLayout, Size{0, 0}};
Label skewValue{&skewLayout, Size{50, 0}}; Label skewValue{&effectsLayout, Size{50, 0}};
HorizontalSlider skewSlider{&skewLayout, Size{~0, 0}}; HorizontalSlider skewSlider{&effectsLayout, Size{~0, 0}};
HorizontalLayout volumeLayout{&layout, Size{~0, 0}}; //
Label volumeLabel{&volumeLayout, Size{65, 0}}; Label volumeLabel{&effectsLayout, Size{0, 0}};
Label volumeValue{&volumeLayout, Size{50, 0}}; Label volumeValue{&effectsLayout, Size{50, 0}};
HorizontalSlider volumeSlider{&volumeLayout, Size{~0, 0}}; HorizontalSlider volumeSlider{&effectsLayout, Size{~0, 0}};
HorizontalLayout balanceLayout{&layout, Size{~0, 0}}; //
Label balanceLabel{&balanceLayout, Size{65, 0}}; Label balanceLabel{&effectsLayout, Size{0, 0}};
Label balanceValue{&balanceLayout, Size{50, 0}}; Label balanceValue{&effectsLayout, Size{50, 0}};
HorizontalSlider balanceSlider{&balanceLayout, Size{~0, 0}}; HorizontalSlider balanceSlider{&effectsLayout, Size{~0, 0}};
CheckLabel reverb{&layout, Size{~0, 0}}; CheckLabel reverb{&layout, Size{~0, 0}};
}; };
@ -121,37 +121,36 @@ struct PathSettings : TabFrameItem {
auto refreshPaths() -> void; auto refreshPaths() -> void;
public: public:
VerticalLayout layout{this}; TableLayout layout{this};
HorizontalLayout gamesLayout{&layout, Size{~0, 0}}; Label gamesLabel{&layout, Size{0, 0}};
Label gamesLabel{&gamesLayout, Size{80, 0}}; LineEdit gamesPath{&layout, Size{~0, 0}};
LineEdit gamesPath{&gamesLayout, Size{~0, 0}}; Button gamesAssign{&layout, Size{80, 0}};
Button gamesAssign{&gamesLayout, Size{80, 0}}; Button gamesReset{&layout, Size{80, 0}};
Button gamesReset{&gamesLayout, Size{80, 0}}; //
HorizontalLayout patchesLayout{&layout, Size{~0, 0}}; Label patchesLabel{&layout, Size{0, 0}};
Label patchesLabel{&patchesLayout, Size{80, 0}}; LineEdit patchesPath{&layout, Size{~0, 0}};
LineEdit patchesPath{&patchesLayout, Size{~0, 0}}; Button patchesAssign{&layout, Size{80, 0}};
Button patchesAssign{&patchesLayout, Size{80, 0}}; Button patchesReset{&layout, Size{80, 0}};
Button patchesReset{&patchesLayout, Size{80, 0}}; //
HorizontalLayout savesLayout{&layout, Size{~0, 0}}; Label savesLabel{&layout, Size{0, 0}};
Label savesLabel{&savesLayout, Size{80, 0}}; LineEdit savesPath{&layout, Size{~0, 0}};
LineEdit savesPath{&savesLayout, Size{~0, 0}}; Button savesAssign{&layout, Size{80, 0}};
Button savesAssign{&savesLayout, Size{80, 0}}; Button savesReset{&layout, Size{80, 0}};
Button savesReset{&savesLayout, Size{80, 0}}; //
HorizontalLayout cheatsLayout{&layout, Size{~0, 0}}; Label cheatsLabel{&layout, Size{0, 0}};
Label cheatsLabel{&cheatsLayout, Size{80, 0}}; LineEdit cheatsPath{&layout, Size{~0, 0}};
LineEdit cheatsPath{&cheatsLayout, Size{~0, 0}}; Button cheatsAssign{&layout, Size{80, 0}};
Button cheatsAssign{&cheatsLayout, Size{80, 0}}; Button cheatsReset{&layout, Size{80, 0}};
Button cheatsReset{&cheatsLayout, Size{80, 0}}; //
HorizontalLayout statesLayout{&layout, Size{~0, 0}}; Label statesLabel{&layout, Size{0, 0}};
Label statesLabel{&statesLayout, Size{80, 0}}; LineEdit statesPath{&layout, Size{~0, 0}};
LineEdit statesPath{&statesLayout, Size{~0, 0}}; Button statesAssign{&layout, Size{80, 0}};
Button statesAssign{&statesLayout, Size{80, 0}}; Button statesReset{&layout, Size{80, 0}};
Button statesReset{&statesLayout, Size{80, 0}}; //
HorizontalLayout screenshotsLayout{&layout, Size{~0, 0}}; Label screenshotsLabel{&layout, Size{0, 0}};
Label screenshotsLabel{&screenshotsLayout, Size{80, 0}}; LineEdit screenshotsPath{&layout, Size{~0, 0}};
LineEdit screenshotsPath{&screenshotsLayout, Size{~0, 0}}; Button screenshotsAssign{&layout, Size{80, 0}};
Button screenshotsAssign{&screenshotsLayout, Size{80, 0}}; Button screenshotsReset{&layout, Size{80, 0}};
Button screenshotsReset{&screenshotsLayout, Size{80, 0}};
}; };
struct AdvancedSettings : TabFrameItem { struct AdvancedSettings : TabFrameItem {

View File

@ -2,10 +2,12 @@ VideoSettings::VideoSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Display); setIcon(Icon::Device::Display);
setText("Video"); setText("Video");
layout.setMargin(5); layout.setPadding(5);
colorAdjustmentLabel.setFont(Font().setBold()).setText("Color Adjustment"); colorAdjustmentLabel.setFont(Font().setBold()).setText("Color Adjustment");
luminanceLabel.setAlignment(1.0).setText("Luminance:"); colorLayout.setSize({3, 3});
colorLayout.column(0).setAlignment(1.0);
luminanceLabel.setText("Luminance:");
luminanceValue.setAlignment(0.5); luminanceValue.setAlignment(0.5);
luminanceSlider.setLength(101).setPosition(settings["Video/Luminance"].natural()).onChange([&] { luminanceSlider.setLength(101).setPosition(settings["Video/Luminance"].natural()).onChange([&] {
string value = {luminanceSlider.position(), "%"}; string value = {luminanceSlider.position(), "%"};
@ -13,7 +15,7 @@ VideoSettings::VideoSettings(TabFrame* parent) : TabFrameItem(parent) {
luminanceValue.setText(value); luminanceValue.setText(value);
program->updateVideoPalette(); program->updateVideoPalette();
}).doChange(); }).doChange();
saturationLabel.setAlignment(1.0).setText("Saturation:"); saturationLabel.setText("Saturation:");
saturationValue.setAlignment(0.5); saturationValue.setAlignment(0.5);
saturationSlider.setLength(201).setPosition(settings["Video/Saturation"].natural()).onChange([&] { saturationSlider.setLength(201).setPosition(settings["Video/Saturation"].natural()).onChange([&] {
string value = {saturationSlider.position(), "%"}; string value = {saturationSlider.position(), "%"};
@ -21,7 +23,7 @@ VideoSettings::VideoSettings(TabFrame* parent) : TabFrameItem(parent) {
saturationValue.setText(value); saturationValue.setText(value);
program->updateVideoPalette(); program->updateVideoPalette();
}).doChange(); }).doChange();
gammaLabel.setAlignment(1.0).setText("Gamma:"); gammaLabel.setText("Gamma:");
gammaValue.setAlignment(0.5); gammaValue.setAlignment(0.5);
gammaSlider.setLength(101).setPosition(settings["Video/Gamma"].natural() - 100).onChange([&] { gammaSlider.setLength(101).setPosition(settings["Video/Gamma"].natural() - 100).onChange([&] {
string value = {100 + gammaSlider.position(), "%"}; string value = {100 + gammaSlider.position(), "%"};

View File

@ -1,7 +1,7 @@
CheatDatabase::CheatDatabase() { CheatDatabase::CheatDatabase() {
cheatDatabase = this; cheatDatabase = this;
layout.setMargin(5); layout.setPadding(5);
selectAllButton.setText("Select All").onActivate([&] { selectAllButton.setText("Select All").onActivate([&] {
for(auto item : cheatList.items()) item.setChecked(true); for(auto item : cheatList.items()) item.setChecked(true);
}); });
@ -55,7 +55,7 @@ auto CheatDatabase::addCheats() -> void {
CheatWindow::CheatWindow() { CheatWindow::CheatWindow() {
cheatWindow = this; cheatWindow = this;
layout.setMargin(5); layout.setPadding(5);
nameLabel.setText("Name:"); nameLabel.setText("Name:");
nameValue.onActivate([&] { if(acceptButton.enabled()) acceptButton.doActivate(); }); nameValue.onActivate([&] { if(acceptButton.enabled()) acceptButton.doActivate(); });
nameValue.onChange([&] { doChange(); }); nameValue.onChange([&] { doChange(); });
@ -106,7 +106,7 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Edit::Replace); setIcon(Icon::Edit::Replace);
setText("Cheat Editor"); setText("Cheat Editor");
layout.setMargin(5); layout.setPadding(5);
cheatList.setBatchable(); cheatList.setBatchable();
cheatList.onActivate([&] { cheatList.onActivate([&] {
editButton.doActivate(); editButton.doActivate();
@ -169,7 +169,7 @@ auto CheatEditor::addCheat(Cheat cheat) -> void {
cheats.append(cheat); cheats.append(cheat);
cheats.sort(); cheats.sort();
refresh(); refresh();
for(uint index : range(cheats)) { for(uint index : range(cheats.size())) {
if(cheats[index] == cheat) { cheatList.item(index).setSelected(); break; } if(cheats[index] == cheat) { cheatList.item(index).setSelected(); break; }
} }
cheatList.doChange(); cheatList.doChange();
@ -181,7 +181,7 @@ auto CheatEditor::editCheat(Cheat cheat) -> void {
cheats[item.offset()] = cheat; cheats[item.offset()] = cheat;
cheats.sort(); cheats.sort();
refresh(); refresh();
for(uint index : range(cheats)) { for(uint index : range(cheats.size())) {
if(cheats[index] == cheat) { cheatList.item(index).setSelected(); break; } if(cheats[index] == cheat) { cheatList.item(index).setSelected(); break; }
} }
cheatList.doChange(); cheatList.doChange();
@ -193,7 +193,7 @@ auto CheatEditor::removeCheats() -> void {
if(auto batched = cheatList.batched()) { if(auto batched = cheatList.batched()) {
if(MessageDialog("Are you sure you want to permanently remove the selected cheat(s)?") if(MessageDialog("Are you sure you want to permanently remove the selected cheat(s)?")
.setParent(*toolsWindow).question() == "Yes") { .setParent(*toolsWindow).question() == "Yes") {
for(uint index : rrange(batched)) cheats.remove(batched[index].offset()); for(auto& item : reverse(batched)) cheats.remove(item.offset());
cheats.sort(); cheats.sort();
refresh(); refresh();
synchronizeCodes(); synchronizeCodes();

View File

@ -2,7 +2,7 @@ ManifestViewer::ManifestViewer(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Emblem::Text); setIcon(Icon::Emblem::Text);
setText("Manifest Viewer"); setText("Manifest Viewer");
layout.setMargin(5); layout.setPadding(5);
manifestView.setEditable(false).setWordWrap(false).setFont(Font().setFamily(Font::Mono)); manifestView.setEditable(false).setWordWrap(false).setFont(Font().setFamily(Font::Mono));
} }

View File

@ -1,7 +1,7 @@
StateWindow::StateWindow() { StateWindow::StateWindow() {
stateWindow = this; stateWindow = this;
layout.setMargin(5); layout.setPadding(5);
nameLabel.setText("Name:"); nameLabel.setText("Name:");
nameValue.onActivate([&] { nameValue.onActivate([&] {
if(acceptButton.enabled()) acceptButton.doActivate(); if(acceptButton.enabled()) acceptButton.doActivate();
@ -67,7 +67,7 @@ StateManager::StateManager(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Application::FileManager); setIcon(Icon::Application::FileManager);
setText("State Manager"); setText("State Manager");
layout.setMargin(5); layout.setPadding(5);
stateList.setBatchable(); stateList.setBatchable();
stateList.onActivate([&] { stateList.onActivate([&] {
editButton.doActivate(); editButton.doActivate();

View File

@ -10,7 +10,7 @@ unique_pointer<ToolsWindow> toolsWindow;
ToolsWindow::ToolsWindow() { ToolsWindow::ToolsWindow() {
toolsWindow = this; toolsWindow = this;
layout.setMargin(5); layout.setPadding(5);
setTitle("Tools"); setTitle("Tools");
setSize({600, 400}); setSize({600, 400});

View File

@ -11,13 +11,11 @@ include gba/GNUmakefile
include ws/GNUmakefile include ws/GNUmakefile
include processor/GNUmakefile include processor/GNUmakefile
objects := ruby hiro $(objects) objects := ruby hiro $(if $(call streq,$(platform),windows),hiro-resource) $(objects)
objects += ui-higan ui-program ui-input objects += ui-higan ui-program ui-input
objects += ui-settings ui-tools ui-presentation ui-resource objects += ui-settings ui-tools ui-presentation ui-resource
objects += $(if $(call streq,$(platform),windows),ui-windows)
objects := $(objects:%=obj/%.o) objects := $(objects:%=obj/%.o)
# platform
ifeq ($(platform),windows) ifeq ($(platform),windows)
ruby += video.wgl video.direct3d video.directdraw video.gdi ruby += video.wgl video.direct3d video.directdraw video.gdi
ruby += audio.asio audio.wasapi audio.xaudio2 audio.directsound ruby += audio.asio audio.wasapi audio.xaudio2 audio.directsound
@ -36,23 +34,13 @@ else ifeq ($(platform),bsd)
ruby += input.sdl input.xlib ruby += input.sdl input.xlib
endif endif
# ruby ruby.path := ../ruby
include ../ruby/GNUmakefile include $(ruby.path)/GNUmakefile
link += $(rubylink)
obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/) hiro.path := ../hiro
$(info Compiling $< ...) hiro.resource := $(ui)/resource/higan.rc
@$(compiler) $(rubyflags) -c $< -o $@ include $(hiro.path)/GNUmakefile
# hiro
include ../hiro/GNUmakefile
link += $(hirolink)
obj/hiro.o: ../hiro/hiro.cpp $(call rwildcard,../hiro/)
$(info Compiling $< ...)
@$(compiler) $(hiroflags) -c $< -o $@
# rules
obj/ui-higan.o: $(ui)/higan.cpp obj/ui-higan.o: $(ui)/higan.cpp
obj/ui-program.o: $(ui)/program/program.cpp obj/ui-program.o: $(ui)/program/program.cpp
obj/ui-input.o: $(ui)/input/input.cpp obj/ui-input.o: $(ui)/input/input.cpp
@ -61,14 +49,10 @@ obj/ui-tools.o: $(ui)/tools/tools.cpp
obj/ui-presentation.o: $(ui)/presentation/presentation.cpp obj/ui-presentation.o: $(ui)/presentation/presentation.cpp
obj/ui-resource.o: $(ui)/resource/resource.cpp obj/ui-resource.o: $(ui)/resource/resource.cpp
obj/ui-windows.o: $(ui)/resource/higan.rc
$(info Compiling $< ...)
@$(windres) $(ui)/resource/higan.rc obj/ui-windows.o
# targets # targets
default: information $(objects) all: $(objects)
$(info Linking out/$(name) ...) $(info Linking out/$(name) ...)
+@$(strip $(compiler) -o out/$(name) $(objects) $(link)) +@$(strip $(compiler) -o out/$(name) $(objects) $(options) $(ruby.options) $(hiro.options))
ifeq ($(platform),macos) ifeq ($(platform),macos)
rm -rf out/$(name).app rm -rf out/$(name).app
mkdir -p out/$(name).app/Contents/MacOS/ mkdir -p out/$(name).app/Contents/MacOS/

View File

@ -255,7 +255,7 @@ auto InputManager::poll() -> void {
auto devices = input->poll(); auto devices = input->poll();
bool changed = devices.size() != this->devices.size(); bool changed = devices.size() != this->devices.size();
if(!changed) { if(!changed) {
for(auto n : range(devices)) { for(auto n : range(devices.size())) {
changed = devices[n] != this->devices[n]; changed = devices[n] != this->devices[n];
if(changed) break; if(changed) break;
} }

View File

@ -3,7 +3,7 @@ AboutWindow::AboutWindow() {
setTitle("About higan ..."); setTitle("About higan ...");
setBackgroundColor({255, 255, 240}); setBackgroundColor({255, 255, 240});
layout.setMargin(10); layout.setPadding(10);
auto logo = image{Resource::Logo}; auto logo = image{Resource::Logo};
logo.alphaBlend(0xfffff0); logo.alphaBlend(0xfffff0);
canvas.setIcon(logo); canvas.setIcon(logo);

View File

@ -171,7 +171,7 @@ auto Presentation::updateEmulator() -> void {
inputPort2.setVisible(false).reset(); inputPort2.setVisible(false).reset();
inputPort3.setVisible(false).reset(); inputPort3.setVisible(false).reset();
for(auto n : range(emulator->ports)) { for(auto n : range(emulator->ports.size())) {
if(n >= 3) break; if(n >= 3) break;
auto& port = emulator->ports[n]; auto& port = emulator->ports[n];
auto& menu = (n == 0 ? inputPort1 : n == 1 ? inputPort2 : inputPort3); auto& menu = (n == 0 ? inputPort1 : n == 1 ? inputPort2 : inputPort3);

View File

@ -2,7 +2,7 @@ AdvancedSettings::AdvancedSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Action::Settings); setIcon(Icon::Action::Settings);
setText("Advanced"); setText("Advanced");
layout.setMargin(5); layout.setPadding(5);
driverLabel.setText("Driver Selection").setFont(Font().setBold()); driverLabel.setText("Driver Selection").setFont(Font().setBold());
videoLabel.setText("Video:"); videoLabel.setText("Video:");

View File

@ -2,7 +2,7 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Speaker); setIcon(Icon::Device::Speaker);
setText("Audio"); setText("Audio");
layout.setMargin(5); layout.setPadding(5);
driverLabel.setFont(Font().setBold()).setText("Driver"); driverLabel.setFont(Font().setBold()).setText("Driver");

View File

@ -2,7 +2,7 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Keyboard); setIcon(Icon::Device::Keyboard);
setText("Hotkeys"); setText("Hotkeys");
layout.setMargin(5); layout.setPadding(5);
mappingList.onActivate([&] { assignMapping(); }); mappingList.onActivate([&] { assignMapping(); });
mappingList.onChange([&] { eraseButton.setEnabled((bool)mappingList.selected()); }); mappingList.onChange([&] { eraseButton.setEnabled((bool)mappingList.selected()); });
resetButton.setText("Reset").onActivate([&] { resetButton.setText("Reset").onActivate([&] {

View File

@ -2,7 +2,7 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Joypad); setIcon(Icon::Device::Joypad);
setText("Input"); setText("Input");
layout.setMargin(5); layout.setPadding(5);
defocusLabel.setText("When Focus is Lost:"); defocusLabel.setText("When Focus is Lost:");
pauseEmulation.setText("Pause Emulation").onActivate([&] { pauseEmulation.setText("Pause Emulation").onActivate([&] {
settings["Input/Defocus"].setValue("Pause"); settings["Input/Defocus"].setValue("Pause");
@ -87,7 +87,7 @@ auto InputSettings::reloadPorts() -> void {
auto InputSettings::reloadDevices() -> void { auto InputSettings::reloadDevices() -> void {
deviceList.reset(); deviceList.reset();
for(auto n : range(activePort().devices)) { for(auto n : range(activePort().devices.size())) {
auto& device = activePort().devices[n]; auto& device = activePort().devices[n];
if(!device.mappings) continue; //do not display devices that have no configurable inputs if(!device.mappings) continue; //do not display devices that have no configurable inputs
deviceList.append(ComboButtonItem().setText(device.name).setProperty("index", n)); deviceList.append(ComboButtonItem().setText(device.name).setProperty("index", n));

View File

@ -81,7 +81,7 @@ auto Settings::save() -> void {
SettingsManager::SettingsManager() { SettingsManager::SettingsManager() {
settingsManager = this; settingsManager = this;
layout.setMargin(5); layout.setPadding(5);
statusBar.setFont(Font().setBold()); statusBar.setFont(Font().setBold());
setTitle("Settings"); setTitle("Settings");

View File

@ -1,7 +1,7 @@
SystemProperties::SystemProperties() { SystemProperties::SystemProperties() {
systemProperties = this; systemProperties = this;
layout.setMargin(5); layout.setPadding(5);
systemLabel.setAlignment(1.0).setText("System:"); systemLabel.setAlignment(1.0).setText("System:");
for(auto& emulator : program->emulators) { for(auto& emulator : program->emulators) {
systemOption.append(ComboButtonItem().setText(emulator->information.name)); systemOption.append(ComboButtonItem().setText(emulator->information.name));

View File

@ -2,7 +2,7 @@ SystemSettings::SystemSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Storage); setIcon(Icon::Device::Storage);
setText("Systems"); setText("Systems");
layout.setMargin(5); layout.setPadding(5);
systemList.onActivate([&] { systemList.onActivate([&] {
modifyButton.doActivate(); modifyButton.doActivate();

View File

@ -2,7 +2,7 @@ VideoSettings::VideoSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Device::Display); setIcon(Icon::Device::Display);
setText("Video"); setText("Video");
layout.setMargin(5); layout.setPadding(5);
colorAdjustmentLabel.setFont(Font().setBold()).setText("Color Adjustment"); colorAdjustmentLabel.setFont(Font().setBold()).setText("Color Adjustment");
saturationLabel.setText("Saturation:"); saturationLabel.setText("Saturation:");

View File

@ -1,7 +1,7 @@
CheatDatabase::CheatDatabase() { CheatDatabase::CheatDatabase() {
cheatDatabase = this; cheatDatabase = this;
layout.setMargin(5); layout.setPadding(5);
selectAllButton.setText("Select All").onActivate([&] { selectAllButton.setText("Select All").onActivate([&] {
for(auto& item : cheatList.items()) item.setChecked(true); for(auto& item : cheatList.items()) item.setChecked(true);
}); });

View File

@ -2,7 +2,7 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Edit::Replace); setIcon(Icon::Edit::Replace);
setText("Cheat Editor"); setText("Cheat Editor");
layout.setMargin(5); layout.setPadding(5);
cheatList.append(TableViewHeader().setVisible() cheatList.append(TableViewHeader().setVisible()
.append(TableViewColumn()) .append(TableViewColumn())
.append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) .append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0))

View File

@ -2,7 +2,7 @@ GameNotes::GameNotes(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Emblem::Text); setIcon(Icon::Emblem::Text);
setText("Game Notes"); setText("Game Notes");
layout.setMargin(5); layout.setPadding(5);
notes.setWordWrap(false).setFont(Font().setFamily(Font::Mono)); notes.setWordWrap(false).setFont(Font().setFamily(Font::Mono));
} }

View File

@ -2,7 +2,7 @@ ManifestViewer::ManifestViewer(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Emblem::Text); setIcon(Icon::Emblem::Text);
setText("Manifest Viewer"); setText("Manifest Viewer");
layout.setMargin(5); layout.setPadding(5);
manifestView.setEditable(false).setWordWrap(false).setFont(Font().setFamily(Font::Mono)); manifestView.setEditable(false).setWordWrap(false).setFont(Font().setFamily(Font::Mono));
} }

View File

@ -2,7 +2,7 @@ StateManager::StateManager(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Application::FileManager); setIcon(Icon::Application::FileManager);
setText("State Manager"); setText("State Manager");
layout.setMargin(5); layout.setPadding(5);
stateList.append(TableViewHeader().setVisible() stateList.append(TableViewHeader().setVisible()
.append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) .append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0))
.append(TableViewColumn().setText("Description").setExpandable()) .append(TableViewColumn().setText("Description").setExpandable())

View File

@ -10,7 +10,7 @@ unique_pointer<ToolsManager> toolsManager;
ToolsManager::ToolsManager() { ToolsManager::ToolsManager() {
toolsManager = this; toolsManager = this;
layout.setMargin(5); layout.setPadding(5);
setTitle("Tools"); setTitle("Tools");
setSize({600, 405}); setSize({600, 405});

View File

@ -101,7 +101,7 @@ auto Video::createSprite(uint width, uint height) -> shared_pointer<Sprite> {
} }
auto Video::removeSprite(shared_pointer<Sprite> sprite) -> bool { auto Video::removeSprite(shared_pointer<Sprite> sprite) -> bool {
for(uint n : range(sprites)) { for(uint n : range(sprites.size())) {
if(sprite == sprites[n]) { if(sprite == sprites[n]) {
sprites.remove(n); sprites.remove(n);
return true; return true;

View File

@ -1,6 +1,6 @@
ifeq ($(platform),) ifeq ($(platform),)
hiroflags = $(cppflags) $(flags) -DHIRO_REFERENCE hiro.flags = $(flags.cpp) -DHIRO_REFERENCE
hirolink = hiro.options =
endif endif
ifeq ($(platform),windows) ifeq ($(platform),windows)
@ -9,18 +9,18 @@ ifeq ($(platform),windows)
endif endif
ifeq ($(hiro),windows) ifeq ($(hiro),windows)
hiroflags = $(cppflags) $(flags) -DHIRO_WINDOWS hiro.flags = $(flags.cpp) -DHIRO_WINDOWS
hirolink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi hiro.options = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi
endif endif
ifeq ($(hiro),gtk2) ifeq ($(hiro),gtk2)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0) hiro.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0)
hirolink = $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0) hiro.options = $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0)
endif endif
ifeq ($(hiro),gtk3) ifeq ($(hiro),gtk3)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0) hiro.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0)
hirolink = $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0) hiro.options = $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0)
endif endif
endif endif
@ -30,8 +30,8 @@ ifeq ($(platform),macos)
endif endif
ifeq ($(hiro),cocoa) ifeq ($(hiro),cocoa)
hiroflags = $(objcppflags) $(flags) -w -DHIRO_COCOA hiro.flags = $(flags.objcpp) -w -DHIRO_COCOA
hirolink = -framework Cocoa -framework Carbon -framework Security hiro.options = -framework Cocoa -framework Carbon -framework Security
endif endif
endif endif
@ -41,24 +41,38 @@ ifneq ($(filter $(platform),linux bsd),)
endif endif
ifeq ($(hiro),gtk2) ifeq ($(hiro),gtk2)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0) hiro.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0)
hirolink = -lX11 $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0) hiro.options = -lX11 $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0)
endif endif
ifeq ($(hiro),gtk3) ifeq ($(hiro),gtk3)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0) hiro.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0)
hirolink = -lX11 $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0) hiro.options = -lX11 $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0)
endif endif
ifeq ($(hiro),qt4) ifeq ($(hiro),qt4)
moc = moc-qt4 moc = moc-qt4
hiroflags = $(cppflags) $(flags) -DHIRO_QT=4 $(shell pkg-config --cflags QtCore QtGui) hiro.flags = $(flags.cpp) -DHIRO_QT=4 $(shell pkg-config --cflags QtCore QtGui)
hirolink = -lX11 $(shell pkg-config --libs QtCore QtGui) hiro.options = -lX11 $(shell pkg-config --libs QtCore QtGui)
endif endif
ifeq ($(hiro),qt5) ifeq ($(hiro),qt5)
moc = /usr/local/lib/qt5/bin/moc moc = /usr/local/lib/qt5/bin/moc
hiroflags = -fPIC $(cppflags) $(flags) -DHIRO_QT=5 $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets) hiro.flags = $(flags.cpp) -DHIRO_QT=5 -fPIC $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)
hirolink = -lX11 $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Widgets) hiro.options = -lX11 $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Widgets)
endif endif
endif endif
$(object.path)/hiro.o: $(hiro.path)/hiro.cpp $(call rwildcard,$(hiro.path)) $(call rwildcard,$(nall.path))
$(if $(filter qt%,$(hiro)),$(info Compiling $(hiro.path)/qt/qt.moc ...))
$(if $(filter qt%,$(hiro)),@$(moc) -i -o $(hiro.path)/qt/qt.moc $(hiro.path)/qt/qt.hpp)
$(info Compiling $< ...)
@$(compiler) $(flags) $(hiro.flags) -c $< -o $@
ifeq ($(hiro.resource),)
hiro.resource := $(hiro.path)/windows/hiro.rc
endif
$(object.path)/hiro-resource.o: $(hiro.resource)
$(if $(filter windows,$(hiro)),$(info Compiling $< ...))
$(if $(filter windows,$(hiro)),@$(windres) $< $@)

View File

@ -1,33 +0,0 @@
#if defined(Hiro_Layout)
namespace hiro {
auto pLayout::construct() -> void {
for(auto& sizable : state().sizables) sizable->construct();
}
auto pLayout::destruct() -> void {
for(auto& sizable : state().sizables) sizable->destruct();
}
auto pLayout::setEnabled(bool enabled) -> void {
for(auto& sizable : state().sizables) {
if(auto self = sizable->self()) self->setEnabled(enabled && sizable->enabled(true));
}
}
auto pLayout::setFont(const Font& font) -> void {
for(auto& sizable : state().sizables) {
if(auto self = sizable->self()) self->setFont(font ? font : sizable->font(true));
}
}
auto pLayout::setVisible(bool visible) -> void {
for(auto& sizable : state().sizables) {
if(auto self = sizable->self()) self->setVisible(visible && sizable->visible(true));
}
}
}
#endif

View File

@ -1,15 +0,0 @@
#if defined(Hiro_Layout)
namespace hiro {
struct pLayout : pSizable {
Declare(Layout, Sizable);
auto setEnabled(bool enabled) -> void override;
auto setFont(const Font& font) -> void override;
auto setVisible(bool visible) -> void override;
};
}
#endif

View File

@ -27,6 +27,9 @@ auto pObject::setFocused() -> void {
auto pObject::setFont(const Font& font) -> void { auto pObject::setFont(const Font& font) -> void {
} }
auto pObject::setParent(mObject* parent, int offset) -> void {
}
auto pObject::setVisible(bool visible) -> void { auto pObject::setVisible(bool visible) -> void {
} }

View File

@ -2,7 +2,7 @@
namespace hiro { namespace hiro {
struct pObject { struct pObject : mLock {
pObject(mObject& reference) : reference(reference) {} pObject(mObject& reference) : reference(reference) {}
virtual ~pObject() {} virtual ~pObject() {}
auto self() const -> mObject& { return (mObject&)reference; } auto self() const -> mObject& { return (mObject&)reference; }
@ -16,14 +16,10 @@ struct pObject {
virtual auto setEnabled(bool enabled) -> void; virtual auto setEnabled(bool enabled) -> void;
virtual auto setFocused() -> void; virtual auto setFocused() -> void;
virtual auto setFont(const Font& font) -> void; virtual auto setFont(const Font& font) -> void;
virtual auto setParent(mObject* parent, int offset) -> void;
virtual auto setVisible(bool visible) -> void; virtual auto setVisible(bool visible) -> void;
auto locked() const -> bool { return locks != 0 || Application::state.quit; }
auto lock() -> void { ++locks; }
auto unlock() -> void { --locks; }
mObject& reference; mObject& reference;
signed locks = 0;
}; };
} }

View File

@ -26,7 +26,6 @@
#include "action/menu-radio-item.cpp" #include "action/menu-radio-item.cpp"
#include "sizable.cpp" #include "sizable.cpp"
#include "layout.cpp"
#include "widget/widget.cpp" #include "widget/widget.cpp"
#include "widget/button.cpp" #include "widget/button.cpp"

View File

@ -38,7 +38,6 @@ namespace hiro {
#include "action/menu-radio-item.hpp" #include "action/menu-radio-item.hpp"
#include "sizable.hpp" #include "sizable.hpp"
#include "layout.hpp"
#include "widget/widget.hpp" #include "widget/widget.hpp"
#include "widget/button.hpp" #include "widget/button.hpp"

View File

@ -31,22 +31,22 @@ auto pFrame::destruct() -> void {
} }
} }
auto pFrame::append(sLayout layout) -> void { auto pFrame::append(sSizable sizable) -> void {
} }
auto pFrame::remove(sLayout layout) -> void { auto pFrame::remove(sSizable sizable) -> void {
} }
auto pFrame::setEnabled(bool enabled) -> void { auto pFrame::setEnabled(bool enabled) -> void {
pWidget::setEnabled(enabled); pWidget::setEnabled(enabled);
if(auto layout = _layout()) layout->setEnabled(layout->self().enabled(true)); if(auto& sizable = _sizable()) sizable->setEnabled(sizable->self().enabled(true));
} }
auto pFrame::setFont(const Font& font) -> void { auto pFrame::setFont(const Font& font) -> void {
@autoreleasepool { @autoreleasepool {
[cocoaView setTitleFont:pFont::create(font)]; [cocoaView setTitleFont:pFont::create(font)];
} }
if(auto layout = _layout()) layout->setFont(layout->self().font(true)); if(auto& sizable = _sizable()) sizable->setFont(sizable->self().font(true));
} }
auto pFrame::setGeometry(Geometry geometry) -> void { auto pFrame::setGeometry(Geometry geometry) -> void {
@ -56,8 +56,8 @@ auto pFrame::setGeometry(Geometry geometry) -> void {
geometry.x() - 3, geometry.y() - (empty ? size.height() - 2 : 1), geometry.x() - 3, geometry.y() - (empty ? size.height() - 2 : 1),
geometry.width() + 6, geometry.height() + (empty ? size.height() + 2 : 5) geometry.width() + 6, geometry.height() + (empty ? size.height() + 2 : 5)
}); });
if(auto layout = state().layout) { if(auto& sizable = state().sizable) {
layout->setGeometry({ sizable->setGeometry({
geometry.x() + 1, geometry.y() + (empty ? 1 : size.height() - 2), geometry.x() + 1, geometry.y() + (empty ? 1 : size.height() - 2),
geometry.width() - 2, geometry.height() - (empty ? 1 : size.height() - 1) geometry.width() - 2, geometry.height() - (empty ? 1 : size.height() - 1)
}); });
@ -72,12 +72,12 @@ auto pFrame::setText(const string& text) -> void {
auto pFrame::setVisible(bool visible) -> void { auto pFrame::setVisible(bool visible) -> void {
pWidget::setVisible(visible); pWidget::setVisible(visible);
if(auto layout = _layout()) layout->setVisible(layout->self().visible(true)); if(auto& sizable = _sizable()) sizable->setVisible(sizable->self().visible(true));
} }
auto pFrame::_layout() -> maybe<pLayout&> { auto pFrame::_sizable() -> maybe<pSizable&> {
if(auto layout = state().layout) { if(auto sizable = state().sizable) {
if(auto self = layout->self()) return *self; if(auto self = sizable->self()) return *self;
} }
return nothing; return nothing;
} }

View File

@ -12,15 +12,15 @@ namespace hiro {
struct pFrame : pWidget { struct pFrame : pWidget {
Declare(Frame, Widget) Declare(Frame, Widget)
auto append(sLayout layout) -> void; auto append(sSizable sizable) -> void;
auto remove(sLayout layout) -> void; auto remove(sSizable sizable) -> void;
auto setEnabled(bool enabled) -> void override; auto setEnabled(bool enabled) -> void override;
auto setFont(const Font& font) -> void override; auto setFont(const Font& font) -> void override;
auto setGeometry(Geometry geometry) -> void override; auto setGeometry(Geometry geometry) -> void override;
auto setText(const string& text) -> void; auto setText(const string& text) -> void;
auto setVisible(bool visible) -> void override; auto setVisible(bool visible) -> void override;
auto _layout() -> maybe<pLayout&>; auto _sizable() -> maybe<pSizable&>;
CocoaFrame* cocoaFrame = nullptr; CocoaFrame* cocoaFrame = nullptr;
}; };

View File

@ -8,10 +8,10 @@ auto pTabFrameItem::construct() -> void {
auto pTabFrameItem::destruct() -> void { auto pTabFrameItem::destruct() -> void {
} }
auto pTabFrameItem::append(sLayout layout) -> void { auto pTabFrameItem::append(sSizable sizable) -> void {
} }
auto pTabFrameItem::remove(sLayout layout) -> void { auto pTabFrameItem::remove(sSizable sizable) -> void {
} }
auto pTabFrameItem::setClosable(bool closable) -> void { auto pTabFrameItem::setClosable(bool closable) -> void {

View File

@ -5,8 +5,8 @@ namespace hiro {
struct pTabFrameItem : pObject { struct pTabFrameItem : pObject {
Declare(TabFrameItem, Object) Declare(TabFrameItem, Object)
auto append(sLayout layout) -> void; auto append(sSizable sizable) -> void;
auto remove(sLayout layout) -> void; auto remove(sSizable sizable) -> void;
auto setClosable(bool closable) -> void; auto setClosable(bool closable) -> void;
auto setIcon(const image& icon) -> void; auto setIcon(const image& icon) -> void;
auto setMovable(bool movable) -> void; auto setMovable(bool movable) -> void;

View File

@ -213,12 +213,12 @@ auto pWindow::destruct() -> void {
} }
} }
auto pWindow::append(sLayout layout) -> void { auto pWindow::append(sMenuBar menuBar) -> void {
layout->setGeometry(self().geometry().setPosition(0, 0));
statusBarReposition();
} }
auto pWindow::append(sMenuBar menuBar) -> void { auto pWindow::append(sSizable sizable) -> void {
layout->setGeometry(self().geometry().setPosition(0, 0));
statusBarReposition();
} }
auto pWindow::append(sStatusBar statusBar) -> void { auto pWindow::append(sStatusBar statusBar) -> void {
@ -241,15 +241,15 @@ auto pWindow::frameMargin() const -> Geometry {
} }
} }
auto pWindow::remove(sLayout layout) -> void { auto pWindow::remove(sMenuBar menuBar) -> void {
}
auto pWindow::remove(sSizable sizable) -> void {
@autoreleasepool { @autoreleasepool {
[[cocoaWindow contentView] setNeedsDisplay:YES]; [[cocoaWindow contentView] setNeedsDisplay:YES];
} }
} }
auto pWindow::remove(sMenuBar menuBar) -> void {
}
auto pWindow::remove(sStatusBar statusBar) -> void { auto pWindow::remove(sStatusBar statusBar) -> void {
@autoreleasepool { @autoreleasepool {
[[cocoaWindow statusBar] setHidden:YES]; [[cocoaWindow statusBar] setHidden:YES];

View File

@ -30,13 +30,13 @@ namespace hiro {
struct pWindow : pObject { struct pWindow : pObject {
Declare(Window, Object) Declare(Window, Object)
auto append(sLayout layout) -> void;
auto append(sMenuBar menuBar) -> void; auto append(sMenuBar menuBar) -> void;
auto append(sSizable sizable) -> void;
auto append(sStatusBar statusBar) -> void; auto append(sStatusBar statusBar) -> void;
auto focused() const -> bool override; auto focused() const -> bool override;
auto frameMargin() const -> Geometry; auto frameMargin() const -> Geometry;
auto remove(sLayout layout) -> void;
auto remove(sMenuBar menuBar) -> void; auto remove(sMenuBar menuBar) -> void;
auto remove(sSizable sizable) -> void;
auto remove(sStatusBar statusBar) -> void; auto remove(sStatusBar statusBar) -> void;
auto setBackgroundColor(Color color) -> void; auto setBackgroundColor(Color color) -> void;
auto setDismissable(bool dismissable) -> void; auto setDismissable(bool dismissable) -> void;

View File

@ -47,7 +47,6 @@
#define Hiro_MenuRadioItem #define Hiro_MenuRadioItem
#define Hiro_Sizable #define Hiro_Sizable
#define Hiro_Layout
#define Hiro_Widget #define Hiro_Widget
#define Hiro_Button #define Hiro_Button
#define Hiro_Canvas #define Hiro_Canvas
@ -94,6 +93,7 @@
#define Hiro_FixedLayout #define Hiro_FixedLayout
#define Hiro_HorizontalLayout #define Hiro_HorizontalLayout
#define Hiro_VerticalLayout #define Hiro_VerticalLayout
#define Hiro_TableLayout
#if defined(Hiro_TableView) #if defined(Hiro_TableView)
#define Hiro_ListView #define Hiro_ListView

View File

@ -59,7 +59,7 @@ auto mMenu::setIcon(const image& icon) -> type& {
} }
auto mMenu::setParent(mObject* parent, signed offset) -> type& { auto mMenu::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.actions)) state.actions[n]->destruct(); for(auto& action : reverse(state.actions)) action->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
for(auto& action : state.actions) action->setParent(this, action->offset()); for(auto& action : state.actions) action->setParent(this, action->offset());
return *this; return *this;

View File

@ -68,7 +68,6 @@ namespace hiro {
#include "action/menu-radio-item.cpp" #include "action/menu-radio-item.cpp"
#include "sizable.cpp" #include "sizable.cpp"
#include "layout.cpp"
#include "widget/widget.cpp" #include "widget/widget.cpp"
#include "widget/button.cpp" #include "widget/button.cpp"

View File

@ -51,7 +51,6 @@ Declare(MenuItem)
Declare(MenuCheckItem) Declare(MenuCheckItem)
Declare(MenuRadioItem) Declare(MenuRadioItem)
Declare(Sizable) Declare(Sizable)
Declare(Layout)
Declare(Widget) Declare(Widget)
Declare(Button) Declare(Button)
Declare(Canvas) Declare(Canvas)
@ -98,7 +97,7 @@ struct Color {
using type = Color; using type = Color;
Color(); Color();
Color(signed red, signed green, signed blue, signed alpha = 255); Color(int red, int green, int blue, int alpha = 255);
explicit operator bool() const; explicit operator bool() const;
auto operator==(const Color& source) const -> bool; auto operator==(const Color& source) const -> bool;
@ -109,12 +108,12 @@ struct Color {
auto green() const -> uint8_t; auto green() const -> uint8_t;
auto red() const -> uint8_t; auto red() const -> uint8_t;
auto reset() -> type&; auto reset() -> type&;
auto setAlpha(signed alpha) -> type&; auto setAlpha(int alpha) -> type&;
auto setBlue(signed blue) -> type&; auto setBlue(int blue) -> type&;
auto setColor(Color color = {}) -> type&; auto setColor(Color color = {}) -> type&;
auto setColor(signed red, signed green, signed blue, signed alpha = 255) -> type&; auto setColor(int red, int green, int blue, int alpha = 255) -> type&;
auto setGreen(signed green) -> type&; auto setGreen(int green) -> type&;
auto setRed(signed red) -> type&; auto setRed(int red) -> type&;
auto value() const -> uint32_t; auto value() const -> uint32_t;
//private: //private:
@ -178,22 +177,22 @@ struct Alignment {
struct Cursor { struct Cursor {
using type = Cursor; using type = Cursor;
Cursor(signed offset = 0, signed length = 0); Cursor(int offset = 0, int length = 0);
explicit operator bool() const; explicit operator bool() const;
auto operator==(const Cursor& source) const -> bool; auto operator==(const Cursor& source) const -> bool;
auto operator!=(const Cursor& source) const -> bool; auto operator!=(const Cursor& source) const -> bool;
auto length() const -> signed; auto length() const -> int;
auto offset() const -> signed; auto offset() const -> int;
auto setCursor(signed offset = 0, signed length = 0) -> type&; auto setCursor(int offset = 0, int length = 0) -> type&;
auto setLength(signed length = 0) -> type&; auto setLength(int length = 0) -> type&;
auto setOffset(signed offset = 0) -> type&; auto setOffset(int offset = 0) -> type&;
//private: //private:
struct State { struct State {
signed offset; int offset;
signed length; int length;
} state; } state;
}; };
#endif #endif
@ -359,7 +358,7 @@ struct Hotkey {
//private: //private:
struct State { struct State {
bool active = false; bool active = false;
vector<unsigned> keys; vector<uint> keys;
function<void ()> onPress; function<void ()> onPress;
function<void ()> onRelease; function<void ()> onRelease;
string sequence; string sequence;
@ -458,8 +457,8 @@ struct Keyboard {
Keyboard() = delete; Keyboard() = delete;
static auto append(Hotkey hotkey) -> void; static auto append(Hotkey hotkey) -> void;
static auto hotkey(unsigned position) -> Hotkey; static auto hotkey(uint position) -> Hotkey;
static auto hotkeyCount() -> unsigned; static auto hotkeyCount() -> uint;
static auto hotkeys() -> vector<Hotkey>; static auto hotkeys() -> vector<Hotkey>;
static auto poll() -> vector<bool>; static auto poll() -> vector<bool>;
static auto pressed(const string& key) -> bool; static auto pressed(const string& key) -> bool;
@ -478,7 +477,7 @@ struct Keyboard {
#if defined(Hiro_Mouse) #if defined(Hiro_Mouse)
struct Mouse { struct Mouse {
enum class Button : unsigned { Left, Middle, Right }; enum class Button : uint { Left, Middle, Right };
Mouse() = delete; Mouse() = delete;
@ -512,8 +511,8 @@ struct BrowserWindow {
#if defined(Hiro_MessageWindow) #if defined(Hiro_MessageWindow)
struct MessageWindow { struct MessageWindow {
enum class Buttons : unsigned { Ok, OkCancel, YesNo, YesNoCancel }; enum class Buttons : uint { Ok, OkCancel, YesNo, YesNoCancel };
enum class Response : unsigned { Ok, Cancel, Yes, No }; enum class Response : uint { Ok, Cancel, Yes, No };
using type = MessageWindow; using type = MessageWindow;
@ -585,18 +584,17 @@ struct mObject {
explicit operator bool() const; explicit operator bool() const;
auto abstract() const -> bool; auto abstract() const -> bool;
auto adjustOffset(signed displacement) -> type&; auto adjustOffset(int displacement) -> type&;
auto enabled(bool recursive = false) const -> bool; auto enabled(bool recursive = false) const -> bool;
virtual auto focused() const -> bool; virtual auto focused() const -> bool;
auto font(bool recursive = false) const -> Font; auto font(bool recursive = false) const -> Font;
virtual auto group() const -> Group; virtual auto group() const -> Group;
auto offset() const -> signed; auto offset() const -> int;
auto parent() const -> mObject*; auto parent() const -> mObject*;
auto parentComboButton(bool recursive = false) const -> mComboButton*; auto parentComboButton(bool recursive = false) const -> mComboButton*;
auto parentComboEdit(bool recursive = false) const -> mComboEdit*; auto parentComboEdit(bool recursive = false) const -> mComboEdit*;
auto parentFrame(bool recursive = false) const -> mFrame*; auto parentFrame(bool recursive = false) const -> mFrame*;
auto parentIconView(bool recursive = false) const -> mIconView*; auto parentIconView(bool recursive = false) const -> mIconView*;
auto parentLayout(bool recursive = false) const -> mLayout*;
auto parentMenu(bool recursive = false) const -> mMenu*; auto parentMenu(bool recursive = false) const -> mMenu*;
auto parentMenuBar(bool recursive = false) const -> mMenuBar*; auto parentMenuBar(bool recursive = false) const -> mMenuBar*;
auto parentPopupMenu(bool recursive = false) const -> mPopupMenu*; auto parentPopupMenu(bool recursive = false) const -> mPopupMenu*;
@ -617,7 +615,7 @@ struct mObject {
virtual auto setFocused() -> type&; virtual auto setFocused() -> type&;
virtual auto setFont(const Font& font = {}) -> type&; virtual auto setFont(const Font& font = {}) -> type&;
virtual auto setGroup(sGroup group = {}) -> type&; virtual auto setGroup(sGroup group = {}) -> type&;
virtual auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&; virtual auto setParent(mObject* parent = nullptr, int offset = -1) -> type&;
virtual auto setProperty(const string& name, const string& value = "") -> type&; virtual auto setProperty(const string& name, const string& value = "") -> type&;
virtual auto setVisible(bool visible = true) -> type&; virtual auto setVisible(bool visible = true) -> type&;
auto visible(bool recursive = false) const -> bool; auto visible(bool recursive = false) const -> bool;
@ -626,7 +624,7 @@ struct mObject {
struct State { struct State {
bool enabled = true; bool enabled = true;
Font font; Font font;
signed offset = -1; int offset = -1;
mObject* parent = nullptr; mObject* parent = nullptr;
set<Property> properties; set<Property> properties;
bool visible = true; bool visible = true;
@ -646,8 +644,8 @@ struct mGroup : mObject {
using mObject::remove; using mObject::remove;
auto append(sObject object) -> type&; auto append(sObject object) -> type&;
auto object(unsigned offset) const -> Object; auto object(uint offset) const -> Object;
auto objectCount() const -> unsigned; auto objectCount() const -> uint;
auto objects() const -> vector<Object>; auto objects() const -> vector<Object>;
auto remove(sObject object) -> type&; auto remove(sObject object) -> type&;
@ -663,13 +661,13 @@ struct mTimer : mObject {
Declare(Timer) Declare(Timer)
auto doActivate() const -> void; auto doActivate() const -> void;
auto interval() const -> unsigned; auto interval() const -> uint;
auto onActivate(const function<void ()>& callback = {}) -> type&; auto onActivate(const function<void ()>& callback = {}) -> type&;
auto setInterval(unsigned interval = 0) -> type&; auto setInterval(uint interval = 0) -> type&;
//private: //private:
struct State { struct State {
unsigned interval = 0; uint interval = 0;
function<void ()> onActivate; function<void ()> onActivate;
} state; } state;
}; };
@ -680,22 +678,23 @@ struct mWindow : mObject {
Declare(Window) Declare(Window)
using mObject::remove; using mObject::remove;
auto append(sLayout layout) -> type&; mWindow();
auto append(sMenuBar menuBar) -> type&; auto append(sMenuBar menuBar) -> type&;
auto append(sSizable sizable) -> type&;
auto append(sStatusBar statusBar) -> type&; auto append(sStatusBar statusBar) -> type&;
auto backgroundColor() const -> Color; auto backgroundColor() const -> Color;
auto dismissable() const -> bool; auto dismissable() const -> bool;
auto doClose() const -> void; auto doClose() const -> void;
auto doDrop(string_vector) const -> void; auto doDrop(string_vector) const -> void;
auto doKeyPress(signed) const -> void; auto doKeyPress(int) const -> void;
auto doKeyRelease(signed) const -> void; auto doKeyRelease(int) const -> void;
auto doMove() const -> void; auto doMove() const -> void;
auto doSize() const -> void; auto doSize() const -> void;
auto droppable() const -> bool; auto droppable() const -> bool;
auto frameGeometry() const -> Geometry; auto frameGeometry() const -> Geometry;
auto fullScreen() const -> bool; auto fullScreen() const -> bool;
auto geometry() const -> Geometry; auto geometry() const -> Geometry;
auto layout() const -> Layout;
auto maximized() const -> bool; auto maximized() const -> bool;
auto maximumSize() const -> Size; auto maximumSize() const -> Size;
auto menuBar() const -> MenuBar; auto menuBar() const -> MenuBar;
@ -704,12 +703,12 @@ struct mWindow : mObject {
auto modal() const -> bool; auto modal() const -> bool;
auto onClose(const function<void ()>& callback = {}) -> type&; auto onClose(const function<void ()>& callback = {}) -> type&;
auto onDrop(const function<void (string_vector)>& callback = {}) -> type&; auto onDrop(const function<void (string_vector)>& callback = {}) -> type&;
auto onKeyPress(const function<void (signed)>& callback = {}) -> type&; auto onKeyPress(const function<void (int)>& callback = {}) -> type&;
auto onKeyRelease(const function<void (signed)>& callback = {}) -> type&; auto onKeyRelease(const function<void (int)>& callback = {}) -> type&;
auto onMove(const function<void ()>& callback = {}) -> type&; auto onMove(const function<void ()>& callback = {}) -> type&;
auto onSize(const function<void ()>& callback = {}) -> type&; auto onSize(const function<void ()>& callback = {}) -> type&;
auto remove(sLayout layout) -> type&;
auto remove(sMenuBar menuBar) -> type&; auto remove(sMenuBar menuBar) -> type&;
auto remove(sSizable sizable) -> type&;
auto remove(sStatusBar statusBar) -> type&; auto remove(sStatusBar statusBar) -> type&;
auto reset() -> type& override; auto reset() -> type& override;
auto resizable() const -> bool; auto resizable() const -> bool;
@ -732,6 +731,8 @@ struct mWindow : mObject {
auto setResizable(bool resizable = true) -> type&; auto setResizable(bool resizable = true) -> type&;
auto setSize(Size size) -> type&; auto setSize(Size size) -> type&;
auto setTitle(const string& title = "") -> type&; auto setTitle(const string& title = "") -> type&;
auto setVisible(bool visible = true) -> type&;
auto sizable() const -> Sizable;
auto statusBar() const -> StatusBar; auto statusBar() const -> StatusBar;
auto title() const -> string; auto title() const -> string;
@ -742,7 +743,6 @@ struct mWindow : mObject {
bool droppable = false; bool droppable = false;
bool fullScreen = false; bool fullScreen = false;
Geometry geometry = {128, 128, 256, 256}; Geometry geometry = {128, 128, 256, 256};
sLayout layout;
bool maximized = false; bool maximized = false;
Size maximumSize; Size maximumSize;
bool minimized = false; bool minimized = false;
@ -751,11 +751,12 @@ struct mWindow : mObject {
bool modal = false; bool modal = false;
function<void ()> onClose; function<void ()> onClose;
function<void (string_vector)> onDrop; function<void (string_vector)> onDrop;
function<void (signed)> onKeyPress; function<void (int)> onKeyPress;
function<void (signed)> onKeyRelease; function<void (int)> onKeyRelease;
function<void ()> onMove; function<void ()> onMove;
function<void ()> onSize; function<void ()> onSize;
bool resizable = true; bool resizable = true;
sSizable sizable;
sStatusBar statusBar; sStatusBar statusBar;
string title; string title;
} state; } state;
@ -784,13 +785,13 @@ struct mMenuBar : mObject {
Declare(MenuBar) Declare(MenuBar)
auto append(sMenu menu) -> type&; auto append(sMenu menu) -> type&;
auto menu(unsigned position) const -> Menu; auto menu(uint position) const -> Menu;
auto menuCount() const -> unsigned; auto menuCount() const -> uint;
auto menus() const -> vector<Menu>; auto menus() const -> vector<Menu>;
auto remove() -> type& override; auto remove() -> type& override;
auto remove(sMenu menu) -> type&; auto remove(sMenu menu) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
//private: //private:
struct State { struct State {
@ -806,13 +807,13 @@ struct mPopupMenu : mObject {
Declare(PopupMenu) Declare(PopupMenu)
using mObject::remove; using mObject::remove;
auto action(unsigned position) const -> Action; auto action(uint position) const -> Action;
auto actionCount() const -> unsigned; auto actionCount() const -> uint;
auto actions() const -> vector<Action>; auto actions() const -> vector<Action>;
auto append(sAction action) -> type&; auto append(sAction action) -> type&;
auto remove(sAction action) -> type&; auto remove(sAction action) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setVisible(bool visible = true) -> type& override; auto setVisible(bool visible = true) -> type& override;
//private: //private:
@ -841,15 +842,15 @@ struct mMenu : mAction {
Declare(Menu) Declare(Menu)
using mObject::remove; using mObject::remove;
auto action(unsigned position) const -> Action; auto action(uint position) const -> Action;
auto actionCount() const -> unsigned; auto actionCount() const -> uint;
auto actions() const -> vector<Action>; auto actions() const -> vector<Action>;
auto append(sAction action) -> type&; auto append(sAction action) -> type&;
auto icon() const -> image; auto icon() const -> image;
auto remove(sAction action) -> type&; auto remove(sAction action) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto setIcon(const image& icon = {}) -> type&; auto setIcon(const image& icon = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setText(const string& text = "") -> type&; auto setText(const string& text = "") -> type&;
auto text() const -> string; auto text() const -> string;
@ -952,28 +953,6 @@ struct mSizable : mObject {
}; };
#endif #endif
#if defined(Hiro_Layout)
struct mLayout : mSizable {
Declare(Layout)
virtual auto append(sSizable sizable) -> type&;
virtual auto remove() -> type& override;
virtual auto remove(sSizable sizable) -> type&;
virtual auto reset() -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override;
auto sizable(unsigned position) const -> Sizable;
auto sizableCount() const -> unsigned;
auto sizables() const -> vector<Sizable>;
//private:
struct State {
vector<sSizable> sizables;
} state;
auto destruct() -> void override;
};
#endif
#if defined(Hiro_Widget) #if defined(Hiro_Widget)
struct mWidget : mSizable { struct mWidget : mSizable {
Declare(Widget) Declare(Widget)
@ -1113,14 +1092,14 @@ struct mComboButton : mWidget {
auto append(sComboButtonItem item) -> type&; auto append(sComboButtonItem item) -> type&;
auto doChange() const -> void; auto doChange() const -> void;
auto item(unsigned position) const -> ComboButtonItem; auto item(uint position) const -> ComboButtonItem;
auto itemCount() const -> unsigned; auto itemCount() const -> uint;
auto items() const -> vector<ComboButtonItem>; auto items() const -> vector<ComboButtonItem>;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
auto remove(sComboButtonItem item) -> type&; auto remove(sComboButtonItem item) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto selected() const -> ComboButtonItem; auto selected() const -> ComboButtonItem;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
//private: //private:
struct State { struct State {
@ -1241,17 +1220,17 @@ struct mFrame : mWidget {
Declare(Frame) Declare(Frame)
using mObject::remove; using mObject::remove;
auto append(sLayout layout) -> type&; auto append(sSizable sizable) -> type&;
auto layout() const -> Layout; auto remove(sSizable sizable) -> type&;
auto remove(sLayout layout) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setText(const string& text = "") -> type&; auto setText(const string& text = "") -> type&;
auto sizable() const -> Sizable;
auto text() const -> string; auto text() const -> string;
//private: //private:
struct State { struct State {
sLayout layout; sSizable sizable;
string text; string text;
} state; } state;
@ -1263,34 +1242,34 @@ struct mFrame : mWidget {
struct mHexEdit : mWidget { struct mHexEdit : mWidget {
Declare(HexEdit) Declare(HexEdit)
auto address() const -> unsigned; auto address() const -> uint;
auto backgroundColor() const -> Color; auto backgroundColor() const -> Color;
auto columns() const -> unsigned; auto columns() const -> uint;
auto doRead(unsigned offset) const -> uint8_t; auto doRead(uint offset) const -> uint8_t;
auto doWrite(unsigned offset, uint8_t data) const -> void; auto doWrite(uint offset, uint8_t data) const -> void;
auto foregroundColor() const -> Color; auto foregroundColor() const -> Color;
auto length() const -> unsigned; auto length() const -> uint;
auto onRead(const function<uint8_t (unsigned)>& callback = {}) -> type&; auto onRead(const function<uint8_t (uint)>& callback = {}) -> type&;
auto onWrite(const function<void (unsigned, uint8_t)>& callback = {}) -> type&; auto onWrite(const function<void (uint, uint8_t)>& callback = {}) -> type&;
auto rows() const -> unsigned; auto rows() const -> uint;
auto setAddress(unsigned address = 0) -> type&; auto setAddress(uint address = 0) -> type&;
auto setBackgroundColor(Color color = {}) -> type&; auto setBackgroundColor(Color color = {}) -> type&;
auto setColumns(unsigned columns = 16) -> type&; auto setColumns(uint columns = 16) -> type&;
auto setForegroundColor(Color color = {}) -> type&; auto setForegroundColor(Color color = {}) -> type&;
auto setLength(unsigned length) -> type&; auto setLength(uint length) -> type&;
auto setRows(unsigned rows = 16) -> type&; auto setRows(uint rows = 16) -> type&;
auto update() -> type&; auto update() -> type&;
//private: //private:
struct State { struct State {
unsigned address = 0; uint address = 0;
Color backgroundColor; Color backgroundColor;
unsigned columns = 16; uint columns = 16;
Color foregroundColor; Color foregroundColor;
unsigned length = 0; uint length = 0;
function<uint8_t (unsigned)> onRead; function<uint8_t (uint)> onRead;
function<void (unsigned, uint8_t)> onWrite; function<void (uint, uint8_t)> onWrite;
unsigned rows = 16; uint rows = 16;
} state; } state;
}; };
#endif #endif
@ -1300,17 +1279,17 @@ struct mHorizontalScrollBar : mWidget {
Declare(HorizontalScrollBar) Declare(HorizontalScrollBar)
auto doChange() const -> void; auto doChange() const -> void;
auto length() const -> unsigned; auto length() const -> uint;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
auto position() const -> unsigned; auto position() const -> uint;
auto setLength(unsigned length = 101) -> type&; auto setLength(uint length = 101) -> type&;
auto setPosition(unsigned position = 0) -> type&; auto setPosition(uint position = 0) -> type&;
//private: //private:
struct State { struct State {
unsigned length = 101; uint length = 101;
function<void ()> onChange; function<void ()> onChange;
unsigned position = 0; uint position = 0;
} state; } state;
}; };
#endif #endif
@ -1320,17 +1299,17 @@ struct mHorizontalSlider : mWidget {
Declare(HorizontalSlider) Declare(HorizontalSlider)
auto doChange() const -> void; auto doChange() const -> void;
auto length() const -> unsigned; auto length() const -> uint;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
auto position() const -> unsigned; auto position() const -> uint;
auto setLength(unsigned length = 101) -> type&; auto setLength(uint length = 101) -> type&;
auto setPosition(unsigned position = 0) -> type&; auto setPosition(uint position = 0) -> type&;
//private: //private:
struct State { struct State {
unsigned length = 101; uint length = 101;
function<void ()> onChange; function<void ()> onChange;
unsigned position = 0; uint position = 0;
} state; } state;
}; };
#endif #endif
@ -1349,8 +1328,8 @@ struct mIconView : mWidget {
auto doContext() const -> void; auto doContext() const -> void;
auto flow() const -> Orientation; auto flow() const -> Orientation;
auto foregroundColor() const -> Color; auto foregroundColor() const -> Color;
auto item(unsigned position) const -> IconViewItem; auto item(uint position) const -> IconViewItem;
auto itemCount() const -> unsigned; auto itemCount() const -> uint;
auto items() const -> vector<IconViewItem>; auto items() const -> vector<IconViewItem>;
auto onActivate(const function<void ()>& callback = {}) -> type&; auto onActivate(const function<void ()>& callback = {}) -> type&;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
@ -1364,8 +1343,8 @@ struct mIconView : mWidget {
auto setFlow(Orientation flow = Orientation::Vertical) -> type&; auto setFlow(Orientation flow = Orientation::Vertical) -> type&;
auto setForegroundColor(Color color = {}) -> type&; auto setForegroundColor(Color color = {}) -> type&;
auto setOrientation(Orientation orientation = Orientation::Horizontal) -> type&; auto setOrientation(Orientation orientation = Orientation::Horizontal) -> type&;
auto setParent(mObject* object = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* object = nullptr, int offset = -1) -> type& override;
auto setSelected(const vector<signed>& selections) -> type&; auto setSelected(const vector<int>& selections) -> type&;
//private: //private:
struct State { struct State {
@ -1461,12 +1440,12 @@ struct mLineEdit : mWidget {
struct mProgressBar : mWidget { struct mProgressBar : mWidget {
Declare(ProgressBar) Declare(ProgressBar)
auto position() const -> unsigned; auto position() const -> uint;
auto setPosition(unsigned position) -> type&; auto setPosition(uint position) -> type&;
//private: //private:
struct State { struct State {
unsigned position = 0; uint position = 0;
} state; } state;
}; };
#endif #endif
@ -1559,8 +1538,8 @@ struct mTabFrame : mWidget {
auto doChange() const -> void; auto doChange() const -> void;
auto doClose(sTabFrameItem item) const -> void; auto doClose(sTabFrameItem item) const -> void;
auto doMove(sTabFrameItem from, sTabFrameItem to) const -> void; auto doMove(sTabFrameItem from, sTabFrameItem to) const -> void;
auto item(unsigned position) const -> TabFrameItem; auto item(uint position) const -> TabFrameItem;
auto itemCount() const -> unsigned; auto itemCount() const -> uint;
auto items() const -> vector<TabFrameItem>; auto items() const -> vector<TabFrameItem>;
auto navigation() const -> Navigation; auto navigation() const -> Navigation;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
@ -1569,8 +1548,11 @@ struct mTabFrame : mWidget {
auto remove(sTabFrameItem item) -> type&; auto remove(sTabFrameItem item) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto selected() const -> TabFrameItem; auto selected() const -> TabFrameItem;
auto setEnabled(bool enabled = true) -> type& override;
auto setFont(const Font& font = {}) -> type& override;
auto setNavigation(Navigation navigation = Navigation::Top) -> type&; auto setNavigation(Navigation navigation = Navigation::Top) -> type&;
auto setParent(mObject* object = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* object = nullptr, int offset = -1) -> type& override;
auto setVisible(bool visible = true) -> type& override;
//private: //private:
struct State { struct State {
@ -1589,30 +1571,33 @@ struct mTabFrame : mWidget {
struct mTabFrameItem : mObject { struct mTabFrameItem : mObject {
Declare(TabFrameItem) Declare(TabFrameItem)
auto append(sLayout layout) -> type&; auto append(sSizable sizable) -> type&;
auto closable() const -> bool; auto closable() const -> bool;
auto icon() const -> image; auto icon() const -> image;
auto layout() const -> Layout;
auto movable() const -> bool; auto movable() const -> bool;
auto remove() -> type& override; auto remove() -> type& override;
auto remove(sLayout layout) -> type&; auto remove(sSizable sizable) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto selected() const -> bool; auto selected() const -> bool;
auto setClosable(bool closable = true) -> type&; auto setClosable(bool closable = true) -> type&;
auto setEnabled(bool enabled = true) -> type& override;
auto setFont(const Font& font = {}) -> type& override;
auto setIcon(const image& icon = {}) -> type&; auto setIcon(const image& icon = {}) -> type&;
auto setMovable(bool movable = true) -> type&; auto setMovable(bool movable = true) -> type&;
auto setParent(mObject* object = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* object = nullptr, int offset = -1) -> type& override;
auto setSelected() -> type&; auto setSelected() -> type&;
auto setText(const string& text = "") -> type&; auto setText(const string& text = "") -> type&;
auto setVisible(bool visible = true) -> type& override;
auto sizable() const -> Sizable;
auto text() const -> string; auto text() const -> string;
//private: //private:
struct State { struct State {
bool closable = false; bool closable = false;
image icon; image icon;
sLayout layout;
bool movable = false; bool movable = false;
bool selected = false; bool selected = false;
sSizable sizable;
string text; string text;
} state; } state;
@ -1640,8 +1625,8 @@ struct mTableView : mWidget {
auto doToggle(sTableViewCell cell) const -> void; auto doToggle(sTableViewCell cell) const -> void;
auto foregroundColor() const -> Color; auto foregroundColor() const -> Color;
auto header() const -> TableViewHeader; auto header() const -> TableViewHeader;
auto item(unsigned position) const -> TableViewItem; auto item(uint position) const -> TableViewItem;
auto itemCount() const -> unsigned; auto itemCount() const -> uint;
auto items() const -> vector<TableViewItem>; auto items() const -> vector<TableViewItem>;
auto onActivate(const function<void ()>& callback = {}) -> type&; auto onActivate(const function<void ()>& callback = {}) -> type&;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
@ -1659,11 +1644,11 @@ struct mTableView : mWidget {
auto setBatchable(bool batchable = true) -> type&; auto setBatchable(bool batchable = true) -> type&;
auto setBordered(bool bordered = true) -> type&; auto setBordered(bool bordered = true) -> type&;
auto setForegroundColor(Color color = {}) -> type&; auto setForegroundColor(Color color = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
//private: //private:
struct State { struct State {
unsigned activeColumn = 0; uint activeColumn = 0;
Alignment alignment; Alignment alignment;
Color backgroundColor; Color backgroundColor;
bool batchable = false; bool batchable = false;
@ -1688,18 +1673,20 @@ struct mTableViewHeader : mObject {
Declare(TableViewHeader) Declare(TableViewHeader)
auto append(sTableViewColumn column) -> type&; auto append(sTableViewColumn column) -> type&;
auto column(unsigned position) const -> TableViewColumn; auto column(uint position) const -> TableViewColumn;
auto columnCount() const -> unsigned; auto columnCount() const -> uint;
auto columns() const -> vector<TableViewColumn>; auto columns() const -> vector<TableViewColumn>;
auto remove() -> type& override; auto remove() -> type& override;
auto remove(sTableViewColumn column) -> type&; auto remove(sTableViewColumn column) -> type&;
auto reset() -> type&; auto reset() -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
//private: //private:
struct State { struct State {
vector<sTableViewColumn> columns; vector<sTableViewColumn> columns;
} state; } state;
auto destruct() -> void override;
}; };
#endif #endif
@ -1762,8 +1749,8 @@ struct mTableViewItem : mObject {
auto alignment() const -> Alignment; auto alignment() const -> Alignment;
auto append(sTableViewCell cell) -> type&; auto append(sTableViewCell cell) -> type&;
auto backgroundColor() const -> Color; auto backgroundColor() const -> Color;
auto cell(unsigned position) const -> TableViewCell; auto cell(uint position) const -> TableViewCell;
auto cellCount() const -> unsigned; auto cellCount() const -> uint;
auto cells() const -> vector<TableViewCell>; auto cells() const -> vector<TableViewCell>;
auto foregroundColor() const -> Color; auto foregroundColor() const -> Color;
auto remove() -> type& override; auto remove() -> type& override;
@ -1774,7 +1761,7 @@ struct mTableViewItem : mObject {
auto setBackgroundColor(Color color = {}) -> type&; auto setBackgroundColor(Color color = {}) -> type&;
auto setFocused() -> type& override; auto setFocused() -> type& override;
auto setForegroundColor(Color color = {}) -> type&; auto setForegroundColor(Color color = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setSelected(bool selected = true) -> type&; auto setSelected(bool selected = true) -> type&;
//private: //private:
@ -1785,6 +1772,8 @@ struct mTableViewItem : mObject {
Color foregroundColor; Color foregroundColor;
bool selected = false; bool selected = false;
} state; } state;
auto destruct() -> void override;
}; };
#endif #endif
@ -1869,7 +1858,7 @@ struct mTreeView : mWidget {
auto doToggle(sTreeViewItem item) const -> void; auto doToggle(sTreeViewItem item) const -> void;
auto foregroundColor() const -> Color; auto foregroundColor() const -> Color;
auto item(const string& path) const -> TreeViewItem; auto item(const string& path) const -> TreeViewItem;
auto itemCount() const -> unsigned; auto itemCount() const -> uint;
auto items() const -> vector<TreeViewItem>; auto items() const -> vector<TreeViewItem>;
auto onActivate(const function<void ()>& callback = {}) -> type&; auto onActivate(const function<void ()>& callback = {}) -> type&;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
@ -1880,7 +1869,7 @@ struct mTreeView : mWidget {
auto selected() const -> TreeViewItem; auto selected() const -> TreeViewItem;
auto setBackgroundColor(Color color = {}) -> type&; auto setBackgroundColor(Color color = {}) -> type&;
auto setForegroundColor(Color color = {}) -> type&; auto setForegroundColor(Color color = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&; auto setParent(mObject* parent = nullptr, int offset = -1) -> type&;
//private: //private:
struct State { struct State {
@ -1909,7 +1898,7 @@ struct mTreeViewItem : mObject {
auto foregroundColor(bool recursive = false) const -> Color; auto foregroundColor(bool recursive = false) const -> Color;
auto icon() const -> image; auto icon() const -> image;
auto item(const string& path) const -> TreeViewItem; auto item(const string& path) const -> TreeViewItem;
auto itemCount() const -> unsigned; auto itemCount() const -> uint;
auto items() const -> vector<TreeViewItem>; auto items() const -> vector<TreeViewItem>;
auto path() const -> string; auto path() const -> string;
auto remove() -> type& override; auto remove() -> type& override;
@ -1922,7 +1911,7 @@ struct mTreeViewItem : mObject {
auto setFocused() -> type& override; auto setFocused() -> type& override;
auto setForegroundColor(Color color = {}) -> type&; auto setForegroundColor(Color color = {}) -> type&;
auto setIcon(const image& icon = {}) -> type&; auto setIcon(const image& icon = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&; auto setParent(mObject* parent = nullptr, int offset = -1) -> type&;
auto setSelected() -> type&; auto setSelected() -> type&;
auto setText(const string& text = "") -> type&; auto setText(const string& text = "") -> type&;
auto text() const -> string; auto text() const -> string;
@ -1947,17 +1936,17 @@ struct mVerticalScrollBar : mWidget {
Declare(VerticalScrollBar) Declare(VerticalScrollBar)
auto doChange() const -> void; auto doChange() const -> void;
auto length() const -> unsigned; auto length() const -> uint;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
auto position() const -> unsigned; auto position() const -> uint;
auto setLength(unsigned length = 101) -> type&; auto setLength(uint length = 101) -> type&;
auto setPosition(unsigned position = 0) -> type&; auto setPosition(uint position = 0) -> type&;
//private: //private:
struct State { struct State {
unsigned length = 101; uint length = 101;
function<void ()> onChange; function<void ()> onChange;
unsigned position = 0; uint position = 0;
} state; } state;
}; };
#endif #endif
@ -1967,17 +1956,17 @@ struct mVerticalSlider : mWidget {
Declare(VerticalSlider) Declare(VerticalSlider)
auto doChange() const -> void; auto doChange() const -> void;
auto length() const -> unsigned; auto length() const -> uint;
auto onChange(const function<void ()>& callback = {}) -> type&; auto onChange(const function<void ()>& callback = {}) -> type&;
auto position() const -> unsigned; auto position() const -> uint;
auto setLength(unsigned length = 101) -> type&; auto setLength(uint length = 101) -> type&;
auto setPosition(unsigned position = 0) -> type&; auto setPosition(uint position = 0) -> type&;
//private: //private:
struct State { struct State {
unsigned length = 101; uint length = 101;
function<void ()> onChange; function<void ()> onChange;
unsigned position = 0; uint position = 0;
} state; } state;
}; };
#endif #endif
@ -2014,6 +2003,7 @@ struct mViewport : mWidget {
#undef Declare #undef Declare
#include "lock.hpp"
#include "shared.hpp" #include "shared.hpp"
} }

View File

@ -9,7 +9,7 @@ Gradient::operator bool() const {
auto Gradient::operator==(const Gradient& source) const -> bool { auto Gradient::operator==(const Gradient& source) const -> bool {
if(state.colors.size() != source.state.colors.size()) return false; if(state.colors.size() != source.state.colors.size()) return false;
for(auto n : range(state.colors)) { for(auto n : range(state.colors.size())) {
if(state.colors[n] != source.state.colors[n]) return false; if(state.colors[n] != source.state.colors[n]) return false;
} }
return true; return true;

View File

@ -37,7 +37,7 @@ auto mGroup::objects() const -> vector<Object> {
auto mGroup::remove(sObject object) -> type& { auto mGroup::remove(sObject object) -> type& {
object->setGroup(); object->setGroup();
for(auto offset : range(state.objects)) { for(auto offset : range(state.objects.size())) {
if(auto shared = state.objects[offset].acquire()) { if(auto shared = state.objects[offset].acquire()) {
if(object == shared) { if(object == shared) {
state.objects.remove(offset); state.objects.remove(offset);

View File

@ -1,70 +0,0 @@
#if defined(Hiro_Layout)
auto mLayout::allocate() -> pObject* {
return new pLayout(*this);
}
auto mLayout::destruct() -> void {
for(auto& sizable : state.sizables) sizable->destruct();
mSizable::destruct();
}
//
auto mLayout::append(sSizable sizable) -> type& {
state.sizables.append(sizable);
sizable->setParent(this, sizableCount() - 1);
setGeometry(geometry());
return *this;
}
auto mLayout::remove() -> type& {
#if defined(Hiro_TabFrame)
if(auto tabFrameItem = parentTabFrameItem()) tabFrameItem->remove(tabFrameItem->layout());
#endif
if(auto layout = parentLayout()) layout->remove(layout->sizable(offset()));
if(auto window = parentWindow()) window->remove(window->layout());
setParent();
for(auto& sizable : state.sizables) sizable->setParent(this, sizable->offset());
return *this;
}
auto mLayout::remove(sSizable sizable) -> type& {
auto offset = sizable->offset();
sizable->setParent();
state.sizables.remove(offset);
for(auto n : range(offset, sizableCount())) {
state.sizables[n]->adjustOffset(-1);
}
setGeometry(geometry());
return *this;
}
auto mLayout::reset() -> type& {
while(state.sizables) remove(state.sizables.right());
return *this;
}
auto mLayout::setParent(mObject* parent, signed offset) -> type& {
for(auto& sizable : state.sizables) sizable->destruct();
mObject::setParent(parent, offset);
for(auto& sizable : state.sizables) sizable->setParent(this, sizable->offset());
return *this;
}
auto mLayout::sizable(unsigned position) const -> Sizable {
if(position < sizableCount()) return state.sizables[position];
return {};
}
auto mLayout::sizableCount() const -> unsigned {
return state.sizables.size();
}
auto mLayout::sizables() const -> vector<Sizable> {
vector<Sizable> sizables;
for(auto& sizable : sizables) sizables.append(sizable);
return sizables;
}
#endif

18
hiro/core/lock.hpp Normal file
View File

@ -0,0 +1,18 @@
#pragma once
//shared functionality used for pObject on all platforms
struct mLock {
auto locked() const -> bool { return locks || Application::state.quit; }
auto lock() -> void { ++locks; }
auto unlock() -> void { --locks; }
struct Handle {
Handle(const mLock& self) : self(self) { ++self.locks; }
~Handle() { --self.locks; }
const mLock& self;
};
auto acquire() const -> Handle { return {*this}; }
mutable int locks = 0;
};

View File

@ -55,7 +55,7 @@ auto mMenuBar::reset() -> type& {
} }
auto mMenuBar::setParent(mObject* parent, signed offset) -> type& { auto mMenuBar::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.menus)) state.menus[n]->destruct(); for(auto& menu : reverse(state.menus)) menu->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
for(auto& menu : state.menus) menu->setParent(this, menu->offset()); for(auto& menu : state.menus) menu->setParent(this, menu->offset());
return *this; return *this;

View File

@ -26,7 +26,7 @@ auto mObject::destruct() -> void {
// //
//used to test if returned items "exist" from eg Window::layout(), ListView::selected(), etc. //used to test if returned items "exist" from eg Window::sizable(), ListView::selected(), etc.
mObject::operator bool() const { mObject::operator bool() const {
return parent() || !abstract(); return parent() || !abstract();
} }
@ -130,16 +130,6 @@ auto mObject::parentIconView(bool recursive) const -> mIconView* {
} }
#endif #endif
#if defined(Hiro_Layout)
auto mObject::parentLayout(bool recursive) const -> mLayout* {
if(auto layout = dynamic_cast<mLayout*>(parent())) return layout;
if(recursive) {
if(auto object = parent()) return object->parentLayout(true);
}
return nullptr;
}
#endif
#if defined(Hiro_Menu) #if defined(Hiro_Menu)
auto mObject::parentMenu(bool recursive) const -> mMenu* { auto mObject::parentMenu(bool recursive) const -> mMenu* {
if(auto menu = dynamic_cast<mMenu*>(parent())) return menu; if(auto menu = dynamic_cast<mMenu*>(parent())) return menu;
@ -308,7 +298,8 @@ auto mObject::setGroup(sGroup group) -> type& {
return *this; return *this;
} }
auto mObject::setParent(mObject* parent, signed offset) -> type& { auto mObject::setParent(mObject* parent, int offset) -> type& {
signal(setParent, parent, offset);
destruct(); destruct();
state.parent = parent; state.parent = parent;
state.offset = offset; state.offset = offset;

View File

@ -50,7 +50,7 @@ auto mPopupMenu::reset() -> type& {
} }
auto mPopupMenu::setParent(mObject* parent, signed offset) -> type& { auto mPopupMenu::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.actions)) state.actions[n]->destruct(); for(auto& action : reverse(state.actions)) action->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
for(auto& action : state.actions) action->construct(); for(auto& action : state.actions) action->construct();
return *this; return *this;

View File

@ -43,15 +43,6 @@
auto minimumSize() const { return self().minimumSize(); } \ auto minimumSize() const { return self().minimumSize(); } \
auto setGeometry(Geometry geometry) { return self().setGeometry(geometry), *this; } \ auto setGeometry(Geometry geometry) { return self().setGeometry(geometry), *this; } \
#define DeclareSharedLayout(Name) \
DeclareSharedSizable(Name) \
auto append(sSizable sizable) { return self().append(sizable), *this; } \
auto remove(sSizable sizable) { return self().remove(sizable), *this; } \
auto reset() { return self().reset(), *this; } \
auto sizable(unsigned position) { return self().sizable(position); } \
auto sizableCount() const { return self().sizableCount(); } \
auto sizables() const { return self().sizables(); } \
#define DeclareSharedWidget(Name) \ #define DeclareSharedWidget(Name) \
DeclareSharedSizable(Name) \ DeclareSharedSizable(Name) \
auto doSize() const { return self().doSize(); } \ auto doSize() const { return self().doSize(); } \
@ -194,13 +185,6 @@ struct Sizable : sSizable {
}; };
#endif #endif
#if defined(Hiro_Layout)
struct Layout : sLayout {
DeclareSharedLayout(Layout)
using internalType = mLayout;
};
#endif
#if defined(Hiro_Widget) #if defined(Hiro_Widget)
struct Widget : sWidget { struct Widget : sWidget {
DeclareSharedWidget(Widget) DeclareSharedWidget(Widget)
@ -382,11 +366,11 @@ struct Frame : sFrame {
DeclareSharedWidget(Frame) DeclareSharedWidget(Frame)
using internalType = mFrame; using internalType = mFrame;
auto append(sLayout layout) { return self().append(layout), *this; } auto append(sSizable sizable) { return self().append(sizable), *this; }
auto layout() const { return self().layout(); } auto remove(sSizable sizable) { return self().remove(sizable), *this; }
auto remove(sLayout layout) { return self().remove(layout), *this; }
auto reset() { return self().reset(), *this; } auto reset() { return self().reset(), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; } auto setText(const string& text = "") { return self().setText(text), *this; }
auto sizable() const { return self().sizable(); }
auto text() const { return self().text(); } auto text() const { return self().text(); }
}; };
#endif #endif
@ -594,12 +578,11 @@ struct TabFrameItem : sTabFrameItem {
DeclareSharedObject(TabFrameItem) DeclareSharedObject(TabFrameItem)
using internalType = mTabFrameItem; using internalType = mTabFrameItem;
auto append(sLayout layout) { return self().append(layout), *this; } auto append(sSizable sizable) { return self().append(sizable), *this; }
auto closable() const { return self().closable(); } auto closable() const { return self().closable(); }
auto icon() const { return self().icon(); } auto icon() const { return self().icon(); }
auto layout() const { return self().layout(); }
auto movable() const { return self().movable(); } auto movable() const { return self().movable(); }
auto remove(sLayout layout) { return self().remove(layout), *this; } auto remove(sSizable sizable) { return self().remove(sizable), *this; }
auto reset() { return self().reset(), *this; } auto reset() { return self().reset(), *this; }
auto selected() const { return self().selected(); } auto selected() const { return self().selected(); }
auto setClosable(bool closable = true) { return self().setClosable(closable), *this; } auto setClosable(bool closable = true) { return self().setClosable(closable), *this; }
@ -607,6 +590,7 @@ struct TabFrameItem : sTabFrameItem {
auto setMovable(bool movable = true) { return self().setMovable(movable), *this; } auto setMovable(bool movable = true) { return self().setMovable(movable), *this; }
auto setSelected() { return self().setSelected(), *this; } auto setSelected() { return self().setSelected(), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; } auto setText(const string& text = "") { return self().setText(text), *this; }
auto sizable() const { return self().sizable(); }
auto text() const { return self().text(); } auto text() const { return self().text(); }
}; };
#endif #endif
@ -940,8 +924,8 @@ struct Window : sWindow {
DeclareSharedObject(Window) DeclareSharedObject(Window)
using internalType = mWindow; using internalType = mWindow;
auto append(sLayout layout) { return self().append(layout), *this; }
auto append(sMenuBar menuBar) { return self().append(menuBar), *this; } auto append(sMenuBar menuBar) { return self().append(menuBar), *this; }
auto append(sSizable sizable) { return self().append(sizable), *this; }
auto append(sStatusBar statusBar) { return self().append(statusBar), *this; } auto append(sStatusBar statusBar) { return self().append(statusBar), *this; }
auto backgroundColor() const { return self().backgroundColor(); } auto backgroundColor() const { return self().backgroundColor(); }
auto dismissable() const { return self().dismissable(); } auto dismissable() const { return self().dismissable(); }
@ -955,7 +939,6 @@ struct Window : sWindow {
auto frameGeometry() const { return self().frameGeometry(); } auto frameGeometry() const { return self().frameGeometry(); }
auto fullScreen() const { return self().fullScreen(); } auto fullScreen() const { return self().fullScreen(); }
auto geometry() const { return self().geometry(); } auto geometry() const { return self().geometry(); }
auto layout() const { return self().layout(); }
auto maximized() const { return self().maximized(); } auto maximized() const { return self().maximized(); }
auto maximumSize() const { return self().maximumSize(); } auto maximumSize() const { return self().maximumSize(); }
auto menuBar() const { return self().menuBar(); } auto menuBar() const { return self().menuBar(); }
@ -968,8 +951,8 @@ struct Window : sWindow {
auto onKeyRelease(const function<void (signed)>& callback = {}) { return self().onKeyRelease(callback), *this; } auto onKeyRelease(const function<void (signed)>& callback = {}) { return self().onKeyRelease(callback), *this; }
auto onMove(const function<void ()>& callback = {}) { return self().onMove(callback), *this; } auto onMove(const function<void ()>& callback = {}) { return self().onMove(callback), *this; }
auto onSize(const function<void ()>& callback = {}) { return self().onSize(callback), *this; } auto onSize(const function<void ()>& callback = {}) { return self().onSize(callback), *this; }
auto remove(sLayout layout) { return self().remove(layout), *this; }
auto remove(sMenuBar menuBar) { return self().remove(menuBar), *this; } auto remove(sMenuBar menuBar) { return self().remove(menuBar), *this; }
auto remove(sSizable sizable) { return self().remove(sizable), *this; }
auto remove(sStatusBar statusBar) { return self().remove(statusBar), *this; } auto remove(sStatusBar statusBar) { return self().remove(statusBar), *this; }
auto reset() { return self().reset(), *this; } auto reset() { return self().reset(), *this; }
auto resizable() const { return self().resizable(); } auto resizable() const { return self().resizable(); }
@ -992,6 +975,7 @@ struct Window : sWindow {
auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; } auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; }
auto setSize(Size size) { return self().setSize(size), *this; } auto setSize(Size size) { return self().setSize(size), *this; }
auto setTitle(const string& title = "") { return self().setTitle(title), *this; } auto setTitle(const string& title = "") { return self().setTitle(title), *this; }
auto sizable() const { return self().sizable(); }
auto statusBar() const { return self().statusBar(); } auto statusBar() const { return self().statusBar(); }
auto title() const { return self().title(); } auto title() const { return self().title(); }
}; };

View File

@ -5,6 +5,7 @@ auto mComboEdit::allocate() -> pObject* {
} }
auto mComboEdit::destruct() -> void { auto mComboEdit::destruct() -> void {
for(auto& item : state.items) item->destruct();
mWidget::destruct(); mWidget::destruct();
} }

View File

@ -5,40 +5,36 @@ auto mFrame::allocate() -> pObject* {
} }
auto mFrame::destruct() -> void { auto mFrame::destruct() -> void {
if(auto& layout = state.layout) layout->destruct(); if(auto& sizable = state.sizable) sizable->destruct();
mWidget::destruct(); mWidget::destruct();
} }
// //
auto mFrame::append(sLayout layout) -> type& { auto mFrame::append(sSizable sizable) -> type& {
if(auto& layout = state.layout) remove(layout); if(auto& sizable = state.sizable) remove(sizable);
state.layout = layout; state.sizable = sizable;
layout->setParent(this, 0); sizable->setParent(this, 0);
signal(append, layout); signal(append, sizable);
return *this; return *this;
} }
auto mFrame::layout() const -> Layout { auto mFrame::remove(sSizable sizable) -> type& {
return state.layout; signal(remove, sizable);
} sizable->setParent();
state.sizable.reset();
auto mFrame::remove(sLayout layout) -> type& {
signal(remove, layout);
layout->setParent();
state.layout.reset();
return *this; return *this;
} }
auto mFrame::reset() -> type& { auto mFrame::reset() -> type& {
if(auto& layout = state.layout) remove(layout); if(auto& sizable = state.sizable) remove(sizable);
return *this; return *this;
} }
auto mFrame::setParent(mObject* object, signed offset) -> type& { auto mFrame::setParent(mObject* object, int offset) -> type& {
if(auto& layout = state.layout) layout->destruct(); if(auto& sizable = state.sizable) sizable->destruct();
mObject::setParent(object, offset); mObject::setParent(object, offset);
if(auto& layout = state.layout) layout->setParent(this, 0); if(auto& sizable = state.sizable) sizable->setParent(this, 0);
return *this; return *this;
} }
@ -48,6 +44,10 @@ auto mFrame::setText(const string& text) -> type& {
return *this; return *this;
} }
auto mFrame::sizable() const -> Sizable {
return state.sizable;
}
auto mFrame::text() const -> string { auto mFrame::text() const -> string {
return state.text; return state.text;
} }

View File

@ -143,7 +143,7 @@ auto mIconView::setOrientation(Orientation orientation) -> type& {
} }
auto mIconView::setParent(mObject* parent, signed offset) -> type& { auto mIconView::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct(); for(auto& item : reverse(state.items)) item->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset()); for(auto& item : state.items) item->setParent(this, item->offset());
return *this; return *this;

View File

@ -5,17 +5,17 @@ auto mTabFrameItem::allocate() -> pObject* {
} }
auto mTabFrameItem::destruct() -> void { auto mTabFrameItem::destruct() -> void {
if(auto& layout = state.layout) layout->destruct(); if(auto& sizable = state.sizable) sizable->destruct();
mObject::destruct(); mObject::destruct();
} }
// //
auto mTabFrameItem::append(sLayout layout) -> type& { auto mTabFrameItem::append(sSizable sizable) -> type& {
if(auto& layout = state.layout) remove(layout); if(auto& sizable = state.sizable) remove(sizable);
state.layout = layout; state.sizable = sizable;
layout->setParent(this, 0); sizable->setParent(this, 0);
signal(append, layout); signal(append, sizable);
return *this; return *this;
} }
@ -27,10 +27,6 @@ auto mTabFrameItem::icon() const -> image {
return state.icon; return state.icon;
} }
auto mTabFrameItem::layout() const -> Layout {
return state.layout;
}
auto mTabFrameItem::movable() const -> bool { auto mTabFrameItem::movable() const -> bool {
return state.movable; return state.movable;
} }
@ -40,15 +36,15 @@ auto mTabFrameItem::remove() -> type& {
return *this; return *this;
} }
auto mTabFrameItem::remove(sLayout layout) -> type& { auto mTabFrameItem::remove(sSizable sizable) -> type& {
signal(remove, layout); signal(remove, sizable);
state.layout.reset(); state.sizable.reset();
layout->setParent(); sizable->setParent();
return *this; return *this;
} }
auto mTabFrameItem::reset() -> type& { auto mTabFrameItem::reset() -> type& {
if(auto layout = state.layout) remove(layout); if(auto& sizable = state.sizable) remove(sizable);
return *this; return *this;
} }
@ -62,6 +58,18 @@ auto mTabFrameItem::setClosable(bool closable) -> type& {
return *this; return *this;
} }
auto mTabFrameItem::setEnabled(bool enabled) -> type& {
mObject::setEnabled(enabled);
if(auto& sizable = state.sizable) sizable->setEnabled(sizable->enabled());
return *this;
}
auto mTabFrameItem::setFont(const Font& font) -> type& {
mObject::setFont(font);
if(auto& sizable = state.sizable) sizable->setFont(sizable->font());
return *this;
}
auto mTabFrameItem::setIcon(const image& icon) -> type& { auto mTabFrameItem::setIcon(const image& icon) -> type& {
state.icon = icon; state.icon = icon;
signal(setIcon, icon); signal(setIcon, icon);
@ -74,10 +82,10 @@ auto mTabFrameItem::setMovable(bool movable) -> type& {
return *this; return *this;
} }
auto mTabFrameItem::setParent(mObject* parent, signed offset) -> type& { auto mTabFrameItem::setParent(mObject* parent, int offset) -> type& {
if(auto layout = state.layout) layout->destruct(); if(auto& sizable = state.sizable) sizable->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
if(auto layout = state.layout) layout->setParent(this, layout->offset()); if(auto& sizable = state.sizable) sizable->setParent(this, sizable->offset());
return *this; return *this;
} }
@ -96,6 +104,16 @@ auto mTabFrameItem::setText(const string& text) -> type& {
return *this; return *this;
} }
auto mTabFrameItem::setVisible(bool visible) -> type& {
mObject::setVisible(visible);
if(auto& sizable = state.sizable) sizable->setVisible(sizable->visible());
return *this;
}
auto mTabFrameItem::sizable() const -> Sizable {
return state.sizable;
}
auto mTabFrameItem::text() const -> string { auto mTabFrameItem::text() const -> string {
return state.text; return state.text;
} }

View File

@ -32,8 +32,7 @@ auto mTabFrame::doMove(sTabFrameItem from, sTabFrameItem to) const -> void {
} }
auto mTabFrame::item(unsigned position) const -> TabFrameItem { auto mTabFrame::item(unsigned position) const -> TabFrameItem {
if(position < itemCount()) return state.items[position]; return state.items(position, {});
return {};
} }
auto mTabFrame::itemCount() const -> unsigned { auto mTabFrame::itemCount() const -> unsigned {
@ -88,17 +87,35 @@ auto mTabFrame::selected() const -> TabFrameItem {
return {}; return {};
} }
auto mTabFrame::setEnabled(bool enabled) -> type& {
mWidget::setEnabled(enabled);
for(auto& item : state.items) item->setEnabled(item->enabled());
return *this;
}
auto mTabFrame::setFont(const Font& font) -> type& {
mWidget::setFont(font);
for(auto& item : state.items) item->setFont(item->font());
return *this;
}
auto mTabFrame::setNavigation(Navigation navigation) -> type& { auto mTabFrame::setNavigation(Navigation navigation) -> type& {
state.navigation = navigation; state.navigation = navigation;
signal(setNavigation, navigation); signal(setNavigation, navigation);
return *this; return *this;
} }
auto mTabFrame::setParent(mObject* parent, signed offset) -> type& { auto mTabFrame::setParent(mObject* parent, int offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct(); for(auto& item : reverse(state.items)) item->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset()); for(auto& item : state.items) item->setParent(this, item->offset());
return *this; return *this;
} }
auto mTabFrame::setVisible(bool visible) -> type& {
mWidget::setVisible(visible);
for(auto& item : state.items) item->setVisible(item->visible());
return *this;
}
#endif #endif

View File

@ -6,8 +6,10 @@ auto mTableViewColumn::allocate() -> pObject* {
// //
//TODO: active(), setActive() ... is this the best way to do this?
auto mTableViewColumn::active() const -> bool { auto mTableViewColumn::active() const -> bool {
if(auto tableView = parentTableView()) return tableView->state.activeColumn == offset(); if(auto tableView = parentTableView(true)) return tableView->state.activeColumn == offset();
return false; return false;
} }
@ -40,7 +42,7 @@ auto mTableViewColumn::icon() const -> image {
} }
auto mTableViewColumn::remove() -> type& { auto mTableViewColumn::remove() -> type& {
if(auto tableView = parentTableViewHeader()) tableView->remove(*this); if(auto tableViewHeader = parentTableViewHeader()) tableViewHeader->remove(*this);
return *this; return *this;
} }
@ -49,7 +51,7 @@ auto mTableViewColumn::resizable() const -> bool {
} }
auto mTableViewColumn::setActive() -> type& { auto mTableViewColumn::setActive() -> type& {
if(auto tableView = parentTableView()) tableView->state.activeColumn = offset(); if(auto tableView = parentTableView(true)) tableView->state.activeColumn = offset();
signal(setActive); signal(setActive);
return *this; return *this;
} }

View File

@ -4,6 +4,11 @@ auto mTableViewHeader::allocate() -> pObject* {
return new pTableViewHeader(*this); return new pTableViewHeader(*this);
} }
auto mTableViewHeader::destruct() -> void {
for(auto& column : state.columns) column->destruct();
mObject::destruct();
}
// //
auto mTableViewHeader::append(sTableViewColumn column) -> type& { auto mTableViewHeader::append(sTableViewColumn column) -> type& {
@ -44,7 +49,7 @@ auto mTableViewHeader::remove(sTableViewColumn column) -> type& {
} }
auto mTableViewHeader::reset() -> type& { auto mTableViewHeader::reset() -> type& {
for(auto n : rrange(state.columns)) remove(state.columns[n]); while(state.columns) remove(state.columns.right());
return *this; return *this;
} }

View File

@ -4,6 +4,11 @@ auto mTableViewItem::allocate() -> pObject* {
return new pTableViewItem(*this); return new pTableViewItem(*this);
} }
auto mTableViewItem::destruct() -> void {
for(auto& cell : state.cells) cell->destruct();
mObject::destruct();
}
// //
auto mTableViewItem::alignment() const -> Alignment { auto mTableViewItem::alignment() const -> Alignment {
@ -56,7 +61,7 @@ auto mTableViewItem::remove(sTableViewCell cell) -> type& {
} }
auto mTableViewItem::reset() -> type& { auto mTableViewItem::reset() -> type& {
for(auto n : rrange(state.cells)) remove(state.cells[n]); while(state.cells) remove(state.cells.right());
return *this; return *this;
} }

View File

@ -146,7 +146,7 @@ auto mTableView::remove(sTableViewItem item) -> type& {
} }
auto mTableView::reset() -> type& { auto mTableView::reset() -> type& {
for(auto n : rrange(state.items)) remove(state.items[n]); while(state.items) remove(state.items.right());
if(auto& header = state.header) remove(header); if(auto& header = state.header) remove(header);
return *this; return *this;
} }
@ -194,7 +194,7 @@ auto mTableView::setForegroundColor(Color color) -> type& {
} }
auto mTableView::setParent(mObject* parent, signed offset) -> type& { auto mTableView::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct(); for(auto& item : reverse(state.items)) item->destruct();
if(auto& header = state.header) header->destruct(); if(auto& header = state.header) header->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
if(auto& header = state.header) header->setParent(this, 0); if(auto& header = state.header) header->setParent(this, 0);

View File

@ -144,7 +144,7 @@ auto mTreeViewItem::setIcon(const image& icon) -> type& {
} }
auto mTreeViewItem::setParent(mObject* parent, signed offset) -> type& { auto mTreeViewItem::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct(); for(auto& item : reverse(state.items)) item->destruct();
mObject::setParent(parent, offset); mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset()); for(auto& item : state.items) item->setParent(this, item->offset());
} }

View File

@ -93,7 +93,7 @@ auto mTreeView::remove(sTreeViewItem item) -> type& {
auto mTreeView::reset() -> type& { auto mTreeView::reset() -> type& {
state.selectedPath.reset(); state.selectedPath.reset();
for(auto n : rrange(state.items)) remove(state.items[n]); while(state.items) remove(state.items.right());
return *this; return *this;
} }
@ -114,7 +114,7 @@ auto mTreeView::setForegroundColor(Color color) -> type& {
} }
auto mTreeView::setParent(mObject* object, signed offset) -> type& { auto mTreeView::setParent(mObject* object, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct(); for(auto& item : reverse(state.items)) item->destruct();
mObject::setParent(object, offset); mObject::setParent(object, offset);
for(auto& item : state.items) item->setParent(this, item->offset()); for(auto& item : state.items) item->setParent(this, item->offset());
return *this; return *this;

View File

@ -16,7 +16,8 @@ auto mWidget::onSize(const function<void ()>& callback) -> type& {
} }
auto mWidget::remove() -> type& { auto mWidget::remove() -> type& {
if(auto layout = parentLayout()) layout->remove(layout->sizable(offset())); //TODO: how to implement this after removing mLayout?
//if(auto layout = parentLayout()) layout->remove(layout->sizable(offset()));
setParent(); setParent();
return *this; return *this;
} }

View File

@ -1,28 +1,22 @@
#if defined(Hiro_Window) #if defined(Hiro_Window)
mWindow::mWindow() {
mObject::state.visible = false;
}
auto mWindow::allocate() -> pObject* { auto mWindow::allocate() -> pObject* {
return new pWindow(*this); return new pWindow(*this);
} }
auto mWindow::destruct() -> void { auto mWindow::destruct() -> void {
if(auto& layout = state.layout) layout->destruct();
if(auto& menuBar = state.menuBar) menuBar->destruct(); if(auto& menuBar = state.menuBar) menuBar->destruct();
if(auto& sizable = state.sizable) sizable->destruct();
if(auto& statusBar = state.statusBar) statusBar->destruct(); if(auto& statusBar = state.statusBar) statusBar->destruct();
mObject::destruct(); mObject::destruct();
} }
// //
auto mWindow::append(sLayout layout) -> type& {
if(auto& layout = state.layout) remove(layout);
state.layout = layout;
layout->setGeometry(geometry().setPosition(0, 0));
layout->setParent(this, 0);
layout->setGeometry(geometry().setPosition(0, 0));
signal(append, layout);
return *this;
}
auto mWindow::append(sMenuBar menuBar) -> type& { auto mWindow::append(sMenuBar menuBar) -> type& {
if(auto& menuBar = state.menuBar) remove(menuBar); if(auto& menuBar = state.menuBar) remove(menuBar);
menuBar->setParent(this, 0); menuBar->setParent(this, 0);
@ -31,6 +25,14 @@ auto mWindow::append(sMenuBar menuBar) -> type& {
return *this; return *this;
} }
auto mWindow::append(sSizable sizable) -> type& {
if(auto& sizable = state.sizable) remove(sizable);
state.sizable = sizable;
sizable->setParent(this, 0);
signal(append, sizable);
return *this;
}
auto mWindow::append(sStatusBar statusBar) -> type& { auto mWindow::append(sStatusBar statusBar) -> type& {
if(auto& statusBar = state.statusBar) remove(statusBar); if(auto& statusBar = state.statusBar) remove(statusBar);
statusBar->setParent(this, 0); statusBar->setParent(this, 0);
@ -91,10 +93,6 @@ auto mWindow::geometry() const -> Geometry {
return state.geometry; return state.geometry;
} }
auto mWindow::layout() const -> Layout {
return state.layout;
}
auto mWindow::maximized() const -> bool { auto mWindow::maximized() const -> bool {
return state.maximized; return state.maximized;
} }
@ -149,18 +147,17 @@ auto mWindow::onSize(const function<void ()>& callback) -> type& {
return *this; return *this;
} }
auto mWindow::remove(sLayout layout) -> type& { auto mWindow::remove(sMenuBar menuBar) -> type& {
signal(remove, layout); signal(remove, menuBar);
layout->setParent(); menuBar->setParent();
state.layout.reset(); state.menuBar.reset();
return *this; return *this;
} }
auto mWindow::remove(sMenuBar menuBar) -> type& { auto mWindow::remove(sSizable sizable) -> type& {
signal(remove, menuBar); signal(remove, sizable);
menuBar->reset(); sizable->setParent();
menuBar->setParent(); state.sizable.reset();
state.menuBar.reset();
return *this; return *this;
} }
@ -172,8 +169,8 @@ auto mWindow::remove(sStatusBar statusBar) -> type& {
} }
auto mWindow::reset() -> type& { auto mWindow::reset() -> type& {
if(auto& layout = state.layout) remove(layout);
if(auto& menuBar = state.menuBar) remove(menuBar); if(auto& menuBar = state.menuBar) remove(menuBar);
if(auto& sizable = state.sizable) remove(sizable);
if(auto& statusBar = state.statusBar) remove(statusBar); if(auto& statusBar = state.statusBar) remove(statusBar);
return *this; return *this;
} }
@ -255,9 +252,7 @@ auto mWindow::setFullScreen(bool fullScreen) -> type& {
auto mWindow::setGeometry(Geometry geometry) -> type& { auto mWindow::setGeometry(Geometry geometry) -> type& {
state.geometry = geometry; state.geometry = geometry;
signal(setGeometry, geometry); signal(setGeometry, geometry);
if(auto& layout = state.layout) { if(auto& sizable = state.sizable) sizable->setGeometry(sizable->geometry());
layout->setGeometry(geometry.setPosition(0, 0));
}
return *this; return *this;
} }
@ -323,6 +318,18 @@ auto mWindow::setTitle(const string& title) -> type& {
return *this; return *this;
} }
auto mWindow::setVisible(bool visible) -> type& {
mObject::setVisible(visible);
if(auto& menuBar = state.menuBar) menuBar->setVisible(menuBar->visible());
if(auto& sizable = state.sizable) sizable->setVisible(sizable->visible());
if(auto& statusBar = state.statusBar) statusBar->setVisible(statusBar->visible());
return *this;
}
auto mWindow::sizable() const -> Sizable {
return state.sizable;
}
auto mWindow::statusBar() const -> StatusBar { auto mWindow::statusBar() const -> StatusBar {
return state.statusBar; return state.statusBar;
} }

View File

@ -149,7 +149,7 @@ auto BrowserDialogWindow::isMatch(const string& name) -> bool {
auto BrowserDialogWindow::run() -> BrowserDialog::Response { auto BrowserDialogWindow::run() -> BrowserDialog::Response {
response = {}; response = {};
layout.setMargin(5); layout.setPadding(5);
pathName.onActivate([&] { setPath(pathName.text()); }); pathName.onActivate([&] { setPath(pathName.text()); });
pathRefresh.setBordered(false).setIcon(Icon::Action::Refresh).onActivate([&] { setPath(state.path); }); pathRefresh.setBordered(false).setIcon(Icon::Action::Refresh).onActivate([&] { setPath(state.path); });
pathHome.setBordered(false).setIcon(Icon::Go::Home).onActivate([&] { setPath(Path::user()); }); pathHome.setBordered(false).setIcon(Icon::Go::Home).onActivate([&] { setPath(Path::user()); });

View File

@ -6,7 +6,7 @@ namespace hiro {
#include "fixed-layout.cpp" #include "fixed-layout.cpp"
#include "horizontal-layout.cpp" #include "horizontal-layout.cpp"
#include "vertical-layout.cpp" #include "vertical-layout.cpp"
#include "list-view-item.cpp" #include "table-layout.cpp"
#include "list-view.cpp" #include "list-view.cpp"
#include "browser-dialog.cpp" #include "browser-dialog.cpp"
#include "message-dialog.cpp" #include "message-dialog.cpp"

View File

@ -3,7 +3,7 @@ namespace hiro {
#include "fixed-layout.hpp" #include "fixed-layout.hpp"
#include "horizontal-layout.hpp" #include "horizontal-layout.hpp"
#include "vertical-layout.hpp" #include "vertical-layout.hpp"
#include "list-view-item.hpp" #include "table-layout.hpp"
#include "list-view.hpp" #include "list-view.hpp"
#include "shared.hpp" #include "shared.hpp"
#include "browser-dialog.hpp" #include "browser-dialog.hpp"

View File

@ -1,61 +1,142 @@
#if defined(Hiro_FixedLayout) #if defined(Hiro_FixedLayout)
auto mFixedLayout::append(sSizable sizable, Geometry geometry) -> type& { auto mFixedLayout::append(sSizable sizable, Geometry geometry) -> type& {
properties.append({geometry}); FixedLayoutCell cell;
mLayout::append(sizable); cell->setSizable(sizable);
sizable->setGeometry(geometry); cell->setGeometry(geometry);
return *this; cell->setParent(this, cellCount());
state.cells.append(cell);
return synchronize();
} }
auto mFixedLayout::modify(sSizable sizable, Geometry geometry) -> type& { auto mFixedLayout::cell(uint position) const -> FixedLayoutCell {
if(sizable && this->sizable(sizable->offset()) == sizable) { return state.cells(position, {});
auto& properties = this->properties[sizable->offset()]; }
properties.geometry = geometry;
auto mFixedLayout::cell(sSizable sizable) const -> FixedLayoutCell {
for(auto& cell : state.cells) {
if(cell->state.sizable == sizable) return cell;
} }
return *this; return {};
}
auto mFixedLayout::cellCount() const -> uint {
return state.cells.size();
}
auto mFixedLayout::destruct() -> void {
for(auto& cell : state.cells) cell->destruct();
return mSizable::destruct();
} }
auto mFixedLayout::minimumSize() const -> Size { auto mFixedLayout::minimumSize() const -> Size {
float width = Size::Minimum, height = Size::Minimum; float width = 0, height = 0;
for(auto n : range(sizableCount())) { for(auto& cell : state.cells) {
width = max(width, sizable(n)->minimumSize().width()); width = max(width, cell.sizable().minimumSize().width());
height = max(height, sizable(n)->minimumSize().height()); height = max(height, cell.sizable().minimumSize().height());
} }
return {width, height}; return {width, height};
} }
auto mFixedLayout::remove(sSizable sizable) -> type& { auto mFixedLayout::remove(sFixedLayoutCell cell) -> type& {
properties.remove(sizable->offset()); if(cell->parent() != this) return *this;
mLayout::remove(sizable); auto offset = cell->offset();
return *this; cell->setParent();
state.cells.remove(offset);
for(uint n : range(offset, cellCount())) state.cells[n]->adjustOffset(-1);
return synchronize();
} }
auto mFixedLayout::reset() -> type& { auto mFixedLayout::reset() -> type& {
mLayout::reset(); while(state.cells) remove(state.cells.right());
properties.reset(); return synchronize();
return *this;
} }
auto mFixedLayout::setEnabled(bool enabled) -> type& { auto mFixedLayout::setEnabled(bool enabled) -> type& {
mLayout::setEnabled(enabled); mSizable::setEnabled(enabled);
for(auto n : range(sizableCount())) { for(auto& cell : state.cells) cell.sizable().setEnabled(cell.sizable().enabled());
sizable(n)->setEnabled(sizable(n)->enabled());
}
return *this; return *this;
} }
auto mFixedLayout::setFont(const Font& font) -> type& { auto mFixedLayout::setFont(const Font& font) -> type& {
mLayout::setFont(font); mSizable::setFont(font);
for(auto n : range(sizableCount())) { for(auto& cell : state.cells) cell.sizable().setFont(cell.sizable().font());
sizable(n)->setFont(sizable(n)->font()); return *this;
} }
auto mFixedLayout::setParent(mObject* parent, int offset) -> type& {
for(auto& cell : reverse(state.cells)) cell->destruct();
mSizable::setParent(parent, offset);
for(auto& cell : state.cells) cell->setParent(this, cell->offset());
return *this; return *this;
} }
auto mFixedLayout::setVisible(bool visible) -> type& { auto mFixedLayout::setVisible(bool visible) -> type& {
mLayout::setVisible(visible); mSizable::setVisible(visible);
for(auto n : range(sizableCount())) { for(auto& cell : state.cells) cell.sizable().setVisible(cell.sizable().visible());
sizable(n)->setVisible(sizable(n)->visible()); return synchronize();
}
auto mFixedLayout::synchronize() -> type& {
setGeometry(geometry());
return *this;
}
//
auto mFixedLayoutCell::destruct() -> void {
if(auto& sizable = state.sizable) sizable->destruct();
mObject::destruct();
}
auto mFixedLayoutCell::geometry() const -> Geometry {
return state.geometry;
}
auto mFixedLayoutCell::setEnabled(bool enabled) -> type& {
mObject::setEnabled(enabled);
state.sizable->setEnabled(state.sizable->enabled());
return *this;
}
auto mFixedLayoutCell::setFont(const Font& font) -> type& {
mObject::setFont(font);
state.sizable->setFont(state.sizable->font());
return *this;
}
auto mFixedLayoutCell::setGeometry(Geometry geometry) -> type& {
state.geometry = geometry;
return synchronize();
}
auto mFixedLayoutCell::setParent(mObject* parent, int offset) -> type& {
state.sizable->destruct();
mObject::setParent(parent, offset);
state.sizable->setParent(this, 0);
return *this;
}
auto mFixedLayoutCell::setSizable(sSizable sizable) -> type& {
state.sizable = sizable;
return synchronize();
}
auto mFixedLayoutCell::setVisible(bool visible) -> type& {
mObject::setVisible(visible);
state.sizable->setVisible(state.sizable->visible());
return *this;
}
auto mFixedLayoutCell::sizable() const -> Sizable {
return state.sizable;
}
auto mFixedLayoutCell::synchronize() -> type& {
if(auto parent = this->parent()) {
if(auto fixedLayout = dynamic_cast<mFixedLayout*>(parent)) {
fixedLayout->synchronize();
}
} }
return *this; return *this;
} }

View File

@ -1,23 +1,61 @@
#if defined(Hiro_FixedLayout) #if defined(Hiro_FixedLayout)
struct mFixedLayout : mLayout { struct FixedLayout;
struct FixedLayoutCell;
struct mFixedLayout;
struct mFixedLayoutCell;
using sFixedLayout = shared_pointer<mFixedLayout>;
using sFixedLayoutCell = shared_pointer<mFixedLayoutCell>;
struct mFixedLayout : mSizable {
using type = mFixedLayout; using type = mFixedLayout;
using mLayout::append; using mSizable::remove;
using mLayout::remove;
auto append(sSizable sizable, Geometry geometry) -> type&; auto append(sSizable sizable, Geometry geometry) -> type&;
auto modify(sSizable sizable, Geometry geometry) -> type&; auto cell(uint position) const -> FixedLayoutCell;
auto cell(sSizable sizable) const -> FixedLayoutCell;
auto cellCount() const -> uint;
auto minimumSize() const -> Size override; auto minimumSize() const -> Size override;
auto remove(sSizable sizable) -> type& override; auto remove(sFixedLayoutCell cell) -> type&;
auto reset() -> type& override; auto reset() -> type& override;
auto setEnabled(bool enabled = true) -> type& override; auto setEnabled(bool enabled) -> type& override;
auto setFont(const Font& font = {}) -> type& override; auto setFont(const Font& font) -> type& override;
auto setVisible(bool visible = true) ->type& override; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setVisible(bool visible) ->type& override;
auto synchronize() -> type&;
struct Property { private:
auto destruct() -> void override;
struct State {
vector<FixedLayoutCell> cells;
} state;
};
struct mFixedLayoutCell : mObject {
using type = mFixedLayoutCell;
auto geometry() const -> Geometry;
auto setEnabled(bool enabled) -> type& override;
auto setFont(const Font& font) -> type& override;
auto setGeometry(Geometry geometry) -> type&;
auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setSizable(sSizable sizable) -> type&;
auto setVisible(bool visible) -> type& override;
auto sizable() const -> Sizable;
auto synchronize() -> type&;
private:
auto destruct() -> void override;
struct State {
Geometry geometry; Geometry geometry;
}; sSizable sizable;
vector<Property> properties; } state;
friend class mFixedLayout;
}; };
#endif #endif

View File

@ -1,149 +1,280 @@
#if defined(Hiro_HorizontalLayout) #if defined(Hiro_HorizontalLayout)
auto mHorizontalLayout::append(sSizable sizable, Size size, float spacing) -> type& { auto mHorizontalLayout::alignment() const -> maybe<float> {
properties.append({size.width(), size.height(), spacing < 0 ? settings.spacing : spacing}); return state.alignment;
mLayout::append(sizable);
return *this;
} }
auto mHorizontalLayout::modify(sSizable sizable, Size size, float spacing) -> type& { auto mHorizontalLayout::append(sSizable sizable, Size size, float spacing) -> type& {
if(sizable && this->sizable(sizable->offset()) == sizable) { HorizontalLayoutCell cell;
auto& properties = this->properties[sizable->offset()]; cell->setSizable(sizable);
properties.setWidth(size.width()); cell->setSize(size);
properties.setHeight(size.height()); cell->setSpacing(spacing);
properties.setSpacing(spacing); cell->setParent(this, cellCount());
state.cells.append(cell);
return synchronize();
}
auto mHorizontalLayout::cell(uint position) const -> HorizontalLayoutCell {
return state.cells(position, {});
}
auto mHorizontalLayout::cell(sSizable sizable) const -> HorizontalLayoutCell {
for(auto& cell : state.cells) {
if(cell->state.sizable == sizable) return cell;
} }
return *this; return {};
}
auto mHorizontalLayout::cellCount() const -> uint {
return state.cells.size();
}
auto mHorizontalLayout::destruct() -> void {
for(auto& cell : state.cells) cell->destruct();
mSizable::destruct();
} }
auto mHorizontalLayout::minimumSize() const -> Size { auto mHorizontalLayout::minimumSize() const -> Size {
float width = 0, height = 0; float width = 0;
for(auto index : range(cellCount())) {
for(auto n : range(sizableCount())) { auto cell = this->cell(index);
auto& child = properties[sizable(n)->offset()]; if(cell.size().width() == Size::Minimum || cell.size().width() == Size::Maximum) {
if(child.width() == Size::Minimum || child.width() == Size::Maximum) { width += cell.sizable().minimumSize().width();
width += sizable(n)->minimumSize().width();
} else { } else {
width += child.width(); width += cell.size().width();
} }
if(&child != &properties.right()) width += child.spacing(); if(index != cellCount() - 1) width += cell.spacing();
} }
for(auto n : range(sizableCount())) { float height = 0;
auto& child = properties[sizable(n)->offset()]; for(auto index : range(cellCount())) {
if(child.height() == Size::Minimum || child.height() == Size::Maximum) { auto cell = this->cell(index);
height = max(height, sizable(n)->minimumSize().height()); if(cell.size().height() == Size::Minimum || cell.size().height() == Size::Maximum) {
height = max(height, cell.sizable().minimumSize().height());
continue; continue;
} }
height = max(height, child.height()); height = max(height, cell.size().height());
} }
return { return {
settings.padding.x() + width + settings.padding.width(), padding().x() + width + padding().width(),
settings.padding.y() + height + settings.padding.height() padding().y() + height + padding().height()
}; };
} }
auto mHorizontalLayout::remove(sSizable sizable) -> type& { auto mHorizontalLayout::padding() const -> Geometry {
properties.remove(sizable->offset()); return state.padding;
mLayout::remove(sizable); }
return *this;
auto mHorizontalLayout::remove(sHorizontalLayoutCell cell) -> type& {
if(cell->parent() != this) return *this;
auto offset = cell->offset();
cell->setParent();
state.cells.remove(offset);
for(uint n : range(offset, cellCount())) state.cells[n]->adjustOffset(-1);
return synchronize();
} }
auto mHorizontalLayout::reset() -> type& { auto mHorizontalLayout::reset() -> type& {
mLayout::reset(); while(state.cells) remove(state.cells.right());
properties.reset(); return synchronize();
return *this;
} }
auto mHorizontalLayout::setAlignment(float alignment) -> type& { auto mHorizontalLayout::setAlignment(maybe<float> alignment) -> type& {
settings.alignment = max(0.0, min(1.0, alignment)); state.alignment = alignment;
return *this; return synchronize();
} }
auto mHorizontalLayout::setEnabled(bool enabled) -> type& { auto mHorizontalLayout::setEnabled(bool enabled) -> type& {
mLayout::setEnabled(enabled); mSizable::setEnabled(enabled);
for(auto n : range(sizableCount())) { for(auto& cell : state.cells) cell.sizable().setEnabled(cell.sizable().enabled());
sizable(n)->setEnabled(sizable(n)->enabled());
}
return *this; return *this;
} }
auto mHorizontalLayout::setFont(const Font& font) -> type& { auto mHorizontalLayout::setFont(const Font& font) -> type& {
mLayout::setFont(font); mSizable::setFont(font);
for(auto n : range(sizableCount())) { for(auto& cell : state.cells) cell.sizable().setFont(cell.sizable().font());
sizable(n)->setFont(sizable(n)->font());
}
return *this; return *this;
} }
auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& { auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
mLayout::setGeometry(containerGeometry); mSizable::setGeometry(geometry);
auto window = parentWindow(true);
if(!window || !window->visible()) return *this;
auto properties = this->properties; geometry.setX(geometry.x() + padding().x());
for(auto n : range(sizableCount())) { geometry.setY(geometry.y() + padding().y());
auto& child = properties[sizable(n)->offset()]; geometry.setWidth (geometry.width() - padding().x() - padding().width());
if(child.width() == Size::Minimum) child.setWidth(sizable(n)->minimumSize().width()); geometry.setHeight(geometry.height() - padding().y() - padding().height());
if(child.height() == Size::Minimum) child.setHeight(sizable(n)->minimumSize().height());
vector<float> widths;
widths.resize(cellCount());
uint maximumWidths = 0;
for(auto index : range(cellCount())) {
auto cell = this->cell(index);
float width = 0;
if(cell.size().width() == Size::Maximum) {
width = Size::Maximum;
maximumWidths++;
} else if(cell.size().width() == Size::Minimum) {
width = cell.sizable().minimumSize().width();
} else {
width = cell.size().width();
}
widths[index] = width;
} }
Geometry geometry = containerGeometry; float fixedWidth = 0;
geometry.setX (geometry.x() + settings.padding.x()); for(uint index : range(state.cells.size())) {
geometry.setY (geometry.y() + settings.padding.y()); if(widths[index] != Size::Maximum) fixedWidth += widths[index];
geometry.setWidth (geometry.width() - settings.padding.x() - settings.padding.width()); if(index != cellCount() - 1) fixedWidth += cell(index).spacing();
geometry.setHeight(geometry.height() - settings.padding.y() - settings.padding.height());
float minimumWidth = 0, maximumWidthCounter = 0;
for(auto& child : properties) {
if(child.width() == Size::Maximum) maximumWidthCounter++;
if(child.width() != Size::Maximum) minimumWidth += child.width();
if(&child != &properties.right()) minimumWidth += child.spacing();
} }
for(auto& child : properties) { float maximumWidth = (geometry.width() - fixedWidth) / maximumWidths;
if(child.width() == Size::Maximum) child.setWidth((geometry.width() - minimumWidth) / maximumWidthCounter); for(auto& width : widths) {
if(child.height() == Size::Maximum) child.setHeight(geometry.height()); if(width == Size::Maximum) width = maximumWidth;
} }
float maximumHeight = 0; float height = 0;
for(auto& child : properties) maximumHeight = max(maximumHeight, child.height()); for(auto index : range(cellCount())) {
auto cell = this->cell(index);
for(auto n : range(sizableCount())) { if(cell.size().height() == Size::Maximum) {
auto& child = properties[sizable(n)->offset()]; height = geometry.height();
float pivot = (maximumHeight - child.height()) * settings.alignment; break;
Geometry childGeometry = {geometry.x(), geometry.y() + pivot, child.width(), child.height()}; } else if(cell.size().height() == Size::Minimum) {
if(childGeometry.width() < 1) childGeometry.setWidth (1); height = max(height, cell.sizable().minimumSize().height());
if(childGeometry.height() < 1) childGeometry.setHeight(1); } else {
sizable(n)->setGeometry(childGeometry); height = max(height, cell.size().height());
}
geometry.setX (geometry.x() + child.width() + child.spacing());
geometry.setWidth(geometry.width() - child.width() + child.spacing());
} }
return *this; float geometryX = geometry.x();
} float geometryY = geometry.y();
for(auto index : range(cellCount())) {
float geometryWidth = widths[index];
float geometryHeight = height;
auto cell = this->cell(index);
auto alignment = cell.alignment();
if(!alignment) alignment = this->alignment();
if(!alignment) alignment = 0.5;
float cellWidth = geometryWidth;
float cellHeight = cell.size().height();
if(cellHeight == Size::Minimum) cellHeight = cell.sizable()->minimumSize().height();
if(cellHeight == Size::Maximum) cellHeight = geometryHeight;
float cellX = geometryX;
float cellY = geometryY + alignment() * (geometryHeight - cellHeight);
cell.sizable().setGeometry({cellX, cellY, cellWidth, cellHeight});
geometryX += geometryWidth + cell.spacing();
}
auto mHorizontalLayout::setMargin(float margin) -> type& {
setPadding({margin, margin, margin, margin});
return *this; return *this;
} }
auto mHorizontalLayout::setPadding(Geometry padding) -> type& { auto mHorizontalLayout::setPadding(Geometry padding) -> type& {
settings.padding = padding; state.padding = padding;
setGeometry(geometry()); return synchronize();
}
auto mHorizontalLayout::setParent(mObject* parent, int offset) -> type& {
for(auto& cell : reverse(state.cells)) cell->destruct();
mSizable::setParent(parent, offset);
for(auto& cell : state.cells) cell->setParent(this, cell->offset());
return *this; return *this;
} }
auto mHorizontalLayout::setSpacing(float spacing) -> type& { auto mHorizontalLayout::setSpacing(float spacing) -> type& {
settings.spacing = spacing; state.spacing = spacing;
return synchronize();
}
auto mHorizontalLayout::setVisible(bool visible) -> type& {
mSizable::setVisible(visible);
for(auto& cell : state.cells) cell.sizable().setVisible(cell.sizable().visible());
return synchronize();
}
auto mHorizontalLayout::spacing() const -> float {
return state.spacing;
}
auto mHorizontalLayout::synchronize() -> type& {
setGeometry(geometry()); setGeometry(geometry());
return *this; return *this;
} }
auto mHorizontalLayout::setVisible(bool visible) -> type& { //
mLayout::setVisible(visible);
for(auto n : range(sizableCount())) { auto mHorizontalLayoutCell::alignment() const -> maybe<float> {
sizable(n)->setVisible(sizable(n)->visible()); return state.alignment;
}
auto mHorizontalLayoutCell::destruct() -> void {
if(auto& sizable = state.sizable) sizable->destruct();
mObject::destruct();
}
auto mHorizontalLayoutCell::setAlignment(maybe<float> alignment) -> type& {
state.alignment = alignment;
return synchronize();
}
auto mHorizontalLayoutCell::setEnabled(bool enabled) -> type& {
mObject::setEnabled(enabled);
state.sizable->setEnabled(state.sizable->enabled());
return *this;
}
auto mHorizontalLayoutCell::setFont(const Font& font) -> type& {
mObject::setFont(font);
state.sizable->setFont(state.sizable->font());
return *this;
}
auto mHorizontalLayoutCell::setParent(mObject* parent, int offset) -> type& {
state.sizable->destruct();
mObject::setParent(parent, offset);
state.sizable->setParent(this, 0);
return *this;
}
auto mHorizontalLayoutCell::setSizable(sSizable sizable) -> type& {
state.sizable = sizable;
return synchronize();
}
auto mHorizontalLayoutCell::setSize(Size size) -> type& {
state.size = size;
return synchronize();
}
auto mHorizontalLayoutCell::setSpacing(float spacing) -> type& {
state.spacing = spacing;
return synchronize();
}
auto mHorizontalLayoutCell::setVisible(bool visible) -> type& {
mObject::setVisible(visible);
state.sizable->setVisible(state.sizable->visible());
return *this;
}
auto mHorizontalLayoutCell::sizable() const -> Sizable {
return state.sizable;
}
auto mHorizontalLayoutCell::size() const -> Size {
return state.size;
}
auto mHorizontalLayoutCell::spacing() const -> float {
return state.spacing;
}
auto mHorizontalLayoutCell::synchronize() -> type& {
if(auto parent = this->parent()) {
if(auto horizontalLayout = dynamic_cast<mHorizontalLayout*>(parent)) {
horizontalLayout->synchronize();
}
} }
return *this; return *this;
} }

View File

@ -1,38 +1,77 @@
#if defined(Hiro_HorizontalLayout) #if defined(Hiro_HorizontalLayout)
struct mHorizontalLayout : mLayout { struct HorizontalLayout;
struct HorizontalLayoutCell;
struct mHorizontalLayout;
struct mHorizontalLayoutCell;
using sHorizontalLayout = shared_pointer<mHorizontalLayout>;
using sHorizontalLayoutCell = shared_pointer<mHorizontalLayoutCell>;
struct mHorizontalLayout : mSizable {
using type = mHorizontalLayout; using type = mHorizontalLayout;
using mLayout::append; using mSizable::remove;
using mLayout::remove;
auto alignment() const -> maybe<float>;
auto append(sSizable sizable, Size size, float spacing = 5) -> type&; auto append(sSizable sizable, Size size, float spacing = 5) -> type&;
auto cell(uint position) const -> HorizontalLayoutCell;
auto cell(sSizable sizable) const -> HorizontalLayoutCell;
auto cellCount() const -> uint;
auto minimumSize() const -> Size override; auto minimumSize() const -> Size override;
auto modify(sSizable sizable, Size size, float spacing = 5) -> type&; auto padding() const -> Geometry;
auto remove(sSizable sizable) -> type& override; auto remove(sHorizontalLayoutCell cell) -> type&;
auto reset() -> type& override; auto reset() -> type& override;
auto setAlignment(float alignment = 0.5) -> type&; auto setAlignment(maybe<float> alignment) -> type&;
auto setEnabled(bool enabled = true) -> type& override; auto setEnabled(bool enabled) -> type& override;
auto setFont(const Font& font = {}) -> type& override; auto setFont(const Font& font) -> type& override;
auto setGeometry(Geometry geometry) -> type& override; auto setGeometry(Geometry geometry) -> type& override;
auto setMargin(float margin = 0) -> type&; auto setPadding(Geometry padding) -> type&;
auto setPadding(Geometry padding = {}) -> type&; auto setParent(mObject* parent = nullptr, int offset = -1) -> type&;
auto setSpacing(float spacing = 5) -> type&; auto setSpacing(float spacing) -> type&;
auto setVisible(bool visible = true) -> type&; auto setVisible(bool visible) -> type& override;
auto spacing() const -> float;
auto synchronize() -> type&;
struct Settings { private:
float alignment = 0.5; auto destruct() -> void override;
struct State {
maybe<float> alignment;
vector<HorizontalLayoutCell> cells;
Geometry padding; Geometry padding;
float spacing = 5; float spacing = 5;
} settings; } state;
};
struct Property : Size { struct mHorizontalLayoutCell : mObject {
Property() = default; using type = mHorizontalLayoutCell;
Property(float width, float height, float spacing) : Size(width, height), _spacing(spacing) {}
auto setSpacing(float spacing) -> Property& { return _spacing = spacing, *this; } auto alignment() const -> maybe<float>;
auto spacing() const -> float { return _spacing; } auto setAlignment(maybe<float> alignment) -> type&;
float _spacing = 0; auto setEnabled(bool enabled) -> type& override;
}; auto setFont(const Font& font) -> type& override;
vector<Property> properties; auto setParent(mObject* parent = nullptr, int offset = -1) -> type& override;
auto setSizable(sSizable sizable) -> type&;
auto setSize(Size size) -> type&;
auto setSpacing(float spacing) -> type&;
auto setVisible(bool visible) -> type& override;
auto sizable() const -> Sizable;
auto size() const -> Size;
auto spacing() const -> float;
auto synchronize() -> type&;
private:
auto destruct() -> void override;
struct State {
maybe<float> alignment;
sSizable sizable;
Size size;
float spacing = 5;
} state;
friend class mHorizontalLayout;
}; };
#endif #endif

View File

@ -1,49 +0,0 @@
#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

View File

@ -1,24 +0,0 @@
#if defined(Hiro_ListView)
struct ListViewItem;
struct mListViewItem;
using sListViewItem = shared_pointer<mListViewItem>;
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

View File

@ -72,4 +72,52 @@ auto mListView::selected() const -> ListViewItem {
return ListViewItem{mTableView::selected()}; return ListViewItem{mTableView::selected()};
} }
//
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 #endif

View File

@ -1,8 +1,13 @@
#if defined(Hiro_ListView) #if defined(Hiro_ListView)
struct ListView; struct ListView;
struct ListViewItem;
struct mListView; struct mListView;
struct mListViewItem;
using sListView = shared_pointer<mListView>; using sListView = shared_pointer<mListView>;
using sListViewItem = shared_pointer<mListViewItem>;
struct mListView : mTableView { struct mListView : mTableView {
using type = mListView; using type = mListView;
@ -30,4 +35,21 @@ struct mListView : mTableView {
} state; } state;
}; };
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 #endif

View File

@ -52,10 +52,10 @@ auto MessageDialog::_run() -> string {
HorizontalLayout controlLayout{&layout, Size{~0, 0}}; HorizontalLayout controlLayout{&layout, Size{~0, 0}};
Widget controlSpacer{&controlLayout, Size{~0, 0}}; Widget controlSpacer{&controlLayout, Size{~0, 0}};
layout.setMargin(5); layout.setPadding(5);
messageIcon.setIcon(state.icon); messageIcon.setIcon(state.icon);
messageText.setText(state.text); messageText.setText(state.text);
for(auto n : range(state.buttons)) { for(auto n : range(state.buttons.size())) {
Button button{&controlLayout, Size{80, 0}, 5}; Button button{&controlLayout, Size{80, 0}, 5};
button.onActivate([&, n] { state.response = state.buttons[n]; window.setModal(false); }); button.onActivate([&, n] { state.response = state.buttons[n]; window.setModal(false); });
button.setText(state.buttons[n]); button.setText(state.buttons[n]);

View File

@ -1,41 +1,142 @@
#if defined(Hiro_FixedLayout) #if defined(Hiro_FixedLayout)
using sFixedLayout = shared_pointer<mFixedLayout>; struct FixedLayoutCell : sFixedLayoutCell {
DeclareSharedObject(FixedLayoutCell)
auto geometry() const { return self().geometry(); }
auto setGeometry(Geometry geometry) { return self().setGeometry(geometry), *this; }
auto setSizable(sSizable sizable) { return self().setSizable(sizable), *this; }
auto sizable() const { return self().sizable(); }
};
struct FixedLayout : sFixedLayout { struct FixedLayout : sFixedLayout {
DeclareSharedLayout(FixedLayout) DeclareSharedSizable(FixedLayout)
auto append(sSizable sizable, Geometry geometry) { return self().append(sizable, geometry), *this; } auto append(sSizable sizable, Geometry geometry) { return self().append(sizable, geometry), *this; }
auto modify(sSizable sizable, Geometry geometry) { return self().modify(sizable, geometry), *this; } auto cell(uint position) const { return self().cell(position); }
auto cell(sSizable sizable) const { return self().cell(sizable); }
auto cellCount() const { return self().cellCount(); }
auto remove(sFixedLayoutCell cell) { return self().remove(cell), *this; }
auto reset() { return self().reset(), *this; }
}; };
#endif #endif
#if defined(Hiro_HorizontalLayout) #if defined(Hiro_HorizontalLayout)
using sHorizontalLayout = shared_pointer<mHorizontalLayout>; struct HorizontalLayoutCell : sHorizontalLayoutCell {
struct HorizontalLayout : sHorizontalLayout { DeclareSharedObject(HorizontalLayoutCell)
DeclareSharedLayout(HorizontalLayout)
auto alignment() const { return self().alignment(); }
auto setAlignment(maybe<float> alignment = {}) { return self().setAlignment(alignment), *this; }
auto setSizable(sSizable sizable) { return self().setSizable(sizable), *this; }
auto setSize(Size size) { return self().setSize(size), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
auto sizable() const { return self().sizable(); }
auto size() const { return self().size(); }
auto spacing() const { return self().spacing(); }
};
struct HorizontalLayout : sHorizontalLayout {
DeclareSharedSizable(HorizontalLayout)
auto alignment() const { return self().alignment(); }
auto append(sSizable sizable, Size size, float spacing = 5) { return self().append(sizable, size, spacing), *this; } auto append(sSizable sizable, Size size, float spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, float spacing = 5) { return self().modify(sizable, size, spacing), *this; } auto cell(uint position) const { return self().cell(position); }
auto setAlignment(float alignment = 0.5) { return self().setAlignment(alignment), *this; } auto cell(sSizable sizable) const { return self().cell(sizable); }
auto setMargin(float margin = 0) { return self().setMargin(margin), *this; } auto cellCount() const { return self().cellCount(); }
auto remove(sHorizontalLayoutCell cell) { return self().remove(cell), *this; }
auto reset() { return self().reset(), *this; }
auto setAlignment(maybe<float> alignment = {}) { return self().setAlignment(alignment), *this; }
auto setPadding(float padding) { return self().setPadding({padding, padding, padding, padding}), *this; }
auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; } auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; } auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
}; };
#endif #endif
#if defined(Hiro_VerticalLayout) #if defined(Hiro_VerticalLayout)
using sVerticalLayout = shared_pointer<mVerticalLayout>; struct VerticalLayoutCell : sVerticalLayoutCell {
struct VerticalLayout : sVerticalLayout { DeclareSharedObject(VerticalLayoutCell)
DeclareSharedLayout(VerticalLayout)
auto alignment() const { return self().alignment(); }
auto setAlignment(maybe<float> alignment = {}) { return self().setAlignment(alignment), *this; }
auto setSizable(sSizable sizable) { return self().setSizable(sizable), *this; }
auto setSize(Size size) { return self().setSize(size), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
auto sizable() const { return self().sizable(); }
auto size() const { return self().size(); }
auto spacing() const { return self().spacing(); }
};
struct VerticalLayout : sVerticalLayout {
DeclareSharedSizable(VerticalLayout)
auto alignment() const { return self().alignment(); }
auto append(sSizable sizable, Size size, float spacing = 5) { return self().append(sizable, size, spacing), *this; } auto append(sSizable sizable, Size size, float spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, float spacing = 5) { return self().modify(sizable, size, spacing), *this; } auto cell(uint position) const { return self().cell(position); }
auto setAlignment(float alignment = 0.0) { return self().setAlignment(alignment), *this; } auto cell(sSizable sizable) const { return self().cell(sizable); }
auto setMargin(float margin = 0) { return self().setMargin(margin), *this; } auto cellCount() const { return self().cellCount(); }
auto remove(sSizable sizable) { return self().remove(sizable), *this; }
auto remove(sVerticalLayoutCell cell) { return self().remove(cell), *this; }
auto reset() { return self().reset(), *this; }
auto setAlignment(maybe<float> alignment = {}) { return self().setAlignment(alignment), *this; }
auto setPadding(float padding) { return self().setPadding({padding, padding, padding, padding}), *this; }
auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; } auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; } auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
}; };
#endif #endif
#if defined(Hiro_TableLayout)
struct TableLayoutCell : sTableLayoutCell {
DeclareSharedObject(TableLayoutCell)
auto alignment() const { return self().alignment(); }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
auto setSizable(sSizable sizable) { return self().setSizable(sizable), *this; }
auto setSize(Size size) { return self().setSize(size), *this; }
auto sizable() const { return self().sizable(); }
auto size() const { return self().size(); }
};
struct TableLayoutColumn : sTableLayoutColumn {
DeclareSharedObject(TableLayoutColumn)
auto alignment() const { return self().alignment(); }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
auto spacing() const { return self().spacing(); }
};
struct TableLayoutRow : sTableLayoutRow {
DeclareSharedObject(TableLayoutRow)
auto alignment() const { return self().alignment(); }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
auto spacing() const { return self().spacing(); }
};
struct TableLayout : sTableLayout {
DeclareSharedSizable(TableLayout)
auto alignment() const { return self().alignment(); }
auto append(sSizable sizable, Size size) { return self().append(sizable, size), *this; }
auto cell(uint position) const { return self().cell(position); }
auto cell(uint x, uint y) const { return self().cell(x, y); }
auto cell(sSizable sizable) const { return self().cell(sizable); }
auto cellCount() const { return self().cellCount(); }
auto column(uint position) const { return self().column(position); }
auto columnCount() const { return self().columnCount(); }
auto padding() const { return self().padding(); }
auto remove(sTableLayoutCell cell) { return self().remove(cell), *this; }
auto reset() { return self().reset(), *this; }
auto row(uint position) const { return self().row(position); }
auto rowCount() const { return self().rowCount(); }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
auto setPadding(float padding) { return self().setPadding({padding, padding, padding, padding}), *this; }
auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; }
auto setSize(Size size) { return self().setSize(size), *this; }
auto size() const { return self().size(); }
};
#endif
#if defined(Hiro_ListView) #if defined(Hiro_ListView)
struct ListViewItem : sListViewItem { struct ListViewItem : sListViewItem {
DeclareSharedObject(ListViewItem) DeclareSharedObject(ListViewItem)
@ -56,9 +157,7 @@ struct ListViewItem : sListViewItem {
auto setText(const string& text = "") { return self().setText(text), *this; } auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); } auto text() const { return self().text(); }
}; };
#endif
#if defined(Hiro_ListView)
struct ListView : sListView { struct ListView : sListView {
DeclareSharedWidget(ListView) DeclareSharedWidget(ListView)

Some files were not shown because too many files have changed in this diff Show More