mirror of https://github.com/bsnes-emu/bsnes.git
Update to v075r15 release.
byuu says: phoenix/GTK+ rewrite completed. All three targets should now be 100% operational with full resize support.
This commit is contained in:
parent
7c3aaf12b0
commit
c31543ea58
|
@ -7,6 +7,8 @@
|
||||||
#include "../windows/windows.cpp"
|
#include "../windows/windows.cpp"
|
||||||
#elif defined(PHOENIX_QT)
|
#elif defined(PHOENIX_QT)
|
||||||
#include "../qt/qt.cpp"
|
#include "../qt/qt.cpp"
|
||||||
|
#elif defined(PHOENIX_GTK)
|
||||||
|
#include "../gtk/gtk.cpp"
|
||||||
#elif defined(PHOENIX_REFERENCE)
|
#elif defined(PHOENIX_REFERENCE)
|
||||||
#include "../reference/reference.cpp"
|
#include "../reference/reference.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
static void Action_setFont(GtkWidget *widget, gpointer font) {
|
||||||
|
if(font == 0) return;
|
||||||
|
gtk_widget_modify_font(widget, (PangoFontDescription*)font);
|
||||||
|
if(GTK_IS_CONTAINER(widget)) {
|
||||||
|
gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)Action_setFont, (PangoFontDescription*)font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pAction::setEnabled(bool enabled) {
|
||||||
|
gtk_widget_set_sensitive(widget, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pAction::setFont(Font &font) {
|
||||||
|
Action_setFont(widget, font.p.gtkFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pAction::setVisible(bool visible) {
|
||||||
|
gtk_widget_set_visible(widget, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pAction::constructor() {
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
static void MenuCheckItem_tick(MenuCheckItem *self) {
|
||||||
|
if(self->p.locked == false && self->onTick) self->onTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pMenuCheckItem::checked() {
|
||||||
|
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuCheckItem::setChecked(bool checked) {
|
||||||
|
locked = true;
|
||||||
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), checked);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuCheckItem::setText(const string &text) {
|
||||||
|
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuCheckItem::constructor() {
|
||||||
|
widget = gtk_check_menu_item_new_with_label("");
|
||||||
|
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(MenuCheckItem_tick), (gpointer)&menuCheckItem);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
static void MenuItem_tick(MenuItem *self) {
|
||||||
|
if(self->onTick) self->onTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuItem::setText(const string &text) {
|
||||||
|
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuItem::constructor() {
|
||||||
|
widget = gtk_menu_item_new_with_label("");
|
||||||
|
g_signal_connect_swapped(G_OBJECT(widget), "activate", G_CALLBACK(MenuItem_tick), (gpointer)&menuItem);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
static void MenuRadioItem_tick(MenuRadioItem *self) {
|
||||||
|
if(self->p.locked == false && self->checked() && self->onTick) self->onTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pMenuRadioItem::checked() {
|
||||||
|
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuRadioItem::setChecked() {
|
||||||
|
locked = true;
|
||||||
|
foreach(item, menuRadioItem.state.group) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), false);
|
||||||
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), true);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuRadioItem::setGroup(const reference_array<MenuRadioItem&> &group) {
|
||||||
|
foreach(item, group, n) {
|
||||||
|
if(n == 0) continue;
|
||||||
|
GSList *currentGroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group[0].p.widget));
|
||||||
|
if(currentGroup != gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item.p.widget))) {
|
||||||
|
gtk_radio_menu_item_set_group(GTK_RADIO_MENU_ITEM(item.p.widget), currentGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuRadioItem::setText(const string &text) {
|
||||||
|
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenuRadioItem::constructor() {
|
||||||
|
widget = gtk_radio_menu_item_new_with_label(0, "");
|
||||||
|
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(MenuRadioItem_tick), (gpointer)&menuRadioItem);
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
void pMenuSeparator::constructor() {
|
||||||
|
widget = gtk_separator_menu_item_new();
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
void pMenu::append(Action &action) {
|
||||||
|
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), action.p.widget);
|
||||||
|
gtk_widget_show(action.p.widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenu::setFont(Font &font) {
|
||||||
|
pAction::setFont(font);
|
||||||
|
foreach(item, menu.state.action) item.p.setFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenu::setText(const string &text) {
|
||||||
|
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pMenu::constructor() {
|
||||||
|
submenu = gtk_menu_new();
|
||||||
|
widget = gtk_menu_item_new_with_label("");
|
||||||
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), submenu);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
void pFont::setBold(bool bold) {
|
||||||
|
pango_font_description_set_weight(gtkFont, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pFont::setFamily(const string &family) {
|
||||||
|
pango_font_description_set_family(gtkFont, family);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pFont::setItalic(bool italic) {
|
||||||
|
pango_font_description_set_style(gtkFont, italic ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pFont::setSize(unsigned size) {
|
||||||
|
pango_font_description_set_size(gtkFont, size * PANGO_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pFont::setUnderline(bool underline) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void pFont::constructor() {
|
||||||
|
gtkFont = pango_font_description_new();
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
#include "gtk.hpp"
|
||||||
|
|
||||||
|
#include "settings.cpp"
|
||||||
|
#include "font.cpp"
|
||||||
|
#include "message-window.cpp"
|
||||||
|
#include "window.cpp"
|
||||||
|
|
||||||
|
#include "action/action.cpp"
|
||||||
|
#include "action/menu.cpp"
|
||||||
|
#include "action/menu-separator.cpp"
|
||||||
|
#include "action/menu-item.cpp"
|
||||||
|
#include "action/menu-check-item.cpp"
|
||||||
|
#include "action/menu-radio-item.cpp"
|
||||||
|
|
||||||
|
#include "widget/widget.cpp"
|
||||||
|
#include "widget/button.cpp"
|
||||||
|
#include "widget/check-box.cpp"
|
||||||
|
#include "widget/combo-box.cpp"
|
||||||
|
#include "widget/hex-edit.cpp"
|
||||||
|
#include "widget/horizontal-slider.cpp"
|
||||||
|
#include "widget/label.cpp"
|
||||||
|
#include "widget/line-edit.cpp"
|
||||||
|
#include "widget/list-view.cpp"
|
||||||
|
#include "widget/progress-bar.cpp"
|
||||||
|
#include "widget/radio-box.cpp"
|
||||||
|
#include "widget/text-edit.cpp"
|
||||||
|
#include "widget/vertical-slider.cpp"
|
||||||
|
#include "widget/viewport.cpp"
|
||||||
|
|
||||||
|
unsigned pOS::desktopWidth() {
|
||||||
|
return gdk_screen_get_width(gdk_screen_get_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pOS::desktopHeight() {
|
||||||
|
return gdk_screen_get_height(gdk_screen_get_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
static string pOS_fileDialog(bool save, Window &parent, const string &path, const lstring &filter) {
|
||||||
|
string name;
|
||||||
|
|
||||||
|
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||||
|
save == 0 ? "Load File" : "Save File",
|
||||||
|
&parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0,
|
||||||
|
save == 0 ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
|
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||||
|
(const gchar*)0
|
||||||
|
);
|
||||||
|
|
||||||
|
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||||
|
|
||||||
|
foreach(filterItem, filter) {
|
||||||
|
GtkFileFilter *gtkFilter = gtk_file_filter_new();
|
||||||
|
gtk_file_filter_set_name(gtkFilter, filterItem);
|
||||||
|
lstring part;
|
||||||
|
part.split("(", filterItem);
|
||||||
|
part[1].rtrim<1>(")");
|
||||||
|
lstring list;
|
||||||
|
list.split(",", part[1]);
|
||||||
|
foreach(pattern, list) gtk_file_filter_add_pattern(gtkFilter, pattern);
|
||||||
|
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), gtkFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
|
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||||
|
name = temp;
|
||||||
|
g_free(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
string pOS::fileLoad(Window &parent, const string &path, const lstring &filter) {
|
||||||
|
return pOS_fileDialog(0, parent, path, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
string pOS::fileSave(Window &parent, const string &path, const lstring &filter) {
|
||||||
|
return pOS_fileDialog(1, parent, path, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
string pOS::folderSelect(Window &parent, const string &path) {
|
||||||
|
string name;
|
||||||
|
|
||||||
|
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||||
|
"Select Folder",
|
||||||
|
&parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0,
|
||||||
|
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
|
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||||
|
(const gchar*)0
|
||||||
|
);
|
||||||
|
|
||||||
|
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||||
|
|
||||||
|
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
|
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||||
|
name = temp;
|
||||||
|
g_free(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
if(name == "") return "";
|
||||||
|
if(name.endswith("/") == false) name.append("/");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pOS::main() {
|
||||||
|
gtk_main();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pOS::pending() {
|
||||||
|
return gtk_events_pending();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pOS::process() {
|
||||||
|
while(pending()) gtk_main_iteration_do(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pOS::quit() {
|
||||||
|
settings.save();
|
||||||
|
gtk_main_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pOS::initialize() {
|
||||||
|
settings.load();
|
||||||
|
|
||||||
|
int argc = 1;
|
||||||
|
char *argv[2];
|
||||||
|
argv[0] = new char[8];
|
||||||
|
argv[1] = 0;
|
||||||
|
strcpy(argv[0], "phoenix");
|
||||||
|
char **argvp = argv;
|
||||||
|
gtk_init(&argc, &argvp);
|
||||||
|
|
||||||
|
gtk_rc_parse_string(
|
||||||
|
"style \"phoenix-gtk\"\n"
|
||||||
|
"{\n"
|
||||||
|
" GtkComboBox::appears-as-list = 1\n"
|
||||||
|
" GtkTreeView::vertical-separator = 0\n"
|
||||||
|
"}\n"
|
||||||
|
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
|
||||||
|
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,348 @@
|
||||||
|
struct Settings : public configuration {
|
||||||
|
unsigned frameGeometryX;
|
||||||
|
unsigned frameGeometryY;
|
||||||
|
unsigned frameGeometryWidth;
|
||||||
|
unsigned frameGeometryHeight;
|
||||||
|
|
||||||
|
void load();
|
||||||
|
void save();
|
||||||
|
Settings();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pFont;
|
||||||
|
struct pWindow;
|
||||||
|
struct pMenu;
|
||||||
|
struct pLayout;
|
||||||
|
struct pWidget;
|
||||||
|
|
||||||
|
struct pObject {
|
||||||
|
bool locked;
|
||||||
|
|
||||||
|
pObject() {
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pOS : public pObject {
|
||||||
|
static unsigned desktopWidth();
|
||||||
|
static unsigned desktopHeight();
|
||||||
|
static string fileLoad(Window &parent, const string &path, const lstring &filter);
|
||||||
|
static string fileSave(Window &parent, const string &path, const lstring &filter);
|
||||||
|
static string folderSelect(Window &parent, const string &path);
|
||||||
|
static void main();
|
||||||
|
static bool pending();
|
||||||
|
static void process();
|
||||||
|
static void quit();
|
||||||
|
|
||||||
|
static void initialize();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pFont : public pObject {
|
||||||
|
Font &font;
|
||||||
|
PangoFontDescription *gtkFont;
|
||||||
|
|
||||||
|
void setBold(bool bold);
|
||||||
|
void setFamily(const string &family);
|
||||||
|
void setItalic(bool italic);
|
||||||
|
void setSize(unsigned size);
|
||||||
|
void setUnderline(bool underline);
|
||||||
|
|
||||||
|
pFont(Font &font) : font(font) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pMessageWindow : public pObject {
|
||||||
|
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||||
|
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||||
|
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||||
|
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pWindow : public pObject {
|
||||||
|
Window &window;
|
||||||
|
GtkWidget *widget;
|
||||||
|
GtkWidget *menuContainer;
|
||||||
|
GtkWidget *formContainer;
|
||||||
|
GtkWidget *statusContainer;
|
||||||
|
GtkWidget *menu;
|
||||||
|
GtkWidget *status;
|
||||||
|
|
||||||
|
void append(Layout &layout);
|
||||||
|
void append(Menu &menu);
|
||||||
|
void append(Widget &widget);
|
||||||
|
Geometry frameGeometry();
|
||||||
|
bool focused();
|
||||||
|
Geometry geometry();
|
||||||
|
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
||||||
|
void setFrameGeometry(const Geometry &geometry);
|
||||||
|
void setFocused();
|
||||||
|
void setFullScreen(bool fullScreen);
|
||||||
|
void setGeometry(const Geometry &geometry);
|
||||||
|
void setMenuFont(Font &font);
|
||||||
|
void setMenuVisible(bool visible);
|
||||||
|
void setResizable(bool resizable);
|
||||||
|
void setStatusFont(Font &font);
|
||||||
|
void setStatusText(const string &text);
|
||||||
|
void setStatusVisible(bool visible);
|
||||||
|
void setTitle(const string &text);
|
||||||
|
void setVisible(bool visible);
|
||||||
|
void setWidgetFont(Font &font);
|
||||||
|
|
||||||
|
pWindow(Window &window) : window(window) {}
|
||||||
|
void constructor();
|
||||||
|
void updateFrameGeometry();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pAction : public pObject {
|
||||||
|
Action &action;
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
void setVisible(bool visible);
|
||||||
|
|
||||||
|
pAction(Action &action) : action(action) {}
|
||||||
|
void constructor();
|
||||||
|
virtual void setFont(Font &font);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pMenu : public pAction {
|
||||||
|
Menu &menu;
|
||||||
|
GtkWidget *submenu;
|
||||||
|
|
||||||
|
void append(Action &action);
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pMenu(Menu &menu) : pAction(menu), menu(menu) {}
|
||||||
|
void constructor();
|
||||||
|
void setFont(Font &font);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pMenuSeparator : public pAction {
|
||||||
|
MenuSeparator &menuSeparator;
|
||||||
|
|
||||||
|
pMenuSeparator(MenuSeparator &menuSeparator) : pAction(menuSeparator), menuSeparator(menuSeparator) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pMenuItem : public pAction {
|
||||||
|
MenuItem &menuItem;
|
||||||
|
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pMenuItem(MenuItem &menuItem) : pAction(menuItem), menuItem(menuItem) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pMenuCheckItem : public pAction {
|
||||||
|
MenuCheckItem &menuCheckItem;
|
||||||
|
|
||||||
|
bool checked();
|
||||||
|
void setChecked(bool checked);
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pMenuCheckItem(MenuCheckItem &menuCheckItem) : pAction(menuCheckItem), menuCheckItem(menuCheckItem) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pMenuRadioItem : public pAction {
|
||||||
|
MenuRadioItem &menuRadioItem;
|
||||||
|
|
||||||
|
bool checked();
|
||||||
|
void setChecked();
|
||||||
|
void setGroup(const reference_array<MenuRadioItem&> &group);
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pMenuRadioItem(MenuRadioItem &menuRadioItem) : pAction(menuRadioItem), menuRadioItem(menuRadioItem) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pWidget : public pObject {
|
||||||
|
Widget &widget;
|
||||||
|
GtkWidget *gtkWidget;
|
||||||
|
pWindow *parentWindow;
|
||||||
|
|
||||||
|
bool enabled();
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
virtual void setFocused();
|
||||||
|
virtual void setFont(Font &font);
|
||||||
|
void setGeometry(const Geometry &geometry);
|
||||||
|
void setVisible(bool visible);
|
||||||
|
|
||||||
|
pWidget(Widget &widget) : widget(widget) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pButton : public pWidget {
|
||||||
|
Button &button;
|
||||||
|
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pButton(Button &button) : pWidget(button), button(button) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pCheckBox : public pWidget {
|
||||||
|
CheckBox &checkBox;
|
||||||
|
|
||||||
|
bool checked();
|
||||||
|
void setChecked(bool checked);
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pCheckBox(CheckBox &checkBox) : pWidget(checkBox), checkBox(checkBox) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pComboBox : public pWidget {
|
||||||
|
ComboBox &comboBox;
|
||||||
|
unsigned itemCounter;
|
||||||
|
|
||||||
|
void append(const string &text);
|
||||||
|
void reset();
|
||||||
|
unsigned selection();
|
||||||
|
void setSelection(unsigned row);
|
||||||
|
|
||||||
|
pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pHexEdit : public pWidget {
|
||||||
|
HexEdit &hexEdit;
|
||||||
|
GtkWidget *container;
|
||||||
|
GtkWidget *subWidget;
|
||||||
|
GtkWidget *scrollBar;
|
||||||
|
GtkTextBuffer *textBuffer;
|
||||||
|
GtkTextMark *textCursor;
|
||||||
|
|
||||||
|
void setColumns(unsigned columns);
|
||||||
|
void setLength(unsigned length);
|
||||||
|
void setOffset(unsigned offset);
|
||||||
|
void setRows(unsigned rows);
|
||||||
|
void update();
|
||||||
|
|
||||||
|
pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {}
|
||||||
|
void constructor();
|
||||||
|
unsigned cursorPosition();
|
||||||
|
bool keyPress(unsigned scancode);
|
||||||
|
void scroll(unsigned position);
|
||||||
|
void setCursorPosition(unsigned position);
|
||||||
|
void setScroll();
|
||||||
|
void updateScroll();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pHorizontalSlider : public pWidget {
|
||||||
|
HorizontalSlider &horizontalSlider;
|
||||||
|
|
||||||
|
unsigned position();
|
||||||
|
void setLength(unsigned length);
|
||||||
|
void setPosition(unsigned position);
|
||||||
|
|
||||||
|
pHorizontalSlider(HorizontalSlider &horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pLabel : public pWidget {
|
||||||
|
Label &label;
|
||||||
|
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pLabel(Label &label) : pWidget(label), label(label) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pLineEdit : public pWidget {
|
||||||
|
LineEdit &lineEdit;
|
||||||
|
|
||||||
|
void setEditable(bool editable);
|
||||||
|
void setText(const string &text);
|
||||||
|
string text();
|
||||||
|
|
||||||
|
pLineEdit(LineEdit &lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pListView : public pWidget {
|
||||||
|
ListView &listView;
|
||||||
|
GtkWidget *subWidget;
|
||||||
|
GtkListStore *store;
|
||||||
|
struct GtkColumn {
|
||||||
|
GtkCellRenderer *renderer;
|
||||||
|
GtkTreeViewColumn *column;
|
||||||
|
GtkWidget *label;
|
||||||
|
};
|
||||||
|
linear_vector<GtkColumn> column;
|
||||||
|
|
||||||
|
void append(const lstring &text);
|
||||||
|
void autosizeColumns();
|
||||||
|
bool checked(unsigned row);
|
||||||
|
void modify(unsigned row, const lstring &text);
|
||||||
|
void modify(unsigned row, unsigned column, const string &text);
|
||||||
|
void reset();
|
||||||
|
optional<unsigned> selection();
|
||||||
|
void setCheckable(bool checkable);
|
||||||
|
void setChecked(unsigned row, bool checked);
|
||||||
|
void setHeaderText(const lstring &text);
|
||||||
|
void setHeaderVisible(bool visible);
|
||||||
|
void setSelection(unsigned row);
|
||||||
|
|
||||||
|
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
|
||||||
|
void constructor();
|
||||||
|
void create();
|
||||||
|
void setFocused();
|
||||||
|
void setFont(Font &font);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pProgressBar : public pWidget {
|
||||||
|
ProgressBar &progressBar;
|
||||||
|
|
||||||
|
void setPosition(unsigned position);
|
||||||
|
|
||||||
|
pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pRadioBox : public pWidget {
|
||||||
|
RadioBox &radioBox;
|
||||||
|
|
||||||
|
bool checked();
|
||||||
|
void setChecked();
|
||||||
|
void setGroup(const reference_array<RadioBox&> &group);
|
||||||
|
void setText(const string &text);
|
||||||
|
|
||||||
|
pRadioBox(RadioBox &radioBox) : pWidget(radioBox), radioBox(radioBox) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pTextEdit : public pWidget {
|
||||||
|
TextEdit &textEdit;
|
||||||
|
GtkWidget *subWidget;
|
||||||
|
GtkTextBuffer *textBuffer;
|
||||||
|
|
||||||
|
void setCursorPosition(unsigned position);
|
||||||
|
void setEditable(bool editable);
|
||||||
|
void setText(const string &text);
|
||||||
|
void setWordWrap(bool wordWrap);
|
||||||
|
string text();
|
||||||
|
|
||||||
|
pTextEdit(TextEdit &textEdit) : pWidget(textEdit), textEdit(textEdit) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pVerticalSlider : public pWidget {
|
||||||
|
VerticalSlider &verticalSlider;
|
||||||
|
|
||||||
|
unsigned position();
|
||||||
|
void setLength(unsigned length);
|
||||||
|
void setPosition(unsigned position);
|
||||||
|
|
||||||
|
pVerticalSlider(VerticalSlider &verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pViewport : public pWidget {
|
||||||
|
Viewport &viewport;
|
||||||
|
|
||||||
|
uintptr_t handle();
|
||||||
|
|
||||||
|
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
|
||||||
|
void constructor();
|
||||||
|
};
|
|
@ -0,0 +1,61 @@
|
||||||
|
static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons buttons, gint response) {
|
||||||
|
if(response == GTK_RESPONSE_OK) return MessageWindow::Response::Ok;
|
||||||
|
if(response == GTK_RESPONSE_CANCEL) return MessageWindow::Response::Cancel;
|
||||||
|
if(response == GTK_RESPONSE_YES) return MessageWindow::Response::Yes;
|
||||||
|
if(response == GTK_RESPONSE_NO) return MessageWindow::Response::No;
|
||||||
|
if(buttons == MessageWindow::Buttons::OkCancel) return MessageWindow::Response::Cancel;
|
||||||
|
if(buttons == MessageWindow::Buttons::YesNo) return MessageWindow::Response::No;
|
||||||
|
return MessageWindow::Response::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||||
|
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||||
|
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||||
|
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||||
|
GtkWidget *dialog = gtk_message_dialog_new(
|
||||||
|
&parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0,
|
||||||
|
GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, buttonsType, "%s", (const char*)text
|
||||||
|
);
|
||||||
|
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return MessageWindow_response(buttons, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||||
|
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||||
|
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||||
|
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||||
|
GtkWidget *dialog = gtk_message_dialog_new(
|
||||||
|
&parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0,
|
||||||
|
GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, buttonsType, "%s", (const char*)text
|
||||||
|
);
|
||||||
|
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return MessageWindow_response(buttons, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||||
|
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||||
|
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||||
|
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||||
|
GtkWidget *dialog = gtk_message_dialog_new(
|
||||||
|
&parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0,
|
||||||
|
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, buttonsType, "%s", (const char*)text
|
||||||
|
);
|
||||||
|
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return MessageWindow_response(buttons, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||||
|
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||||
|
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||||
|
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||||
|
GtkWidget *dialog = gtk_message_dialog_new(
|
||||||
|
&parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0,
|
||||||
|
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, buttonsType, "%s", (const char*)text
|
||||||
|
);
|
||||||
|
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
return MessageWindow_response(buttons, response);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
static Settings settings;
|
||||||
|
|
||||||
|
void Settings::load() {
|
||||||
|
string path = { userpath(), ".config/phoenix/gtk.cfg" };
|
||||||
|
configuration::load(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::save() {
|
||||||
|
string path = { userpath(), ".config/" };
|
||||||
|
mkdir(path, 0755);
|
||||||
|
path.append("phoenix/");
|
||||||
|
mkdir(path, 0755);
|
||||||
|
path.append("gtk.cfg");
|
||||||
|
configuration::save(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Settings() {
|
||||||
|
attach(frameGeometryX = 0, "frameGeometryX");
|
||||||
|
attach(frameGeometryY = 0, "frameGeometryY");
|
||||||
|
attach(frameGeometryWidth = 0, "frameGeometryWidth");
|
||||||
|
attach(frameGeometryHeight = 0, "frameGeometryHeight");
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
static void Button_tick(Button *self) {
|
||||||
|
if(self->onTick) self->onTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pButton::setText(const string &text) {
|
||||||
|
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pButton::constructor() {
|
||||||
|
gtkWidget = gtk_button_new();
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "clicked", G_CALLBACK(Button_tick), (gpointer)&button);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
static void CheckBox_tick(CheckBox *self) {
|
||||||
|
if(self->p.locked == false && self->onTick) self->onTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pCheckBox::checked() {
|
||||||
|
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtkWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pCheckBox::setChecked(bool checked) {
|
||||||
|
locked = true;
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkWidget), checked);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pCheckBox::setText(const string &text) {
|
||||||
|
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pCheckBox::constructor() {
|
||||||
|
gtkWidget = gtk_check_button_new_with_label("");
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(CheckBox_tick), (gpointer)&checkBox);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
static void ComboBox_change(ComboBox *self) {
|
||||||
|
if(self->p.locked == false && self->onChange) self->onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pComboBox::append(const string &text) {
|
||||||
|
gtk_combo_box_append_text(GTK_COMBO_BOX(gtkWidget), text);
|
||||||
|
if(itemCounter++ == 0) setSelection(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pComboBox::reset() {
|
||||||
|
locked = true;
|
||||||
|
for(signed n = itemCounter - 1; n >= 0; n--) {
|
||||||
|
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), n);
|
||||||
|
}
|
||||||
|
itemCounter = 0;
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pComboBox::selection() {
|
||||||
|
return gtk_combo_box_get_active(GTK_COMBO_BOX(gtkWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pComboBox::setSelection(unsigned row) {
|
||||||
|
locked = true;
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(gtkWidget), row);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pComboBox::constructor() {
|
||||||
|
itemCounter = 0;
|
||||||
|
gtkWidget = gtk_combo_box_new_text();
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "changed", G_CALLBACK(ComboBox_change), (gpointer)&comboBox);
|
||||||
|
}
|
|
@ -0,0 +1,246 @@
|
||||||
|
static bool HexEdit_keyPress(GtkWidget *widget, GdkEventKey *event, HexEdit *self) {
|
||||||
|
return self->p.keyPress(event->keyval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HexEdit_scroll(GtkRange *range, GtkScrollType scroll, gdouble value, HexEdit *self) {
|
||||||
|
self->p.scroll((unsigned)value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::setColumns(unsigned columns) {
|
||||||
|
setScroll();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::setLength(unsigned length) {
|
||||||
|
setScroll();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::setOffset(unsigned offset) {
|
||||||
|
setScroll();
|
||||||
|
updateScroll();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::setRows(unsigned rows) {
|
||||||
|
setScroll();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::update() {
|
||||||
|
if(!hexEdit.onRead) {
|
||||||
|
gtk_text_buffer_set_text(textBuffer, "", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned position = cursorPosition();
|
||||||
|
|
||||||
|
string output;
|
||||||
|
unsigned offset = hexEdit.state.offset;
|
||||||
|
for(unsigned row = 0; row < hexEdit.state.rows; row++) {
|
||||||
|
output.append(hex<8>(offset));
|
||||||
|
output.append(" ");
|
||||||
|
|
||||||
|
string hexdata;
|
||||||
|
string ansidata = " ";
|
||||||
|
for(unsigned column = 0; column < hexEdit.state.columns; column++) {
|
||||||
|
if(offset < hexEdit.state.length) {
|
||||||
|
uint8_t data = hexEdit.onRead(offset++);
|
||||||
|
hexdata.append(hex<2>(data));
|
||||||
|
hexdata.append(" ");
|
||||||
|
char buffer[2] = { data >= 0x20 && data <= 0x7e ? (char)data : '.', 0 };
|
||||||
|
ansidata.append(buffer);
|
||||||
|
} else {
|
||||||
|
hexdata.append(" ");
|
||||||
|
ansidata.append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output.append(hexdata);
|
||||||
|
output.append(ansidata);
|
||||||
|
if(offset >= hexEdit.state.length) break;
|
||||||
|
if(row != hexEdit.state.rows - 1) output.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_text_buffer_set_text(textBuffer, output, -1);
|
||||||
|
if(position == 0) position = 10; //start at first position where hex values can be entered
|
||||||
|
setCursorPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::constructor() {
|
||||||
|
gtkWidget = gtk_hbox_new(false, 0);
|
||||||
|
|
||||||
|
container = gtk_scrolled_window_new(0, 0);
|
||||||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
|
||||||
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(container), GTK_SHADOW_ETCHED_IN);
|
||||||
|
|
||||||
|
subWidget = gtk_text_view_new();
|
||||||
|
gtk_text_view_set_editable(GTK_TEXT_VIEW(subWidget), false);
|
||||||
|
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_NONE);
|
||||||
|
gtk_container_add(GTK_CONTAINER(container), subWidget);
|
||||||
|
g_signal_connect(G_OBJECT(subWidget), "key-press-event", G_CALLBACK(HexEdit_keyPress), (gpointer)&hexEdit);
|
||||||
|
|
||||||
|
scrollBar = gtk_vscrollbar_new((GtkAdjustment*)0);
|
||||||
|
gtk_range_set_range(GTK_RANGE(scrollBar), 0, 255);
|
||||||
|
gtk_range_set_increments(GTK_RANGE(scrollBar), 1, 16);
|
||||||
|
gtk_widget_set_sensitive(scrollBar, false);
|
||||||
|
g_signal_connect(G_OBJECT(scrollBar), "change-value", G_CALLBACK(HexEdit_scroll), (gpointer)&hexEdit);
|
||||||
|
|
||||||
|
gtk_box_pack_start(GTK_BOX(gtkWidget), container, true, true, 0);
|
||||||
|
gtk_box_pack_start(GTK_BOX(gtkWidget), scrollBar, false, false, 1);
|
||||||
|
|
||||||
|
textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(subWidget));
|
||||||
|
textCursor = gtk_text_buffer_get_mark(textBuffer, "insert");
|
||||||
|
|
||||||
|
gtk_widget_show(scrollBar);
|
||||||
|
gtk_widget_show(subWidget);
|
||||||
|
gtk_widget_show(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pHexEdit::cursorPosition() {
|
||||||
|
GtkTextIter iter;
|
||||||
|
gtk_text_buffer_get_iter_at_mark(textBuffer, &iter, textCursor);
|
||||||
|
return gtk_text_iter_get_offset(&iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pHexEdit::keyPress(unsigned scancode) {
|
||||||
|
if(!hexEdit.onRead) return false;
|
||||||
|
|
||||||
|
unsigned position = cursorPosition();
|
||||||
|
unsigned lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 1;
|
||||||
|
unsigned cursorY = position / lineWidth;
|
||||||
|
unsigned cursorX = position % lineWidth;
|
||||||
|
|
||||||
|
if(scancode == GDK_Home) {
|
||||||
|
setCursorPosition(cursorY * lineWidth + 10);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scancode == GDK_End) {
|
||||||
|
setCursorPosition(cursorY * lineWidth + 10 + (hexEdit.state.columns * 3 - 1));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scancode == GDK_Up) {
|
||||||
|
if(cursorY != 0) return false;
|
||||||
|
|
||||||
|
signed newOffset = hexEdit.state.offset - hexEdit.state.columns;
|
||||||
|
if(newOffset >= 0) {
|
||||||
|
hexEdit.setOffset(newOffset);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scancode == GDK_Down) {
|
||||||
|
if(cursorY != hexEdit.state.rows - 1) return false;
|
||||||
|
|
||||||
|
signed newOffset = hexEdit.state.offset + hexEdit.state.columns;
|
||||||
|
if(newOffset + hexEdit.state.columns * hexEdit.state.rows - (hexEdit.state.columns - 1) <= hexEdit.state.length) {
|
||||||
|
hexEdit.setOffset(newOffset);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scancode == GDK_Page_Up) {
|
||||||
|
signed newOffset = hexEdit.state.offset - hexEdit.state.columns * hexEdit.state.rows;
|
||||||
|
if(newOffset >= 0) {
|
||||||
|
hexEdit.setOffset(newOffset);
|
||||||
|
} else {
|
||||||
|
hexEdit.setOffset(0);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scancode == GDK_Page_Down) {
|
||||||
|
signed newOffset = hexEdit.state.offset + hexEdit.state.columns * hexEdit.state.rows;
|
||||||
|
for(unsigned n = 0; n < hexEdit.state.rows; n++) {
|
||||||
|
if(newOffset + hexEdit.state.columns * hexEdit.state.rows - (hexEdit.state.columns - 1) <= hexEdit.state.length) {
|
||||||
|
hexEdit.setOffset(newOffset);
|
||||||
|
update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newOffset -= hexEdit.state.columns;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert scancode to hex nibble
|
||||||
|
if(scancode >= '0' && scancode <= '9') scancode = scancode - '0';
|
||||||
|
else if(scancode >= 'A' && scancode <= 'F') scancode = scancode - 'A' + 10;
|
||||||
|
else if(scancode >= 'a' && scancode <= 'f') scancode = scancode - 'a' + 10;
|
||||||
|
else return false; //not a valid hex value
|
||||||
|
|
||||||
|
if(cursorX >= 10) {
|
||||||
|
//not on an offset
|
||||||
|
cursorX -= 10;
|
||||||
|
if((cursorX % 3) != 2) {
|
||||||
|
//not on a space
|
||||||
|
bool cursorNibble = (cursorX % 3) == 1; //0 = high, 1 = low
|
||||||
|
cursorX /= 3;
|
||||||
|
if(cursorX < hexEdit.state.columns) {
|
||||||
|
//not in ANSI region
|
||||||
|
unsigned offset = hexEdit.state.offset + (cursorY * hexEdit.state.columns + cursorX);
|
||||||
|
|
||||||
|
if(offset >= hexEdit.state.length) return false; //do not edit past end of data
|
||||||
|
uint8_t data = hexEdit.onRead(offset);
|
||||||
|
|
||||||
|
//write modified value
|
||||||
|
if(cursorNibble == 1) {
|
||||||
|
data = (data & 0xf0) | (scancode << 0);
|
||||||
|
} else {
|
||||||
|
data = (data & 0x0f) | (scancode << 4);
|
||||||
|
}
|
||||||
|
if(hexEdit.onWrite) hexEdit.onWrite(offset, data);
|
||||||
|
|
||||||
|
//auto-advance cursor to next nibble/byte
|
||||||
|
position++;
|
||||||
|
if(cursorNibble && cursorX != hexEdit.state.columns - 1) position++;
|
||||||
|
setCursorPosition(position);
|
||||||
|
|
||||||
|
//refresh output to reflect modified data
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::scroll(unsigned position) {
|
||||||
|
unsigned rows = hexEdit.state.length / hexEdit.state.columns;
|
||||||
|
if(position >= rows) position = rows - 1;
|
||||||
|
hexEdit.setOffset(position * hexEdit.state.columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::setCursorPosition(unsigned position) {
|
||||||
|
GtkTextIter iter;
|
||||||
|
gtk_text_buffer_get_iter_at_mark(textBuffer, &iter, textCursor);
|
||||||
|
|
||||||
|
//GTK+ will throw many errors to the terminal if you set iterator past end of buffer
|
||||||
|
GtkTextIter endIter;
|
||||||
|
gtk_text_buffer_get_end_iter(textBuffer, &iter);
|
||||||
|
unsigned endPosition = gtk_text_iter_get_offset(&iter);
|
||||||
|
|
||||||
|
gtk_text_iter_set_offset(&iter, min(position, endPosition));
|
||||||
|
gtk_text_buffer_place_cursor(textBuffer, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::setScroll() {
|
||||||
|
unsigned rows = hexEdit.state.length / hexEdit.state.columns;
|
||||||
|
if(rows) rows--;
|
||||||
|
if(rows) {
|
||||||
|
gtk_range_set_range(GTK_RANGE(scrollBar), 0, rows);
|
||||||
|
gtk_widget_set_sensitive(scrollBar, true);
|
||||||
|
} else {
|
||||||
|
gtk_widget_set_sensitive(scrollBar, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHexEdit::updateScroll() {
|
||||||
|
unsigned row = hexEdit.state.offset / hexEdit.state.columns;
|
||||||
|
gtk_range_set_value(GTK_RANGE(scrollBar), row);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
static void HorizontalSlider_change(HorizontalSlider *self) {
|
||||||
|
if(self->state.position == self->position()) return;
|
||||||
|
self->state.position = self->position();
|
||||||
|
if(self->onChange) self->onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pHorizontalSlider::position() {
|
||||||
|
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHorizontalSlider::setLength(unsigned length) {
|
||||||
|
length += length == 0;
|
||||||
|
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHorizontalSlider::setPosition(unsigned position) {
|
||||||
|
gtk_range_set_value(GTK_RANGE(gtkWidget), position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pHorizontalSlider::constructor() {
|
||||||
|
gtkWidget = gtk_hscale_new_with_range(0, 100, 1);
|
||||||
|
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)&horizontalSlider);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
void pLabel::setText(const string &text) {
|
||||||
|
gtk_label_set_text(GTK_LABEL(gtkWidget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pLabel::constructor() {
|
||||||
|
gtkWidget = gtk_label_new("");
|
||||||
|
gtk_misc_set_alignment(GTK_MISC(gtkWidget), 0.0, 0.5);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
static void LineEdit_activate(LineEdit *self) {
|
||||||
|
if(self->onActivate) self->onActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LineEdit_change(LineEdit *self) {
|
||||||
|
if(self->p.locked == false && self->onChange) self->onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pLineEdit::setEditable(bool editable) {
|
||||||
|
gtk_entry_set_editable(GTK_ENTRY(gtkWidget), editable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pLineEdit::setText(const string &text) {
|
||||||
|
locked = true;
|
||||||
|
gtk_entry_set_text(GTK_ENTRY(gtkWidget), text);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string pLineEdit::text() {
|
||||||
|
return gtk_entry_get_text(GTK_ENTRY(gtkWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pLineEdit::constructor() {
|
||||||
|
gtkWidget = gtk_entry_new();
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "activate", G_CALLBACK(LineEdit_activate), (gpointer)&lineEdit);
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "changed", G_CALLBACK(LineEdit_change), (gpointer)&lineEdit);
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
static void ListView_activate(ListView *self) {
|
||||||
|
signed selection = -1;
|
||||||
|
if(self->onActivate) self->onActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListView_change(ListView *self) {
|
||||||
|
signed selection = -1;
|
||||||
|
self->state.selection = self->selection();
|
||||||
|
if(self->onChange) self->onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListView_tick(GtkCellRendererToggle *cell, gchar *path_string, ListView *self) {
|
||||||
|
unsigned row = decimal(path_string);
|
||||||
|
self->setChecked(row, !self->checked(row));
|
||||||
|
if(self->onTick) self->onTick(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::append(const lstring &text) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gtk_list_store_append(store, &iter);
|
||||||
|
foreach(item, text, n) gtk_list_store_set(store, &iter, 1 + n, (const char*)item, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::autosizeColumns() {
|
||||||
|
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(subWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pListView::checked(unsigned row) {
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreePath *path = gtk_tree_path_new_from_string(string(row));
|
||||||
|
GtkTreeIter iter;
|
||||||
|
bool state;
|
||||||
|
gtk_tree_model_get_iter(model, &iter, path);
|
||||||
|
gtk_tree_model_get(model, &iter, 0, &state, -1);
|
||||||
|
gtk_tree_path_free(path);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::modify(unsigned row, const lstring &text) {
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreeIter iter;
|
||||||
|
for(unsigned i = 0; i <= row; i++) {
|
||||||
|
if(i == 0) gtk_tree_model_get_iter_first(model, &iter);
|
||||||
|
else gtk_tree_model_iter_next(model, &iter);
|
||||||
|
}
|
||||||
|
foreach(item, text, n) gtk_list_store_set(store, &iter, 1 + n, (const char*)item, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::modify(unsigned row, unsigned column, const string &text) {
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreeIter iter;
|
||||||
|
for(unsigned i = 0; i <= row; i++) {
|
||||||
|
if(i == 0) gtk_tree_model_get_iter_first(model, &iter);
|
||||||
|
else gtk_tree_model_iter_next(model, &iter);
|
||||||
|
}
|
||||||
|
gtk_list_store_set(store, &iter, 1 + column, (const char*)text, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::reset() {
|
||||||
|
listView.state.selection = { false, 0 };
|
||||||
|
gtk_list_store_clear(GTK_LIST_STORE(store));
|
||||||
|
gtk_tree_view_set_model(GTK_TREE_VIEW(subWidget), GTK_TREE_MODEL(store));
|
||||||
|
//reset gtk_scrolled_window scrollbar position to 0,0 (top-left), as ListView is now empty
|
||||||
|
gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(gtkWidget), 0);
|
||||||
|
gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(gtkWidget), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<unsigned> pListView::selection() {
|
||||||
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreeIter iter;
|
||||||
|
if(gtk_tree_model_get_iter_first(model, &iter) == false) return { false, 0 };
|
||||||
|
if(gtk_tree_selection_iter_is_selected(selection, &iter) == true) return { true, 0 };
|
||||||
|
for(unsigned n = 1;; n++) {
|
||||||
|
if(gtk_tree_model_iter_next(model, &iter) == false) return { false, 0 };
|
||||||
|
if(gtk_tree_selection_iter_is_selected(selection, &iter) == true) return { true, n };
|
||||||
|
}
|
||||||
|
return { false, 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setCheckable(bool checkable) {
|
||||||
|
gtk_tree_view_column_set_visible(column[0].column, checkable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setChecked(unsigned row, bool checked) {
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreePath *path = gtk_tree_path_new_from_string(string(row));
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gtk_tree_model_get_iter(model, &iter, path);
|
||||||
|
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, checked, -1);
|
||||||
|
gtk_tree_path_free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setHeaderText(const lstring &text) {
|
||||||
|
create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setHeaderVisible(bool visible) {
|
||||||
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(subWidget), visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setSelection(unsigned row) {
|
||||||
|
signed current = -1;
|
||||||
|
if(auto position = selection()) current = position();
|
||||||
|
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||||
|
gtk_tree_selection_unselect_all(selection);
|
||||||
|
|
||||||
|
GtkTreeIter iter;
|
||||||
|
if(gtk_tree_model_get_iter_first(model, &iter) == false) return;
|
||||||
|
if(row == 0) {
|
||||||
|
gtk_tree_selection_select_iter(selection, &iter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(unsigned n = 1;; n++) {
|
||||||
|
if(gtk_tree_model_iter_next(model, &iter) == false) return;
|
||||||
|
if(row == n) {
|
||||||
|
gtk_tree_selection_select_iter(selection, &iter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::constructor() {
|
||||||
|
gtkWidget = 0;
|
||||||
|
subWidget = 0;
|
||||||
|
create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::create() {
|
||||||
|
if(subWidget) gtk_widget_destroy(subWidget);
|
||||||
|
if(gtkWidget) gtk_widget_destroy(gtkWidget);
|
||||||
|
|
||||||
|
gtkWidget = gtk_scrolled_window_new(0, 0);
|
||||||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||||
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkWidget), GTK_SHADOW_ETCHED_IN);
|
||||||
|
|
||||||
|
lstring headerText;
|
||||||
|
headerText.append(""); //checkbox column
|
||||||
|
foreach(headerItem, listView.state.headerText) headerText.append(headerItem);
|
||||||
|
if(headerText.size() == 1) headerText.append("");
|
||||||
|
|
||||||
|
GType *v = (GType*)malloc(headerText.size() * sizeof(GType));
|
||||||
|
foreach(header, headerText, n) v[n] = (n == 0 ? G_TYPE_BOOLEAN : G_TYPE_STRING);
|
||||||
|
store = gtk_list_store_newv(headerText.size(), v);
|
||||||
|
free(v);
|
||||||
|
|
||||||
|
subWidget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||||
|
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
|
||||||
|
g_object_unref(G_OBJECT(store));
|
||||||
|
|
||||||
|
foreach(header, headerText, n) {
|
||||||
|
if(n == 0) {
|
||||||
|
column[n].renderer = gtk_cell_renderer_toggle_new();
|
||||||
|
column[n].column = gtk_tree_view_column_new_with_attributes("", column[n].renderer, "active", n, (void*)0);
|
||||||
|
gtk_tree_view_column_set_resizable(column[n].column, false);
|
||||||
|
gtk_tree_view_column_set_visible(column[n].column, false);
|
||||||
|
g_signal_connect(column[n].renderer, "toggled", G_CALLBACK(ListView_tick), (gpointer)&listView);
|
||||||
|
} else {
|
||||||
|
column[n].renderer = gtk_cell_renderer_text_new();
|
||||||
|
column[n].column = gtk_tree_view_column_new_with_attributes("", column[n].renderer, "text", n, (void*)0);
|
||||||
|
gtk_tree_view_column_set_resizable(column[n].column, true);
|
||||||
|
}
|
||||||
|
column[n].label = gtk_label_new(header);
|
||||||
|
gtk_tree_view_column_set_widget(GTK_TREE_VIEW_COLUMN(column[n].column), column[n].label);
|
||||||
|
gtk_tree_view_append_column(GTK_TREE_VIEW(subWidget), column[n].column);
|
||||||
|
gtk_widget_show(column[n].label);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(subWidget), headerText.size() >= 3); //two or more columns + checkbox column
|
||||||
|
gtk_tree_view_set_search_column(GTK_TREE_VIEW(subWidget), 1);
|
||||||
|
|
||||||
|
g_signal_connect_swapped(G_OBJECT(subWidget), "cursor-changed", G_CALLBACK(ListView_change), (gpointer)&listView);
|
||||||
|
g_signal_connect_swapped(G_OBJECT(subWidget), "row-activated", G_CALLBACK(ListView_activate), (gpointer)&listView);
|
||||||
|
|
||||||
|
setHeaderVisible(listView.state.headerVisible);
|
||||||
|
setCheckable(listView.state.checkable);
|
||||||
|
foreach(text, listView.state.text) append(text);
|
||||||
|
foreach(checked, listView.state.checked, n) setChecked(n, checked);
|
||||||
|
if(auto selection = listView.state.selection) setSelection(selection());
|
||||||
|
autosizeColumns();
|
||||||
|
|
||||||
|
gtk_widget_show(subWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setFocused() {
|
||||||
|
gtk_widget_grab_focus(subWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pListView::setFont(Font &font) {
|
||||||
|
pWidget::setFont(font);
|
||||||
|
for(unsigned n = 0; n < 1 + listView.state.headerText.size(); n++) {
|
||||||
|
gtk_widget_modify_font(column[n].label, font.p.gtkFont);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
void pProgressBar::setPosition(unsigned position) {
|
||||||
|
position = position <= 100 ? position : 0;
|
||||||
|
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gtkWidget), (double)position / 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pProgressBar::constructor() {
|
||||||
|
gtkWidget = gtk_progress_bar_new();
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
static void RadioBox_tick(RadioBox *self) {
|
||||||
|
if(self->p.locked == false && self->checked() && self->onTick) self->onTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pRadioBox::checked() {
|
||||||
|
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtkWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pRadioBox::setChecked() {
|
||||||
|
locked = true;
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkWidget), true);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pRadioBox::setGroup(const reference_array<RadioBox&> &group) {
|
||||||
|
foreach(item, group, n) {
|
||||||
|
if(n == 0) continue;
|
||||||
|
GSList *currentGroup = gtk_radio_button_get_group(GTK_RADIO_BUTTON(group[0].p.gtkWidget));
|
||||||
|
if(currentGroup != gtk_radio_button_get_group(GTK_RADIO_BUTTON(gtkWidget))) {
|
||||||
|
gtk_radio_button_set_group(GTK_RADIO_BUTTON(gtkWidget), currentGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pRadioBox::setText(const string &text) {
|
||||||
|
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pRadioBox::constructor() {
|
||||||
|
gtkWidget = gtk_radio_button_new_with_label(0, "");
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(RadioBox_tick), (gpointer)&radioBox);
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
static void TextEdit_change(TextEdit *self) {
|
||||||
|
if(self->p.locked == false && self->onChange) self->onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pTextEdit::setCursorPosition(unsigned position) {
|
||||||
|
GtkTextMark *mark = gtk_text_buffer_get_mark(textBuffer, "insert");
|
||||||
|
GtkTextIter iter;
|
||||||
|
gtk_text_buffer_get_end_iter(textBuffer, &iter);
|
||||||
|
gtk_text_iter_set_offset(&iter, min(position, gtk_text_iter_get_offset(&iter)));
|
||||||
|
gtk_text_buffer_place_cursor(textBuffer, &iter);
|
||||||
|
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(subWidget), mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pTextEdit::setEditable(bool editable) {
|
||||||
|
gtk_text_view_set_editable(GTK_TEXT_VIEW(subWidget), editable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pTextEdit::setText(const string &text) {
|
||||||
|
locked = true;
|
||||||
|
gtk_text_buffer_set_text(textBuffer, text, -1);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pTextEdit::setWordWrap(bool wordWrap) {
|
||||||
|
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), wordWrap ? GTK_WRAP_WORD_CHAR : GTK_WRAP_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
string pTextEdit::text() {
|
||||||
|
GtkTextIter start, end;
|
||||||
|
gtk_text_buffer_get_start_iter(textBuffer, &start);
|
||||||
|
gtk_text_buffer_get_end_iter(textBuffer, &end);
|
||||||
|
char *temp = gtk_text_buffer_get_text(textBuffer, &start, &end, true);
|
||||||
|
string text = temp;
|
||||||
|
g_free(temp);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pTextEdit::constructor() {
|
||||||
|
gtkWidget = gtk_scrolled_window_new(0, 0);
|
||||||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||||
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkWidget), GTK_SHADOW_ETCHED_IN);
|
||||||
|
subWidget = gtk_text_view_new();
|
||||||
|
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_WORD_CHAR);
|
||||||
|
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
|
||||||
|
textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(subWidget));
|
||||||
|
g_signal_connect_swapped(G_OBJECT(textBuffer), "changed", G_CALLBACK(TextEdit_change), (gpointer)&textEdit);
|
||||||
|
gtk_widget_show(subWidget);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
static void VerticalSlider_change(VerticalSlider *self) {
|
||||||
|
if(self->state.position == self->position()) return;
|
||||||
|
self->state.position = self->position();
|
||||||
|
if(self->onChange) self->onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pVerticalSlider::position() {
|
||||||
|
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pVerticalSlider::setLength(unsigned length) {
|
||||||
|
length += length == 0;
|
||||||
|
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pVerticalSlider::setPosition(unsigned position) {
|
||||||
|
gtk_range_set_value(GTK_RANGE(gtkWidget), position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pVerticalSlider::constructor() {
|
||||||
|
gtkWidget = gtk_vscale_new_with_range(0, 100, 1);
|
||||||
|
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
|
||||||
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)&verticalSlider);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
uintptr_t pViewport::handle() {
|
||||||
|
return GDK_WINDOW_XID(gtkWidget->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pViewport::constructor() {
|
||||||
|
gtkWidget = gtk_drawing_area_new();
|
||||||
|
//gtk_widget_set_double_buffered(gtkWidget, false);
|
||||||
|
|
||||||
|
GdkColor color;
|
||||||
|
color.pixel = 0;
|
||||||
|
color.red = 0;
|
||||||
|
color.green = 0;
|
||||||
|
color.blue = 0;
|
||||||
|
gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, &color);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
static void Widget_setFont(GtkWidget *widget, gpointer font) {
|
||||||
|
if(font == 0) return;
|
||||||
|
gtk_widget_modify_font(widget, (PangoFontDescription*)font);
|
||||||
|
if(GTK_IS_CONTAINER(widget)) {
|
||||||
|
gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)Widget_setFont, font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pWidget::enabled() {
|
||||||
|
return gtk_widget_get_sensitive(gtkWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWidget::setEnabled(bool enabled) {
|
||||||
|
gtk_widget_set_sensitive(gtkWidget, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWidget::setFocused() {
|
||||||
|
gtk_widget_grab_focus(gtkWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWidget::setFont(Font &font) {
|
||||||
|
Widget_setFont(gtkWidget, font.p.gtkFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWidget::setGeometry(const Geometry &geometry) {
|
||||||
|
if(parentWindow) gtk_fixed_move(GTK_FIXED(parentWindow->formContainer), gtkWidget, geometry.x, geometry.y);
|
||||||
|
unsigned width = (signed)geometry.width <= 0 ? 1U : geometry.width;
|
||||||
|
unsigned height = (signed)geometry.height <= 0 ? 1U : geometry.height;
|
||||||
|
gtk_widget_set_size_request(gtkWidget, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWidget::setVisible(bool visible) {
|
||||||
|
if(widget.state.abstract) visible = false;
|
||||||
|
gtk_widget_set_visible(gtkWidget, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWidget::constructor() {
|
||||||
|
parentWindow = 0;
|
||||||
|
if(widget.state.abstract) gtkWidget = gtk_label_new("");
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
static void Action_setFont(GtkWidget *widget, gpointer font);
|
||||||
|
static void Widget_setFont(GtkWidget *widget, gpointer font);
|
||||||
|
|
||||||
|
static gint Window_close(Window *window) {
|
||||||
|
if(window->onClose) window->onClose();
|
||||||
|
window->setVisible(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean Window_configure(GtkWindow *widget, GdkEvent *event, Window *window) {
|
||||||
|
if(gtk_widget_get_realized(window->p.widget) == false) return false;
|
||||||
|
window->p.updateFrameGeometry();
|
||||||
|
|
||||||
|
signed eventX = event->configure.x, eventY = event->configure.y;
|
||||||
|
unsigned eventWidth = event->configure.width, eventHeight = event->configure.height;
|
||||||
|
|
||||||
|
if(window->p.locked == false && window->state.fullScreen == false) {
|
||||||
|
if(window->state.geometry.x != eventX || window->state.geometry.y != eventY) {
|
||||||
|
window->state.geometry.x = eventX;
|
||||||
|
window->state.geometry.y = eventY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(window->onMove) window->onMove();
|
||||||
|
|
||||||
|
eventHeight -= window->state.menuVisible ? window->p.menu->allocation.height : 0;
|
||||||
|
eventHeight -= window->state.statusVisible ? window->p.status->allocation.height : 0;
|
||||||
|
|
||||||
|
if(window->p.locked == false && window->state.fullScreen == false) {
|
||||||
|
if(window->state.geometry.width != eventWidth || window->state.geometry.height != eventHeight) {
|
||||||
|
window->state.geometry.width = eventWidth;
|
||||||
|
window->state.geometry.height = eventHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(layout, window->state.layout) {
|
||||||
|
Geometry geometry = window->geometry();
|
||||||
|
geometry.x = geometry.y = 0;
|
||||||
|
layout.setGeometry(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(window->onSize) window->onSize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::append(Layout &layout) {
|
||||||
|
layout.setParent(window);
|
||||||
|
Geometry geometry = this->geometry();
|
||||||
|
geometry.x = geometry.y = 0;
|
||||||
|
layout.setGeometry(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::append(Menu &subMenu) {
|
||||||
|
if(window.state.menuFont) subMenu.p.setFont(*window.state.menuFont);
|
||||||
|
gtk_menu_bar_append(menu, subMenu.p.widget);
|
||||||
|
gtk_widget_show(subMenu.p.widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::append(Widget &widget) {
|
||||||
|
widget.p.parentWindow = this;
|
||||||
|
if(!widget.state.font && window.state.widgetFont) {
|
||||||
|
widget.setFont(*window.state.widgetFont);
|
||||||
|
}
|
||||||
|
gtk_fixed_put(GTK_FIXED(formContainer), widget.p.gtkWidget, 0, 0);
|
||||||
|
widget.setVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry pWindow::frameGeometry() {
|
||||||
|
if(window.state.fullScreen == true) return { 0, 0, OS::desktopWidth(), OS::desktopHeight() };
|
||||||
|
return {
|
||||||
|
window.state.geometry.x - settings.frameGeometryX,
|
||||||
|
window.state.geometry.y - settings.frameGeometryY,
|
||||||
|
window.state.geometry.width + settings.frameGeometryWidth,
|
||||||
|
window.state.geometry.height + settings.frameGeometryHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pWindow::focused() {
|
||||||
|
return gtk_window_is_active(GTK_WINDOW(widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry pWindow::geometry() {
|
||||||
|
if(window.state.fullScreen == true) {
|
||||||
|
unsigned menuHeight = 0, statusHeight = 0;
|
||||||
|
if(window.state.menuVisible) menuHeight = menu->allocation.height;
|
||||||
|
if(window.state.statusVisible) statusHeight = menu->allocation.height;
|
||||||
|
return { 0, menuHeight, OS::desktopWidth(), OS::desktopHeight() - menuHeight - statusHeight };
|
||||||
|
}
|
||||||
|
return window.state.geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
|
||||||
|
GdkColor color;
|
||||||
|
color.pixel = (red << 16) | (green << 8) | (blue << 0);
|
||||||
|
color.red = (red << 8) | (red << 0);
|
||||||
|
color.green = (green << 8) | (green << 0);
|
||||||
|
color.blue = (blue << 8) | (blue << 0);
|
||||||
|
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setFrameGeometry(const Geometry &geometry) {
|
||||||
|
window.setGeometry({
|
||||||
|
geometry.x + settings.frameGeometryX, geometry.y + settings.frameGeometryY,
|
||||||
|
geometry.width - settings.frameGeometryWidth, geometry.height - settings.frameGeometryHeight
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setFocused() {
|
||||||
|
gtk_window_present(GTK_WINDOW(widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setFullScreen(bool fullScreen) {
|
||||||
|
if(fullScreen == false) {
|
||||||
|
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
||||||
|
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
|
||||||
|
gtk_window_set_decorated(GTK_WINDOW(widget), true);
|
||||||
|
locked = true;
|
||||||
|
for(unsigned n = 0; n < 4; n++) {
|
||||||
|
setGeometry(window.state.geometry);
|
||||||
|
gtk_widget_set_size_request(widget, -1, -1);
|
||||||
|
OS::process();
|
||||||
|
usleep(2000);
|
||||||
|
}
|
||||||
|
locked = false;
|
||||||
|
} else {
|
||||||
|
gtk_window_fullscreen(GTK_WINDOW(widget));
|
||||||
|
gtk_window_set_decorated(GTK_WINDOW(widget), false);
|
||||||
|
gtk_widget_set_size_request(widget, OS::desktopWidth(), OS::desktopHeight());
|
||||||
|
gtk_window_set_resizable(GTK_WINDOW(widget), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setGeometry(const Geometry &geometry) {
|
||||||
|
gtk_window_move(GTK_WINDOW(widget), geometry.x - settings.frameGeometryX, geometry.y - settings.frameGeometryY);
|
||||||
|
gtk_window_resize(GTK_WINDOW(widget), 1, 1);
|
||||||
|
gtk_widget_set_size_request(formContainer, geometry.width, geometry.height);
|
||||||
|
foreach(layout, window.state.layout) {
|
||||||
|
Geometry geometry = this->geometry();
|
||||||
|
geometry.x = geometry.y = 0;
|
||||||
|
layout.setGeometry(geometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setMenuFont(Font &font) {
|
||||||
|
foreach(item, window.state.menu) item.p.setFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setMenuVisible(bool visible) {
|
||||||
|
gtk_widget_set_visible(menu, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setResizable(bool resizable) {
|
||||||
|
gtk_window_set_resizable(GTK_WINDOW(widget), resizable);
|
||||||
|
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(status), resizable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setStatusFont(Font &font) {
|
||||||
|
Widget_setFont(status, (gpointer)font.p.gtkFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setStatusText(const string &text) {
|
||||||
|
gtk_statusbar_pop(GTK_STATUSBAR(status), 1);
|
||||||
|
gtk_statusbar_push(GTK_STATUSBAR(status), 1, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setStatusVisible(bool visible) {
|
||||||
|
gtk_widget_set_visible(status, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setTitle(const string &text) {
|
||||||
|
gtk_window_set_title(GTK_WINDOW(widget), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setVisible(bool visible) {
|
||||||
|
gtk_widget_set_visible(widget, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::setWidgetFont(Font &font) {
|
||||||
|
foreach(item, window.state.widget) {
|
||||||
|
if(!item.state.font) item.setFont(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::constructor() {
|
||||||
|
widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_resizable(GTK_WINDOW(widget), true);
|
||||||
|
gtk_widget_set_app_paintable(widget, true);
|
||||||
|
gtk_widget_add_events(widget, GDK_CONFIGURE);
|
||||||
|
|
||||||
|
menuContainer = gtk_vbox_new(false, 0);
|
||||||
|
gtk_container_add(GTK_CONTAINER(widget), menuContainer);
|
||||||
|
gtk_widget_show(menuContainer);
|
||||||
|
|
||||||
|
menu = gtk_menu_bar_new();
|
||||||
|
gtk_box_pack_start(GTK_BOX(menuContainer), menu, false, false, 0);
|
||||||
|
|
||||||
|
formContainer = gtk_fixed_new();
|
||||||
|
gtk_box_pack_start(GTK_BOX(menuContainer), formContainer, true, true, 0);
|
||||||
|
gtk_widget_show(formContainer);
|
||||||
|
|
||||||
|
statusContainer = gtk_event_box_new();
|
||||||
|
status = gtk_statusbar_new();
|
||||||
|
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(status), true);
|
||||||
|
gtk_container_add(GTK_CONTAINER(statusContainer), status);
|
||||||
|
gtk_box_pack_start(GTK_BOX(menuContainer), statusContainer, false, false, 0);
|
||||||
|
gtk_widget_show(statusContainer);
|
||||||
|
|
||||||
|
setTitle("");
|
||||||
|
setGeometry(window.state.geometry);
|
||||||
|
|
||||||
|
g_signal_connect_swapped(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window);
|
||||||
|
g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pWindow::updateFrameGeometry() {
|
||||||
|
#if defined(PLATFORM_X)
|
||||||
|
Display *display = XOpenDisplay(0);
|
||||||
|
XWindowAttributes attributes, parentAttributes;
|
||||||
|
XGetWindowAttributes(display, GDK_WINDOW_XID(widget->window), &attributes);
|
||||||
|
X11Window rootWindow, parentWindow, *childWindow = 0;
|
||||||
|
unsigned int childCount;
|
||||||
|
XQueryTree(display, GDK_WINDOW_XID(widget->window), &rootWindow, &parentWindow, &childWindow, &childCount);
|
||||||
|
XGetWindowAttributes(display, parentWindow, &parentAttributes);
|
||||||
|
if(childWindow) XFree(childWindow);
|
||||||
|
XCloseDIsplay(display);
|
||||||
|
|
||||||
|
settings.frameGeometryX = attributes.x;
|
||||||
|
settings.frameGeometryY = attributes.y;
|
||||||
|
settings.frameGeometryWidth = parentAttributes.width - attributes.width;
|
||||||
|
settings.frameGeometryHeight = parentAttributes.height - attributes.height;
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -13,6 +13,17 @@
|
||||||
#elif defined(PHOENIX_QT)
|
#elif defined(PHOENIX_QT)
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
#elif defined(PHOENIX_GTK)
|
||||||
|
#define None X11None
|
||||||
|
#define Window X11Window
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
|
||||||
|
#undef None
|
||||||
|
#undef Window
|
||||||
#elif defined(PHOENIX_REFERENCE)
|
#elif defined(PHOENIX_REFERENCE)
|
||||||
#else
|
#else
|
||||||
#error "phoenix: unrecognized target"
|
#error "phoenix: unrecognized target"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Meta object code from reading C++ file 'qt.moc.hpp'
|
** Meta object code from reading C++ file 'qt.moc.hpp'
|
||||||
**
|
**
|
||||||
** Created: Fri Feb 18 07:05:10 2011
|
** Created: Tue Feb 22 04:37:04 2011
|
||||||
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
|
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
|
||||||
**
|
**
|
||||||
** WARNING! All changes made in this file will be lost!
|
** WARNING! All changes made in this file will be lost!
|
||||||
|
|
|
@ -19,6 +19,14 @@ void pComboBox::constructor() {
|
||||||
setParent(Window::None);
|
setParent(Window::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pComboBox::setGeometry(const Geometry &geometry) {
|
||||||
|
SetWindowPos(hwnd, NULL, geometry.x, geometry.y, geometry.width, 200, SWP_NOZORDER);
|
||||||
|
RECT rc;
|
||||||
|
GetWindowRect(hwnd, &rc);
|
||||||
|
unsigned adjustedHeight = geometry.height - ((rc.bottom - rc.top) - SendMessage(hwnd, CB_GETITEMHEIGHT, (WPARAM)-1, 0));
|
||||||
|
SendMessage(hwnd, CB_SETITEMHEIGHT, (WPARAM)-1, adjustedHeight);
|
||||||
|
}
|
||||||
|
|
||||||
void pComboBox::setParent(Window &parent) {
|
void pComboBox::setParent(Window &parent) {
|
||||||
if(hwnd) DestroyWindow(hwnd);
|
if(hwnd) DestroyWindow(hwnd);
|
||||||
hwnd = CreateWindow(
|
hwnd = CreateWindow(
|
||||||
|
|
|
@ -102,6 +102,11 @@ void pListView::constructor() {
|
||||||
setParent(Window::None);
|
setParent(Window::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pListView::setGeometry(const Geometry &geometry) {
|
||||||
|
pWidget::setGeometry(geometry);
|
||||||
|
autosizeColumns();
|
||||||
|
}
|
||||||
|
|
||||||
void pListView::setParent(Window &parent) {
|
void pListView::setParent(Window &parent) {
|
||||||
if(hwnd) DestroyWindow(hwnd);
|
if(hwnd) DestroyWindow(hwnd);
|
||||||
hwnd = CreateWindowEx(
|
hwnd = CreateWindowEx(
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
bool pWidget::enabled() {
|
bool pWidget::enabled() {
|
||||||
return false;
|
return IsWindowEnabled(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setEnabled(bool enabled) {
|
void pWidget::setEnabled(bool enabled) {
|
||||||
|
EnableWindow(hwnd, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setFocused() {
|
void pWidget::setFocused() {
|
||||||
|
SetFocus(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setFont(Font &font) {
|
void pWidget::setFont(Font &font) {
|
||||||
|
SendMessage(hwnd, WM_SETFONT, (WPARAM)font.p.hfont, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setGeometry(const Geometry &geometry) {
|
void pWidget::setGeometry(const Geometry &geometry) {
|
||||||
|
@ -16,10 +19,13 @@ void pWidget::setGeometry(const Geometry &geometry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setVisible(bool visible) {
|
void pWidget::setVisible(bool visible) {
|
||||||
|
if(widget.state.abstract) visible = false;
|
||||||
|
ShowWindow(hwnd, visible ? SW_SHOWNORMAL : SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::constructor() {
|
void pWidget::constructor() {
|
||||||
hwnd = 0;
|
hwnd = 0;
|
||||||
|
if(widget.state.abstract) setParent(Window::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setDefaultFont() {
|
void pWidget::setDefaultFont() {
|
||||||
|
@ -31,4 +37,7 @@ void pWidget::setDefaultFont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWidget::setParent(Window &parent) {
|
void pWidget::setParent(Window &parent) {
|
||||||
|
if(hwnd) DestroyWindow(hwnd);
|
||||||
|
hwnd = CreateWindow(L"phoenix_label", L"", WS_CHILD, 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0);
|
||||||
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&widget);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,16 @@ void pWindow::setFocused() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWindow::setFullScreen(bool fullScreen) {
|
void pWindow::setFullScreen(bool fullScreen) {
|
||||||
|
locked = true;
|
||||||
|
if(fullScreen == false) {
|
||||||
|
SetWindowLongPtr(hwnd, GWL_STYLE, WS_VISIBLE | (window.state.resizable ? ResizableStyle : FixedStyle));
|
||||||
|
setGeometry(window.state.geometry);
|
||||||
|
} else {
|
||||||
|
SetWindowLongPtr(hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
|
||||||
|
Geometry margin = frameMargin();
|
||||||
|
setGeometry({ margin.x, margin.y, GetSystemMetrics(SM_CXSCREEN) - margin.width, GetSystemMetrics(SM_CYSCREEN) - margin.height });
|
||||||
|
}
|
||||||
|
locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWindow::setGeometry(const Geometry &geometry) {
|
void pWindow::setGeometry(const Geometry &geometry) {
|
||||||
|
@ -95,7 +105,7 @@ void pWindow::setResizable(bool resizable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWindow::setStatusFont(Font &font) {
|
void pWindow::setStatusFont(Font &font) {
|
||||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)font.p.hfont, 0);
|
SendMessage(hstatus, WM_SETFONT, (WPARAM)font.p.hfont, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWindow::setStatusText(const string &text) {
|
void pWindow::setStatusText(const string &text) {
|
||||||
|
@ -138,8 +148,10 @@ void pWindow::constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry pWindow::frameMargin() {
|
Geometry pWindow::frameMargin() {
|
||||||
|
unsigned style = window.state.resizable ? ResizableStyle : FixedStyle;
|
||||||
|
if(window.state.fullScreen) style = 0;
|
||||||
RECT rc = { 0, 0, 640, 480 };
|
RECT rc = { 0, 0, 640, 480 };
|
||||||
AdjustWindowRect(&rc, window.state.resizable ? ResizableStyle : FixedStyle, window.state.menuVisible);
|
AdjustWindowRect(&rc, style, window.state.menuVisible);
|
||||||
unsigned statusHeight = 0;
|
unsigned statusHeight = 0;
|
||||||
if(window.state.statusVisible) {
|
if(window.state.statusVisible) {
|
||||||
RECT src;
|
RECT src;
|
||||||
|
|
|
@ -160,7 +160,7 @@ struct pWidget : public pObject {
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
void setFont(Font &font);
|
void setFont(Font &font);
|
||||||
void setGeometry(const Geometry &geometry);
|
virtual void setGeometry(const Geometry &geometry);
|
||||||
void setVisible(bool visible);
|
void setVisible(bool visible);
|
||||||
|
|
||||||
pWidget(Widget &widget) : widget(widget) {}
|
pWidget(Widget &widget) : widget(widget) {}
|
||||||
|
@ -201,6 +201,7 @@ struct pComboBox : public pWidget {
|
||||||
|
|
||||||
pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {}
|
pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {}
|
||||||
void constructor();
|
void constructor();
|
||||||
|
void setGeometry(const Geometry &geometry);
|
||||||
void setParent(Window &parent);
|
void setParent(Window &parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,6 +274,7 @@ struct pListView : public pWidget {
|
||||||
|
|
||||||
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
|
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
|
||||||
void constructor();
|
void constructor();
|
||||||
|
void setGeometry(const Geometry &geometry);
|
||||||
void setParent(Window &parent);
|
void setParent(Window &parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
namespace Info {
|
namespace Info {
|
||||||
static const char Name[] = "bsnes";
|
static const char Name[] = "bsnes";
|
||||||
static const char Version[] = "075.14";
|
static const char Version[] = "075.15";
|
||||||
static const unsigned SerializerVersion = 18;
|
static const unsigned SerializerVersion = 18;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUGGER
|
//#define DEBUGGER
|
||||||
|
|
||||||
#include <libco/libco.h>
|
#include <libco/libco.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue