Update to v106r38 release.

byuu says:

Changelog:

  - hiro: added Qt5 support
  - hiro: added GTK3 support (currently runs very poorly)
  - bsnes: number of recent games and quick state slots can be changed
    programmatically now
      - I may expose this as a configuration file setting, but probably
        not within the GUI
  - nall: use -Wno-everything when compiling with Clang
      - sorry, Clang's meaningless warning messages are just endless ...
This commit is contained in:
Tim Allen 2018-06-10 18:06:02 +10:00
parent 173a5d67bc
commit 15b67922b3
30 changed files with 1132 additions and 719 deletions

View File

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

View File

@ -106,26 +106,21 @@ Presentation::Presentation() {
toolsMenu.setText("Tools").setVisible(false); toolsMenu.setText("Tools").setVisible(false);
saveState.setText("Save State"); saveState.setText("Save State");
saveState1.setText("Slot 1").onActivate([&] { program->saveState("Quick/Slot 1"); }); for(uint index : range(QuickStates)) {
saveState2.setText("Slot 2").onActivate([&] { program->saveState("Quick/Slot 2"); }); saveState.append(MenuItem().setText({"Slot ", 1 + index}).onActivate([=] {
saveState3.setText("Slot 3").onActivate([&] { program->saveState("Quick/Slot 3"); }); program->saveState({"Quick/Slot ", 1 + index});
saveState4.setText("Slot 4").onActivate([&] { program->saveState("Quick/Slot 4"); }); }));
saveState5.setText("Slot 5").onActivate([&] { program->saveState("Quick/Slot 5"); }); }
saveState6.setText("Slot 6").onActivate([&] { program->saveState("Quick/Slot 6"); });
saveState7.setText("Slot 7").onActivate([&] { program->saveState("Quick/Slot 7"); });
saveState8.setText("Slot 8").onActivate([&] { program->saveState("Quick/Slot 8"); });
saveState9.setText("Slot 9").onActivate([&] { program->saveState("Quick/Slot 9"); });
loadState.setText("Load State"); loadState.setText("Load State");
loadState1.setText("Slot 1").onActivate([&] { program->loadState("Quick/Slot 1"); }); for(uint index : range(QuickStates)) {
loadState2.setText("Slot 2").onActivate([&] { program->loadState("Quick/Slot 2"); }); loadState.append(MenuItem().setText({"Slot ", 1 + index}).onActivate([=] {
loadState3.setText("Slot 3").onActivate([&] { program->loadState("Quick/Slot 3"); }); program->loadState({"Quick/Slot ", 1 + index});
loadState4.setText("Slot 4").onActivate([&] { program->loadState("Quick/Slot 4"); }); }));
loadState5.setText("Slot 5").onActivate([&] { program->loadState("Quick/Slot 5"); }); }
loadState6.setText("Slot 6").onActivate([&] { program->loadState("Quick/Slot 6"); }); loadState.append(MenuSeparator());
loadState7.setText("Slot 7").onActivate([&] { program->loadState("Quick/Slot 7"); }); loadState.append(MenuItem().setText("Recovery Slot").onActivate([&] {
loadState8.setText("Slot 8").onActivate([&] { program->loadState("Quick/Slot 8"); }); program->loadState("Quick/Recovery Slot");
loadState9.setText("Slot 9").onActivate([&] { program->loadState("Quick/Slot 9"); }); }));
loadState0.setText("Recovery Slot").onActivate([&] { program->loadState("Quick/Recovery Slot"); });
pauseEmulation.setText("Pause Emulation").onToggle([&] { pauseEmulation.setText("Pause Emulation").onToggle([&] {
if(pauseEmulation.checked()) audio->clear(); if(pauseEmulation.checked()) audio->clear();
}); });
@ -291,7 +286,7 @@ auto Presentation::toggleFullscreenMode() -> void {
auto Presentation::updateRecentGames() -> void { auto Presentation::updateRecentGames() -> void {
loadRecentGame.reset(); loadRecentGame.reset();
for(auto index : range(5)) { for(auto index : range(RecentGames)) {
MenuItem item; MenuItem item;
if(auto game = settings[string{"Game/Recent/", 1 + index}].text()) { if(auto game = settings[string{"Game/Recent/", 1 + index}].text()) {
string displayName; string displayName;
@ -311,49 +306,25 @@ auto Presentation::updateRecentGames() -> void {
} }
loadRecentGame.append(MenuSeparator()); loadRecentGame.append(MenuSeparator());
loadRecentGame.append(MenuItem().setText("Clear List").onActivate([&] { loadRecentGame.append(MenuItem().setText("Clear List").onActivate([&] {
settings("Game/Recent/1").setValue(""); for(auto index : range(RecentGames)) {
settings("Game/Recent/2").setValue(""); settings({"Game/Recent/", 1 + index}).setValue("");
settings("Game/Recent/3").setValue(""); }
settings("Game/Recent/4").setValue("");
settings("Game/Recent/5").setValue("");
updateRecentGames(); updateRecentGames();
})); }));
} }
auto Presentation::addRecentGame(string location) -> void { auto Presentation::addRecentGame(string location) -> void {
auto game1 = settings["Game/Recent/1"].text(); for(uint index : range(RecentGames + 1)) {
auto game2 = settings["Game/Recent/2"].text(); auto value = settings[{"Game/Recent/", 1 + index}].text();
auto game3 = settings["Game/Recent/3"].text(); if(!value || value == location) {
auto game4 = settings["Game/Recent/4"].text(); for(uint n : rrange(index + 1)) {
auto game5 = settings["Game/Recent/5"].text(); if(1 + n > RecentGames) continue;
settings({"Game/Recent/", 1 + n}).setValue(settings[{"Game/Recent/", n}].text());
if(game1 == location) {
game1 = location;
} else if(game2 == location) {
game2 = game1;
game1 = location;
} else if(game3 == location) {
game3 = game2;
game2 = game1;
game1 = location;
} else if(game4 == location) {
game4 = game3;
game3 = game2;
game2 = game1;
game1 = location;
} else {
game5 = game4;
game4 = game3;
game3 = game2;
game2 = game1;
game1 = location;
} }
break;
settings("Game/Recent/1").setValue(game1); }
settings("Game/Recent/2").setValue(game2); }
settings("Game/Recent/3").setValue(game3); settings("Game/Recent/1").setValue(location);
settings("Game/Recent/4").setValue(game4);
settings("Game/Recent/5").setValue(game5);
updateRecentGames(); updateRecentGames();
} }

View File

@ -9,6 +9,8 @@ struct AboutWindow : Window {
}; };
struct Presentation : Window { struct Presentation : Window {
enum : uint { RecentGames = 9, QuickStates = 9 };
Presentation(); Presentation();
auto drawIcon(uint32_t* output, uint length, uint width, uint height) -> void; auto drawIcon(uint32_t* output, uint length, uint width, uint height) -> void;
auto clearViewport() -> void; auto clearViewport() -> void;
@ -53,27 +55,7 @@ struct Presentation : Window {
MenuItem advancedSettings{&settingsMenu}; MenuItem advancedSettings{&settingsMenu};
Menu toolsMenu{&menuBar}; Menu toolsMenu{&menuBar};
Menu saveState{&toolsMenu}; Menu saveState{&toolsMenu};
MenuItem saveState1{&saveState};
MenuItem saveState2{&saveState};
MenuItem saveState3{&saveState};
MenuItem saveState4{&saveState};
MenuItem saveState5{&saveState};
MenuItem saveState6{&saveState};
MenuItem saveState7{&saveState};
MenuItem saveState8{&saveState};
MenuItem saveState9{&saveState};
Menu loadState{&toolsMenu}; Menu loadState{&toolsMenu};
MenuItem loadState1{&loadState};
MenuItem loadState2{&loadState};
MenuItem loadState3{&loadState};
MenuItem loadState4{&loadState};
MenuItem loadState5{&loadState};
MenuItem loadState6{&loadState};
MenuItem loadState7{&loadState};
MenuItem loadState8{&loadState};
MenuItem loadState9{&loadState};
MenuSeparator loadStateSeparator{&loadState};
MenuItem loadState0{&loadState};
MenuCheckItem pauseEmulation{&toolsMenu}; MenuCheckItem pauseEmulation{&toolsMenu};
MenuSeparator toolsSeparator{&toolsMenu}; MenuSeparator toolsSeparator{&toolsMenu};
MenuItem cheatEditor{&toolsMenu}; MenuItem cheatEditor{&toolsMenu};

View File

@ -13,10 +13,15 @@ ifeq ($(platform),windows)
hirolink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi hirolink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi
endif endif
ifeq ($(hiro),gtk) ifeq ($(hiro),gtk2)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0) hiroflags = $(cppflags) $(flags) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0)
hirolink = $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0) hirolink = $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0)
endif endif
ifeq ($(hiro),gtk3)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0)
hirolink = $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0)
endif
endif endif
ifeq ($(platform),macos) ifeq ($(platform),macos)
@ -32,16 +37,28 @@ endif
ifneq ($(filter $(platform),linux bsd),) ifneq ($(filter $(platform),linux bsd),)
ifeq ($(hiro),) ifeq ($(hiro),)
hiro := gtk hiro := gtk2
endif endif
ifeq ($(hiro),gtk) ifeq ($(hiro),gtk2)
hiroflags = $(cppflags) $(flags) -DHIRO_GTK $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0) hiroflags = $(cppflags) $(flags) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0 gtksourceview-2.0)
hirolink = -lX11 $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0) hirolink = -lX11 $(shell pkg-config --libs gtk+-2.0 gtksourceview-2.0)
endif endif
ifeq ($(hiro),qt) ifeq ($(hiro),gtk3)
hiroflags = $(cppflags) $(flags) -DHIRO_QT $(shell pkg-config --cflags QtCore QtGui) hiroflags = $(cppflags) $(flags) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0 gtksourceview-3.0)
hirolink = -lX11 $(shell pkg-config --libs gtk+-3.0 gtksourceview-3.0)
endif
ifeq ($(hiro),qt4)
moc = moc-qt4
hiroflags = $(cppflags) $(flags) -DHIRO_QT=4 $(shell pkg-config --cflags QtCore QtGui)
hirolink = -lX11 $(shell pkg-config --libs QtCore QtGui) hirolink = -lX11 $(shell pkg-config --libs QtCore QtGui)
endif endif
ifeq ($(hiro),qt5)
moc = /usr/local/lib/qt5/bin/moc
hiroflags = -fPIC $(cppflags) $(flags) -DHIRO_QT=5 $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)
hirolink = -lX11 $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Widgets)
endif
endif endif

View File

@ -50,7 +50,7 @@ auto pApplication::initialize() -> void {
int argc = 1; int argc = 1;
char* argv[] = {name.get(), nullptr}; char* argv[] = {name.get(), nullptr};
#else #else
//--g-fatal-warnings will force a trap on Gtk-CRITICAL errors //--g-fatal-warnings will force a trap on Gtk-CRITICAL and Gtk-WARNING messages
//this allows gdb to perform a backtrace to find an error's origin point //this allows gdb to perform a backtrace to find an error's origin point
int argc = 2; int argc = 2;
char* argv[] = {name.get(), new char[19], nullptr}; char* argv[] = {name.get(), new char[19], nullptr};
@ -75,6 +75,7 @@ auto pApplication::initialize() -> void {
g_object_set(gtkSettings, "gtk-im-module", "gtk-im-context-simple", nullptr); g_object_set(gtkSettings, "gtk-im-module", "gtk-im-context-simple", nullptr);
#endif #endif
#if HIRO_GTK==2
gtk_rc_parse_string(R"( gtk_rc_parse_string(R"(
style "HiroWindow" style "HiroWindow"
{ {
@ -99,6 +100,9 @@ auto pApplication::initialize() -> void {
} }
widget_class "*.<GtkNotebook>.<GtkHBox>.<GtkButton>" style "HiroTabFrameCloseButton" widget_class "*.<GtkNotebook>.<GtkHBox>.<GtkButton>" style "HiroTabFrameCloseButton"
)"); )");
#elif HIRO_GTK==3
//TODO: is there any alternative here with GTK3?
#endif
pKeyboard::initialize(); pKeyboard::initialize();
} }

View File

@ -41,181 +41,181 @@ auto pKeyboard::_pressed(const char* state, uint16_t code) -> bool {
auto pKeyboard::_translate(unsigned code) -> signed { auto pKeyboard::_translate(unsigned code) -> signed {
switch(code) { switch(code) {
case GDK_Escape: return 0; case GDK_KEY_Escape: return 0;
case GDK_F1: return 0; case GDK_KEY_F1: return 0;
case GDK_F2: return 0; case GDK_KEY_F2: return 0;
case GDK_F3: return 0; case GDK_KEY_F3: return 0;
case GDK_F4: return 0; case GDK_KEY_F4: return 0;
case GDK_F5: return 0; case GDK_KEY_F5: return 0;
case GDK_F6: return 0; case GDK_KEY_F6: return 0;
case GDK_F7: return 0; case GDK_KEY_F7: return 0;
case GDK_F8: return 0; case GDK_KEY_F8: return 0;
case GDK_F9: return 0; case GDK_KEY_F9: return 0;
case GDK_F10: return 0; case GDK_KEY_F10: return 0;
case GDK_F11: return 0; case GDK_KEY_F11: return 0;
case GDK_F12: return 0; case GDK_KEY_F12: return 0;
case GDK_Print: return 0; case GDK_KEY_Print: return 0;
case GDK_Scroll_Lock: return 0; case GDK_KEY_Scroll_Lock: return 0;
case GDK_Pause: return 0; case GDK_KEY_Pause: return 0;
case GDK_Insert: return 0; case GDK_KEY_Insert: return 0;
case GDK_Delete: return 0; case GDK_KEY_Delete: return 0;
case GDK_Home: return 0; case GDK_KEY_Home: return 0;
case GDK_End: return 0; case GDK_KEY_End: return 0;
case GDK_Prior: return 0; case GDK_KEY_Prior: return 0;
case GDK_Next: return 0; case GDK_KEY_Next: return 0;
case GDK_Up: return 0; case GDK_KEY_Up: return 0;
case GDK_Down: return 0; case GDK_KEY_Down: return 0;
case GDK_Left: return 0; case GDK_KEY_Left: return 0;
case GDK_Right: return 0; case GDK_KEY_Right: return 0;
case GDK_grave: return '`'; case GDK_KEY_grave: return '`';
case GDK_1: return '1'; case GDK_KEY_1: return '1';
case GDK_2: return '2'; case GDK_KEY_2: return '2';
case GDK_3: return '3'; case GDK_KEY_3: return '3';
case GDK_4: return '4'; case GDK_KEY_4: return '4';
case GDK_5: return '5'; case GDK_KEY_5: return '5';
case GDK_6: return '6'; case GDK_KEY_6: return '6';
case GDK_7: return '7'; case GDK_KEY_7: return '7';
case GDK_8: return '8'; case GDK_KEY_8: return '8';
case GDK_9: return '9'; case GDK_KEY_9: return '9';
case GDK_0: return '0'; case GDK_KEY_0: return '0';
case GDK_minus: return '-'; case GDK_KEY_minus: return '-';
case GDK_equal: return '='; case GDK_KEY_equal: return '=';
case GDK_BackSpace: return '\b'; case GDK_KEY_BackSpace: return '\b';
case GDK_asciitilde: return '~'; case GDK_KEY_asciitilde: return '~';
case GDK_exclam: return '!'; case GDK_KEY_exclam: return '!';
case GDK_at: return '@'; case GDK_KEY_at: return '@';
case GDK_numbersign: return '#'; case GDK_KEY_numbersign: return '#';
case GDK_dollar: return '$'; case GDK_KEY_dollar: return '$';
case GDK_percent: return '%'; case GDK_KEY_percent: return '%';
case GDK_asciicircum: return '^'; case GDK_KEY_asciicircum: return '^';
case GDK_ampersand: return '&'; case GDK_KEY_ampersand: return '&';
case GDK_asterisk: return '*'; case GDK_KEY_asterisk: return '*';
case GDK_parenleft: return '('; case GDK_KEY_parenleft: return '(';
case GDK_parenright: return ')'; case GDK_KEY_parenright: return ')';
case GDK_underscore: return '_'; case GDK_KEY_underscore: return '_';
case GDK_plus: return '+'; case GDK_KEY_plus: return '+';
case GDK_Tab: return '\t'; case GDK_KEY_Tab: return '\t';
case GDK_Caps_Lock: return 0; case GDK_KEY_Caps_Lock: return 0;
case GDK_Return: return '\n'; case GDK_KEY_Return: return '\n';
case GDK_Shift_L: return 0; case GDK_KEY_Shift_L: return 0;
case GDK_Shift_R: return 0; case GDK_KEY_Shift_R: return 0;
case GDK_Control_L: return 0; case GDK_KEY_Control_L: return 0;
case GDK_Control_R: return 0; case GDK_KEY_Control_R: return 0;
case GDK_Alt_L: return 0; case GDK_KEY_Alt_L: return 0;
case GDK_Alt_R: return 0; case GDK_KEY_Alt_R: return 0;
case GDK_Super_L: return 0; case GDK_KEY_Super_L: return 0;
case GDK_Super_R: return 0; case GDK_KEY_Super_R: return 0;
case GDK_Menu: return 0; case GDK_KEY_Menu: return 0;
case GDK_space: return ' '; case GDK_KEY_space: return ' ';
case GDK_bracketleft: return '['; case GDK_KEY_bracketleft: return '[';
case GDK_bracketright: return ']'; case GDK_KEY_bracketright: return ']';
case GDK_backslash: return '\\'; case GDK_KEY_backslash: return '\\';
case GDK_semicolon: return ';'; case GDK_KEY_semicolon: return ';';
case GDK_apostrophe: return '\''; case GDK_KEY_apostrophe: return '\'';
case GDK_comma: return ','; case GDK_KEY_comma: return ',';
case GDK_period: return '.'; case GDK_KEY_period: return '.';
case GDK_slash: return '/'; case GDK_KEY_slash: return '/';
case GDK_braceleft: return '{'; case GDK_KEY_braceleft: return '{';
case GDK_braceright: return '}'; case GDK_KEY_braceright: return '}';
case GDK_bar: return '|'; case GDK_KEY_bar: return '|';
case GDK_colon: return ':'; case GDK_KEY_colon: return ':';
case GDK_quotedbl: return '\"'; case GDK_KEY_quotedbl: return '\"';
case GDK_less: return '<'; case GDK_KEY_less: return '<';
case GDK_greater: return '>'; case GDK_KEY_greater: return '>';
case GDK_question: return '?'; case GDK_KEY_question: return '?';
case GDK_A: return 'A'; case GDK_KEY_A: return 'A';
case GDK_B: return 'B'; case GDK_KEY_B: return 'B';
case GDK_C: return 'C'; case GDK_KEY_C: return 'C';
case GDK_D: return 'D'; case GDK_KEY_D: return 'D';
case GDK_E: return 'E'; case GDK_KEY_E: return 'E';
case GDK_F: return 'F'; case GDK_KEY_F: return 'F';
case GDK_G: return 'G'; case GDK_KEY_G: return 'G';
case GDK_H: return 'H'; case GDK_KEY_H: return 'H';
case GDK_I: return 'I'; case GDK_KEY_I: return 'I';
case GDK_J: return 'J'; case GDK_KEY_J: return 'J';
case GDK_K: return 'K'; case GDK_KEY_K: return 'K';
case GDK_L: return 'L'; case GDK_KEY_L: return 'L';
case GDK_M: return 'M'; case GDK_KEY_M: return 'M';
case GDK_N: return 'N'; case GDK_KEY_N: return 'N';
case GDK_O: return 'O'; case GDK_KEY_O: return 'O';
case GDK_P: return 'P'; case GDK_KEY_P: return 'P';
case GDK_Q: return 'Q'; case GDK_KEY_Q: return 'Q';
case GDK_R: return 'R'; case GDK_KEY_R: return 'R';
case GDK_S: return 'S'; case GDK_KEY_S: return 'S';
case GDK_T: return 'T'; case GDK_KEY_T: return 'T';
case GDK_U: return 'U'; case GDK_KEY_U: return 'U';
case GDK_V: return 'V'; case GDK_KEY_V: return 'V';
case GDK_W: return 'W'; case GDK_KEY_W: return 'W';
case GDK_X: return 'X'; case GDK_KEY_X: return 'X';
case GDK_Y: return 'Y'; case GDK_KEY_Y: return 'Y';
case GDK_Z: return 'Z'; case GDK_KEY_Z: return 'Z';
case GDK_a: return 'a'; case GDK_KEY_a: return 'a';
case GDK_b: return 'b'; case GDK_KEY_b: return 'b';
case GDK_c: return 'c'; case GDK_KEY_c: return 'c';
case GDK_d: return 'd'; case GDK_KEY_d: return 'd';
case GDK_e: return 'e'; case GDK_KEY_e: return 'e';
case GDK_f: return 'f'; case GDK_KEY_f: return 'f';
case GDK_g: return 'g'; case GDK_KEY_g: return 'g';
case GDK_h: return 'h'; case GDK_KEY_h: return 'h';
case GDK_i: return 'i'; case GDK_KEY_i: return 'i';
case GDK_j: return 'j'; case GDK_KEY_j: return 'j';
case GDK_k: return 'k'; case GDK_KEY_k: return 'k';
case GDK_l: return 'l'; case GDK_KEY_l: return 'l';
case GDK_m: return 'm'; case GDK_KEY_m: return 'm';
case GDK_n: return 'n'; case GDK_KEY_n: return 'n';
case GDK_o: return 'o'; case GDK_KEY_o: return 'o';
case GDK_p: return 'p'; case GDK_KEY_p: return 'p';
case GDK_q: return 'q'; case GDK_KEY_q: return 'q';
case GDK_r: return 'r'; case GDK_KEY_r: return 'r';
case GDK_s: return 's'; case GDK_KEY_s: return 's';
case GDK_t: return 't'; case GDK_KEY_t: return 't';
case GDK_u: return 'u'; case GDK_KEY_u: return 'u';
case GDK_v: return 'v'; case GDK_KEY_v: return 'v';
case GDK_w: return 'w'; case GDK_KEY_w: return 'w';
case GDK_x: return 'x'; case GDK_KEY_x: return 'x';
case GDK_y: return 'y'; case GDK_KEY_y: return 'y';
case GDK_z: return 'z'; case GDK_KEY_z: return 'z';
case GDK_Num_Lock: return 0; case GDK_KEY_Num_Lock: return 0;
case GDK_KP_Divide: return '/'; case GDK_KEY_KP_Divide: return '/';
case GDK_KP_Multiply: return '*'; case GDK_KEY_KP_Multiply: return '*';
case GDK_KP_Subtract: return '-'; case GDK_KEY_KP_Subtract: return '-';
case GDK_KP_Add: return '+'; case GDK_KEY_KP_Add: return '+';
case GDK_KP_Enter: return '\n'; case GDK_KEY_KP_Enter: return '\n';
case GDK_KP_Decimal: return '.'; case GDK_KEY_KP_Decimal: return '.';
case GDK_KP_1: return '1'; case GDK_KEY_KP_1: return '1';
case GDK_KP_2: return '2'; case GDK_KEY_KP_2: return '2';
case GDK_KP_3: return '3'; case GDK_KEY_KP_3: return '3';
case GDK_KP_4: return '4'; case GDK_KEY_KP_4: return '4';
case GDK_KP_5: return '5'; case GDK_KEY_KP_5: return '5';
case GDK_KP_6: return '6'; case GDK_KEY_KP_6: return '6';
case GDK_KP_7: return '7'; case GDK_KEY_KP_7: return '7';
case GDK_KP_8: return '8'; case GDK_KEY_KP_8: return '8';
case GDK_KP_9: return '9'; case GDK_KEY_KP_9: return '9';
case GDK_KP_0: return '0'; case GDK_KEY_KP_0: return '0';
case GDK_KP_Home: return 0; case GDK_KEY_KP_Home: return 0;
case GDK_KP_End: return 0; case GDK_KEY_KP_End: return 0;
case GDK_KP_Page_Up: return 0; case GDK_KEY_KP_Page_Up: return 0;
case GDK_KP_Page_Down: return 0; case GDK_KEY_KP_Page_Down: return 0;
case GDK_KP_Up: return 0; case GDK_KEY_KP_Up: return 0;
case GDK_KP_Down: return 0; case GDK_KEY_KP_Down: return 0;
case GDK_KP_Left: return 0; case GDK_KEY_KP_Left: return 0;
case GDK_KP_Right: return 0; case GDK_KEY_KP_Right: return 0;
case GDK_KP_Begin: return 0; case GDK_KEY_KP_Begin: return 0;
case GDK_KP_Insert: return 0; case GDK_KEY_KP_Insert: return 0;
case GDK_KP_Delete: return 0; case GDK_KEY_KP_Delete: return 0;
} }
return 0; return 0;

View File

@ -2,7 +2,11 @@ namespace hiro {
Settings::Settings() { Settings::Settings() {
string path = {Path::userData(), "hiro/"}; string path = {Path::userData(), "hiro/"};
auto document = BML::unserialize(file::read({path, "gtk.bml"})); #if HIRO_GTK==2
auto document = BML::unserialize(file::read({path, "gtk2.bml"}));
#elif HIRO_GTK==3
auto document = BML::unserialize(file::read({path, "gtk3.bml"}));
#endif
auto get = [&](string_view name) { auto get = [&](string_view name) {
return document[name]; return document[name];
@ -32,7 +36,11 @@ Settings::~Settings() {
set("Geometry/MenuHeight", geometry.menuHeight); set("Geometry/MenuHeight", geometry.menuHeight);
set("Geometry/StatusHeight", geometry.statusHeight); set("Geometry/StatusHeight", geometry.statusHeight);
file::write({path, "gtk.bml"}, BML::serialize(document)); #if HIRO_GTK==2
file::write({path, "gtk2.bml"}, BML::serialize(document));
#elif HIRO_GTK==3
file::write({path, "gtk3.bml"}, BML::serialize(document));
#endif
} }
} }

View File

@ -132,7 +132,11 @@ auto pCanvas::_onExpose(GdkEventExpose* expose) -> void {
height = geometry.height(); height = geometry.height();
} }
#if HIRO_GTK==2
gdk_draw_pixbuf(gtk_widget_get_window(gtkWidget), nullptr, surface, sx, sy, dx, dy, width, height, GDK_RGB_DITHER_NONE, 0, 0); gdk_draw_pixbuf(gtk_widget_get_window(gtkWidget), nullptr, surface, sx, sy, dx, dy, width, height, GDK_RGB_DITHER_NONE, 0, 0);
#elif HIRO_GTK==3
//TODO: use cairo here, but how? no examples show to use sx, sy
#endif
} }
auto pCanvas::_rasterize() -> void { auto pCanvas::_rasterize() -> void {

View File

@ -26,7 +26,11 @@ static auto HexEdit_scroll(GtkRange* range, GtkScrollType scroll, double value,
} }
auto pHexEdit::construct() -> void { auto pHexEdit::construct() -> void {
#if HIRO_GTK==2
gtkWidget = gtk_hbox_new(false, 0); gtkWidget = gtk_hbox_new(false, 0);
#elif HIRO_GTK==3
gtkWidget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
#endif
container = gtk_scrolled_window_new(0, 0); container = gtk_scrolled_window_new(0, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
@ -37,7 +41,11 @@ auto pHexEdit::construct() -> void {
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_NONE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_NONE);
gtk_container_add(GTK_CONTAINER(container), subWidget); gtk_container_add(GTK_CONTAINER(container), subWidget);
scrollBar = gtk_vscrollbar_new((GtkAdjustment*)nullptr); #if HIRO_GTK==2
scrollBar = gtk_vscrollbar_new(nullptr);
#elif HIRO_GTK==3
scrollBar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, nullptr);
#endif
gtk_range_set_range(GTK_RANGE(scrollBar), 0, 255); gtk_range_set_range(GTK_RANGE(scrollBar), 0, 255);
gtk_range_set_increments(GTK_RANGE(scrollBar), 1, 16); gtk_range_set_increments(GTK_RANGE(scrollBar), 1, 16);
gtk_widget_set_sensitive(scrollBar, false); gtk_widget_set_sensitive(scrollBar, false);
@ -77,7 +85,7 @@ auto pHexEdit::destruct() -> void {
} }
auto pHexEdit::focused() const -> bool { auto pHexEdit::focused() const -> bool {
return GTK_WIDGET_HAS_FOCUS(subWidget) || GTK_WIDGET_HAS_FOCUS(scrollBar); return gtk_widget_has_focus(subWidget) || gtk_widget_has_focus(scrollBar);
} }
auto pHexEdit::setAddress(unsigned address) -> void { auto pHexEdit::setAddress(unsigned address) -> void {
@ -166,17 +174,17 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool {
signed cursorY = position / lineWidth; signed cursorY = position / lineWidth;
signed cursorX = position % lineWidth; signed cursorX = position % lineWidth;
if(scancode == GDK_Home) { if(scancode == GDK_KEY_Home) {
setCursorPosition(cursorY * lineWidth + 10); setCursorPosition(cursorY * lineWidth + 10);
return true; return true;
} }
if(scancode == GDK_End) { if(scancode == GDK_KEY_End) {
setCursorPosition(cursorY * lineWidth + 10 + (state().columns * 3 - 1)); setCursorPosition(cursorY * lineWidth + 10 + (state().columns * 3 - 1));
return true; return true;
} }
if(scancode == GDK_Up) { if(scancode == GDK_KEY_Up) {
if(cursorY != 0) return false; if(cursorY != 0) return false;
signed newAddress = state().address - state().columns; signed newAddress = state().address - state().columns;
@ -187,7 +195,7 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool {
return true; return true;
} }
if(scancode == GDK_Down) { if(scancode == GDK_KEY_Down) {
if(cursorY >= rows() - 1) return true; if(cursorY >= rows() - 1) return true;
if(cursorY != state().rows - 1) return false; if(cursorY != state().rows - 1) return false;
@ -199,7 +207,7 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool {
return true; return true;
} }
if(scancode == GDK_Page_Up) { if(scancode == GDK_KEY_Page_Up) {
signed newAddress = state().address - state().columns * state().rows; signed newAddress = state().address - state().columns * state().rows;
if(newAddress >= 0) { if(newAddress >= 0) {
self().setAddress(newAddress); self().setAddress(newAddress);
@ -210,7 +218,7 @@ auto pHexEdit::keyPress(unsigned scancode, unsigned mask) -> bool {
return true; return true;
} }
if(scancode == GDK_Page_Down) { if(scancode == GDK_KEY_Page_Down) {
signed newAddress = state().address + state().columns * state().rows; signed newAddress = state().address + state().columns * state().rows;
for(auto n : range(state().rows)) { for(auto n : range(state().rows)) {
if(newAddress + state().columns * state().rows - (state().columns - 1) <= state().length) { if(newAddress + state().columns * state().rows - (state().columns - 1) <= state().length) {

View File

@ -10,7 +10,11 @@ static auto HorizontalScrollBar_change(GtkRange* gtkRange, pHorizontalScrollBar*
} }
auto pHorizontalScrollBar::construct() -> void { auto pHorizontalScrollBar::construct() -> void {
gtkWidget = gtk_hscrollbar_new(0); #if HIRO_GTK==2
gtkWidget = gtk_hscrollbar_new(nullptr);
#elif HIRO_GTK==3
gtkWidget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, nullptr);
#endif
setLength(state().length); setLength(state().length);
setPosition(state().position); setPosition(state().position);

View File

@ -10,7 +10,11 @@ static auto HorizontalSlider_change(GtkRange* gtkRange, pHorizontalSlider* p) ->
} }
auto pHorizontalSlider::construct() -> void { auto pHorizontalSlider::construct() -> void {
#if HIRO_GTK==2
gtkWidget = gtk_hscale_new_with_range(0, 100, 1); gtkWidget = gtk_hscale_new_with_range(0, 100, 1);
#elif HIRO_GTK==3
gtkWidget = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 100, 1);
#endif
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false); gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
setLength(state().length); setLength(state().length);

View File

@ -65,7 +65,11 @@ auto pTabFrame::append(sTabFrameItem item) -> void {
lock(); lock();
Tab tab; Tab tab;
tab.child = gtk_fixed_new(); tab.child = gtk_fixed_new();
#if HIRO_GTK==2
tab.container = gtk_hbox_new(false, 0); tab.container = gtk_hbox_new(false, 0);
#elif HIRO_GTK==3
tab.container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
#endif
tab.image = gtk_image_new(); tab.image = gtk_image_new();
tab.title = gtk_label_new(""); tab.title = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(tab.title), 0.0, 0.5); gtk_misc_set_alignment(GTK_MISC(tab.title), 0.0, 0.5);
@ -259,10 +263,14 @@ auto pTabFrame::_tabHeight() -> unsigned {
signed height = 1; signed height = 1;
for(auto n : range(self().items())) { for(auto n : range(self().items())) {
height = max(height, tabs[n].image->allocation.height); GtkAllocation imageAllocation, titleAllocation, closeAllocation;
height = max(height, tabs[n].title->allocation.height); gtk_widget_get_allocation(tabs[n].image, &imageAllocation);
gtk_widget_get_allocation(tabs[n].title, &titleAllocation);
gtk_widget_get_allocation(tabs[n].close, &closeAllocation);
height = max(height, imageAllocation.height);
height = max(height, titleAllocation.height);
if(!state().items[n]->closable()) continue; if(!state().items[n]->closable()) continue;
height = max(height, tabs[n].close->allocation.height); height = max(height, closeAllocation.height);
} }
return height; return height;
@ -272,8 +280,12 @@ auto pTabFrame::_tabWidth() -> unsigned {
signed width = 1; signed width = 1;
for(auto n : range(self().items())) { for(auto n : range(self().items())) {
width = max(width, tabs[n].image->allocation.width + tabs[n].title->allocation.width + GtkAllocation imageAllocation, titleAllocation, closeAllocation;
(state().items[n]->closable() ? tabs[n].close->allocation.width : 0) gtk_widget_get_allocation(tabs[n].image, &imageAllocation);
gtk_widget_get_allocation(tabs[n].title, &titleAllocation);
gtk_widget_get_allocation(tabs[n].close, &closeAllocation);
width = max(width, imageAllocation.width + titleAllocation.width +
(state().items[n]->closable() ? closeAllocation.width : 0)
); );
} }

View File

@ -7,7 +7,11 @@ auto pTableViewColumn::construct() -> void {
auto handle = grandparent.data(); auto handle = grandparent.data();
unsigned offset = self().offset(); unsigned offset = self().offset();
#if HIRO_GTK==2
gtkHeader = gtk_hbox_new(false, 0); gtkHeader = gtk_hbox_new(false, 0);
#elif HIRO_GTK==3
gtkHeader = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
#endif
gtkHeaderIcon = gtk_image_new(); gtkHeaderIcon = gtk_image_new();
gtk_box_pack_start(GTK_BOX(gtkHeader), gtkHeaderIcon, false, false, 0); gtk_box_pack_start(GTK_BOX(gtkHeader), gtkHeaderIcon, false, false, 0);

View File

@ -57,7 +57,7 @@ auto pTableView::append(sTableViewItem item) -> void {
} }
auto pTableView::focused() const -> bool { auto pTableView::focused() const -> bool {
return GTK_WIDGET_HAS_FOCUS(gtkTreeView); return gtk_widget_has_focus(GTK_WIDGET(gtkTreeView));
} }
auto pTableView::remove(sTableViewHeader header) -> void { auto pTableView::remove(sTableViewHeader header) -> void {
@ -82,7 +82,9 @@ auto pTableView::resizeColumns() -> void {
signed maximumWidth = self().geometry().width() - 6; signed maximumWidth = self().geometry().width() - 6;
if(auto scrollBar = gtk_scrolled_window_get_vscrollbar(gtkScrolledWindow)) { if(auto scrollBar = gtk_scrolled_window_get_vscrollbar(gtkScrolledWindow)) {
if(gtk_widget_get_visible(scrollBar)) maximumWidth -= scrollBar->allocation.width; GtkAllocation allocation;
gtk_widget_get_allocation(scrollBar, &allocation);
if(gtk_widget_get_visible(scrollBar)) maximumWidth -= allocation.width;
} }
signed expandWidth = 0; signed expandWidth = 0;

View File

@ -48,7 +48,7 @@ auto pTextEdit::destruct() -> void {
} }
auto pTextEdit::focused() const -> bool { auto pTextEdit::focused() const -> bool {
return GTK_WIDGET_HAS_FOCUS(subWidget); return gtk_widget_has_focus(subWidget);
} }
auto pTextEdit::setBackgroundColor(Color color) -> void { auto pTextEdit::setBackgroundColor(Color color) -> void {

View File

@ -10,7 +10,11 @@ static auto VerticalScrollBar_change(GtkRange* gtkRange, pVerticalScrollBar* p)
} }
auto pVerticalScrollBar::construct() -> void { auto pVerticalScrollBar::construct() -> void {
gtkWidget = gtk_vscrollbar_new(0); #if HIRO_GTK==2
gtkWidget = gtk_vscrollbar_new(nullptr);
#elif HIRO_GTK==3
gtkWidget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, nullptr);
#endif
setLength(state().length); setLength(state().length);
setPosition(state().position); setPosition(state().position);

View File

@ -10,7 +10,11 @@ static auto VerticalSlider_change(GtkRange* gtkRange, pVerticalSlider* p) -> voi
} }
auto pVerticalSlider::construct() -> void { auto pVerticalSlider::construct() -> void {
#if HIRO_GTK==2
gtkWidget = gtk_vscale_new_with_range(0, 100, 1); gtkWidget = gtk_vscale_new_with_range(0, 100, 1);
#elif HIRO_GTK==3
gtkWidget = gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL, 0, 100, 1);
#endif
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false); gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
setLength(state().length); setLength(state().length);

View File

@ -10,6 +10,10 @@ GtkSelectionData* data, unsigned type, unsigned timestamp, pViewport* p) -> void
p->self().doDrop(paths); p->self().doDrop(paths);
} }
static auto Viewport_expose(GtkWidget* widget, GdkEventExpose* event) -> signed {
return true;
}
static auto Viewport_mouseLeave(GtkWidget* widget, GdkEventButton* event, pViewport* p) -> signed { static auto Viewport_mouseLeave(GtkWidget* widget, GdkEventButton* event, pViewport* p) -> signed {
p->self().doMouseLeave(); p->self().doMouseLeave();
return true; return true;
@ -41,7 +45,7 @@ static auto Viewport_mouseRelease(GtkWidget* widget, GdkEventButton* event, pVie
auto pViewport::construct() -> void { auto pViewport::construct() -> void {
gtkWidget = gtk_drawing_area_new(); gtkWidget = gtk_drawing_area_new();
gtk_widget_add_events(gtkWidget, gtk_widget_add_events(gtkWidget,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK); GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK);
GdkColor color; GdkColor color;
color.pixel = 0; color.pixel = 0;
@ -55,6 +59,7 @@ auto pViewport::construct() -> void {
g_signal_connect(G_OBJECT(gtkWidget), "button-press-event", G_CALLBACK(Viewport_mousePress), (gpointer)this); g_signal_connect(G_OBJECT(gtkWidget), "button-press-event", G_CALLBACK(Viewport_mousePress), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "button-release-event", G_CALLBACK(Viewport_mouseRelease), (gpointer)this); g_signal_connect(G_OBJECT(gtkWidget), "button-release-event", G_CALLBACK(Viewport_mouseRelease), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "drag-data-received", G_CALLBACK(Viewport_dropEvent), (gpointer)this); g_signal_connect(G_OBJECT(gtkWidget), "drag-data-received", G_CALLBACK(Viewport_dropEvent), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "expose-event", G_CALLBACK(Viewport_expose), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "leave-notify-event", G_CALLBACK(Viewport_mouseLeave), (gpointer)this); g_signal_connect(G_OBJECT(gtkWidget), "leave-notify-event", G_CALLBACK(Viewport_mouseLeave), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "motion-notify-event", G_CALLBACK(Viewport_mouseMove), (gpointer)this); g_signal_connect(G_OBJECT(gtkWidget), "motion-notify-event", G_CALLBACK(Viewport_mouseMove), (gpointer)this);

View File

@ -20,7 +20,7 @@ auto pWidget::container(mWidget& widget) -> GtkWidget* {
auto pWidget::focused() const -> bool { auto pWidget::focused() const -> bool {
if(!gtkWidget) return false; if(!gtkWidget) return false;
return GTK_WIDGET_HAS_FOCUS(gtkWidget); return gtk_widget_has_focus(gtkWidget);
} }
auto pWidget::setEnabled(bool enabled) -> void { auto pWidget::setEnabled(bool enabled) -> void {
@ -51,8 +51,10 @@ auto pWidget::setGeometry(Geometry geometry) -> void {
auto time = chrono::millisecond(); auto time = chrono::millisecond();
while(chrono::millisecond() - time < 20) { while(chrono::millisecond() - time < 20) {
gtk_main_iteration_do(false); gtk_main_iteration_do(false);
if(gtkWidget->allocation.width != geometry.width ()) continue; GtkAllocation allocation;
if(gtkWidget->allocation.height != geometry.height()) continue; gtk_widget_get_allocation(gtkWidget, &allocation);
if(allocation.width != geometry.width ()) continue;
if(allocation.height != geometry.height()) continue;
break; break;
} }
locked = false; locked = false;

View File

@ -12,17 +12,16 @@ static auto Window_close(GtkWidget* widget, GdkEvent* event, pWindow* p) -> sign
return true; return true;
} }
static auto Window_expose(GtkWidget* widget, GdkEvent* event, pWindow* p) -> signed { //GTK3 draw: called into by GTK2 expose-event
static auto Window_draw(GtkWidget* widget, cairo_t* context, pWindow* p) -> signed {
if(auto color = p->state().backgroundColor) { if(auto color = p->state().backgroundColor) {
cairo_t* context = gdk_cairo_create(widget->window);
double red = (double)color.red() / 255.0; double red = (double)color.red() / 255.0;
double green = (double)color.green() / 255.0; double green = (double)color.green() / 255.0;
double blue = (double)color.blue() / 255.0; double blue = (double)color.blue() / 255.0;
double alpha = (double)color.alpha() / 255.0; double alpha = (double)color.alpha() / 255.0;
if(gdk_screen_is_composited(gdk_screen_get_default()) if(gdk_screen_is_composited(gdk_screen_get_default())
&& gdk_screen_get_rgba_colormap(gdk_screen_get_default()) && gdk_screen_get_rgba_visual(gdk_screen_get_default())
) { ) {
cairo_set_source_rgba(context, red, green, blue, alpha); cairo_set_source_rgba(context, red, green, blue, alpha);
} else { } else {
@ -36,6 +35,15 @@ static auto Window_expose(GtkWidget* widget, GdkEvent* event, pWindow* p) -> sig
return false; return false;
} }
//GTK2 expose-event
static auto Window_expose(GtkWidget* widget, GdkEvent* event, pWindow* p) -> signed {
if(auto color = p->state().backgroundColor) {
cairo_t* context = gdk_cairo_create(gtk_widget_get_window(widget));
return Window_draw(widget, context, p);
}
return false;
}
static auto Window_configure(GtkWidget* widget, GdkEvent* event, pWindow* p) -> signed { static auto Window_configure(GtkWidget* widget, GdkEvent* event, pWindow* p) -> signed {
if(!gtk_widget_get_realized(p->widget)) return false; if(!gtk_widget_get_realized(p->widget)) return false;
if(!p->pObject::state().visible) return false; if(!p->pObject::state().visible) return false;
@ -43,7 +51,11 @@ static auto Window_configure(GtkWidget* widget, GdkEvent* event, pWindow* p) ->
GdkRectangle border, client; GdkRectangle border, client;
gdk_window_get_frame_extents(gdkWindow, &border); gdk_window_get_frame_extents(gdkWindow, &border);
#if HIRO_GTK==2
gdk_window_get_geometry(gdkWindow, nullptr, nullptr, &client.width, &client.height, nullptr); gdk_window_get_geometry(gdkWindow, nullptr, nullptr, &client.width, &client.height, nullptr);
#elif HIRO_GTK==3
gdk_window_get_geometry(gdkWindow, nullptr, nullptr, &client.width, &client.height);
#endif
gdk_window_get_origin(gdkWindow, &client.x, &client.y); gdk_window_get_origin(gdkWindow, &client.x, &client.y);
if(!p->state().fullScreen) { if(!p->state().fullScreen) {
@ -85,11 +97,19 @@ GtkSelectionData* data, unsigned type, unsigned timestamp, pWindow* p) -> void {
p->self().doDrop(paths); p->self().doDrop(paths);
} }
static auto Window_getPreferredWidth(GtkWidget* widget, int* minimalWidth, int* naturalWidth) -> void {
//TODO: get pWindow; use sizeRequest
}
static auto Window_getPreferredHeight(GtkWidget* widget, int* minimalHeight, int* naturalHeight) -> void {
//TODO: get pWindow; use sizeRequest
}
static auto Window_keyPress(GtkWidget* widget, GdkEventKey* event, pWindow* p) -> signed { static auto Window_keyPress(GtkWidget* widget, GdkEventKey* event, pWindow* p) -> signed {
if(auto key = pKeyboard::_translate(event->keyval)) { if(auto key = pKeyboard::_translate(event->keyval)) {
p->self().doKeyPress(key); p->self().doKeyPress(key);
} }
if(p->state().dismissable && event->keyval == GDK_Escape) { if(p->state().dismissable && event->keyval == GDK_KEY_Escape) {
if(p->state().onClose) { if(p->state().onClose) {
p->self().doClose(); p->self().doClose();
} else { } else {
@ -147,14 +167,18 @@ auto pWindow::construct() -> void {
else if(_setIcon("/usr/local/share/pixmaps/")); else if(_setIcon("/usr/local/share/pixmaps/"));
else if(_setIcon("/usr/share/pixmaps/")); else if(_setIcon("/usr/share/pixmaps/"));
GdkColormap* colormap = gdk_screen_get_rgba_colormap(gdk_screen_get_default()); auto visual = gdk_screen_get_rgba_visual(gdk_screen_get_default());
if(!colormap) colormap = gdk_screen_get_rgb_colormap(gdk_screen_get_default()); if(!visual) visual = gdk_screen_get_system_visual(gdk_screen_get_default());
if(colormap) gtk_widget_set_colormap(widget, colormap); if(visual) gtk_widget_set_visual(widget, visual);
gtk_widget_set_app_paintable(widget, true); gtk_widget_set_app_paintable(widget, true);
gtk_widget_add_events(widget, GDK_CONFIGURE); gtk_widget_add_events(widget, GDK_CONFIGURE);
#if HIRO_GTK==2
menuContainer = gtk_vbox_new(false, 0); menuContainer = gtk_vbox_new(false, 0);
#elif HIRO_GTK==3
menuContainer = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
#endif
gtk_container_add(GTK_CONTAINER(widget), menuContainer); gtk_container_add(GTK_CONTAINER(widget), menuContainer);
gtk_widget_show(menuContainer); gtk_widget_show(menuContainer);
@ -167,7 +191,11 @@ auto pWindow::construct() -> void {
statusContainer = gtk_event_box_new(); statusContainer = gtk_event_box_new();
gtkStatus = gtk_statusbar_new(); gtkStatus = gtk_statusbar_new();
#if HIRO_GTK==2
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(gtkStatus), true); gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(gtkStatus), true);
#elif HIRO_GTK==3
gtk_window_set_has_resize_grip(GTK_WINDOW(widget), true);
#endif
gtk_container_add(GTK_CONTAINER(statusContainer), gtkStatus); gtk_container_add(GTK_CONTAINER(statusContainer), gtkStatus);
gtk_box_pack_start(GTK_BOX(menuContainer), statusContainer, false, false, 0); gtk_box_pack_start(GTK_BOX(menuContainer), statusContainer, false, false, 0);
gtk_widget_show(statusContainer); gtk_widget_show(statusContainer);
@ -179,13 +207,23 @@ auto pWindow::construct() -> void {
setTitle(state().title); setTitle(state().title);
g_signal_connect(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)this); g_signal_connect(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)this);
#if HIRO_GTK==2
g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(Window_expose), (gpointer)this); g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(Window_expose), (gpointer)this);
#elif HIRO_GTK==3
g_signal_connect(G_OBJECT(widget), "draw", G_CALLBACK(Window_draw), (gpointer)this);
#endif
g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)this); g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)this);
g_signal_connect(G_OBJECT(widget), "drag-data-received", G_CALLBACK(Window_drop), (gpointer)this); g_signal_connect(G_OBJECT(widget), "drag-data-received", G_CALLBACK(Window_drop), (gpointer)this);
g_signal_connect(G_OBJECT(widget), "key-press-event", G_CALLBACK(Window_keyPress), (gpointer)this); g_signal_connect(G_OBJECT(widget), "key-press-event", G_CALLBACK(Window_keyPress), (gpointer)this);
g_signal_connect(G_OBJECT(widget), "key-release-event", G_CALLBACK(Window_keyRelease), (gpointer)this); g_signal_connect(G_OBJECT(widget), "key-release-event", G_CALLBACK(Window_keyRelease), (gpointer)this);
g_signal_connect(G_OBJECT(formContainer), "size-allocate", G_CALLBACK(Window_sizeAllocate), (gpointer)this); g_signal_connect(G_OBJECT(formContainer), "size-allocate", G_CALLBACK(Window_sizeAllocate), (gpointer)this);
#if HIRO_GTK==2
g_signal_connect(G_OBJECT(formContainer), "size-request", G_CALLBACK(Window_sizeRequest), (gpointer)this); g_signal_connect(G_OBJECT(formContainer), "size-request", G_CALLBACK(Window_sizeRequest), (gpointer)this);
#elif HIRO_GTK==3
auto widgetClass = GTK_WIDGET_GET_CLASS(formContainer);
widgetClass->get_preferred_width = Window_getPreferredWidth;
widgetClass->get_preferred_height = Window_getPreferredHeight;
#endif
} }
auto pWindow::destruct() -> void { auto pWindow::destruct() -> void {
@ -316,7 +354,13 @@ auto pWindow::setModal(bool modal) -> void {
auto pWindow::setResizable(bool resizable) -> void { auto pWindow::setResizable(bool resizable) -> void {
gtk_window_set_resizable(GTK_WINDOW(widget), resizable); gtk_window_set_resizable(GTK_WINDOW(widget), resizable);
#if HIRO_GTK==2
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(gtkStatus), resizable); gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(gtkStatus), resizable);
#elif HIRO_GTK==3
bool statusBarVisible = false;
if(auto statusBar = state().statusBar) statusBarVisible = statusBar->visible();
gtk_window_set_has_resize_grip(GTK_WINDOW(widget), resizable && statusBarVisible);
#endif
} }
auto pWindow::setTitle(const string& title) -> void { auto pWindow::setTitle(const string& title) -> void {
@ -428,6 +472,7 @@ auto pWindow::_setStatusText(const string& text) -> void {
auto pWindow::_setStatusVisible(bool visible) -> void { auto pWindow::_setStatusVisible(bool visible) -> void {
gtk_widget_set_visible(gtkStatus, visible); gtk_widget_set_visible(gtkStatus, visible);
setResizable(self().resizable());
} }
auto pWindow::_statusHeight() const -> signed { auto pWindow::_statusHeight() const -> signed {

View File

@ -32,21 +32,30 @@ auto pApplication::quit() -> void {
//obviously, it is used as sparingly as possible //obviously, it is used as sparingly as possible
auto pApplication::syncX() -> void { auto pApplication::syncX() -> void {
for(auto n : range(8)) { for(auto n : range(8)) {
#if HIRO_QT==4
QApplication::syncX(); QApplication::syncX();
#elif HIRO_QT==5
QApplication::sync();
#endif
Application::processEvents(); Application::processEvents();
usleep(2000); usleep(2000);
} }
} }
auto pApplication::initialize() -> void { auto pApplication::initialize() -> void {
#if HIRO_QT==5 && defined(PLATFORM_BSD)
setenv("QTCOMPOSE", "/usr/local/lib/X11/locale/", 0);
#endif
display = XOpenDisplay(0); display = XOpenDisplay(0);
auto name = Application::state.name ? Application::state.name : string{"hiro"}; auto name = Application::state.name ? Application::state.name : string{"hiro"};
int argc = 1; //QApplication stores references to argc;
char* argv[] = {name.get(), nullptr}; //and will access them after pApplication::initialize() returns
char** argvp = argv; static int argc = 1;
static char* argv[] = {name.get(), nullptr};
static char** argvp = argv;
qtApplication = new QApplication(argc, argvp); qtApplication = new QApplication(argc, argvp);
pKeyboard::initialize(); pKeyboard::initialize();

View File

@ -1,5 +1,8 @@
#include <QApplication> #include <QApplication>
#include <QtGui> #include <QtGui>
#if HIRO_QT==5
#include <QtWidgets>
#endif
#include <nall/xorg/guard.hpp> #include <nall/xorg/guard.hpp>
#define XK_MISCELLANY #define XK_MISCELLANY
#define XK_LATIN1 #define XK_LATIN1
@ -12,5 +15,7 @@
//Qt 4.8.0 and earlier improperly define the QLOCATION macro //Qt 4.8.0 and earlier improperly define the QLOCATION macro
//in C++11, it is detected as a malformed user-defined literal //in C++11, it is detected as a malformed user-defined literal
//below is a workaround to fix compilation errors caused by this //below is a workaround to fix compilation errors caused by this
#if HIRO_QT==4
#undef QLOCATION #undef QLOCATION
#define QLOCATION "\0" __FILE__ ":" QTOSTRING(__LINE__) #define QLOCATION "\0" __FILE__ ":" QTOSTRING(__LINE__)
#endif

View File

@ -1,4 +1,4 @@
//moc-qt4 -i -o qt.moc qt.hpp //$(moc) -i -o qt.moc qt.hpp
/* /*
Qt requires moc in order to bind callbacks, which causes many complications. Qt requires moc in order to bind callbacks, which causes many complications.

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,11 @@ namespace hiro {
Settings::Settings() { Settings::Settings() {
string path = {Path::userData(), "hiro/"}; string path = {Path::userData(), "hiro/"};
auto document = BML::unserialize(file::read({path, "qt.bml"})); #if HIRO_QT==4
auto document = BML::unserialize(file::read({path, "qt4.bml"}));
#elif HIRO_QT==5
auto document = BML::unserialize(file::read({path, "qt5.bml"}));
#endif
auto get = [&](string_view name) { auto get = [&](string_view name) {
return document[name]; return document[name];
@ -32,7 +36,11 @@ Settings::~Settings() {
set("Geometry/MenuHeight", geometry.menuHeight); set("Geometry/MenuHeight", geometry.menuHeight);
set("Geometry/StatusHeight", geometry.statusHeight); set("Geometry/StatusHeight", geometry.statusHeight);
file::write({path, "qt.bml"}, BML::serialize(document)); #if HIRO_QT==4
file::write({path, "qt4.bml"}, BML::serialize(document));
#elif HIRO_QT==5
file::write({path, "qt5.bml"}, BML::serialize(document));
#endif
} }
} }

View File

@ -78,10 +78,18 @@ auto pTableViewColumn::_parent() -> maybe<pTableViewHeader&> {
auto pTableViewColumn::_setState() -> void { auto pTableViewColumn::_setState() -> void {
if(auto header = _parent()) { if(auto header = _parent()) {
if(auto parent = header->_parent()) { if(auto parent = header->_parent()) {
#if HIRO_QT==4
parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed);
#elif HIRO_QT==5
parent->qtTableView->header()->setSectionResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed);
#endif
bool clickable = false; bool clickable = false;
for(auto& column : header->state().columns) clickable |= column->state.sortable; for(auto& column : header->state().columns) clickable |= column->state.sortable;
#if HIRO_QT==4
parent->qtTableView->header()->setClickable(clickable); parent->qtTableView->header()->setClickable(clickable);
#elif HIRO_QT==5
parent->qtTableView->header()->setSectionsClickable(clickable);
#endif
parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text)); parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text));
parent->qtTableView->setColumnHidden(self().offset(), !self().visible()); parent->qtTableView->setColumnHidden(self().offset(), !self().visible());

View File

@ -8,7 +8,11 @@ auto pTableView::construct() -> void {
qtTableView->setContextMenuPolicy(Qt::CustomContextMenu); qtTableView->setContextMenuPolicy(Qt::CustomContextMenu);
qtTableView->setRootIsDecorated(false); qtTableView->setRootIsDecorated(false);
qtTableView->setHeaderHidden(true); qtTableView->setHeaderHidden(true);
#if HIRO_QT==4
qtTableView->header()->setMovable(false); qtTableView->header()->setMovable(false);
#elif HIRO_QT==5
qtTableView->header()->setSectionsMovable(false);
#endif
qtTableViewDelegate = new QtTableViewDelegate(*this); qtTableViewDelegate = new QtTableViewDelegate(*this);
qtTableView->setItemDelegate(qtTableViewDelegate); qtTableView->setItemDelegate(qtTableViewDelegate);

View File

@ -135,7 +135,11 @@ auto pWindow::setFullScreen(bool fullScreen) -> void {
auto pWindow::setGeometry(Geometry geometry) -> void { auto pWindow::setGeometry(Geometry geometry) -> void {
lock(); lock();
Application::processEvents(); Application::processEvents();
#if HIRO_QT==4
QApplication::syncX(); QApplication::syncX();
#elif HIRO_QT==5
QApplication::sync();
#endif
setResizable(state().resizable); setResizable(state().resizable);
qtWindow->move(geometry.x() - frameMargin().x(), geometry.y() - frameMargin().y()); qtWindow->move(geometry.x() - frameMargin().x(), geometry.y() - frameMargin().y());

View File

@ -86,7 +86,7 @@ endif
# clang settings # clang settings
ifeq ($(findstring clang++,$(compiler)),clang++) ifeq ($(findstring clang++,$(compiler)),clang++)
flags += -fno-strict-aliasing -fwrapv flags += -fno-strict-aliasing -fwrapv -Wno-everything
# gcc settings # gcc settings
else ifeq ($(findstring g++,$(compiler)),g++) else ifeq ($(findstring g++,$(compiler)),g++)
flags += -fno-strict-aliasing -fwrapv flags += -fno-strict-aliasing -fwrapv

View File

@ -107,8 +107,9 @@ private:
return false; return false;
} }
XSetWindowAttributes setAttributes = {0}; XSetWindowAttributes setAttributes = {};
setAttributes.border_pixel = 0; setAttributes.border_pixel = 0;
setAttributes.event_mask = ExposureMask;
_window = XCreateWindow(_display, (Window)_context, _window = XCreateWindow(_display, (Window)_context,
0, 0, 256, 256, 0, 0, 0, 256, 256, 0,
getAttributes.depth, InputOutput, getAttributes.visual, getAttributes.depth, InputOutput, getAttributes.visual,