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
build := stable
nall.path := ../nall
include $(nall.path)/GNUmakefile
object.path := obj
flags += -I..
objects := obj/hiro.o
objects += obj/genius.o
objects += $(if $(call streq,$(platform),windows),obj/resource.o)
hiro.path := ../hiro
hiro.resource := data/$(name).rc
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) ...)
+@$(strip $(compiler) -o out/$(name) $(objects) $(link) $(hirolink))
+@$(strip $(compiler) -o out/$(name) $(objects) $(options) $(hiro.options))
ifeq ($(platform),macos)
rm -rf out/$(name).app
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
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
$(info Compiling $< ...)
@$(compiler) $(cppflags) $(flags) -o obj/genius.o -c genius.cpp
obj/resource.o: data/$(name).rc
$(info Compiling $< ...)
@$(windres) data/$(name).rc obj/resource.o
@$(compiler) $(flags.cpp) $(flags) -o obj/genius.o -c genius.cpp
clean:
ifeq ($(platform),macos)

View File

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

View File

@ -1,11 +1,13 @@
build := performance
openmp := true
include ../nall/GNUmakefile
nall.path := ../nall
include $(nall.path)/GNUmakefile
binary := application
target := bsnes
objects := libco emulator audio video resource
object.path := obj
flags += -I. -I..
ifeq ($(platform),windows)
@ -38,9 +40,9 @@ endif
compile = \
$(strip \
$(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,$<), \
$(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 {
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();
}
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
for(auto& filter : channels[c].filters) {
switch(filter.order) {

View File

@ -13,7 +13,7 @@ using namespace nall;
namespace Emulator {
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 License = "GPLv3";
static const string Website = "https://byuu.org/";

View File

@ -7,7 +7,7 @@ auto V30MZ::serialize(serializer& s) -> void {
if(s.mode() == serializer::Save) {
uint8 _prefixes[7] = {0};
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.array(_prefixes);
} else {
@ -16,7 +16,7 @@ auto V30MZ::serialize(serializer& s) -> void {
s.integer(_prefixCount);
s.array(_prefixes);
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);

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];
if(!item.valid) continue;

View File

@ -5,13 +5,11 @@ include sfc/GNUmakefile
include gb/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-settings ui-tools ui-resource
objects += $(if $(call streq,$(platform),windows),ui-windows)
objects := $(objects:%=obj/%.o)
# platform
ifeq ($(platform),windows)
ruby += video.wgl video.direct3d video.directdraw video.gdi
ruby += audio.asio audio.wasapi audio.xaudio2 audio.directsound
@ -30,23 +28,13 @@ else ifeq ($(platform),bsd)
ruby += input.sdl input.xlib
endif
# ruby
include ../ruby/GNUmakefile
link += $(rubylink)
ruby.path := ../ruby
include $(ruby.path)/GNUmakefile
obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/)
$(info Compiling $< ...)
@$(compiler) $(rubyflags) -c $< -o $@
hiro.path := ../hiro
hiro.resource := $(ui)/resource/bsnes.rc
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-program.o: $(ui)/program/program.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-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
default: information $(objects)
all: $(objects)
$(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)
rm -rf out/$(name).app
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/icons/
mkdir -p $(prefix)/share/$(name)/
mkdir -p $(prefix)/share/$(name)/locales/
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).png $(prefix)/share/icons/$(name).png
endif

View File

@ -4,6 +4,7 @@ unique_pointer<Video> video;
unique_pointer<Audio> audio;
unique_pointer<Input> input;
unique_pointer<Emulator::Interface> emulator;
Locale ns;
auto locate(string name) -> string {
string location = {Path::program(), name};
@ -19,9 +20,16 @@ auto locate(string name) -> string {
}
#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");
emulator = new SuperFamicom::Interface;
new Program(args);
new Program(arguments);
Application::run();
}

View File

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

View File

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

View File

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

View File

@ -3,10 +3,10 @@
unique_pointer<AboutWindow> aboutWindow;
unique_pointer<Presentation> presentation;
Presentation::Presentation() {
Presentation::Presentation() : Locale::Namespace(ns, "Presentation") {
presentation = this;
systemMenu.setText("System");
systemMenu.setText(tr("System"));
loadGame.setIcon(Icon::Action::Open).setText("Load Game ...").onActivate([&] {
program->load();
});
@ -55,7 +55,7 @@ Presentation::Presentation() {
}
quit.setIcon(Icon::Action::Quit).setText("Quit").onActivate([&] { program->quit(); });
settingsMenu.setText("Settings");
settingsMenu.setText(tr("Settings"));
sizeMenu.setIcon(Icon::Emblem::Image).setText("Size");
updateSizeMenu();
outputMenu.setIcon(Icon::Emblem::Image).setText("Output");
@ -115,7 +115,7 @@ Presentation::Presentation() {
pathSettings.setIcon(Icon::Emblem::Folder).setText("Paths ...").onActivate([&] { settingsWindow->show(4); });
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");
for(uint index : range(QuickStates)) {
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); });
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([&] {
invoke("https://doc.byuu.org/bsnes/");
});
@ -469,7 +469,7 @@ auto Presentation::addRecentGame(string location) -> void {
for(uint index : range(RecentGames + 1)) {
auto value = settings[{"Game/Recent/", 1 + index}].text();
if(!value || value == location) {
for(uint n : rrange(index + 1)) {
for(uint n : reverse(range(index + 1))) {
if(1 + n > RecentGames) continue;
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();
VerticalLayout layout{this};
Canvas canvas{&layout, Size{400, 85}, 0};
HorizontalLayout informationLayout{&layout, Size{~0, ~0}};
Label informationLeft{&informationLayout, Size{~0, 0}, 3};
Label informationRight{&informationLayout, Size{~0, 0}};
TableLayout tableLayout{&layout, Size{~0, 0}};
Label versionLabel{&tableLayout, 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 { StatusHeight = 24 };

View File

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

View File

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

View File

@ -18,11 +18,11 @@ auto Program::updateStatus() -> void {
string frameRate;
if(!emulator->loaded()) {
frameRate = "Unloaded";
frameRate = tr("Unloaded");
} else if(presentation->pauseEmulation.checked()) {
frameRate = "Paused";
frameRate = tr("Paused");
} else if(!focused() && settingsWindow->input.pauseEmulation.checked()) {
frameRate = "Paused";
frameRate = tr("Paused");
} else {
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);
setText("Advanced");
layout.setMargin(5);
layout.setPadding(5);
driversLabel.setText("Drivers").setFont(Font().setBold());
videoDriverLabel.setText("Video:");

View File

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

View File

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

View File

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

View File

@ -2,9 +2,11 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Emblem::Folder);
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);
gamesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -17,7 +19,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths();
});
patchesLabel.setAlignment(1.0).setText("Patches:");
patchesLabel.setText("Patches:");
patchesPath.setEditable(false);
patchesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -30,7 +32,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths();
});
savesLabel.setAlignment(1.0).setText("Saves:");
savesLabel.setText("Saves:");
savesPath.setEditable(false);
savesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -43,7 +45,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths();
});
cheatsLabel.setAlignment(1.0).setText("Cheats:");
cheatsLabel.setText("Cheats:");
cheatsPath.setEditable(false);
cheatsAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -56,7 +58,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths();
});
statesLabel.setAlignment(1.0).setText("States:");
statesLabel.setText("States:");
statesPath.setEditable(false);
statesAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {
@ -69,7 +71,7 @@ PathSettings::PathSettings(TabFrame* parent) : TabFrameItem(parent) {
refreshPaths();
});
screenshotsLabel.setAlignment(1.0).setText("Screenshots:");
screenshotsLabel.setText("Screenshots:");
screenshotsPath.setEditable(false);
screenshotsAssign.setText("Assign ...").onActivate([&] {
if(auto location = BrowserDialog().setParent(*settingsWindow).selectFolder()) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -171,7 +171,7 @@ auto Presentation::updateEmulator() -> void {
inputPort2.setVisible(false).reset();
inputPort3.setVisible(false).reset();
for(auto n : range(emulator->ports)) {
for(auto n : range(emulator->ports.size())) {
if(n >= 3) break;
auto& port = emulator->ports[n];
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);
setText("Advanced");
layout.setMargin(5);
layout.setPadding(5);
driverLabel.setText("Driver Selection").setFont(Font().setBold());
videoLabel.setText("Video:");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Edit::Replace);
setText("Cheat Editor");
layout.setMargin(5);
layout.setPadding(5);
cheatList.append(TableViewHeader().setVisible()
.append(TableViewColumn())
.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);
setText("Game Notes");
layout.setMargin(5);
layout.setPadding(5);
notes.setWordWrap(false).setFont(Font().setFamily(Font::Mono));
}

View File

@ -2,7 +2,7 @@ ManifestViewer::ManifestViewer(TabFrame* parent) : TabFrameItem(parent) {
setIcon(Icon::Emblem::Text);
setText("Manifest Viewer");
layout.setMargin(5);
layout.setPadding(5);
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);
setText("State Manager");
layout.setMargin(5);
layout.setPadding(5);
stateList.append(TableViewHeader().setVisible()
.append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0))
.append(TableViewColumn().setText("Description").setExpandable())

View File

@ -10,7 +10,7 @@ unique_pointer<ToolsManager> toolsManager;
ToolsManager::ToolsManager() {
toolsManager = this;
layout.setMargin(5);
layout.setPadding(5);
setTitle("Tools");
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 {
for(uint n : range(sprites)) {
for(uint n : range(sprites.size())) {
if(sprite == sprites[n]) {
sprites.remove(n);
return true;

View File

@ -1,6 +1,6 @@
ifeq ($(platform),)
hiroflags = $(cppflags) $(flags) -DHIRO_REFERENCE
hirolink =
hiro.flags = $(flags.cpp) -DHIRO_REFERENCE
hiro.options =
endif
ifeq ($(platform),windows)
@ -9,18 +9,18 @@ ifeq ($(platform),windows)
endif
ifeq ($(hiro),windows)
hiroflags = $(cppflags) $(flags) -DHIRO_WINDOWS
hirolink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi
hiro.flags = $(flags.cpp) -DHIRO_WINDOWS
hiro.options = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi
endif
ifeq ($(hiro),gtk2)
hiroflags = $(cppflags) $(flags) -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.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0)
hiro.options = $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0)
endif
ifeq ($(hiro),gtk3)
hiroflags = $(cppflags) $(flags) -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.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0)
hiro.options = $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0)
endif
endif
@ -30,8 +30,8 @@ ifeq ($(platform),macos)
endif
ifeq ($(hiro),cocoa)
hiroflags = $(objcppflags) $(flags) -w -DHIRO_COCOA
hirolink = -framework Cocoa -framework Carbon -framework Security
hiro.flags = $(flags.objcpp) -w -DHIRO_COCOA
hiro.options = -framework Cocoa -framework Carbon -framework Security
endif
endif
@ -41,24 +41,38 @@ ifneq ($(filter $(platform),linux bsd),)
endif
ifeq ($(hiro),gtk2)
hiroflags = $(cppflags) $(flags) -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.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0)
hiro.options = -lX11 $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0)
endif
ifeq ($(hiro),gtk3)
hiroflags = $(cppflags) $(flags) -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.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0)
hiro.options = -lX11 $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0)
endif
ifeq ($(hiro),qt4)
moc = moc-qt4
hiroflags = $(cppflags) $(flags) -DHIRO_QT=4 $(shell pkg-config --cflags QtCore QtGui)
hirolink = -lX11 $(shell pkg-config --libs QtCore QtGui)
hiro.flags = $(flags.cpp) -DHIRO_QT=4 $(shell pkg-config --cflags QtCore QtGui)
hiro.options = -lX11 $(shell pkg-config --libs QtCore QtGui)
endif
ifeq ($(hiro),qt5)
moc = /usr/local/lib/qt5/bin/moc
hiroflags = -fPIC $(cppflags) $(flags) -DHIRO_QT=5 $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)
hirolink = -lX11 $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Widgets)
hiro.flags = $(flags.cpp) -DHIRO_QT=5 -fPIC $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)
hiro.options = -lX11 $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Widgets)
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::setParent(mObject* parent, int offset) -> void {
}
auto pObject::setVisible(bool visible) -> void {
}

View File

@ -2,7 +2,7 @@
namespace hiro {
struct pObject {
struct pObject : mLock {
pObject(mObject& reference) : reference(reference) {}
virtual ~pObject() {}
auto self() const -> mObject& { return (mObject&)reference; }
@ -16,14 +16,10 @@ struct pObject {
virtual auto setEnabled(bool enabled) -> void;
virtual auto setFocused() -> void;
virtual auto setFont(const Font& font) -> void;
virtual auto setParent(mObject* parent, int offset) -> 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;
signed locks = 0;
};
}

View File

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

View File

@ -38,7 +38,6 @@ namespace hiro {
#include "action/menu-radio-item.hpp"
#include "sizable.hpp"
#include "layout.hpp"
#include "widget/widget.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 {
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 {
@autoreleasepool {
[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 {
@ -56,8 +56,8 @@ auto pFrame::setGeometry(Geometry geometry) -> void {
geometry.x() - 3, geometry.y() - (empty ? size.height() - 2 : 1),
geometry.width() + 6, geometry.height() + (empty ? size.height() + 2 : 5)
});
if(auto layout = state().layout) {
layout->setGeometry({
if(auto& sizable = state().sizable) {
sizable->setGeometry({
geometry.x() + 1, geometry.y() + (empty ? 1 : size.height() - 2),
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 {
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&> {
if(auto layout = state().layout) {
if(auto self = layout->self()) return *self;
auto pFrame::_sizable() -> maybe<pSizable&> {
if(auto sizable = state().sizable) {
if(auto self = sizable->self()) return *self;
}
return nothing;
}

View File

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

View File

@ -8,10 +8,10 @@ auto pTabFrameItem::construct() -> 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 {

View File

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

View File

@ -213,12 +213,12 @@ auto pWindow::destruct() -> void {
}
}
auto pWindow::append(sLayout layout) -> void {
layout->setGeometry(self().geometry().setPosition(0, 0));
statusBarReposition();
auto pWindow::append(sMenuBar menuBar) -> void {
}
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 {
@ -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 {
[[cocoaWindow contentView] setNeedsDisplay:YES];
}
}
auto pWindow::remove(sMenuBar menuBar) -> void {
}
auto pWindow::remove(sStatusBar statusBar) -> void {
@autoreleasepool {
[[cocoaWindow statusBar] setHidden:YES];

View File

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

View File

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

View File

@ -59,7 +59,7 @@ auto mMenu::setIcon(const image& icon) -> 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);
for(auto& action : state.actions) action->setParent(this, action->offset());
return *this;

View File

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

View File

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

View File

@ -9,7 +9,7 @@ Gradient::operator bool() const {
auto Gradient::operator==(const Gradient& source) const -> bool {
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;
}
return true;

View File

@ -37,7 +37,7 @@ auto mGroup::objects() const -> vector<Object> {
auto mGroup::remove(sObject object) -> type& {
object->setGroup();
for(auto offset : range(state.objects)) {
for(auto offset : range(state.objects.size())) {
if(auto shared = state.objects[offset].acquire()) {
if(object == shared) {
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& {
for(auto n : rrange(state.menus)) state.menus[n]->destruct();
for(auto& menu : reverse(state.menus)) menu->destruct();
mObject::setParent(parent, offset);
for(auto& menu : state.menus) menu->setParent(this, menu->offset());
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 {
return parent() || !abstract();
}
@ -130,16 +130,6 @@ auto mObject::parentIconView(bool recursive) const -> mIconView* {
}
#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)
auto mObject::parentMenu(bool recursive) const -> mMenu* {
if(auto menu = dynamic_cast<mMenu*>(parent())) return menu;
@ -308,7 +298,8 @@ auto mObject::setGroup(sGroup group) -> type& {
return *this;
}
auto mObject::setParent(mObject* parent, signed offset) -> type& {
auto mObject::setParent(mObject* parent, int offset) -> type& {
signal(setParent, parent, offset);
destruct();
state.parent = parent;
state.offset = offset;

View File

@ -50,7 +50,7 @@ auto mPopupMenu::reset() -> 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);
for(auto& action : state.actions) action->construct();
return *this;

View File

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

View File

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

View File

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

View File

@ -143,7 +143,7 @@ auto mIconView::setOrientation(Orientation orientation) -> 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);
for(auto& item : state.items) item->setParent(this, item->offset());
return *this;

View File

@ -5,17 +5,17 @@ auto mTabFrameItem::allocate() -> pObject* {
}
auto mTabFrameItem::destruct() -> void {
if(auto& layout = state.layout) layout->destruct();
if(auto& sizable = state.sizable) sizable->destruct();
mObject::destruct();
}
//
auto mTabFrameItem::append(sLayout layout) -> type& {
if(auto& layout = state.layout) remove(layout);
state.layout = layout;
layout->setParent(this, 0);
signal(append, layout);
auto mTabFrameItem::append(sSizable sizable) -> type& {
if(auto& sizable = state.sizable) remove(sizable);
state.sizable = sizable;
sizable->setParent(this, 0);
signal(append, sizable);
return *this;
}
@ -27,10 +27,6 @@ auto mTabFrameItem::icon() const -> image {
return state.icon;
}
auto mTabFrameItem::layout() const -> Layout {
return state.layout;
}
auto mTabFrameItem::movable() const -> bool {
return state.movable;
}
@ -40,15 +36,15 @@ auto mTabFrameItem::remove() -> type& {
return *this;
}
auto mTabFrameItem::remove(sLayout layout) -> type& {
signal(remove, layout);
state.layout.reset();
layout->setParent();
auto mTabFrameItem::remove(sSizable sizable) -> type& {
signal(remove, sizable);
state.sizable.reset();
sizable->setParent();
return *this;
}
auto mTabFrameItem::reset() -> type& {
if(auto layout = state.layout) remove(layout);
if(auto& sizable = state.sizable) remove(sizable);
return *this;
}
@ -62,6 +58,18 @@ auto mTabFrameItem::setClosable(bool closable) -> type& {
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& {
state.icon = icon;
signal(setIcon, icon);
@ -74,10 +82,10 @@ auto mTabFrameItem::setMovable(bool movable) -> type& {
return *this;
}
auto mTabFrameItem::setParent(mObject* parent, signed offset) -> type& {
if(auto layout = state.layout) layout->destruct();
auto mTabFrameItem::setParent(mObject* parent, int offset) -> type& {
if(auto& sizable = state.sizable) sizable->destruct();
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;
}
@ -96,6 +104,16 @@ auto mTabFrameItem::setText(const string& text) -> type& {
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 {
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 {
if(position < itemCount()) return state.items[position];
return {};
return state.items(position, {});
}
auto mTabFrame::itemCount() const -> unsigned {
@ -88,17 +87,35 @@ auto mTabFrame::selected() const -> TabFrameItem {
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& {
state.navigation = navigation;
signal(setNavigation, navigation);
return *this;
}
auto mTabFrame::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct();
auto mTabFrame::setParent(mObject* parent, int offset) -> type& {
for(auto& item : reverse(state.items)) item->destruct();
mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset());
return *this;
}
auto mTabFrame::setVisible(bool visible) -> type& {
mWidget::setVisible(visible);
for(auto& item : state.items) item->setVisible(item->visible());
return *this;
}
#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 {
if(auto tableView = parentTableView()) return tableView->state.activeColumn == offset();
if(auto tableView = parentTableView(true)) return tableView->state.activeColumn == offset();
return false;
}
@ -40,7 +42,7 @@ auto mTableViewColumn::icon() const -> image {
}
auto mTableViewColumn::remove() -> type& {
if(auto tableView = parentTableViewHeader()) tableView->remove(*this);
if(auto tableViewHeader = parentTableViewHeader()) tableViewHeader->remove(*this);
return *this;
}
@ -49,7 +51,7 @@ auto mTableViewColumn::resizable() const -> bool {
}
auto mTableViewColumn::setActive() -> type& {
if(auto tableView = parentTableView()) tableView->state.activeColumn = offset();
if(auto tableView = parentTableView(true)) tableView->state.activeColumn = offset();
signal(setActive);
return *this;
}

View File

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

View File

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

View File

@ -146,7 +146,7 @@ auto mTableView::remove(sTableViewItem item) -> 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);
return *this;
}
@ -194,7 +194,7 @@ auto mTableView::setForegroundColor(Color color) -> 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();
mObject::setParent(parent, offset);
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& {
for(auto n : rrange(state.items)) state.items[n]->destruct();
for(auto& item : reverse(state.items)) item->destruct();
mObject::setParent(parent, 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& {
state.selectedPath.reset();
for(auto n : rrange(state.items)) remove(state.items[n]);
while(state.items) remove(state.items.right());
return *this;
}
@ -114,7 +114,7 @@ auto mTreeView::setForegroundColor(Color color) -> 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);
for(auto& item : state.items) item->setParent(this, item->offset());
return *this;

View File

@ -16,7 +16,8 @@ auto mWidget::onSize(const function<void ()>& callback) -> 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();
return *this;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,23 +1,61 @@
#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 mLayout::append;
using mLayout::remove;
using mSizable::remove;
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 remove(sSizable sizable) -> type& override;
auto remove(sFixedLayoutCell cell) -> type&;
auto reset() -> type& override;
auto setEnabled(bool enabled = true) -> type& override;
auto setFont(const Font& font = {}) -> type& override;
auto setVisible(bool visible = true) ->type& override;
auto setEnabled(bool enabled) -> type& override;
auto setFont(const Font& font) -> 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;
};
vector<Property> properties;
sSizable sizable;
} state;
friend class mFixedLayout;
};
#endif

View File

@ -1,149 +1,280 @@
#if defined(Hiro_HorizontalLayout)
auto mHorizontalLayout::append(sSizable sizable, Size size, float spacing) -> type& {
properties.append({size.width(), size.height(), spacing < 0 ? settings.spacing : spacing});
mLayout::append(sizable);
return *this;
auto mHorizontalLayout::alignment() const -> maybe<float> {
return state.alignment;
}
auto mHorizontalLayout::modify(sSizable sizable, Size size, float spacing) -> type& {
if(sizable && this->sizable(sizable->offset()) == sizable) {
auto& properties = this->properties[sizable->offset()];
properties.setWidth(size.width());
properties.setHeight(size.height());
properties.setSpacing(spacing);
auto mHorizontalLayout::append(sSizable sizable, Size size, float spacing) -> type& {
HorizontalLayoutCell cell;
cell->setSizable(sizable);
cell->setSize(size);
cell->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 {
float width = 0, height = 0;
for(auto n : range(sizableCount())) {
auto& child = properties[sizable(n)->offset()];
if(child.width() == Size::Minimum || child.width() == Size::Maximum) {
width += sizable(n)->minimumSize().width();
float width = 0;
for(auto index : range(cellCount())) {
auto cell = this->cell(index);
if(cell.size().width() == Size::Minimum || cell.size().width() == Size::Maximum) {
width += cell.sizable().minimumSize().width();
} 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())) {
auto& child = properties[sizable(n)->offset()];
if(child.height() == Size::Minimum || child.height() == Size::Maximum) {
height = max(height, sizable(n)->minimumSize().height());
float height = 0;
for(auto index : range(cellCount())) {
auto cell = this->cell(index);
if(cell.size().height() == Size::Minimum || cell.size().height() == Size::Maximum) {
height = max(height, cell.sizable().minimumSize().height());
continue;
}
height = max(height, child.height());
height = max(height, cell.size().height());
}
return {
settings.padding.x() + width + settings.padding.width(),
settings.padding.y() + height + settings.padding.height()
padding().x() + width + padding().width(),
padding().y() + height + padding().height()
};
}
auto mHorizontalLayout::remove(sSizable sizable) -> type& {
properties.remove(sizable->offset());
mLayout::remove(sizable);
return *this;
auto mHorizontalLayout::padding() const -> Geometry {
return state.padding;
}
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& {
mLayout::reset();
properties.reset();
return *this;
while(state.cells) remove(state.cells.right());
return synchronize();
}
auto mHorizontalLayout::setAlignment(float alignment) -> type& {
settings.alignment = max(0.0, min(1.0, alignment));
return *this;
auto mHorizontalLayout::setAlignment(maybe<float> alignment) -> type& {
state.alignment = alignment;
return synchronize();
}
auto mHorizontalLayout::setEnabled(bool enabled) -> type& {
mLayout::setEnabled(enabled);
for(auto n : range(sizableCount())) {
sizable(n)->setEnabled(sizable(n)->enabled());
}
mSizable::setEnabled(enabled);
for(auto& cell : state.cells) cell.sizable().setEnabled(cell.sizable().enabled());
return *this;
}
auto mHorizontalLayout::setFont(const Font& font) -> type& {
mLayout::setFont(font);
for(auto n : range(sizableCount())) {
sizable(n)->setFont(sizable(n)->font());
}
mSizable::setFont(font);
for(auto& cell : state.cells) cell.sizable().setFont(cell.sizable().font());
return *this;
}
auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& {
mLayout::setGeometry(containerGeometry);
auto mHorizontalLayout::setGeometry(Geometry geometry) -> type& {
mSizable::setGeometry(geometry);
auto window = parentWindow(true);
if(!window || !window->visible()) return *this;
auto properties = this->properties;
for(auto n : range(sizableCount())) {
auto& child = properties[sizable(n)->offset()];
if(child.width() == Size::Minimum) child.setWidth(sizable(n)->minimumSize().width());
if(child.height() == Size::Minimum) child.setHeight(sizable(n)->minimumSize().height());
geometry.setX(geometry.x() + padding().x());
geometry.setY(geometry.y() + padding().y());
geometry.setWidth (geometry.width() - padding().x() - padding().width());
geometry.setHeight(geometry.height() - padding().y() - padding().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;
geometry.setX (geometry.x() + settings.padding.x());
geometry.setY (geometry.y() + settings.padding.y());
geometry.setWidth (geometry.width() - settings.padding.x() - settings.padding.width());
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();
float fixedWidth = 0;
for(uint index : range(state.cells.size())) {
if(widths[index] != Size::Maximum) fixedWidth += widths[index];
if(index != cellCount() - 1) fixedWidth += cell(index).spacing();
}
for(auto& child : properties) {
if(child.width() == Size::Maximum) child.setWidth((geometry.width() - minimumWidth) / maximumWidthCounter);
if(child.height() == Size::Maximum) child.setHeight(geometry.height());
float maximumWidth = (geometry.width() - fixedWidth) / maximumWidths;
for(auto& width : widths) {
if(width == Size::Maximum) width = maximumWidth;
}
float maximumHeight = 0;
for(auto& child : properties) maximumHeight = max(maximumHeight, child.height());
for(auto n : range(sizableCount())) {
auto& child = properties[sizable(n)->offset()];
float pivot = (maximumHeight - child.height()) * settings.alignment;
Geometry childGeometry = {geometry.x(), geometry.y() + pivot, child.width(), child.height()};
if(childGeometry.width() < 1) childGeometry.setWidth (1);
if(childGeometry.height() < 1) childGeometry.setHeight(1);
sizable(n)->setGeometry(childGeometry);
geometry.setX (geometry.x() + child.width() + child.spacing());
geometry.setWidth(geometry.width() - child.width() + child.spacing());
float height = 0;
for(auto index : range(cellCount())) {
auto cell = this->cell(index);
if(cell.size().height() == Size::Maximum) {
height = geometry.height();
break;
} else if(cell.size().height() == Size::Minimum) {
height = max(height, cell.sizable().minimumSize().height());
} else {
height = max(height, cell.size().height());
}
}
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;
}
auto mHorizontalLayout::setPadding(Geometry padding) -> type& {
settings.padding = padding;
setGeometry(geometry());
state.padding = padding;
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;
}
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());
return *this;
}
auto mHorizontalLayout::setVisible(bool visible) -> type& {
mLayout::setVisible(visible);
for(auto n : range(sizableCount())) {
sizable(n)->setVisible(sizable(n)->visible());
//
auto mHorizontalLayoutCell::alignment() const -> maybe<float> {
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;
}

View File

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

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

View File

@ -52,10 +52,10 @@ auto MessageDialog::_run() -> string {
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
Widget controlSpacer{&controlLayout, Size{~0, 0}};
layout.setMargin(5);
layout.setPadding(5);
messageIcon.setIcon(state.icon);
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.onActivate([&, n] { state.response = state.buttons[n]; window.setModal(false); });
button.setText(state.buttons[n]);

View File

@ -1,41 +1,142 @@
#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 {
DeclareSharedLayout(FixedLayout)
DeclareSharedSizable(FixedLayout)
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
#if defined(Hiro_HorizontalLayout)
using sHorizontalLayout = shared_pointer<mHorizontalLayout>;
struct HorizontalLayout : sHorizontalLayout {
DeclareSharedLayout(HorizontalLayout)
struct HorizontalLayoutCell : sHorizontalLayoutCell {
DeclareSharedObject(HorizontalLayoutCell)
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 modify(sSizable sizable, Size size, float spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(float alignment = 0.5) { return self().setAlignment(alignment), *this; }
auto setMargin(float margin = 0) { return self().setMargin(margin), *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(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 setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
};
#endif
#if defined(Hiro_VerticalLayout)
using sVerticalLayout = shared_pointer<mVerticalLayout>;
struct VerticalLayout : sVerticalLayout {
DeclareSharedLayout(VerticalLayout)
struct VerticalLayoutCell : sVerticalLayoutCell {
DeclareSharedObject(VerticalLayoutCell)
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 modify(sSizable sizable, Size size, float spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(float alignment = 0.0) { return self().setAlignment(alignment), *this; }
auto setMargin(float margin = 0) { return self().setMargin(margin), *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(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 setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
};
#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)
struct ListViewItem : sListViewItem {
DeclareSharedObject(ListViewItem)
@ -56,9 +157,7 @@ struct ListViewItem : sListViewItem {
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
};
#endif
#if defined(Hiro_ListView)
struct ListView : sListView {
DeclareSharedWidget(ListView)

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