Update to v094r43 release.

byuu says:

Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)

Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.

Also enhanced the command-line game loading. You can now use any of
these methods:

    higan /path/to/game-folder.sfc
    higan /path/to/game-folder.sfc/
    higan /path/to/game-folder.sfc/program.rom

The idea is to support launchers that insist on loading files only.

Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.

Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.

Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
This commit is contained in:
Tim Allen 2015-08-30 12:08:26 +10:00
parent c45633550e
commit 0c87bdabed
230 changed files with 1939 additions and 1408 deletions

View File

@ -8,7 +8,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "094.42";
static const string Version = "094.43";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";

View File

@ -9,15 +9,17 @@
* As such, this file is really only meant for disabling individual widgets or menu items.
*/
#define Hiro_Application
#define Hiro_Color
#define Hiro_Gradient
#define Hiro_Alignment
#define Hiro_Cursor
#define Hiro_Position
#define Hiro_Size
#define Hiro_Geometry
#define Hiro_Font
#define Hiro_Image
#define Hiro_Application
#define Hiro_Desktop
#define Hiro_Monitor
#define Hiro_Keyboard
@ -63,7 +65,7 @@
#define Hiro_ProgressBar
#define Hiro_RadioButton
#define Hiro_RadioLabel
#define Hiro_SourceView
#define Hiro_SourceEdit
#define Hiro_TabFrame
#define Hiro_TextEdit
#define Hiro_TreeView
@ -86,6 +88,6 @@
#if defined(HIRO_WINDOWS) || defined(HIRO_QT)
#undef Hiro_Console
#undef Hiro_IconView
#undef Hiro_SourceView
#undef Hiro_SourceEdit
#undef Hiro_TreeView
#endif

View File

@ -10,8 +10,8 @@ auto mMenuItem::doActivate() const -> void {
if(state.onActivate) return state.onActivate();
}
auto mMenuItem::icon() const -> image {
return state.icon;
auto mMenuItem::image() const -> Image {
return state.image;
}
auto mMenuItem::onActivate(const function<void ()>& callback) -> type& {
@ -19,9 +19,9 @@ auto mMenuItem::onActivate(const function<void ()>& callback) -> type& {
return *this;
}
auto mMenuItem::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mMenuItem::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -39,9 +39,8 @@ auto mMenuRadioItem::setChecked() -> type& {
}
auto mMenuRadioItem::setGroup(sGroup group) -> type& {
state.group = group;
state.group = group ? group : Group{&instance};
signal(setGroup, group);
if(group && group->objectCount() == 1) setChecked();
return *this;
}

View File

@ -33,8 +33,8 @@ auto mMenu::append(sAction action) -> type& {
return *this;
}
auto mMenu::icon() const -> image {
return state.icon;
auto mMenu::image() const -> Image {
return state.image;
}
auto mMenu::remove(sAction action) -> type& {
@ -51,9 +51,16 @@ auto mMenu::reset() -> type& {
return *this;
}
auto mMenu::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mMenu::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}
auto mMenu::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.actions)) state.actions[n]->destruct();
mObject::setParent(parent, offset);
for(auto& action : state.actions) action->setParent(this, action->offset());
return *this;
}

View File

@ -17,6 +17,10 @@ auto Alignment::horizontal() const -> double {
return state.horizontal;
}
auto Alignment::reset() -> type& {
return setAlignment(-1.0, -1.0);
}
auto Alignment::setAlignment(double horizontal, double vertical) -> type& {
state.horizontal = horizontal;
state.vertical = vertical;

View File

@ -6,7 +6,7 @@ auto Application::doMain() -> void {
if(state.onMain) return state.onMain();
}
auto Application::font() -> string {
auto Application::font() -> Font {
return state.font;
}
@ -35,7 +35,7 @@ auto Application::quit() -> void {
return pApplication::quit();
}
auto Application::setFont(const string& font) -> void {
auto Application::setFont(const Font& font) -> void {
state.font = font;
}

View File

@ -9,7 +9,7 @@ Color::Color(signed red, signed green, signed blue, signed alpha) {
}
Color::operator bool() const {
return !empty();
return state.red || state.green || state.blue || state.alpha;
}
auto Color::operator==(const Color& source) const -> bool {
@ -28,10 +28,6 @@ auto Color::blue() const -> uint8_t {
return state.blue;
}
auto Color::empty() const -> bool {
return state.red == 0 && state.green == 0 && state.blue == 0 && state.alpha == 0;
}
auto Color::green() const -> uint8_t {
return state.green;
}
@ -40,6 +36,10 @@ auto Color::red() const -> uint8_t {
return state.red;
}
auto Color::reset() -> type& {
return setColor(0, 0, 0, 0);
}
auto Color::setAlpha(signed alpha) -> type& {
state.alpha = max(0, min(255, alpha));
return *this;
@ -73,7 +73,7 @@ auto Color::setRed(signed red) -> type& {
}
auto Color::value() const -> uint32_t {
return (state.alpha << 24) + (state.red << 16) + (state.green << 8) + (state.blue << 0);
return state.alpha << 24 | state.red << 16 | state.green << 8 | state.blue << 0;
}
#endif

View File

@ -31,13 +31,17 @@ using namespace nall;
(delegate ? self()->function(__VA_ARGS__) : decltype(self()->function(__VA_ARGS__))())
namespace hiro {
#include "application.cpp"
#include "color.cpp"
#include "gradient.cpp"
#include "alignment.cpp"
#include "cursor.cpp"
#include "position.cpp"
#include "size.cpp"
#include "geometry.cpp"
#include "font.cpp"
#include "image.cpp"
#include "application.cpp"
#include "desktop.cpp"
#include "monitor.cpp"
#include "keyboard.cpp"

View File

@ -13,7 +13,6 @@
#include <nall/vector.hpp>
using nall::function;
using nall::image;
using nall::lstring;
using nall::maybe;
using nall::shared_pointer;
@ -23,6 +22,9 @@ using nall::vector;
namespace hiro {
struct Font;
struct Keyboard;
#define Declare(Name) \
struct Name; \
struct m##Name; \
@ -30,11 +32,9 @@ namespace hiro {
using s##Name = shared_pointer<m##Name>; \
using w##Name = shared_pointer_weak<m##Name>; \
Declare(Keyboard)
Declare(Object)
Declare(Group)
Declare(Timer)
Declare(Hotkey)
Declare(Window)
Declare(StatusBar)
Declare(MenuBar)
@ -83,64 +83,8 @@ Declare(Viewport)
#undef Declare
enum class Edge : unsigned { Top, Bottom, Left, Right };
enum class Orientation : unsigned { Horizontal, Vertical };
enum class Placement : unsigned { Top, Bottom, Left, Right };
#if defined(Hiro_Application)
struct Application {
Application() = delete;
static auto doMain() -> void;
static auto font() -> string;
static auto name() -> string;
static auto onMain(const function<void ()>& callback = {}) -> void;
static auto run() -> void;
static auto pendingEvents() -> bool;
static auto processEvents() -> void;
static auto quit() -> void;
static auto setFont(const string& font = "") -> void;
static auto setName(const string& name = "") -> void;
struct Windows {
static auto doModalChange(bool modal) -> void;
static auto onModalChange(const function<void (bool)>& callback = {}) -> void;
};
struct Cocoa {
static auto doAbout() -> void;
static auto doActivate() -> void;
static auto doPreferences() -> void;
static auto doQuit() -> void;
static auto onAbout(const function<void ()>& callback = {}) -> void;
static auto onActivate(const function<void ()>& callback = {}) -> void;
static auto onPreferences(const function<void ()>& callback = {}) -> void;
static auto onQuit(const function<void ()>& callback = {}) -> void;
};
//private:
struct State {
string font;
string name;
function<void ()> onMain;
bool quit = false;
struct Windows {
function<void (bool)> onModalChange;
} windows;
struct Cocoa {
function<void ()> onAbout;
function<void ()> onActivate;
function<void ()> onPreferences;
function<void ()> onQuit;
} cocoa;
};
static State state;
static auto initialize() -> void;
};
#endif
enum class Navigation : unsigned { Top, Bottom, Left, Right };
#if defined(Hiro_Color)
struct Color {
@ -155,9 +99,9 @@ struct Color {
auto alpha() const -> uint8_t;
auto blue() const -> uint8_t;
auto empty() const -> bool;
auto green() const -> uint8_t;
auto red() const -> uint8_t;
auto reset() -> type&;
auto setAlpha(signed alpha) -> type&;
auto setBlue(signed blue) -> type&;
auto setColor(Color color = {}) -> type&;
@ -168,10 +112,31 @@ struct Color {
//private:
struct State {
signed red;
signed green;
signed blue;
signed alpha;
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha;
} state;
};
#endif
#if defined(Hiro_Gradient)
struct Gradient {
using type = Gradient;
Gradient();
explicit operator bool() const;
auto operator==(const Gradient& source) const -> bool;
auto operator!=(const Gradient& source) const -> bool;
auto setBilinear(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> type&;
auto setHorizontal(Color left, Color right) -> type&;
auto setVertical(Color top, Color bottom) -> type&;
//private:
struct State {
vector<Color> colors;
} state;
};
#endif
@ -188,6 +153,7 @@ struct Alignment {
auto operator!=(const Alignment& source) const -> bool;
auto horizontal() const -> double;
auto reset() -> type&;
auto setAlignment(double horizontal = -1.0, double vertical = 0.5) -> type&;
auto setHorizontal(double horizontal) -> type&;
auto setVertical(double vertical) -> type&;
@ -195,8 +161,32 @@ struct Alignment {
//private:
struct State {
double horizontal;
double vertical;
float horizontal;
float vertical;
} state;
};
#endif
#if defined(Hiro_Cursor)
struct Cursor {
using type = Cursor;
Cursor(signed offset = 0, signed 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&;
//private:
struct State {
signed offset;
signed length;
} state;
};
#endif
@ -208,9 +198,11 @@ struct Position {
Position();
Position(signed x, signed y);
explicit operator bool() const;
auto operator==(const Position& source) const -> bool;
auto operator!=(const Position& source) const -> bool;
auto reset() -> type&;
auto setPosition(Position position = {}) -> type&;
auto setPosition(signed x, signed y) -> type&;
auto setX(signed x) -> type&;
@ -233,10 +225,12 @@ struct Size {
Size();
Size(signed width, signed height);
explicit operator bool() const;
auto operator==(const Size& source) const -> bool;
auto operator!=(const Size& source) const -> bool;
auto height() const -> signed;
auto reset() -> type&;
auto setHeight(signed height) -> type&;
auto setSize(Size source = {}) -> type&;
auto setSize(signed width, signed height) -> type&;
@ -263,11 +257,13 @@ struct Geometry {
Geometry(signed x, signed y, signed width, signed height);
Geometry(const string& text);
explicit operator bool() const;
auto operator==(const Geometry& source) const -> bool;
auto operator!=(const Geometry& source) const -> bool;
auto height() const -> signed;
auto position() const -> Position;
auto reset() -> type&;
auto setGeometry(Geometry geometry = {}) -> type&;
auto setGeometry(Position position, Size size) -> type&;
auto setGeometry(signed x, signed y, signed width, signed height) -> type&;
@ -299,8 +295,7 @@ struct Geometry {
struct Font {
using type = Font;
Font();
Font(const string& family, unsigned size = 0);
Font(const string& family = "", unsigned size = 0);
explicit operator bool() const;
auto operator==(const Font& source) const -> bool;
@ -309,27 +304,143 @@ struct Font {
auto bold() const -> bool;
auto family() const -> string;
auto italic() const -> bool;
auto reset() -> type&;
auto setBold(bool bold = true) -> type&;
auto setFamily(const string& family = "") -> type&;
auto setItalic(bool italic = true) -> type&;
auto setSize(unsigned size = 0) -> type&;
auto size() const -> unsigned;
auto size(const string& text) const -> Size;
static auto serif(unsigned size = 0, const string& style = "") -> string;
static auto sans(unsigned size = 0, const string& style = "") -> string;
static auto monospace(unsigned size = 0, const string& style = "") -> string;
static auto size(const string& font, const string& text = " ") -> Size;
static const string Sans;
static const string Serif;
static const string Mono;
//private:
struct State {
string family;
unsigned size = 0;
bool bold = false;
bool italic = false;
unsigned size;
bool bold;
bool italic;
} state;
};
#endif
#if defined(Hiro_Image)
struct Image {
using type = Image;
Image();
Image(const Image& source);
Image(const string& source);
Image(const vector<uint8_t>& source);
Image(const uint32_t* data, Size size);
~Image();
explicit operator bool() const;
auto operator=(const Image& source) -> type&;
auto data() const -> uint32_t*;
auto height() const -> signed;
auto reset() -> type&;
auto setImage(const uint32_t* data, Size size) -> type&;
auto setSize(Size size = {}) -> type&;
auto size() const -> Size;
auto width() const -> signed;
//private:
struct State {
uint32_t* data = nullptr;
Size size;
} state;
};
#endif
#if defined(Hiro_Hotkey)
struct Hotkey {
using type = Hotkey;
Hotkey();
Hotkey(const string& sequence);
explicit operator bool() const;
auto operator==(const Hotkey& source) const -> bool;
auto operator!=(const Hotkey& source) const -> bool;
auto doPress() const -> void;
auto doRelease() const -> void;
auto onPress(const function<void ()>& callback = {}) -> type&;
auto onRelease(const function<void ()>& callback = {}) -> type&;
auto reset() -> type&;
auto sequence() const -> string;
auto setSequence(const string& sequence = "") -> type&;
//private:
struct State {
bool active = false;
vector<unsigned> keys;
function<void ()> onPress;
function<void ()> onRelease;
string sequence;
};
shared_pointer<State> state;
};
#endif
#if defined(Hiro_Application)
struct Application {
Application() = delete;
static auto doMain() -> void;
static auto font() -> Font;
static auto name() -> string;
static auto onMain(const function<void ()>& callback = {}) -> void;
static auto run() -> void;
static auto pendingEvents() -> bool;
static auto processEvents() -> void;
static auto quit() -> void;
static auto setFont(const Font& font = {}) -> void;
static auto setName(const string& name = "") -> void;
struct Windows {
static auto doModalChange(bool modal) -> void;
static auto onModalChange(const function<void (bool)>& callback = {}) -> void;
};
struct Cocoa {
static auto doAbout() -> void;
static auto doActivate() -> void;
static auto doPreferences() -> void;
static auto doQuit() -> void;
static auto onAbout(const function<void ()>& callback = {}) -> void;
static auto onActivate(const function<void ()>& callback = {}) -> void;
static auto onPreferences(const function<void ()>& callback = {}) -> void;
static auto onQuit(const function<void ()>& callback = {}) -> void;
};
//private:
struct State {
Font font;
string name;
function<void ()> onMain;
bool quit = false;
struct Windows {
function<void (bool)> onModalChange;
} windows;
struct Cocoa {
function<void ()> onAbout;
function<void ()> onActivate;
function<void ()> onPreferences;
function<void ()> onQuit;
} cocoa;
};
static State state;
static auto initialize() -> void;
};
#endif
#if defined(Hiro_Desktop)
struct Desktop {
Desktop() = delete;
@ -353,19 +464,20 @@ struct Monitor {
struct Keyboard {
Keyboard() = delete;
static auto append(sHotkey hotkey) -> void;
static auto append(Hotkey hotkey) -> void;
static auto hotkey(unsigned position) -> Hotkey;
static auto hotkeys() -> unsigned;
static auto hotkeyCount() -> unsigned;
static auto hotkeys() -> vector<Hotkey>;
static auto poll() -> vector<bool>;
static auto pressed(const string& key) -> bool;
static auto released(const string& key) -> bool;
static auto remove(sHotkey hotkey) -> void;
static auto remove(Hotkey hotkey) -> void;
static const vector<string> keys;
//private:
struct State {
vector<sHotkey> hotkeys;
vector<Hotkey> hotkeys;
};
static State state;
};
@ -439,6 +551,7 @@ struct MessageWindow {
auto self() const -> const p##Name* { return (const p##Name*)delegate; } \
auto bind(const s##Name& instance) -> void { \
this->instance = instance; \
setGroup(); \
if(!abstract()) construct(); \
} \
auto unbind() -> void { \
@ -463,7 +576,7 @@ struct mObject {
auto adjustOffset(signed displacement) -> type&;
auto enabled(bool recursive = false) const -> bool;
virtual auto focused() const -> bool;
auto font(bool recursive = false) const -> string;
auto font(bool recursive = false) const -> Font;
virtual auto group() const -> Group;
auto offset() const -> signed;
auto parent() const -> mObject*;
@ -488,7 +601,7 @@ struct mObject {
virtual auto reset() -> type&;
virtual auto setEnabled(bool enabled = true) -> type&;
virtual auto setFocused() -> type&;
virtual auto setFont(const string& font = "") -> 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 setVisible(bool visible = true) -> type&;
@ -497,7 +610,7 @@ struct mObject {
//private:
struct State {
bool enabled = true;
string font;
Font font;
signed offset = -1;
mObject* parent = nullptr;
bool visible = true;
@ -529,32 +642,6 @@ struct mGroup : mObject {
};
#endif
#if defined(Hiro_Hotkey)
struct mHotkey : mObject {
Declare(Hotkey)
auto doPress() const -> void;
auto doRelease() const -> void;
auto onPress(const function<void ()>& callback = {}) -> type&;
auto onRelease(const function<void ()>& callback = {}) -> type&;
auto owner() const -> wObject;
auto remove() -> type& override;
auto sequence() const -> string;
auto setOwner(sObject owner) -> type&;
auto setSequence(const string& sequence = "") -> type&;
//private:
struct State {
bool active = false;
vector<unsigned> keys;
function<void ()> onPress;
function<void ()> onRelease;
wObject owner;
string sequence;
} state;
};
#endif
#if defined(Hiro_Timer)
struct mTimer : mObject {
Declare(Timer)
@ -672,7 +759,7 @@ struct mMenuBar : mObject {
auto remove() -> type& override;
auto remove(sMenu menu) -> type&;
auto reset() -> type&;
//TODO setParent
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override;
//private:
struct State {
@ -727,18 +814,18 @@ struct mMenu : mAction {
auto actionCount() const -> unsigned;
auto actions() const -> vector<Action>;
auto append(sAction action) -> type&;
auto icon() const -> image;
auto image() const -> Image;
auto remove(sAction action) -> type&;
auto reset() -> type&;
auto setIcon(const image& icon = {}) -> type&;
//TODO setParent
auto setImage(const Image& image = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
vector<sAction> actions;
image icon;
Image image;
string text;
} state;
@ -761,15 +848,15 @@ struct mMenuItem : mAction {
Declare(MenuItem)
auto doActivate() const -> void;
auto icon() const -> image;
auto image() const -> Image;
auto onActivate(const function<void ()>& callback = {}) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
image icon;
Image image;
function<void ()> onActivate;
string text;
} state;
@ -877,11 +964,11 @@ struct mButton : mWidget {
auto bordered() const -> bool;
auto doActivate() const -> void;
auto icon() const -> image;
auto image() const -> Image;
auto onActivate(const function<void ()>& callback = {}) -> type&;
auto orientation() const -> Orientation;
auto setBordered(bool bordered = true) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setOrientation(Orientation orientation = Orientation::Horizontal) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
@ -889,7 +976,7 @@ struct mButton : mWidget {
//private:
struct State {
bool bordered = true;
image icon;
Image image;
function<void ()> onActivate;
Orientation orientation = Orientation::Horizontal;
string text;
@ -909,36 +996,32 @@ struct mCanvas : mWidget {
auto doMouseMove(Position position) const -> void;
auto doMousePress(Mouse::Button button) const -> void;
auto doMouseRelease(Mouse::Button button) const -> void;
auto gradient() const -> vector<Color>;
auto icon() const -> image;
auto gradient() const -> Gradient;
auto image() const -> Image;
auto onDrop(const function<void (lstring)>& callback = {}) -> type&;
auto onMouseLeave(const function<void ()>& callback = {}) -> type&;
auto onMouseMove(const function<void (Position)>& callback = {}) -> type&;
auto onMousePress(const function<void (Mouse::Button)>& callback = {}) -> type&;
auto onMouseRelease(const function<void (Mouse::Button)>& callback = {}) -> type&;
auto setColor(Color color) -> type&;
auto setData(Size size) -> type&;
auto setColor(Color color = {}) -> type&;
auto setDroppable(bool droppable = true) -> type&;
auto setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> type&;
auto setHorizontalGradient(Color left, Color right) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setVerticalGradient(Color top, Color bottom) -> type&;
auto setGradient(Gradient gradient = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setSize(Size size = {}) -> type&;
auto size() const -> Size;
auto update() -> type&;
//private:
struct State {
Color color;
vector<uint32_t> data;
bool droppable = false;
vector<Color> gradient = {{}, {}, {}, {}};
image icon;
Gradient gradient;
Image image;
function<void (lstring)> onDrop;
function<void ()> onMouseLeave;
function<void (Position)> onMouseMove;
function<void (Mouse::Button)> onMousePress;
function<void (Mouse::Button)> onMouseRelease;
Size size;
} state;
};
#endif
@ -950,12 +1033,12 @@ struct mCheckButton : mWidget {
auto bordered() const -> bool;
auto checked() const -> bool;
auto doToggle() const -> void;
auto icon() const -> image;
auto image() const -> Image;
auto onToggle(const function<void ()>& callback = {}) -> type&;
auto orientation() const -> Orientation;
auto setBordered(bool bordered = true) -> type&;
auto setChecked(bool checked = true) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setOrientation(Orientation orientation = Orientation::Horizontal) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
@ -964,7 +1047,7 @@ struct mCheckButton : mWidget {
struct State {
bool bordered = true;
bool checked = false;
image icon;
Image image;
function<void ()> onToggle;
Orientation orientation = Orientation::Horizontal;
string text;
@ -1022,17 +1105,17 @@ struct mComboButton : mWidget {
struct mComboButtonItem : mObject {
Declare(ComboButtonItem)
auto icon() const -> image;
auto image() const -> Image;
auto remove() -> type& override;
auto selected() const -> bool;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setSelected() -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
image icon;
Image image;
bool selected = false;
string text;
} state;
@ -1073,7 +1156,7 @@ struct mFrame : mWidget {
auto layout() const -> Layout;
auto remove(sLayout layout) -> type&;
auto reset() -> type&;
//TODO setParent()
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
@ -1170,6 +1253,8 @@ struct mIconView : mWidget {
auto append(sIconViewItem item) -> type&;
auto backgroundColor() const -> Color;
auto batchable() const -> bool;
auto batched() const -> vector<IconViewItem>;
auto doActivate() const -> void;
auto doChange() const -> void;
auto doContext() const -> void;
@ -1178,30 +1263,28 @@ struct mIconView : mWidget {
auto item(unsigned position) const -> IconViewItem;
auto itemCount() const -> unsigned;
auto items() const -> vector<IconViewItem>;
auto multiSelect() const -> bool;
auto onActivate(const function<void ()>& callback = {}) -> type&;
auto onChange(const function<void ()>& callback = {}) -> type&;
auto onContext(const function<void ()>& callback = {}) -> type&;
auto orientation() const -> Orientation;
auto remove(sIconViewItem item) -> type&;
auto reset() -> type&;
auto selected() const -> maybe<unsigned>;
auto selectedItems() const -> vector<unsigned>;
auto selected() const -> IconViewItem;
auto setBackgroundColor(Color color = {}) -> type&;
auto setBatchable(bool batchable = true) -> type&;
auto setFlow(Orientation flow = Orientation::Vertical) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
auto setMultiSelect(bool multipleSelections = true) -> type&;
auto setOrientation(Orientation orientation = Orientation::Horizontal) -> type&;
//TODO setParent()
auto setParent(mObject* object = nullptr, signed offset = -1) -> type& override;
auto setSelected(const vector<signed>& selections) -> type&;
//private:
struct State {
Color backgroundColor;
bool batchable = false;
Color foregroundColor;
Orientation flow = Orientation::Vertical;
vector<sIconViewItem> items;
bool multiSelect = false;
function<void ()> onActivate;
function<void ()> onChange;
function<void ()> onContext;
@ -1216,17 +1299,17 @@ struct mIconView : mWidget {
struct mIconViewItem : mObject {
Declare(IconViewItem)
auto icon() const -> image;
auto image() const -> Image;
auto remove() -> type& override;
auto selected() const -> bool;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setSelected(bool selected = true) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
image icon;
Image image;
bool selected = false;
string text;
} state;
@ -1318,7 +1401,6 @@ struct mListView : mWidget {
auto setBatchable(bool batchable = true) -> type&;
auto setBordered(bool bordered = true) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
auto setGridVisible(bool visible = true) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type& override;
//private:
@ -1373,7 +1455,7 @@ struct mListViewColumn : mObject {
auto expandable() const -> bool;
auto foregroundColor() const -> Color;
auto horizontalAlignment() const -> double;
auto icon() const -> image;
auto image() const -> Image;
auto remove() -> type& override;
auto resizable() const -> bool;
auto setActive() -> type&;
@ -1383,7 +1465,7 @@ struct mListViewColumn : mObject {
auto setExpandable(bool expandable = true) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
auto setHorizontalAlignment(double alignment = 0.0) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setResizable(bool resizable = true) -> type&;
auto setSortable(bool sortable = true) -> type&;
auto setText(const string& text = "") -> type&;
@ -1403,7 +1485,7 @@ struct mListViewColumn : mObject {
bool expandable = false;
Color foregroundColor;
double horizontalAlignment = 0.0;
image icon;
Image image;
bool resizable = true;
bool sortable = false;
string text;
@ -1454,15 +1536,15 @@ struct mListViewCell : mObject {
auto backgroundColor(bool recursive = false) const -> Color;
auto checkable() const -> bool;
auto checked() const -> bool;
auto font(bool recursive = false) const -> string;
auto font(bool recursive = false) const -> Font;
auto foregroundColor(bool recursive = false) const -> Color;
auto icon() const -> image;
auto image() const -> Image;
auto setAlignment(Alignment alignment = {}) -> type&;
auto setBackgroundColor(Color color = {}) -> type&;
auto setCheckable(bool checkable = true) -> type&;
auto setChecked(bool checked = true) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
@ -1473,7 +1555,7 @@ struct mListViewCell : mObject {
bool checkable = false;
bool checked = false;
Color foregroundColor;
image icon;
Image image;
string text;
} state;
};
@ -1501,13 +1583,13 @@ struct mRadioButton : mWidget {
auto checked() const -> bool;
auto doActivate() const -> void;
auto group() const -> Group override;
auto icon() const -> image;
auto image() const -> Image;
auto onActivate(const function<void ()>& callback = {}) -> type&;
auto orientation() const -> Orientation;
auto setBordered(bool bordered = true) -> type&;
auto setChecked() -> type&;
auto setGroup(sGroup group = {}) -> type& override;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setOrientation(Orientation orientation = Orientation::Horizontal) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
@ -1517,7 +1599,7 @@ struct mRadioButton : mWidget {
bool bordered = true;
bool checked = false;
sGroup group;
image icon;
Image image;
function<void ()> onActivate;
Orientation orientation = Orientation::Horizontal;
string text;
@ -1552,22 +1634,20 @@ struct mRadioLabel : mWidget {
struct mSourceEdit : mWidget {
Declare(SourceEdit)
auto cursor() const -> Cursor;
auto doChange() const -> void;
auto doMove() const -> void;
auto onChange(const function<void ()>& callback = {}) -> type&;
auto onMove(const function<void ()>& callback = {}) -> type&;
auto position() const -> unsigned;
auto setPosition(signed position) -> type&;
auto setSelected(Position selected) -> type&;
auto setCursor(Cursor cursor = {}) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
Cursor cursor;
function<void ()> onChange;
function<void ()> onMove;
unsigned position = 0;
Position selected;
string text;
} state;
};
@ -1583,23 +1663,23 @@ struct mTabFrame : mWidget {
auto doChange() const -> void;
auto doClose(sTabFrameItem item) const -> void;
auto doMove(sTabFrameItem from, sTabFrameItem to) const -> void;
auto edge() const -> Edge;
auto item(unsigned position) const -> TabFrameItem;
auto itemCount() const -> unsigned;
auto items() const -> vector<TabFrameItem>;
auto navigation() const -> Navigation;
auto onChange(const function<void ()>& callback = {}) -> type&;
auto onClose(const function<void (TabFrameItem)>& callback = {}) -> type&;
auto onMove(const function<void (TabFrameItem, TabFrameItem)>& callback = {}) -> type&;
auto remove(sTabFrameItem item) -> type&;
auto reset() -> type&;
auto selected() const -> TabFrameItem;
auto setEdge(Edge edge = Edge::Top) -> type&;
auto setNavigation(Navigation navigation = Navigation::Top) -> type&;
auto setParent(mObject* object = nullptr, signed offset = -1) -> type& override;
//private:
struct State {
Edge edge = Edge::Top;
vector<sTabFrameItem> items;
Navigation navigation = Navigation::Top;
function<void ()> onChange;
function<void (TabFrameItem)> onClose;
function<void (TabFrameItem, TabFrameItem)> onMove;
@ -1615,7 +1695,7 @@ struct mTabFrameItem : mObject {
auto append(sLayout layout) -> type&;
auto closable() const -> bool;
auto icon() const -> image;
auto image() const -> Image;
auto layout() const -> Layout;
auto movable() const -> bool;
auto remove() -> type& override;
@ -1623,7 +1703,7 @@ struct mTabFrameItem : mObject {
auto reset() -> type&;
auto selected() const -> bool;
auto setClosable(bool closable = true) -> type&;
auto setIcon(const image& icon = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setMovable(bool movable = true) -> type&;
auto setParent(mObject* object = nullptr, signed offset = -1) -> type& override;
auto setSelected() -> type&;
@ -1633,7 +1713,7 @@ struct mTabFrameItem : mObject {
//private:
struct State {
bool closable = false;
image icon;
Image image;
sLayout layout;
bool movable = false;
bool selected = false;
@ -1649,7 +1729,7 @@ struct mTextEdit : mWidget {
Declare(TextEdit)
auto backgroundColor() const -> Color;
auto cursorPosition() const -> unsigned;
auto cursor() const -> Cursor;
auto doChange() const -> void;
auto doMove() const -> void;
auto editable() const -> bool;
@ -1657,7 +1737,7 @@ struct mTextEdit : mWidget {
auto onChange(const function<void ()>& callback = {}) -> type&;
auto onMove(const function<void ()>& callback = {}) -> type&;
auto setBackgroundColor(Color color = {}) -> type&;
auto setCursorPosition(unsigned position) -> type&;
auto setCursor(Cursor cursor = {}) -> type&;
auto setEditable(bool editable = true) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
auto setText(const string& text = "") -> type&;
@ -1668,7 +1748,7 @@ struct mTextEdit : mWidget {
//private:
struct State {
Color backgroundColor;
unsigned cursorPosition = 0;
Cursor cursor;
bool editable = true;
Color foregroundColor;
function<void ()> onChange;
@ -1686,13 +1766,10 @@ struct mTreeView : mWidget {
auto append(sTreeViewItem item) -> type&;
auto backgroundColor() const -> Color;
auto checkable() const -> bool;
auto collapse() -> type&;
auto doActivate() const -> void;
auto doChange() const -> void;
auto doContext() const -> void;
auto doToggle(sTreeViewItem item) const -> void;
auto expand() -> type&;
auto foregroundColor() const -> Color;
auto item(const string& path) const -> TreeViewItem;
auto itemCount() const -> unsigned;
@ -1705,14 +1782,12 @@ struct mTreeView : mWidget {
auto reset() -> type&;
auto selected() const -> TreeViewItem;
auto setBackgroundColor(Color color = {}) -> type&;
auto setCheckable(bool checkable = true) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
//TODO setParent
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&;
//private:
struct State {
Color backgroundColor;
bool checkable = false;
Color foregroundColor;
vector<sTreeViewItem> items;
function<void ()> onActivate;
@ -1731,8 +1806,11 @@ struct mTreeViewItem : mObject {
Declare(TreeViewItem)
auto append(sTreeViewItem item) -> type&;
auto backgroundColor(bool recursive = false) const -> Color;
auto checkable() const -> bool;
auto checked() const -> bool;
auto icon() const -> image;
auto foregroundColor(bool recursive = false) const -> Color;
auto image() const -> Image;
auto item(const string& path) const -> TreeViewItem;
auto itemCount() const -> unsigned;
auto items() const -> vector<TreeViewItem>;
@ -1740,18 +1818,25 @@ struct mTreeViewItem : mObject {
auto remove() -> type& override;
auto remove(sTreeViewItem item) -> type&;
auto selected() const -> bool;
auto setBackgroundColor(Color color = {}) -> type&;
auto setCheckable(bool checkable = true) -> type&;
auto setChecked(bool checked = true) -> type&;
auto setExpanded(bool expanded = true) -> type&;
auto setFocused() -> type& override;
auto setIcon(const image& icon = {}) -> type&;
//TODO setParent
auto setForegroundColor(Color color = {}) -> type&;
auto setImage(const Image& image = {}) -> type&;
auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&;
auto setSelected() -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
Color backgroundColor;
bool checkable = false;
bool checked = false;
image icon;
Color foregroundColor;
Image image;
vector<sTreeViewItem> items;
string text;
} state;

43
hiro/core/cursor.cpp Normal file
View File

@ -0,0 +1,43 @@
#if defined(Hiro_Cursor)
Cursor::Cursor(signed offset, signed length) {
setCursor(offset, length);
}
Cursor::operator bool() const {
return offset() && length();
}
auto Cursor::operator==(const Cursor& source) const -> bool {
return offset() == source.offset() && length() == source.length();
}
auto Cursor::operator!=(const Cursor& source) const -> bool {
return !operator==(source);
}
auto Cursor::length() const -> signed {
return state.length;
}
auto Cursor::offset() const -> signed {
return state.offset;
}
auto Cursor::setCursor(signed offset, signed length) -> type& {
state.offset = offset;
state.length = length;
return *this;
}
auto Cursor::setOffset(signed offset) -> type& {
state.offset = offset;
return *this;
}
auto Cursor::setLength(signed length) -> type& {
state.length = length;
return *this;
}
#endif

View File

@ -1,11 +1,14 @@
#if defined(Hiro_Font)
Font::Font() {
}
const string Font::Sans = "{sans}";
const string Font::Serif = "{serif}";
const string Font::Mono = "{mono}";
Font::Font(const string& family, unsigned size) {
state.family = family;
state.size = size;
setFamily(family);
setSize(size);
state.bold = false;
state.italic = false;
}
Font::operator bool() const {
@ -13,8 +16,8 @@ Font::operator bool() const {
}
auto Font::operator==(const Font& source) const -> bool {
return family() == source.family() || size() == source.size() && bold() == source.bold() && italic() == source.italic();
};
return family() == source.family() && size() == source.size() && bold() == source.bold() && italic() == source.italic();
}
auto Font::operator!=(const Font& source) const -> bool {
return !operator==(source);
@ -32,6 +35,14 @@ auto Font::italic() const -> bool {
return state.italic;
}
auto Font::reset() -> type& {
state.family = "";
state.size = 0;
state.bold = false;
state.italic = false;
return *this;
}
auto Font::setBold(bool bold) -> type& {
state.bold = bold;
return *this;
@ -56,22 +67,8 @@ auto Font::size() const -> unsigned {
return state.size;
}
//
auto Font::serif(unsigned size, const string& style) -> string {
return pFont::serif(size, style);
}
auto Font::sans(unsigned size, const string& style) -> string {
return pFont::sans(size, style);
}
auto Font::monospace(unsigned size, const string& style) -> string {
return pFont::monospace(size, style);
}
auto Font::size(const string& font, const string& text) -> Size {
return pFont::size(font, text);
auto Font::size(const string& text) const -> Size {
return pFont::size(*this, text);
}
#endif

View File

@ -20,6 +20,10 @@ Geometry::Geometry(const string& text) {
state.height = integer(part(3));
}
Geometry::operator bool() const {
return state.x || state.y || state.width || state.height;
}
auto Geometry::operator==(const Geometry& source) const -> bool {
return x() == source.x() && y() == source.y() && width() == source.width() && height() == source.height();
}
@ -36,6 +40,10 @@ auto Geometry::position() const -> Position {
return {state.x, state.y};
}
auto Geometry::reset() -> type& {
return setGeometry(0, 0, 0, 0);
}
auto Geometry::setHeight(signed height) -> type& {
state.height = height;
return *this;

37
hiro/core/gradient.cpp Normal file
View File

@ -0,0 +1,37 @@
#if defined(Hiro_Gradient)
Gradient::Gradient() {
}
Gradient::operator bool() const {
return state.colors.size() == 4;
}
auto Gradient::operator==(const Gradient& source) const -> bool {
if(state.colors.size() != source.state.colors.size()) return false;
for(auto n : range(state.colors)) {
if(state.colors[n] != source.state.colors[n]) return false;
}
return true;
}
auto Gradient::operator!=(const Gradient& source) const -> bool {
return !operator==(source);
}
auto Gradient::setBilinear(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> type& {
state.colors = {topLeft, topRight, bottomLeft, bottomRight};
return *this;
}
auto Gradient::setHorizontal(Color left, Color right) -> type& {
state.colors = {left, right, left, right};
return *this;
}
auto Gradient::setVertical(Color top, Color bottom) -> type& {
state.colors = {top, top, bottom, bottom};
return *this;
}
#endif

View File

@ -1,54 +1,59 @@
#if defined(Hiro_Hotkey)
auto mHotkey::allocate() -> pObject* {
return new pHotkey(*this);
Hotkey::Hotkey() : state(new Hotkey::State) {
setSequence();
}
//
auto mHotkey::doPress() const -> void {
if(state.onPress) return state.onPress();
Hotkey::Hotkey(const string& sequence) : state(new Hotkey::State) {
setSequence(sequence);
}
auto mHotkey::doRelease() const -> void {
if(state.onRelease) return state.onRelease();
Hotkey::operator bool() const {
return state->sequence;
}
auto mHotkey::onPress(const function<void ()>& callback) -> type& {
state.onPress = callback;
auto Hotkey::operator==(const Hotkey& source) const -> bool {
return state == source.state;
}
auto Hotkey::operator!=(const Hotkey& source) const -> bool {
return !operator==(source);
}
auto Hotkey::doPress() const -> void {
if(state->onPress) state->onPress();
}
auto Hotkey::doRelease() const -> void {
if(state->onRelease) state->onRelease();
}
auto Hotkey::onPress(const function<void ()>& callback) -> type& {
state->onPress = callback;
return *this;
}
auto mHotkey::onRelease(const function<void ()>& callback) -> type& {
state.onRelease = callback;
auto Hotkey::onRelease(const function<void ()>& callback) -> type& {
state->onRelease = callback;
return *this;
}
auto mHotkey::owner() const -> wObject {
return state.owner;
}
auto mHotkey::remove() -> type& {
//todo: remove from Keyboard::hotkeys
auto Hotkey::reset() -> type& {
setSequence();
return *this;
}
auto mHotkey::sequence() const -> string {
return state.sequence;
auto Hotkey::sequence() const -> string {
return state->sequence;
}
auto mHotkey::setOwner(sObject owner) -> type& {
state.owner = owner;
return *this;
}
auto mHotkey::setSequence(const string& sequence) -> type& {
state.active = false;
state.sequence = sequence;
state.keys.reset();
auto Hotkey::setSequence(const string& sequence) -> type& {
state->active = false;
state->sequence = sequence;
state->keys.reset();
for(auto& key : sequence.split("+")) {
if(auto position = Keyboard::keys.find(key)) {
state.keys.append(*position);
state->keys.append(*position);
}
}
return *this;

83
hiro/core/image.cpp Normal file
View File

@ -0,0 +1,83 @@
#if defined(Hiro_Image)
Image::Image() {
}
Image::Image(const Image& source) {
operator=(source);
}
Image::Image(const string& source) {
nall::image image{source};
image.transform();
setImage((const uint32_t*)image.data(), Size{(signed)image.width(), (signed)image.height()});
}
Image::Image(const vector<uint8_t>& source) {
nall::image image{source};
image.transform();
setImage((const uint32_t*)image.data(), Size{(signed)image.width(), (signed)image.height()});
}
Image::Image(const uint32_t* data, Size size) {
setImage(data, size);
}
Image::~Image() {
reset();
}
Image::operator bool() const {
return state.data;
}
auto Image::operator=(const Image& source) -> type& {
reset();
if(state.size = source.state.size) {
state.data = new uint32_t[state.size.width() * state.size.height()];
memory::copy(state.data, source.state.data, state.size.width() * state.size.height() * sizeof(uint32_t));
}
return *this;
}
auto Image::data() const -> uint32_t* {
return state.data;
}
auto Image::height() const -> signed {
return state.size.height();
}
auto Image::reset() -> type& {
if(state.data) delete[] state.data;
state.data = nullptr;
state.size = {};
return *this;
}
auto Image::setImage(const uint32_t* data, Size size) -> type& {
reset();
if(data && size) {
state.size = size;
state.data = new uint32_t[size.width() * size.height()];
memory::copy(state.data, data, size.width() * size.height() * sizeof(uint32_t));
}
return *this;
}
auto Image::setSize(Size size) -> type& {
state.size = size;
if(state.data) delete[] state.data;
if(state.size) state.data = new uint32_t[size.width() * size.height()];
return *this;
}
auto Image::size() const -> Size {
return state.size;
}
auto Image::width() const -> signed {
return state.size.width();
}
#endif

View File

@ -25,37 +25,36 @@ const vector<string> Keyboard::keys = {
"Enter", //"LeftEnter" | "RightEnter"
};
auto Keyboard::append(sHotkey hotkey) -> void {
auto Keyboard::append(Hotkey hotkey) -> void {
state.hotkeys.append(hotkey);
}
auto Keyboard::hotkey(unsigned position) -> Hotkey {
if(position < hotkeys()) return state.hotkeys[position];
if(position < hotkeyCount()) return state.hotkeys[position];
return {};
}
auto Keyboard::hotkeys() -> unsigned {
auto Keyboard::hotkeyCount() -> unsigned {
return state.hotkeys.size();
}
auto Keyboard::hotkeys() -> vector<Hotkey> {
return state.hotkeys;
}
auto Keyboard::poll() -> vector<bool> {
auto pressed = pKeyboard::poll();
for(auto& hotkey : state.hotkeys) {
bool active = hotkey->state.sequence.size() > 0;
for(auto& key : hotkey->state.keys) {
bool active = hotkey.state->sequence.size() > 0;
for(auto& key : hotkey.state->keys) {
if(pressed[key]) continue;
active = false;
break;
}
if(auto owner = hotkey->state.owner.acquire()) {
//todo: set active = false if owner no longer exists
active &= owner->focused();
}
if(hotkey->state.active != active) {
hotkey->state.active = active;
if( active) hotkey->doPress();
if(!active) hotkey->doRelease();
if(hotkey.state->active != active) {
hotkey.state->active = active;
active ? hotkey.doPress() : hotkey.doRelease();
}
}
@ -71,7 +70,7 @@ auto Keyboard::released(const string& key) -> bool {
return !pressed(key);
}
auto Keyboard::remove(sHotkey hotkey) -> void {
auto Keyboard::remove(Hotkey hotkey) -> void {
if(auto offset = state.hotkeys.find(hotkey)) {
state.hotkeys.remove(*offset);
}

View File

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

View File

@ -68,7 +68,7 @@ auto mObject::focused() const -> bool {
return false;
}
auto mObject::font(bool recursive) const -> string {
auto mObject::font(bool recursive) const -> Font {
if(!recursive || state.font) return state.font;
if(auto object = parent()) return object->font(true);
return Application::font();
@ -277,7 +277,7 @@ auto mObject::setFocused() -> type& {
return *this;
}
auto mObject::setFont(const string& font) -> type& {
auto mObject::setFont(const Font& font) -> type& {
state.font = font;
signal(setFont, this->font(true));
return *this;

View File

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

View File

@ -8,6 +8,10 @@ Position::Position(signed x, signed y) {
setPosition(x, y);
}
Position::operator bool() const {
return state.x || state.y;
}
auto Position::operator==(const Position& source) const -> bool {
return x() == source.x() && y() == source.y();
}
@ -16,6 +20,10 @@ auto Position::operator!=(const Position& source) const -> bool {
return !operator==(source);
}
auto Position::reset() -> type& {
return setPosition(0, 0);
}
auto Position::setPosition(Position position) -> type& {
return setPosition(position.x(), position.y());
}

View File

@ -28,7 +28,7 @@
auto remove() { return self().remove(), *this; } \
auto setEnabled(bool enabled = true) { return self().setEnabled(enabled), *this; } \
auto setFocused() { return self().setFocused(), *this; } \
auto setFont(const string& font = "") { return self().setFont(font), *this; } \
auto setFont(const Font& font = {}) { return self().setFont(font), *this; } \
auto setVisible(bool visible = true) { return self().setVisible(visible), *this; } \
auto visible(bool recursive = false) const { return self().visible(recursive); } \
@ -81,21 +81,6 @@ private:
};
#endif
#if defined(Hiro_Hotkey)
struct Hotkey : sHotkey {
DeclareSharedObject(Hotkey)
auto doPress() const { return self().doPress(); }
auto doRelease() const { return self().doRelease(); }
auto onPress(const function<void ()>& callback = {}) { return self().onPress(callback), *this; }
auto onRelease(const function<void ()>& callback = {}) { return self().onRelease(callback), *this; }
auto owner() const { return self().owner(); }
auto sequence() const { return self().sequence(); }
auto setOwner(sObject owner) { return self().setOwner(owner), *this; }
auto setSequence(const string& sequence = "") { return self().setSequence(sequence), *this; }
};
#endif
#if defined(Hiro_Timer)
struct Timer : sTimer {
DeclareSharedObject(Timer)
@ -121,10 +106,10 @@ struct Menu : sMenu {
auto actionCount() const { return self().actionCount(); }
auto actions() const { return self().actions(); }
auto append(sAction action) { return self().append(action), *this; }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto remove(sAction action) { return self().remove(action), *this; }
auto reset() { return self().reset(), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
};
@ -141,9 +126,9 @@ struct MenuItem : sMenuItem {
DeclareSharedAction(MenuItem)
auto doActivate() const { return self().doActivate(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto onActivate(const function<void ()>& callback = {}) { return self().onActivate(callback), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
};
@ -200,11 +185,11 @@ struct Button : sButton {
auto bordered() const { return self().bordered(); }
auto doActivate() const { return self().doActivate(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto onActivate(const function<void ()>& callback = {}) { return self().onActivate(callback), *this; }
auto orientation() const { return self().orientation(); }
auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setOrientation(Orientation orientation = Orientation::Horizontal) { return self().setOrientation(orientation), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
@ -224,20 +209,17 @@ struct Canvas : sCanvas {
auto doMousePress(Mouse::Button button) const { return self().doMousePress(button); }
auto doMouseRelease(Mouse::Button button) const { return self().doMouseRelease(button); }
auto gradient() const { return self().gradient(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto onDrop(const function<void (lstring)>& callback = {}) { return self().onDrop(callback), *this; }
auto onMouseLeave(const function<void ()>& callback = {}) { return self().onMouseLeave(callback), *this; }
auto onMouseMove(const function<void (Position)>& callback = {}) { return self().onMouseMove(callback), *this; }
auto onMousePress(const function<void (Mouse::Button)>& callback = {}) { return self().onMousePress(callback), *this; }
auto onMouseRelease(const function<void (Mouse::Button)>& callback = {}) { return self().onMouseRelease(callback), *this; }
auto setColor(Color color) { return self().setColor(color), *this; }
auto setData(Size size) { return self().setData(size), *this; }
auto setDroppable(bool droppable = true) { return self().setDroppable(droppable), *this; }
auto setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) { return self().setGradient(topLeft, topRight, bottomLeft, bottomRight), *this; }
auto setHorizontalGradient(Color left, Color right) { return self().setGradient(left, right, left, right), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setVerticalGradient(Color top, Color bottom) { return self().setGradient(top, top, bottom, bottom), *this; }
auto size() const { return self().size(); }
auto setGradient(Gradient gradient = {}) { return self().setGradient(gradient), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setSize(Size size = {}) { return self().setSize(size), *this; }
auto update() { return self().update(), *this; }
};
#endif
@ -249,12 +231,12 @@ struct CheckButton : sCheckButton {
auto bordered() const { return self().bordered(); }
auto checked() const { return self().checked(); }
auto doToggle() const { return self().doToggle(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto onToggle(const function<void ()>& callback = {}) { return self().onToggle(callback), *this; }
auto orientation() const { return self().orientation(); }
auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; }
auto setChecked(bool checked = true) { return self().setChecked(checked), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setOrientation(Orientation orientation = Orientation::Horizontal) { return self().setOrientation(orientation), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
@ -278,9 +260,9 @@ struct CheckLabel : sCheckLabel {
struct ComboButtonItem : sComboButtonItem {
DeclareSharedObject(ComboButtonItem)
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto selected() const { return self().selected(); }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setSelected() { return self().setSelected(), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
@ -388,9 +370,9 @@ struct HorizontalSlider : sHorizontalSlider {
struct IconViewItem : sIconViewItem {
DeclareSharedObject(IconViewItem)
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto selected() const { return self().selected(); }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setSelected(bool selected = true) { return self().setSelected(selected), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
@ -403,6 +385,8 @@ struct IconView : sIconView {
auto append(sIconViewItem item) { return self().append(item), *this; }
auto backgroundColor() const { return self().backgroundColor(); }
auto batchable() const { return self().batchable(); }
auto batched() const { return self().batched(); }
auto doActivate() const { return self().doActivate(); }
auto doChange() const { return self().doChange(); }
auto doContext() const { return self().doContext(); }
@ -411,7 +395,6 @@ struct IconView : sIconView {
auto item(unsigned position) const { return self().item(position); }
auto itemCount() const { return self().itemCount(); }
auto items() const { return self().items(); }
auto multiSelect() const { return self().multiSelect(); }
auto onActivate(const function<void ()>& callback = {}) { return self().onActivate(callback), *this; }
auto onChange(const function<void ()>& callback = {}) { return self().onChange(callback), *this; }
auto onContext(const function<void ()>& callback = {}) { return self().onContext(callback), *this; }
@ -419,11 +402,10 @@ struct IconView : sIconView {
auto remove(sIconViewItem item) { return self().remove(item), *this; }
auto reset() { return self().reset(), *this; }
auto selected() const { return self().selected(); }
auto selectedItems() const { return self().selectedItems(); }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
auto setBatchable(bool batchable = true) { return self().setBatchable(batchable), *this; }
auto setFlow(Orientation orientation = Orientation::Vertical) { return self().setFlow(orientation), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
auto setMultiSelect(bool multiSelect = true) { return self().setMultiSelect(multiSelect), *this; }
auto setOrientation(Orientation orientation = Orientation::Horizontal) { return self().setOrientation(orientation), *this; }
auto setSelected(const vector<signed>& selections) { return self().setSelected(selections), *this; }
};
@ -470,7 +452,7 @@ struct ListViewColumn : sListViewColumn {
auto expandable() const { return self().expandable(); }
auto foregroundColor() const { return self().foregroundColor(); }
auto horizontalAlignment() const { return self().horizontalAlignment(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto resizable() const { return self().resizable(); }
auto setActive() { return self().setActive(), *this; }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
@ -478,12 +460,10 @@ struct ListViewColumn : sListViewColumn {
auto setEditable(bool editable = true) { return self().setEditable(editable), *this; }
auto setExpandable(bool expandable = true) { return self().setExpandable(expandable), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
auto setHorizontalAlignment(double alignment = 0.0) { return self().setHorizontalAlignment(alignment), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; }
auto setSortable(bool sortable = true) { return self().setSortable(sortable), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto setVerticalAlignment(double alignment = 0.5) { return self().setVerticalAlignment(alignment), *this; }
auto setWidth(signed width = 0) { return self().setWidth(width), *this; }
auto sortable() const { return self().sortable(); }
auto text() const { return self().text(); }
@ -513,13 +493,13 @@ struct ListViewCell : sListViewCell {
auto checkable() const { return self().checkable(); }
auto checked() const { return self().checked(); }
auto foregroundColor() const { return self().foregroundColor(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
auto setCheckable(bool checkable = true) const { return self().setCheckable(checkable), *this; }
auto setChecked(bool checked = true) const { return self().setChecked(checked), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
};
@ -603,12 +583,12 @@ struct RadioButton : sRadioButton {
auto checked() const { return self().checked(); }
auto doActivate() const { return self().doActivate(); }
auto group() const { return self().group(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto onActivate(const function<void ()>& callback = {}) { return self().onActivate(callback), *this; }
auto orientation() const { return self().orientation(); }
auto setBordered(bool bordered = true) { return self().setBordered(bordered), *this; }
auto setChecked() { return self().setChecked(), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setOrientation(Orientation orientation = Orientation::Horizontal) { return self().setOrientation(orientation), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
@ -633,13 +613,12 @@ struct RadioLabel : sRadioLabel {
struct SourceEdit : sSourceEdit {
DeclareSharedWidget(SourceEdit)
auto cursor() const { return self().cursor(); }
auto doChange() const { return self().doChange(); }
auto doMove() const { return self().doMove(); }
auto onChange(const function<void ()>& callback = {}) { return self().onChange(callback), *this; }
auto onMove(const function<void ()>& callback = {}) { return self().onMove(callback), *this; }
auto position() const { return self().position(); }
auto setPosition(signed position) { return self().setPosition(position), *this; }
auto setSelected(Position selected) { return self().setSelected(selected), *this; }
auto setCursor(Cursor cursor = {}) { return self().setCursor(cursor), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
};
@ -651,14 +630,14 @@ struct TabFrameItem : sTabFrameItem {
auto append(sLayout layout) { return self().append(layout), *this; }
auto closable() const { return self().closable(); }
auto icon() const { return self().icon(); }
auto image() const { return self().image(); }
auto layout() const { return self().layout(); }
auto movable() const { return self().movable(); }
auto remove(sLayout layout) { return self().remove(layout), *this; }
auto reset() { return self().reset(), *this; }
auto selected() const { return self().selected(); }
auto setClosable(bool closable = true) { return self().setClosable(closable), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
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; }
@ -674,17 +653,17 @@ struct TabFrame : sTabFrame {
auto doChange() const { return self().doChange(); }
auto doClose(sTabFrameItem item) const { return self().doClose(item); }
auto doMove(sTabFrameItem from, sTabFrameItem to) const { return self().doMove(from, to); }
auto edge() const { return self().edge(); }
auto item(unsigned position) const { return self().item(position); }
auto itemCount() const { return self().itemCount(); }
auto items() const { return self().items(); }
auto navigation() const { return self().navigation(); }
auto onChange(const function<void ()>& callback = {}) { return self().onChange(callback), *this; }
auto onClose(const function<void (sTabFrameItem)>& callback = {}) { return self().onClose(callback), *this; }
auto onMove(const function<void (sTabFrameItem, sTabFrameItem)>& callback = {}) { return self().onMove(callback), *this; }
auto remove(sTabFrameItem item) { return self().remove(item), *this; }
auto reset() { return self().reset(), *this; }
auto selected() const { return self().selected(); }
auto setEdge(Edge edge = Edge::Top) { return self().setEdge(edge), *this; }
auto setNavigation(Navigation navigation = Navigation::Top) { return self().setNavigation(navigation), *this; }
};
#endif
@ -693,7 +672,7 @@ struct TextEdit : sTextEdit {
DeclareSharedWidget(TextEdit)
auto backgroundColor() const { return self().backgroundColor(); }
auto cursorPosition() const { return self().cursorPosition(); }
auto cursor() const { return self().cursor(); }
auto doChange() const { return self().doChange(); }
auto doMove() const { return self().doMove(); }
auto editable() const { return self().editable(); }
@ -701,7 +680,7 @@ struct TextEdit : sTextEdit {
auto onChange(const function<void ()>& callback = {}) { return self().onChange(callback), *this; }
auto onMove(const function<void ()>& callback = {}) { return self().onMove(callback), *this; }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
auto setCursorPosition(unsigned position) { return self().setCursorPosition(position), *this; }
auto setCursor(Cursor cursor = {}) { return self().setCursor(cursor), *this; }
auto setEditable(bool editable = true) { return self().setEditable(editable), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
@ -716,16 +695,23 @@ struct TreeViewItem : sTreeViewItem {
DeclareSharedObject(TreeViewItem)
auto append(sTreeViewItem item) { return self().append(item), *this; }
auto backgroundColor() const { return self().backgroundColor(); }
auto checkable() const { return self().checkable(); }
auto checked() const { return self().checked(); }
auto icon() const { return self().icon(); }
auto foregroundColor() const { return self().foregroundColor(); }
auto image() const { return self().image(); }
auto item(const string& path) const { return self().item(path); }
auto itemCount() const { return self().itemCount(); }
auto items() const { return self().items(); }
auto path() const { return self().path(); }
auto remove(sTreeViewItem item) { return self().remove(item), *this; }
auto selected() const { return self().selected(); }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
auto setCheckable(bool checkable = true) { return self().setCheckable(checkable), *this; }
auto setChecked(bool checked = true) { return self().setChecked(checked), *this; }
auto setIcon(const image& icon = {}) { return self().setIcon(icon), *this; }
auto setExpanded(bool expanded = true) { return self().setExpanded(expanded), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
auto setImage(const Image& image = {}) { return self().setImage(image), *this; }
auto setSelected() { return self().setSelected(), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
@ -738,13 +724,10 @@ struct TreeView : sTreeView {
auto append(sTreeViewItem item) { return self().append(item), *this; }
auto backgroundColor() const { return self().backgroundColor(); }
auto checkable() const { return self().checkable(); }
auto collapse() { return self().collapse(), *this; }
auto doActivate() const { return self().doActivate(); }
auto doChange() const { return self().doChange(); }
auto doContext() const { return self().doContext(); }
auto doToggle(sTreeViewItem item) const { return self().doToggle(item); }
auto expand() { return self().expand(), *this; }
auto foregroundColor() const { return self().foregroundColor(); }
auto item(const string& path) const { return self().item(path); }
auto itemCount() const { return self().itemCount(); }
@ -757,7 +740,6 @@ struct TreeView : sTreeView {
auto reset() { return self().reset(), *this; }
auto selected() const { return self().selected(); }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
auto setCheckable(bool checkable = true) { return self().setCheckable(checkable), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
};
#endif

View File

@ -8,6 +8,10 @@ Size::Size(signed width, signed height) {
setSize(width, height);
}
Size::operator bool() const {
return state.width || state.height;
}
auto Size::operator==(const Size& source) const -> bool {
return width() == source.width() && height() == source.height();
}
@ -20,6 +24,10 @@ auto Size::height() const -> signed {
return state.height;
}
auto Size::reset() -> type& {
return setSize(0, 0);
}
auto Size::setHeight(signed height) -> type& {
state.height = height;
return *this;

View File

@ -14,8 +14,8 @@ auto mButton::doActivate() const -> void {
if(state.onActivate) return state.onActivate();
}
auto mButton::icon() const -> image {
return state.icon;
auto mButton::image() const -> Image {
return state.image;
}
auto mButton::onActivate(const function<void ()>& callback) -> type& {
@ -33,9 +33,9 @@ auto mButton::setBordered(bool bordered) -> type& {
return *this;
}
auto mButton::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mButton::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -11,7 +11,7 @@ auto mCanvas::color() const -> Color {
}
auto mCanvas::data() -> uint32_t* {
return state.data.data();
return state.image.data();
}
auto mCanvas::droppable() const -> bool {
@ -38,12 +38,12 @@ auto mCanvas::doMouseRelease(Mouse::Button button) const -> void {
if(state.onMouseRelease) return state.onMouseRelease(button);
}
auto mCanvas::gradient() const -> vector<Color> {
auto mCanvas::gradient() const -> Gradient {
return state.gradient;
}
auto mCanvas::icon() const -> image {
return state.icon;
auto mCanvas::image() const -> Image {
return state.image;
}
auto mCanvas::onDrop(const function<void (lstring)>& callback) -> type& {
@ -72,53 +72,38 @@ auto mCanvas::onMouseRelease(const function<void (Mouse::Button)>& callback) ->
}
auto mCanvas::setColor(Color color) -> type& {
state.size = {};
state.color = color;
signal(setColor, color);
return *this;
}
auto mCanvas::setData(Size size) -> type& {
state.size = size;
state.data.resize(size.width() * size.height());
memory::fill(state.data.data(), size.width() * size.height() * sizeof(uint32_t));
signal(setData, size);
return *this;
}
auto mCanvas::setDroppable(bool droppable) -> type& {
state.droppable = droppable;
signal(setDroppable, droppable);
return *this;
}
auto mCanvas::setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> type& {
state.size = {};
state.gradient[0] = topLeft;
state.gradient[1] = topRight;
state.gradient[2] = bottomLeft;
state.gradient[3] = bottomRight;
signal(setGradient, topLeft, topRight, bottomLeft, bottomRight);
auto mCanvas::setGradient(Gradient gradient) -> type& {
state.gradient = gradient;
signal(setGradient, gradient);
return *this;
}
auto mCanvas::setHorizontalGradient(Color left, Color right) -> type& {
return setGradient(left, right, left, right);
}
auto mCanvas::setIcon(const image& icon) -> type& {
state.size = {(signed)icon.width(), (signed)icon.height()};
state.icon = icon;
signal(setIcon, icon);
auto mCanvas::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}
auto mCanvas::setVerticalGradient(Color top, Color bottom) -> type& {
return setGradient(top, top, bottom, bottom);
auto mCanvas::setSize(Size size) -> type& {
Image image;
image.setSize(size);
memory::fill(image.data(), size.width() * size.height() * sizeof(uint32_t), 0x00);
return setImage(image);
}
auto mCanvas::size() const -> Size {
return state.size;
return state.image.size();
}
auto mCanvas::update() -> type& {

View File

@ -18,8 +18,8 @@ auto mCheckButton::doToggle() const -> void {
if(state.onToggle) return state.onToggle();
}
auto mCheckButton::icon() const -> image {
return state.icon;
auto mCheckButton::image() const -> Image {
return state.image;
}
auto mCheckButton::onToggle(const function<void ()>& callback) -> type& {
@ -43,9 +43,9 @@ auto mCheckButton::setChecked(bool checked) -> type& {
return *this;
}
auto mCheckButton::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mCheckButton::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -6,8 +6,8 @@ auto mComboButtonItem::allocate() -> pObject* {
//
auto mComboButtonItem::icon() const -> image {
return state.icon;
auto mComboButtonItem::image() const -> Image {
return state.image;
}
auto mComboButtonItem::remove() -> type& {
@ -19,9 +19,9 @@ auto mComboButtonItem::selected() const -> bool {
return state.selected;
}
auto mComboButtonItem::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mComboButtonItem::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -33,6 +33,13 @@ auto mFrame::reset() -> type& {
return *this;
}
auto mFrame::setParent(mObject* object, signed offset) -> type& {
if(auto& layout = state.layout) layout->destruct();
mObject::setParent(object, offset);
if(auto& layout = state.layout) layout->setParent(this, 0);
return *this;
}
auto mFrame::setText(const string& text) -> type& {
state.text = text;
signal(setText, text);

View File

@ -6,8 +6,8 @@ auto mIconViewItem::allocate() -> pObject* {
//
auto mIconViewItem::icon() const -> image {
return state.icon;
auto mIconViewItem::image() const -> Image {
return state.image;
}
auto mIconViewItem::remove() -> type& {
@ -19,9 +19,9 @@ auto mIconViewItem::selected() const -> bool {
return state.selected;
}
auto mIconViewItem::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mIconViewItem::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -22,6 +22,18 @@ auto mIconView::backgroundColor() const -> Color {
return state.backgroundColor;
}
auto mIconView::batchable() const -> bool {
return state.batchable;
}
auto mIconView::batched() const -> vector<IconViewItem> {
vector<IconViewItem> items;
for(auto& item : state.items) {
if(item->selected()) items.append(item);
}
return items;
}
auto mIconView::doActivate() const -> void {
if(state.onActivate) return state.onActivate();
}
@ -57,10 +69,6 @@ auto mIconView::items() const -> vector<IconViewItem> {
return items;
}
auto mIconView::multiSelect() const -> bool {
return state.multiSelect;
}
auto mIconView::onActivate(const function<void ()>& callback) -> type& {
state.onActivate = callback;
return *this;
@ -97,19 +105,11 @@ auto mIconView::reset() -> type& {
return *this;
}
auto mIconView::selected() const -> maybe<unsigned> {
auto mIconView::selected() const -> IconViewItem {
for(auto& item : state.items) {
if(item->selected()) return (unsigned)item->offset();
if(item->selected()) return item;
}
return nothing;
}
auto mIconView::selectedItems() const -> vector<unsigned> {
vector<unsigned> result;
for(auto& item : state.items) {
if(item->selected()) result.append(item->offset());
}
return result;
return {};
}
auto mIconView::setBackgroundColor(Color color) -> type& {
@ -118,6 +118,12 @@ auto mIconView::setBackgroundColor(Color color) -> type& {
return *this;
}
auto mIconView::setBatchable(bool batchable) -> type& {
state.batchable = batchable;
signal(setBatchable, batchable);
return *this;
}
auto mIconView::setFlow(Orientation flow) -> type& {
state.flow = flow;
signal(setFlow, flow);
@ -130,18 +136,19 @@ auto mIconView::setForegroundColor(Color color) -> type& {
return *this;
}
auto mIconView::setMultiSelect(bool multiSelect) -> type& {
state.multiSelect = multiSelect;
signal(setMultiSelect, multiSelect);
return *this;
}
auto mIconView::setOrientation(Orientation orientation) -> type& {
state.orientation = orientation;
signal(setOrientation, orientation);
return *this;
}
auto mIconView::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct();
mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset());
return *this;
}
auto mIconView::setSelected(const vector<signed>& selections) -> type& {
bool selectAll = selections(0, 0) == ~0;
for(auto& item : state.items) item->state.selected = selectAll;

View File

@ -54,7 +54,7 @@ auto mListViewCell::checked() const -> bool {
return state.checkable && state.checked;
}
auto mListViewCell::font(bool recursive) const -> string {
auto mListViewCell::font(bool recursive) const -> Font {
if(auto font = mObject::font()) return font;
if(recursive) {
if(auto parent = parentListViewItem()) {
@ -94,8 +94,8 @@ auto mListViewCell::foregroundColor(bool recursive) const -> Color {
return state.foregroundColor;
}
auto mListViewCell::icon() const -> image {
return state.icon;
auto mListViewCell::image() const -> Image {
return state.image;
}
auto mListViewCell::setAlignment(Alignment alignment) -> type& {
@ -129,9 +129,9 @@ auto mListViewCell::setForegroundColor(Color color) -> type& {
return *this;
}
auto mListViewCell::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mListViewCell::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -35,8 +35,8 @@ auto mListViewColumn::horizontalAlignment() const -> double {
return state.horizontalAlignment;
}
auto mListViewColumn::icon() const -> image {
return state.icon;
auto mListViewColumn::image() const -> Image {
return state.image;
}
auto mListViewColumn::remove() -> type& {
@ -91,9 +91,9 @@ auto mListViewColumn::setHorizontalAlignment(double alignment) -> type& {
return *this;
}
auto mListViewColumn::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mListViewColumn::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

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

View File

@ -22,8 +22,8 @@ auto mRadioButton::group() const -> Group {
return state.group;
}
auto mRadioButton::icon() const -> image {
return state.icon;
auto mRadioButton::image() const -> Image {
return state.image;
}
auto mRadioButton::onActivate(const function<void ()>& callback) -> type& {
@ -57,15 +57,14 @@ auto mRadioButton::setChecked() -> type& {
}
auto mRadioButton::setGroup(sGroup group) -> type& {
state.group = group;
state.group = group ? group : Group{&instance};
signal(setGroup, group);
if(group && group->objectCount() == 1) setChecked();
return *this;
}
auto mRadioButton::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mRadioButton::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -39,9 +39,8 @@ auto mRadioLabel::setChecked() -> type& {
}
auto mRadioLabel::setGroup(sGroup group) -> type& {
state.group = group;
state.group = group ? group : Group{&instance};
signal(setGroup, group);
if(group && group->objectCount() == 1) setChecked();
return *this;
}

View File

@ -6,6 +6,10 @@ auto mSourceEdit::allocate() -> pObject* {
//
auto mSourceEdit::cursor() const -> Cursor {
return state.cursor;
}
auto mSourceEdit::doChange() const -> void {
if(state.onChange) return state.onChange();
}
@ -24,22 +28,9 @@ auto mSourceEdit::onMove(const function<void ()>& callback) -> type& {
return *this;
}
auto mSourceEdit::position() const -> unsigned {
return state.position;
}
auto mSourceEdit::setPosition(signed position) -> type& {
state.position = position;
signal(setPosition, position);
return *this;
}
auto mSourceEdit::setSelected(Position selected) -> type& {
if(selected.x() < 0) return *this;
if(selected.y() < 0) selected.setY(-1);
else if(selected.x() > selected.y()) return *this;
state.selected = selected;
signal(setSelected, selected);
auto mSourceEdit::setCursor(Cursor cursor) -> type& {
state.cursor = cursor;
signal(setCursor, cursor);
return *this;
}

View File

@ -23,8 +23,8 @@ auto mTabFrameItem::closable() const -> bool {
return state.closable;
}
auto mTabFrameItem::icon() const -> image {
return state.icon;
auto mTabFrameItem::image() const -> Image {
return state.image;
}
auto mTabFrameItem::layout() const -> Layout {
@ -62,9 +62,9 @@ auto mTabFrameItem::setClosable(bool closable) -> type& {
return *this;
}
auto mTabFrameItem::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mTabFrameItem::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}

View File

@ -12,6 +12,7 @@ auto mTabFrame::destruct() -> void {
//
auto mTabFrame::append(sTabFrameItem item) -> type& {
if(!state.items) item->state.selected = true;
state.items.append(item);
item->setParent(this, itemCount() - 1);
signal(append, item);
@ -30,10 +31,6 @@ auto mTabFrame::doMove(sTabFrameItem from, sTabFrameItem to) const -> void {
if(state.onMove) return state.onMove(from, to);
}
auto mTabFrame::edge() const -> Edge {
return state.edge;
}
auto mTabFrame::item(unsigned position) const -> TabFrameItem {
if(position < itemCount()) return state.items[position];
return {};
@ -49,6 +46,10 @@ auto mTabFrame::items() const -> vector<TabFrameItem> {
return items;
}
auto mTabFrame::navigation() const -> Navigation {
return state.navigation;
}
auto mTabFrame::onChange(const function<void ()>& callback) -> type& {
state.onChange = callback;
return *this;
@ -87,14 +88,14 @@ auto mTabFrame::selected() const -> TabFrameItem {
return {};
}
auto mTabFrame::setEdge(Edge edge) -> type& {
state.edge = edge;
signal(setEdge, edge);
auto mTabFrame::setNavigation(Navigation navigation) -> type& {
state.navigation = navigation;
signal(setNavigation, navigation);
return *this;
}
auto mTabFrame::setParent(mObject* parent, signed offset) -> type& {
for(auto& item : state.items) item->destruct();
for(auto n : rrange(state.items)) state.items[n]->destruct();
mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset());
return *this;

View File

@ -10,8 +10,8 @@ auto mTextEdit::backgroundColor() const -> Color {
return state.backgroundColor;
}
auto mTextEdit::cursorPosition() const -> unsigned {
return state.cursorPosition;
auto mTextEdit::cursor() const -> Cursor {
return state.cursor;
}
auto mTextEdit::doChange() const -> void {
@ -46,9 +46,9 @@ auto mTextEdit::setBackgroundColor(Color color) -> type& {
return *this;
}
auto mTextEdit::setCursorPosition(unsigned position) -> type& {
state.cursorPosition = position;
signal(setCursorPosition, position);
auto mTextEdit::setCursor(Cursor cursor) -> type& {
state.cursor = cursor;
signal(setCursor, cursor);
return *this;
}

View File

@ -18,12 +18,42 @@ auto mTreeViewItem::append(sTreeViewItem item) -> type& {
return *this;
}
auto mTreeViewItem::backgroundColor(bool recursive) const -> Color {
if(auto color = state.backgroundColor) return color;
if(recursive) {
if(auto parent = parentTreeViewItem()) {
if(auto color = parent->backgroundColor(true)) return color;
}
if(auto parent = parentTreeView()) {
if(auto color = parent->backgroundColor()) return color;
}
}
return {};
}
auto mTreeViewItem::checkable() const -> bool {
return state.checkable;
}
auto mTreeViewItem::checked() const -> bool {
return state.checked;
}
auto mTreeViewItem::icon() const -> image {
return state.icon;
auto mTreeViewItem::foregroundColor(bool recursive) const -> Color {
if(auto color = state.foregroundColor) return color;
if(recursive) {
if(auto parent = parentTreeViewItem()) {
if(auto color = parent->foregroundColor(true)) return color;
}
if(auto parent = parentTreeView()) {
if(auto color = parent->foregroundColor()) return color;
}
}
return {};
}
auto mTreeViewItem::image() const -> Image {
return state.image;
}
auto mTreeViewItem::item(const string& path) const -> TreeViewItem {
@ -73,23 +103,52 @@ auto mTreeViewItem::selected() const -> bool {
return false;
}
auto mTreeViewItem::setBackgroundColor(Color color) -> type& {
state.backgroundColor = color;
signal(setBackgroundColor, color);
return *this;
}
auto mTreeViewItem::setCheckable(bool checkable) -> type& {
state.checkable = checkable;
signal(setCheckable, checkable);
return *this;
}
auto mTreeViewItem::setChecked(bool checked) -> type& {
state.checked = checked;
signal(setChecked, checked);
return *this;
}
auto mTreeViewItem::setExpanded(bool expanded) -> type& {
signal(setExpanded, expanded);
return *this;
}
auto mTreeViewItem::setFocused() -> type& {
signal(setFocused);
return *this;
}
auto mTreeViewItem::setIcon(const image& icon) -> type& {
state.icon = icon;
signal(setIcon, icon);
auto mTreeViewItem::setForegroundColor(Color color) -> type& {
state.foregroundColor = color;
signal(setForegroundColor, color);
return *this;
}
auto mTreeViewItem::setImage(const Image& image) -> type& {
state.image = image;
signal(setImage, image);
return *this;
}
auto mTreeViewItem::setParent(mObject* parent, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct();
mObject::setParent(parent, offset);
for(auto& item : state.items) item->setParent(this, item->offset());
}
auto mTreeViewItem::setSelected() -> type& {
signal(setSelected);
return *this;

View File

@ -22,15 +22,6 @@ auto mTreeView::backgroundColor() const -> Color {
return state.backgroundColor;
}
auto mTreeView::checkable() const -> bool {
return state.checkable;
}
auto mTreeView::collapse() -> type& {
signal(collapse);
return *this;
}
auto mTreeView::doActivate() const -> void {
if(state.onActivate) return state.onActivate();
}
@ -47,11 +38,6 @@ auto mTreeView::doToggle(sTreeViewItem item) const -> void {
if(state.onToggle) return state.onToggle(item);
}
auto mTreeView::expand() -> type& {
signal(expand);
return *this;
}
auto mTreeView::foregroundColor() const -> Color {
return state.foregroundColor;
}
@ -107,9 +93,7 @@ auto mTreeView::remove(sTreeViewItem item) -> type& {
auto mTreeView::reset() -> type& {
state.selectedPath.reset();
signal(reset);
for(auto& item : state.items) item->setParent();
state.items.reset();
for(auto n : rrange(state.items)) remove(state.items[n]);
return *this;
}
@ -123,16 +107,17 @@ auto mTreeView::setBackgroundColor(Color color) -> type& {
return *this;
}
auto mTreeView::setCheckable(bool checkable) -> type& {
state.checkable = checkable;
signal(setCheckable, checkable);
return *this;
}
auto mTreeView::setForegroundColor(Color color) -> type& {
state.foregroundColor = color;
signal(setForegroundColor, color);
return *this;
}
auto mTreeView::setParent(mObject* object, signed offset) -> type& {
for(auto n : rrange(state.items)) state.items[n]->destruct();
mObject::setParent(object, offset);
for(auto& item : state.items) item->setParent(this, item->offset());
return *this;
}
#endif

View File

@ -15,8 +15,8 @@ private:
VerticalLayout layout{&window};
HorizontalLayout pathLayout{&layout, Size{~0, 0}, 5};
LineEdit pathName{&pathLayout, Size{~0, 0}, 0};
Button pathHome{&pathLayout, Size{0, 0}, 0};
Button pathRefresh{&pathLayout, Size{0, 0}, 0};
Button pathHome{&pathLayout, Size{0, 0}, 0};
Button pathUp{&pathLayout, Size{0, 0}, 0};
ListView view{&layout, Size{~0, ~0}, 5};
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
@ -118,9 +118,9 @@ auto BrowserDialogWindow::run() -> lstring {
layout.setMargin(5);
pathName.onActivate([&] { setPath(pathName.text()); });
pathHome.setBordered(false).setIcon(Icon::Go::Home).onActivate([&] { setPath(userpath()); });
pathRefresh.setBordered(false).setIcon(Icon::Action::Refresh).onActivate([&] { setPath(state.path); });
pathUp.setBordered(false).setIcon(Icon::Go::Up).onActivate([&] { setPath(state.path.dirname()); });
pathRefresh.setBordered(false).setImage(Icon::Action::Refresh).onActivate([&] { setPath(state.path); });
pathHome.setBordered(false).setImage(Icon::Go::Home).onActivate([&] { setPath(userpath()); });
pathUp.setBordered(false).setImage(Icon::Go::Up).onActivate([&] { setPath(state.path.dirname()); });
view.setBatchable(state.action == "openFiles").onActivate([&] { activate(); }).onChange([&] { change(); });
filterList.setVisible(state.action != "selectFolder").onChange([&] { setPath(state.path); });
for(auto& filter : state.filters) {
@ -175,7 +175,7 @@ auto BrowserDialogWindow::setPath(string path) -> void {
if(folderMode && isMatch(content)) continue;
view.append(ListViewItem()
.append(ListViewCell().setText(content).setIcon(Icon::Emblem::Folder))
.append(ListViewCell().setText(content).setImage(Icon::Emblem::Folder))
);
}
@ -185,7 +185,7 @@ auto BrowserDialogWindow::setPath(string path) -> void {
if(!isMatch(content)) continue;
view.append(ListViewItem()
.append(ListViewCell().setText(content).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File))
.append(ListViewCell().setText(content).setImage(folderMode ? Icon::Action::Open : Icon::Emblem::File))
);
}

View File

@ -7,6 +7,14 @@ auto mFixedLayout::append(sSizable sizable, Geometry geometry) -> type& {
return *this;
}
auto mFixedLayout::modify(sSizable sizable, Geometry geometry) -> type& {
if(sizable && this->sizable(sizable->offset()) == sizable) {
auto& properties = this->properties[sizable->offset()];
properties.geometry = geometry;
}
return *this;
}
auto mFixedLayout::minimumSize() const -> Size {
signed width = Size::Minimum, height = Size::Minimum;
for(auto n : range(sizableCount())) {
@ -36,7 +44,7 @@ auto mFixedLayout::setEnabled(bool enabled) -> type& {
return *this;
}
auto mFixedLayout::setFont(const string& font) -> type& {
auto mFixedLayout::setFont(const Font& font) -> type& {
mLayout::setFont(font);
for(auto n : range(sizableCount())) {
sizable(n)->setFont(sizable(n)->font());

View File

@ -6,11 +6,12 @@ struct mFixedLayout : mLayout {
using mLayout::remove;
auto append(sSizable sizable, Geometry geometry) -> type&;
auto modify(sSizable sizable, Geometry geometry) -> type&;
auto minimumSize() const -> Size override;
auto remove(sSizable sizable) -> type& override;
auto reset() -> type& override;
auto setEnabled(bool enabled = true) -> type& override;
auto setFont(const string& font = "") -> type& override;
auto setFont(const Font& font = {}) -> type& override;
auto setVisible(bool visible = true) ->type& override;
struct Properties {

View File

@ -6,6 +6,16 @@ auto mHorizontalLayout::append(sSizable sizable, Size size, signed spacing) -> t
return *this;
}
auto mHorizontalLayout::modify(sSizable sizable, Size size, signed spacing) -> type& {
if(sizable && this->sizable(sizable->offset()) == sizable) {
auto& properties = this->properties[sizable->offset()];
properties.width = size.width();
properties.height = size.height();
properties.spacing = spacing;
}
return *this;
}
auto mHorizontalLayout::minimumSize() const -> Size {
signed width = 0, height = 0;
@ -56,7 +66,7 @@ auto mHorizontalLayout::setEnabled(bool enabled) -> type& {
return *this;
}
auto mHorizontalLayout::setFont(const string& font) -> type& {
auto mHorizontalLayout::setFont(const Font& font) -> type& {
mLayout::setFont(font);
for(auto n : range(sizableCount())) {
sizable(n)->setFont(sizable(n)->font());

View File

@ -7,11 +7,12 @@ struct mHorizontalLayout : mLayout {
auto append(sSizable sizable, Size size, signed spacing = 5) -> type&;
auto minimumSize() const -> Size override;
auto modify(sSizable sizable, Size size, signed spacing = 5) -> type&;
auto remove(sSizable sizable) -> type& override;
auto reset() -> type& override;
auto setAlignment(double alignment = 0.5) -> type&;
auto setEnabled(bool enabled = true) -> type& override;
auto setFont(const string& font = "") -> type& override;
auto setFont(const Font& font = {}) -> type& override;
auto setGeometry(Geometry geometry) -> type& override;
auto setMargin(signed margin = 0) -> type&;
auto setSpacing(signed spacing = 5) -> type&;

View File

@ -6,19 +6,19 @@ MessageDialog::MessageDialog(const string& text) {
auto MessageDialog::error(const lstring& buttons) -> string {
state.buttons = buttons;
state.icon = Icon::Prompt::Error;
state.image = Icon::Prompt::Error;
return _run();
}
auto MessageDialog::information(const lstring& buttons) -> string {
state.buttons = buttons;
state.icon = Icon::Prompt::Information;
state.image = Icon::Prompt::Information;
return _run();
}
auto MessageDialog::question(const lstring& buttons) -> string {
state.buttons = buttons;
state.icon = Icon::Prompt::Question;
state.image = Icon::Prompt::Question;
return _run();
}
@ -39,7 +39,7 @@ auto MessageDialog::setTitle(const string& title) -> type& {
auto MessageDialog::warning(const lstring& buttons) -> string {
state.buttons = buttons;
state.icon = Icon::Prompt::Warning;
state.image = Icon::Prompt::Warning;
return _run();
}
@ -53,7 +53,7 @@ auto MessageDialog::_run() -> string {
Widget controlSpacer{&controlLayout, Size{~0, 0}};
layout.setMargin(5);
messageIcon.setIcon(state.icon);
messageIcon.setImage(state.image);
messageText.setText(state.text);
for(auto n : range(state.buttons)) {
Button button{&controlLayout, Size{80, 0}, 5};
@ -62,7 +62,7 @@ auto MessageDialog::_run() -> string {
button.setFocused(); //the last button will have effective focus
}
signed widthMessage = 5 + 16 + 5 + Font::size(Font::sans(), state.text).width() + 5;
signed widthMessage = 5 + 16 + 5 + Font().size(state.text).width() + 5;
signed widthButtons = 5 + state.buttons.size() * 85;
signed width = max(320, widthMessage, widthButtons);

View File

@ -15,7 +15,7 @@ struct MessageDialog {
private:
struct State {
lstring buttons;
vector<uint8_t> icon;
vector<uint8_t> image;
sWindow parent;
string response;
string text;

View File

@ -4,6 +4,7 @@ struct FixedLayout : sFixedLayout {
DeclareSharedLayout(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; }
};
#endif
@ -13,6 +14,7 @@ struct HorizontalLayout : sHorizontalLayout {
DeclareSharedLayout(HorizontalLayout)
auto append(sSizable sizable, Size size, signed spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, signed spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(double alignment = 0.5) { return self().setAlignment(alignment), *this; }
auto setMargin(signed margin = 0) { return self().setMargin(margin), *this; }
auto setSpacing(signed spacing = 5) { return self().setSpacing(spacing), *this; }
@ -25,6 +27,7 @@ struct VerticalLayout : sVerticalLayout {
DeclareSharedLayout(VerticalLayout)
auto append(sSizable sizable, Size size, signed spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, signed spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(double alignment = 0.0) { return self().setAlignment(alignment), *this; }
auto setMargin(signed margin = 0) { return self().setMargin(margin), *this; }
auto setSpacing(signed spacing = 5) { return self().setSpacing(spacing), *this; }

View File

@ -6,6 +6,16 @@ auto mVerticalLayout::append(sSizable sizable, Size size, signed spacing) -> typ
return *this;
}
auto mVerticalLayout::modify(sSizable sizable, Size size, signed spacing) -> type& {
if(sizable && this->sizable(sizable->offset()) == sizable) {
auto& properties = this->properties[sizable->offset()];
properties.width = size.width();
properties.height = size.height();
properties.spacing = spacing;
}
return *this;
}
auto mVerticalLayout::minimumSize() const -> Size {
signed width = 0, height = 0;
@ -56,7 +66,7 @@ auto mVerticalLayout::setEnabled(bool enabled) -> type& {
return *this;
}
auto mVerticalLayout::setFont(const string& font) -> type& {
auto mVerticalLayout::setFont(const Font& font) -> type& {
mLayout::setFont(font);
for(auto n : range(sizableCount())) {
sizable(n)->setFont(sizable(n)->font());

View File

@ -6,12 +6,13 @@ struct mVerticalLayout : mLayout {
using mLayout::remove;
auto append(sSizable sizable, Size size, signed spacing = 5) -> type&;
auto modify(sSizable sizable, Size size, signed spacing = 5) -> type&;
auto minimumSize() const -> Size override;
auto remove(sSizable sizable) -> type& override;
auto reset() -> type& override;
auto setAlignment(double alignment = 0.0) -> type&;
auto setEnabled(bool enabled = true) -> type& override;
auto setFont(const string& font = "") -> type& override;
auto setFont(const Font& font = {}) -> type& override;
auto setGeometry(Geometry geometry) -> type& override;
auto setMargin(signed margin = 0) -> type&;
auto setSpacing(signed spacing = 5) -> type&;

View File

@ -12,7 +12,7 @@ auto pAction::setEnabled(bool enabled) -> void {
gtk_widget_set_sensitive(widget, enabled);
}
auto pAction::setFont(const string& font) -> void {
auto pAction::setFont(const Font& font) -> void {
pFont::setFont(widget, font);
}

View File

@ -6,7 +6,7 @@ struct pAction : pObject {
Declare(Action, Object)
auto setEnabled(bool enabled) -> void override;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setVisible(bool visible) -> void override;
auto _mnemonic(string text) -> string;

View File

@ -9,6 +9,7 @@ static auto MenuItem_activate(GtkMenuItem*, pMenuItem* p) -> void {
auto pMenuItem::construct() -> void {
widget = gtk_image_menu_item_new_with_mnemonic("");
g_signal_connect(G_OBJECT(widget), "activate", G_CALLBACK(MenuItem_activate), (gpointer)this);
setImage(state().image);
setText(state().text);
}
@ -16,9 +17,9 @@ auto pMenuItem::destruct() -> void {
if(widget) gtk_widget_destroy(widget), widget = nullptr;
}
auto pMenuItem::setIcon(const image& icon) -> void {
if(icon) {
GtkImage* gtkImage = CreateImage(icon, true);
auto pMenuItem::setImage(const Image& image) -> void {
if(image) {
GtkImage* gtkImage = CreateImage(image, true);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), (GtkWidget*)gtkImage);
} else {
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), nullptr);

View File

@ -5,7 +5,7 @@ namespace hiro {
struct pMenuItem : pAction {
Declare(MenuItem, Action)
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setText(const string& text) -> void;
};

View File

@ -27,8 +27,6 @@ auto pMenuRadioItem::setChecked() -> void {
}
auto pMenuRadioItem::setGroup(sGroup group) -> void {
if(!group) return;
maybe<GtkRadioMenuItem*> gtkRadioMenuItem;
for(auto& weak : group->state.objects) {
if(auto object = weak.acquire()) {
@ -36,9 +34,13 @@ auto pMenuRadioItem::setGroup(sGroup group) -> void {
if(auto self = menuRadioItem->self()) {
self->lock();
gtk_radio_menu_item_set_group(self->gtkRadioMenuItem, nullptr);
if(!gtkRadioMenuItem) gtkRadioMenuItem = self->gtkRadioMenuItem;
else gtk_radio_menu_item_set_group(self->gtkRadioMenuItem, gtk_radio_menu_item_get_group(*gtkRadioMenuItem));
gtk_check_menu_item_set_active(self->gtkCheckMenuItem, menuRadioItem->checked());
if(!gtkRadioMenuItem) {
gtkRadioMenuItem = self->gtkRadioMenuItem;
gtk_check_menu_item_set_active(self->gtkCheckMenuItem, menuRadioItem->state.checked = true);
} else {
gtk_radio_menu_item_set_group(self->gtkRadioMenuItem, gtk_radio_menu_item_get_group(*gtkRadioMenuItem));
gtk_check_menu_item_set_active(self->gtkCheckMenuItem, menuRadioItem->state.checked = false);
}
self->unlock();
}
}

View File

@ -6,6 +6,7 @@ auto pMenu::construct() -> void {
gtkMenu = gtk_menu_new();
widget = gtk_image_menu_item_new_with_mnemonic("");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), gtkMenu);
setImage(state().image);
setText(state().text);
for(auto& action : state().actions) append(*action);
@ -27,16 +28,16 @@ auto pMenu::append(sAction action) -> void {
auto pMenu::remove(sAction action) -> void {
}
auto pMenu::setFont(const string& font) -> void {
auto pMenu::setFont(const Font& font) -> void {
pAction::setFont(font);
for(auto& action : state().actions) {
if(action->self()) action->self()->setFont(action->font(true));
}
}
auto pMenu::setIcon(const image& icon) -> void {
if(icon) {
GtkImage* gtkImage = CreateImage(icon, true);
auto pMenu::setImage(const Image& image) -> void {
if(image) {
GtkImage* gtkImage = CreateImage(image, true);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), (GtkWidget*)gtkImage);
} else {
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), nullptr);

View File

@ -7,8 +7,8 @@ struct pMenu : pAction {
auto append(sAction action) -> void;
auto remove(sAction action) -> void;
auto setFont(const string& font) -> void override;
auto setIcon(const image& icon) -> void;
auto setFont(const Font& font) -> void override;
auto setImage(const Image& image) -> void;
auto setText(const string& text) -> void;
GtkWidget* gtkMenu = nullptr;

View File

@ -2,67 +2,54 @@
namespace hiro {
auto pFont::serif(unsigned size, string style) -> string {
if(size == 0) size = 8;
if(style == "") style = "Normal";
return {"Serif, ", size, ", ", style};
}
auto pFont::sans(unsigned size, string style) -> string {
if(size == 0) size = 8;
if(style == "") style = "Normal";
return {"Sans, ", size, ", ", style};
}
auto pFont::monospace(unsigned size, string style) -> string {
if(size == 0) size = 8;
return {"Liberation Mono, ", size, ", ", style};
}
auto pFont::size(string font, string text) -> Size {
auto pFont::size(const Font& font, const string& text) -> Size {
PangoFontDescription* description = create(font);
Size size = pFont::size(description, text);
free(description);
return size;
}
auto pFont::create(string description) -> PangoFontDescription* {
lstring part = description.split(",", 2L).strip();
auto pFont::size(PangoFontDescription* font, const string& text) -> Size {
PangoContext* context = gdk_pango_context_get_for_screen(gdk_screen_get_default());
PangoLayout* layout = pango_layout_new(context);
pango_layout_set_font_description(layout, font);
pango_layout_set_text(layout, text, -1);
signed width = 0, height = 0;
pango_layout_get_pixel_size(layout, &width, &height);
g_object_unref((gpointer)layout);
return {width, height};
}
string family = "Sans";
unsigned size = 8u;
bool bold = false;
bool italic = false;
auto pFont::family(const string& family) -> string {
#if defined(DISPLAY_WINDOWS)
if(family == Font::Sans ) return "Tahoma";
if(family == Font::Serif) return "Georgia";
if(family == Font::Mono ) return "Lucida Console";
return family ? family : "Tahoma";
#elif defined(DISPLAY_XORG)
if(family == Font::Sans ) return "Sans";
if(family == Font::Serif) return "Serif";
if(family == Font::Mono ) return "Liberation Mono";
return family ? family : "Sans";
#else
return family;
#endif
}
if(part[0] != "") family = part[0];
if(part.size() >= 2) size = decimal(part[1]);
if(part.size() >= 3) bold = (bool)part[2].find("Bold");
if(part.size() >= 3) italic = (bool)part[2].find("Italic");
PangoFontDescription* font = pango_font_description_new();
pango_font_description_set_family(font, family);
pango_font_description_set_size(font, size * PANGO_SCALE);
pango_font_description_set_weight(font, !bold ? PANGO_WEIGHT_NORMAL : PANGO_WEIGHT_BOLD);
pango_font_description_set_style(font, !italic ? PANGO_STYLE_NORMAL : PANGO_STYLE_OBLIQUE);
return font;
auto pFont::create(const Font& font) -> PangoFontDescription* {
auto p = pango_font_description_new();
pango_font_description_set_family(p, family(font.family()));
pango_font_description_set_size(p, (font.size() ? font.size() : 8) * PANGO_SCALE);
pango_font_description_set_weight(p, font.bold() ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
pango_font_description_set_style(p, font.italic() ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL);
return p;
}
auto pFont::free(PangoFontDescription* font) -> void {
pango_font_description_free(font);
}
auto pFont::size(PangoFontDescription* font, string text) -> Size {
PangoContext* context = gdk_pango_context_get_for_screen(gdk_screen_get_default());
PangoLayout* layout = pango_layout_new(context);
pango_layout_set_font_description(layout, font);
pango_layout_set_text(layout, text, -1);
int width = 0, height = 0;
pango_layout_get_pixel_size(layout, &width, &height);
g_object_unref((gpointer)layout);
return {width, height};
}
auto pFont::setFont(GtkWidget* widget, string font) -> void {
auto pFont::setFont(GtkWidget* widget, const Font& font) -> void {
auto gtkFont = pFont::create(font);
pFont::setFont(widget, (gpointer)gtkFont);
pFont::free(gtkFont);

View File

@ -3,15 +3,12 @@
namespace hiro {
struct pFont {
static auto serif(unsigned size, string style) -> string;
static auto sans(unsigned size, string style) -> string;
static auto monospace(unsigned size, string style) -> string;
static auto size(string font, string text) -> Size;
static auto create(string description) -> PangoFontDescription*;
static auto size(const Font& font, const string& text) -> Size;
static auto size(PangoFontDescription* font, const string& text) -> Size;
static auto family(const string& family) -> string;
static auto create(const Font& font) -> PangoFontDescription*;
static auto free(PangoFontDescription* font) -> void;
static auto size(PangoFontDescription* font, string text) -> Size;
static auto setFont(GtkWidget* widget, string font) -> void;
static auto setFont(GtkWidget* widget, const Font& font) -> void;
static auto setFont(GtkWidget* widget, gpointer font) -> void;
};

View File

@ -1,13 +0,0 @@
#if defined(Hiro_Hotkey)
namespace hiro {
auto pHotkey::construct() -> void {
}
auto pHotkey::destruct() -> void {
}
}
#endif

View File

@ -1,11 +0,0 @@
#if defined(Hiro_Hotkey)
namespace hiro {
struct pHotkey : pObject {
Declare(Hotkey, Object)
};
}
#endif

View File

@ -13,7 +13,7 @@ auto pLayout::destruct() -> void {
auto pLayout::setEnabled(bool enabled) -> void {
}
auto pLayout::setFont(const string& font) -> void {
auto pLayout::setFont(const Font& font) -> void {
}
auto pLayout::setVisible(bool visible) -> void {

View File

@ -6,7 +6,7 @@ struct pLayout : pSizable {
Declare(Layout, Sizable)
auto setEnabled(bool enabled) -> void override;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setVisible(bool visible) -> void override;
};

View File

@ -27,7 +27,7 @@ auto pMenuBar::setEnabled(bool enabled) -> void {
}
}
auto pMenuBar::setFont(const string& font) -> void {
auto pMenuBar::setFont(const Font& font) -> void {
if(auto parent = _parent()) {
parent->_setMenuFont(font);
}

View File

@ -8,7 +8,7 @@ struct pMenuBar : pObject {
auto append(sMenu menu) -> void;
auto remove(sMenu menu) -> void;
auto setEnabled(bool enabled) -> void override;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setVisible(bool visible) -> void override;
auto _parent() -> pWindow*;

View File

@ -24,7 +24,7 @@ auto pObject::setEnabled(bool enabled) -> void {
auto pObject::setFocused() -> void {
}
auto pObject::setFont(const string& font) -> void {
auto pObject::setFont(const Font& font) -> void {
}
auto pObject::setVisible(bool visible) -> void {

View File

@ -15,7 +15,7 @@ struct pObject {
virtual auto reset() -> void;
virtual auto setEnabled(bool enabled) -> void;
virtual auto setFocused() -> void;
virtual auto setFont(const string& font) -> void;
virtual auto setFont(const Font& font) -> void;
virtual auto setVisible(bool visible) -> void;
auto locked() const -> bool { return locks != 0; }

View File

@ -12,7 +12,6 @@
#include "object.cpp"
#include "group.cpp"
#include "hotkey.cpp"
#include "timer.cpp"
#include "window.cpp"
#include "status-bar.cpp"

View File

@ -23,7 +23,6 @@ namespace hiro {
#include "object.hpp"
#include "group.hpp"
#include "hotkey.hpp"
#include "timer.hpp"
#include "window.hpp"
#include "status-bar.hpp"

View File

@ -21,7 +21,7 @@ auto pPopupMenu::append(sAction action) -> void {
auto pPopupMenu::remove(sAction action) -> void {
}
auto pPopupMenu::setFont(const string& font) -> void {
auto pPopupMenu::setFont(const Font& font) -> void {
for(auto& action : state().actions) {
if(action->self()) action->self()->setFont(action->font(true));
}

View File

@ -7,7 +7,7 @@ struct pPopupMenu : pObject {
auto append(sAction action) -> void;
auto remove(sAction action) -> void;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setVisible(bool visible) -> void;
GtkWidget* gtkMenu = nullptr;

View File

@ -14,7 +14,7 @@ auto pStatusBar::setEnabled(bool enabled) -> void {
}
}
auto pStatusBar::setFont(const string& font) -> void {
auto pStatusBar::setFont(const Font& font) -> void {
if(auto parent = _parent()) {
parent->_setStatusFont(font);
}

View File

@ -6,7 +6,7 @@ struct pStatusBar : pObject {
Declare(StatusBar, Object)
auto setEnabled(bool enabled) -> void override;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setText(const string& text) -> void;
auto setVisible(bool visible) -> void override;

View File

@ -20,6 +20,34 @@ static auto CreatePixbuf(image icon, bool scale = false) -> GdkPixbuf* {
auto pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, icon.width(), icon.height());
memory::copy(gdk_pixbuf_get_pixels(pixbuf), icon.data(), icon.size());
if(scale) {
auto scaled = gdk_pixbuf_scale_simple(pixbuf, 15, 15, GDK_INTERP_BILINEAR);
g_object_unref(pixbuf);
pixbuf = scaled;
}
return pixbuf;
}
static auto CreatePixbuf(const Image& image, bool scale = false) -> GdkPixbuf* {
if(!image.state.data) return nullptr;
auto pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, image.width(), image.height());
//ARGB -> ABGR conversion
const uint32_t* source = image.data();
uint32_t* target = (uint32_t*)gdk_pixbuf_get_pixels(pixbuf);
for(auto n : range(image.width() * image.height())) {
uint32_t pixel = *source++;
*target++ = (pixel & 0x00ff0000) >> 16 | (pixel & 0xff00ff00) | (pixel & 0x000000ff) << 16;
}
if(scale) {
auto scaled = gdk_pixbuf_scale_simple(pixbuf, 15, 15, GDK_INTERP_BILINEAR);
g_object_unref(pixbuf);
pixbuf = scaled;
}
return pixbuf;
}
@ -30,6 +58,13 @@ static auto CreateImage(const nall::image& image, bool scale = false) -> GtkImag
return gtkImage;
}
static auto CreateImage(const Image& image, bool scale = false) -> GtkImage* {
auto pixbuf = CreatePixbuf(image, scale);
auto gtkImage = (GtkImage*)gtk_image_new_from_pixbuf(pixbuf);
g_object_unref(pixbuf);
return gtkImage;
}
static auto DropPaths(GtkSelectionData* data) -> lstring {
gchar** uris = gtk_selection_data_get_uris(data);
if(uris == nullptr) return {};

View File

@ -9,7 +9,7 @@ auto pButton::construct() -> void {
gtkButton = GTK_BUTTON(gtkWidget);
setBordered(state().bordered);
setIcon(state().icon);
setImage(state().image);
setOrientation(state().orientation);
setText(state().text);
@ -26,13 +26,13 @@ auto pButton::minimumSize() const -> Size {
Size size = pFont::size(self().font(true), state().text);
if(state().orientation == Orientation::Horizontal) {
size.setWidth(size.width() + state().icon.width());
size.setHeight(max(size.height(), state().icon.height()));
size.setWidth(size.width() + state().image.width());
size.setHeight(max(size.height(), state().image.height()));
}
if(state().orientation == Orientation::Vertical) {
size.setWidth(max(size.width(), state().icon.width()));
size.setHeight(size.height() + state().icon.height());
size.setWidth(max(size.width(), state().image.width()));
size.setHeight(size.height() + state().image.height());
}
return {size.width() + (state().text ? 24 : 12), size.height() + 12};
@ -42,9 +42,9 @@ auto pButton::setBordered(bool bordered) -> void {
gtk_button_set_relief(gtkButton, bordered ? GTK_RELIEF_NORMAL : GTK_RELIEF_NONE);
}
auto pButton::setIcon(const image& icon) -> void {
if(icon) {
auto gtkImage = CreateImage(icon);
auto pButton::setImage(const Image& image) -> void {
if(image) {
auto gtkImage = CreateImage(image);
gtk_button_set_image(gtkButton, (GtkWidget*)gtkImage);
} else {
gtk_button_set_image(gtkButton, nullptr);

View File

@ -7,7 +7,7 @@ struct pButton : pWidget {
auto minimumSize() const -> Size override;
auto setBordered(bool bordered) -> void;
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setOrientation(Orientation orientation) -> void;
auto setText(const string& text) -> void;

View File

@ -73,16 +73,11 @@ auto pCanvas::destruct() -> void {
}
auto pCanvas::minimumSize() const -> Size {
return {max(0, state().size.width()), max(0, state().size.height())};
if(auto& image = state().image) return image.size();
return {0, 0};
}
auto pCanvas::setColor(Color color) -> void {
mode = Mode::Color;
update();
}
auto pCanvas::setData(Size size) -> void {
mode = Mode::Data;
update();
}
@ -98,13 +93,11 @@ auto pCanvas::setGeometry(Geometry geometry) -> void {
pWidget::setGeometry(geometry);
}
auto pCanvas::setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> void {
mode = Mode::Gradient;
auto pCanvas::setGradient(Gradient gradient) -> void {
update();
}
auto pCanvas::setIcon(const image& icon) -> void {
mode = Mode::Icon;
auto pCanvas::setImage(const Image& image) -> void {
update();
}
@ -146,14 +139,13 @@ auto pCanvas::_rasterize() -> void {
signed width = 0;
signed height = 0;
if(mode == Mode::Color || mode == Mode::Gradient) {
if(auto& image = state().image) {
width = image.width();
height = image.height();
} else {
width = pSizable::state().geometry.width();
height = pSizable::state().geometry.height();
} else {
width = state().size.width();
height = state().size.height();
}
if(width <= 0 || height <= 0) return;
if(width != surfaceWidth || height != surfaceHeight) _release();
@ -161,33 +153,21 @@ auto pCanvas::_rasterize() -> void {
surfaceHeight = height;
if(!surface) surface = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, width, height);
uint32_t* buffer = (uint32_t*)gdk_pixbuf_get_pixels(surface);
auto buffer = (uint32_t*)gdk_pixbuf_get_pixels(surface);
if(mode == Mode::Color) {
if(auto& image = state().image) {
memory::copy(buffer, state().image.data(), width * height * sizeof(uint32_t));
} else if(auto& gradient = state().gradient) {
auto& colors = gradient.state.colors;
nall::image fill;
fill.allocate(width, height);
fill.gradient(colors[0].value(), colors[1].value(), colors[2].value(), colors[3].value());
memory::copy(buffer, fill.data(), fill.size());
} else {
uint32_t color = state().color.value();
for(auto n : range(width * height)) buffer[n] = color;
}
if(mode == Mode::Gradient) {
image fill;
fill.allocate(width, height);
fill.gradient(
state().gradient[0].value(), state().gradient[1].value(), state().gradient[2].value(), state().gradient[3].value()
);
memory::copy(buffer, fill.data(), fill.size());
}
if(mode == Mode::Icon) {
auto icon = state().icon;
icon.scale(width, height);
icon.transform();
memory::copy(buffer, icon.data(), icon.size());
}
if(mode == Mode::Data) {
memory::copy(buffer, state().data.data(), state().data.size() * sizeof(uint32_t));
}
//ARGB -> ABGR conversion
for(auto n : range(width * height)) {
uint32_t color = *buffer;

View File

@ -7,15 +7,12 @@ struct pCanvas : pWidget {
auto minimumSize() const -> Size;
auto setColor(Color color) -> void;
auto setData(Size size) -> void;
auto setDroppable(bool droppable) -> void;
auto setGeometry(Geometry geometry) -> void override;
auto setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight) -> void;
auto setIcon(const image& icon) -> void;
auto setGradient(Gradient gradient) -> void;
auto setImage(const Image& image) -> void;
auto update() -> void;
enum class Mode : unsigned { Color, Data, Gradient, Icon };
auto _onExpose(GdkEventExpose* event) -> void;
auto _rasterize() -> void;
auto _redraw() -> void;
@ -24,7 +21,6 @@ struct pCanvas : pWidget {
GdkPixbuf* surface = nullptr;
unsigned surfaceWidth = 0;
unsigned surfaceHeight = 0;
Mode mode = Mode::Color;
};
}

View File

@ -12,7 +12,7 @@ auto pCheckButton::construct() -> void {
setBordered(state().bordered);
setChecked(state().checked);
setIcon(state().icon);
setImage(state().image);
setOrientation(state().orientation);
setText(state().text);
@ -29,13 +29,13 @@ auto pCheckButton::minimumSize() const -> Size {
Size size = pFont::size(self().font(true), state().text);
if(state().orientation == Orientation::Horizontal) {
size.setWidth(size.width() + state().icon.width());
size.setHeight(max(size.height(), state().icon.height()));
size.setWidth(size.width() + state().image.width());
size.setHeight(max(size.height(), state().image.height()));
}
if(state().orientation == Orientation::Vertical) {
size.setWidth(max(size.width(), state().icon.width()));
size.setHeight(size.height() + state().icon.height());
size.setWidth(max(size.width(), state().image.width()));
size.setHeight(size.height() + state().image.height());
}
return {size.width() + 24, size.height() + 12};
@ -51,9 +51,9 @@ auto pCheckButton::setChecked(bool checked) -> void {
unlock();
}
auto pCheckButton::setIcon(const image& icon) -> void {
if(icon) {
GtkImage* gtkImage = CreateImage(icon);
auto pCheckButton::setImage(const Image& image) -> void {
if(image) {
GtkImage* gtkImage = CreateImage(image);
gtk_button_set_image(GTK_BUTTON(gtkWidget), (GtkWidget*)gtkImage);
} else {
gtk_button_set_image(GTK_BUTTON(gtkWidget), nullptr);

View File

@ -8,7 +8,7 @@ struct pCheckButton : pWidget {
auto minimumSize() const -> Size override;
auto setBordered(bool bordered) -> void;
auto setChecked(bool checked) -> void;
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setOrientation(Orientation orientation) -> void;
auto setText(const string& text) -> void;
};

View File

@ -8,11 +8,10 @@ auto pComboButtonItem::construct() -> void {
auto pComboButtonItem::destruct() -> void {
}
auto pComboButtonItem::setIcon(image icon) -> void {
auto pComboButtonItem::setImage(const Image& image) -> void {
if(auto parent = _parent()) {
auto size = pFont::size(self().font(true), " ").height();
if(icon) icon.scale(size, size);
auto pixbuf = CreatePixbuf(icon);
auto pixbuf = CreatePixbuf(image, true);
gtk_list_store_set(parent->gtkListStore, &gtkIter, 0, pixbuf, -1);
}
}

View File

@ -5,7 +5,7 @@ namespace hiro {
struct pComboButtonItem : pObject {
Declare(ComboButtonItem, Object)
auto setIcon(image icon) -> void;
auto setImage(const Image& icon) -> void;
auto setSelected() -> void;
auto setText(const string& text) -> void;

View File

@ -32,7 +32,7 @@ auto pComboButton::append(sComboButtonItem item) -> void {
lock();
if(auto self = item->self()) {
gtk_list_store_append(gtkListStore, &self->gtkIter);
self->setIcon(item->state.icon);
self->setImage(item->state.image);
if(item->state.selected) self->setSelected();
self->setText(item->state.text);
}
@ -41,11 +41,11 @@ auto pComboButton::append(sComboButtonItem item) -> void {
}
auto pComboButton::minimumSize() const -> Size {
string font = self().font(true);
auto font = self().font(true);
signed maximumWidth = 0;
for(auto& item : state().items) {
maximumWidth = max(maximumWidth,
(item->state.icon ? pFont::size(font, " ").height() + 2 : 0)
(item->state.image ? pFont::size(font, " ").height() + 2 : 0)
+ pFont::size(font, item->state.text).width()
);
}
@ -69,7 +69,7 @@ auto pComboButton::reset() -> void {
unlock();
}
auto pComboButton::setFont(const string& font) -> void {
auto pComboButton::setFont(const Font& font) -> void {
pWidget::setFont(font);
auto fontDescription = pFont::create(font);
g_object_set(G_OBJECT(gtkCellText), "font-desc", fontDescription, nullptr);

View File

@ -9,7 +9,7 @@ struct pComboButton : pWidget {
auto minimumSize() const -> Size override;
auto remove(sComboButtonItem item) -> void;
auto reset() -> void;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto _updateSelected() -> void;

View File

@ -33,7 +33,7 @@ auto pFrame::setEnabled(bool enabled) -> void {
pWidget::setEnabled(enabled);
}
auto pFrame::setFont(const string& font) -> void {
auto pFrame::setFont(const Font& font) -> void {
if(auto layout = _layout()) layout->setFont(layout->self().font(true));
pFont::setFont(gtkLabel, font);
}

View File

@ -9,7 +9,7 @@ struct pFrame : pWidget {
auto container(mWidget& widget) -> GtkWidget* override;
auto remove(shared_pointer<mLayout> layout) -> void;
auto setEnabled(bool enabled) -> void override;
auto setFont(const string& font) -> 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;

View File

@ -8,9 +8,9 @@ auto pIconViewItem::construct() -> void {
auto pIconViewItem::destruct() -> void {
}
auto pIconViewItem::setIcon(const image& icon) -> void {
auto pIconViewItem::setImage(const Image& image) -> void {
if(auto parent = _parent()) {
parent->setItemIcon(self().offset(), icon);
parent->setItemImage(self().offset(), image);
}
}

View File

@ -5,7 +5,7 @@ namespace hiro {
struct pIconViewItem : pObject {
Declare(IconViewItem, Object)
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setSelected(bool selected) -> void;
auto setText(const string& text) -> void;

View File

@ -39,9 +39,9 @@ auto pIconView::construct() -> void {
gtk_widget_show(subWidget);
setBackgroundColor(state().backgroundColor);
setBatchable(state().batchable);
setFlow(state().flow);
setForegroundColor(state().foregroundColor);
setMultiSelect(state().multiSelect);
setOrientation(state().orientation);
for(auto position : range(self().items())) {
auto& item = state().items[position];
@ -65,7 +65,7 @@ auto pIconView::destruct() -> void {
auto pIconView::append(sIconViewItem item) -> void {
GtkTreeIter iter;
gtk_list_store_append(store, &iter);
setItemIcon(item->offset(), item->state.icon);
setItemImage(item->offset(), item->state.image);
setItemSelected(item->offset(), item->state.selected);
setItemText(item->offset(), item->state.text);
}
@ -92,6 +92,12 @@ auto pIconView::setBackgroundColor(Color color) -> void {
gtk_widget_modify_base(subWidget, GTK_STATE_NORMAL, color ? &gdkColor : nullptr);
}
auto pIconView::setBatchable(bool batchable) -> void {
gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(subWidget),
batchable ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE
);
}
auto pIconView::setFlow(Orientation flow) -> void {
//GTK+ does not support vertical flow ... the closest we can get is a horizontal flow with only one column
if(flow == Orientation::Horizontal) {
@ -115,12 +121,12 @@ auto pIconView::setGeometry(Geometry geometry) -> void {
}
}
auto pIconView::setItemIcon(unsigned position, const image& icon) -> void {
auto pIconView::setItemImage(unsigned position, const Image& image) -> void {
if(position >= self().itemCount()) return;
GtkTreeIter iter;
if(gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, string{position})) {
if(icon) {
GdkPixbuf* pixbuf = CreatePixbuf(icon);
if(image) {
GdkPixbuf* pixbuf = CreatePixbuf(image);
gtk_list_store_set(store, &iter, 0, pixbuf, -1);
} else {
gtk_list_store_set(store, &iter, 0, nullptr, -1);
@ -172,12 +178,6 @@ auto pIconView::setItemText(unsigned position, const string& text) -> void {
}
}
auto pIconView::setMultiSelect(bool multiSelect) -> void {
gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(subWidget),
multiSelect ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE
);
}
auto pIconView::setOrientation(Orientation orientation) -> void {
gtk_icon_view_set_item_orientation(GTK_ICON_VIEW(subWidget),
orientation == Orientation::Horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL

View File

@ -9,16 +9,16 @@ struct pIconView : pWidget {
auto remove(sIconViewItem item) -> void;
auto reset() -> void;
auto setBackgroundColor(Color color) -> void;
auto setBatchable(bool batchable) -> void;
auto setFlow(Orientation flow) -> void;
auto setForegroundColor(Color color) -> void;
auto setGeometry(Geometry geometry) -> void;
auto setItemIcon(unsigned position, const image& icon) -> void;
auto setItemImage(unsigned position, const Image& image) -> void;
auto setItemSelected(unsigned position, bool selected) -> void;
auto setItemSelected(const vector<signed>& selections) -> void;
auto setItemSelectedAll() -> void;
auto setItemSelectedNone() -> void;
auto setItemText(unsigned position, const string& text) -> void;
auto setMultiSelect(bool multiSelect) -> void;
auto setOrientation(Orientation orientation) -> void;
auto _updateSelected() -> void;

View File

@ -25,7 +25,7 @@ auto pListViewCell::setChecked(bool checked) -> void {
auto pListViewCell::setForegroundColor(Color color) -> void {
}
auto pListViewCell::setIcon(const image& icon) -> void {
auto pListViewCell::setImage(const Image& image) -> void {
_setState();
}
@ -50,7 +50,7 @@ auto pListViewCell::_setState() -> void {
if(auto grandparent = _grandparent()) {
grandparent->lock();
gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 0, state().checked, -1);
gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 1, CreatePixbuf(state().icon), -1);
gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 1, CreatePixbuf(state().image), -1);
gtk_list_store_set(grandparent->gtkListStore, &parent->gtkIter, 3 * self().offset() + 2, state().text.data(), -1);
grandparent->unlock();
}

View File

@ -10,7 +10,7 @@ struct pListViewCell : pObject {
auto setCheckable(bool checkable) -> void;
auto setChecked(bool checked) -> void;
auto setForegroundColor(Color color) -> void;
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setText(const string& text) -> void;
auto _grandparent() -> maybe<pListView&>;

View File

@ -75,15 +75,15 @@ auto pListViewColumn::setExpandable(bool expandable) -> void {
}
}
auto pListViewColumn::setFont(const string& font) -> void {
auto pListViewColumn::setFont(const Font& font) -> void {
}
auto pListViewColumn::setForegroundColor(Color color) -> void {
}
auto pListViewColumn::setIcon(const image& icon) -> void {
if(icon) {
gtk_image_set_from_pixbuf(GTK_IMAGE(gtkHeaderIcon), CreatePixbuf(icon));
auto pListViewColumn::setImage(const Image& image) -> void {
if(image) {
gtk_image_set_from_pixbuf(GTK_IMAGE(gtkHeaderIcon), CreatePixbuf(image));
} else {
gtk_image_clear(GTK_IMAGE(gtkHeaderIcon));
}

View File

@ -10,10 +10,10 @@ struct pListViewColumn : pObject {
auto setBackgroundColor(Color color) -> void;
auto setEditable(bool editable) -> void;
auto setExpandable(bool expandable) -> void;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setForegroundColor(Color color) -> void;
auto setHorizontalAlignment(double) -> void {}
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setResizable(bool resizable) -> void;
auto setSortable(bool sortable) -> void;
auto setText(const string& text) -> void;

View File

@ -122,7 +122,7 @@ auto pListView::setFocused() -> void {
gtk_widget_grab_focus(gtkWidgetChild);
}
auto pListView::setFont(const string& font) -> void {
auto pListView::setFont(const Font& font) -> void {
if(auto& header = state().header) {
if(auto self = header->self()) self->_setState();
}
@ -149,11 +149,11 @@ auto pListView::_cellWidth(unsigned _row, unsigned _column) -> unsigned {
if(cell->state.checkable) {
width += 24;
}
if(auto& icon = cell->state.icon) {
width += icon.width() + 2;
if(auto& image = cell->state.image) {
width += image.width() + 2;
}
if(auto& text = cell->state.text) {
width += Font::size(cell->font(true), text).width();
width += pFont::size(cell->font(true), text).width();
}
}
}
@ -164,11 +164,11 @@ auto pListView::_columnWidth(unsigned _column) -> unsigned {
unsigned width = 8;
if(auto& header = state().header) {
if(auto column = header->column(_column)) {
if(auto& icon = column->state.icon) {
width += icon.width() + 2;
if(auto& image = column->state.image) {
width += image.width() + 2;
}
if(auto& text = column->state.text) {
width += Font::size(column->font(true), text).width();
width += pFont::size(column->font(true), text).width();
}
}
}

View File

@ -16,7 +16,7 @@ struct pListView : pWidget {
auto setBatchable(bool batchable) -> void;
auto setBordered(bool bordered) -> void;
auto setFocused() -> void override;
auto setFont(const string& font) -> void override;
auto setFont(const Font& font) -> void override;
auto setForegroundColor(Color color) -> void;
auto setGeometry(Geometry geometry) -> void override;

View File

@ -5,7 +5,7 @@ namespace hiro {
static auto RadioButton_activate(GtkToggleButton*, pRadioButton* p) -> void {
if(p->groupLocked()) return;
bool wasChecked = p->state().checked;
p->setChecked();
p->self().setChecked();
if(!wasChecked) p->self().doActivate();
}
@ -13,7 +13,7 @@ auto pRadioButton::construct() -> void {
gtkWidget = gtk_toggle_button_new();
setBordered(state().bordered);
setIcon(state().icon);
setImage(state().image);
setOrientation(state().orientation);
setText(state().text);
@ -30,13 +30,13 @@ auto pRadioButton::minimumSize() const -> Size {
Size size = pFont::size(self().font(true), state().text);
if(state().orientation == Orientation::Horizontal) {
size.setWidth(size.width() + state().icon.width());
size.setHeight(max(size.height(), state().icon.height()));
size.setWidth(size.width() + state().image.width());
size.setHeight(max(size.height(), state().image.height()));
}
if(state().orientation == Orientation::Vertical) {
size.setWidth(max(size.width(), state().icon.width()));
size.setHeight(size.height() + state().icon.height());
size.setWidth(max(size.width(), state().image.width()));
size.setHeight(size.height() + state().image.height());
}
return {size.width() + 24, size.height() + 12};
@ -47,14 +47,12 @@ auto pRadioButton::setBordered(bool bordered) -> void {
}
auto pRadioButton::setChecked() -> void {
if(!self().group()) return;
for(auto& weak : self().group()->state.objects) {
if(auto object = weak.acquire()) {
if(auto radioButton = dynamic_cast<mRadioButton*>(object.data())) {
if(auto self = radioButton->self()) {
self->lock();
bool checked = self == this;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->gtkWidget), radioButton->state.checked = checked);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->gtkWidget), radioButton->state.checked);
self->unlock();
}
}
@ -63,13 +61,14 @@ auto pRadioButton::setChecked() -> void {
}
auto pRadioButton::setGroup(sGroup group) -> void {
if(!group) return;
bool first = true;
for(auto& weak : group->state.objects) {
if(auto object = weak.acquire()) {
if(auto radioButton = dynamic_cast<mRadioButton*>(object.data())) {
if(auto self = radioButton->self()) {
self->lock();
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->gtkWidget), radioButton->checked());
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->gtkWidget), radioButton->state.checked = first);
first = false;
self->unlock();
}
}
@ -77,9 +76,9 @@ auto pRadioButton::setGroup(sGroup group) -> void {
}
}
auto pRadioButton::setIcon(const image& icon) -> void {
if(icon) {
GtkImage* gtkImage = CreateImage(icon);
auto pRadioButton::setImage(const Image& image) -> void {
if(image) {
GtkImage* gtkImage = CreateImage(image);
gtk_button_set_image(GTK_BUTTON(gtkWidget), (GtkWidget*)gtkImage);
} else {
gtk_button_set_image(GTK_BUTTON(gtkWidget), nullptr);

View File

@ -9,7 +9,7 @@ struct pRadioButton : pWidget {
auto setBordered(bool bordered) -> void;
auto setChecked() -> void;
auto setGroup(sGroup group) -> void;
auto setIcon(const image& icon) -> void;
auto setImage(const Image& image) -> void;
auto setOrientation(Orientation orientation) -> void;
auto setText(const string& text) -> void;

View File

@ -5,7 +5,7 @@ namespace hiro {
static auto RadioLabel_activate(GtkToggleButton*, pRadioLabel* p) -> void {
if(p->groupLocked()) return;
bool wasChecked = p->state().checked;
p->setChecked();
p->self().setChecked();
if(!wasChecked) p->self().doActivate();
}
@ -37,8 +37,6 @@ auto pRadioLabel::setChecked() -> void {
}
auto pRadioLabel::setGroup(sGroup group) -> void {
if(!group) return;
maybe<GtkRadioButton*> gtkRadioButton;
for(auto& weak : group->state.objects) {
if(auto object = weak.acquire()) {
@ -46,9 +44,13 @@ auto pRadioLabel::setGroup(sGroup group) -> void {
if(auto self = radioLabel->self()) {
self->lock();
gtk_radio_button_set_group(self->gtkRadioButton, nullptr);
if(!gtkRadioButton) gtkRadioButton = self->gtkRadioButton;
else gtk_radio_button_set_group(self->gtkRadioButton, gtk_radio_button_get_group(*gtkRadioButton));
gtk_toggle_button_set_active(self->gtkToggleButton, radioLabel->checked());
if(!gtkRadioButton) {
gtkRadioButton = self->gtkRadioButton;
gtk_toggle_button_set_active(self->gtkToggleButton, radioLabel->state.checked = true);
} else {
gtk_radio_button_set_group(self->gtkRadioButton, gtk_radio_button_get_group(*gtkRadioButton));
gtk_toggle_button_set_active(self->gtkToggleButton, radioLabel->state.checked = false);
}
self->unlock();
}
}

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