Update to v075r14 release.

byuu says:

Adds the new phoenix/Windows. Testing would once again be appreciated,
as this is basically a rewrite of the entire core of the GUI.
This commit is contained in:
Tim Allen 2011-02-24 20:25:20 +11:00
parent 3fad0a0105
commit 7c3aaf12b0
111 changed files with 2404 additions and 551 deletions

103
bsnes/nall/reference_array.hpp Executable file
View File

@ -0,0 +1,103 @@
#ifndef NALL_REFERENCE_ARRAY_HPP
#define NALL_REFERENCE_ARRAY_HPP
#include <type_traits>
#include <nall/bit.hpp>
#include <nall/concept.hpp>
namespace nall {
template<typename T> struct reference_array {
protected:
typedef typename std::remove_reference<T>::type *Tptr;
Tptr *pool;
unsigned poolsize, buffersize;
public:
unsigned size() const { return buffersize; }
unsigned capacity() const { return poolsize; }
void reset() {
if(pool) free(pool);
pool = 0;
poolsize = 0;
buffersize = 0;
}
void reserve(unsigned newsize) {
if(newsize == poolsize) return;
pool = (Tptr*)realloc(pool, newsize * sizeof(T));
poolsize = newsize;
buffersize = min(buffersize, newsize);
}
void resize(unsigned newsize) {
if(newsize > poolsize) reserve(bit::round(newsize));
buffersize = newsize;
}
void append(const T data) {
unsigned index = buffersize++;
if(index >= poolsize) resize(index + 1);
pool[index] = &data;
}
template<typename... Args> reference_array(Args&... args) : pool(0), poolsize(0), buffersize(0) {
construct(args...);
}
~reference_array() {
reset();
}
reference_array& operator=(const reference_array &source) {
if(pool) free(pool);
buffersize = source.buffersize;
poolsize = source.poolsize;
pool = (Tptr*)malloc(sizeof(T) * poolsize);
memcpy(pool, source.pool, sizeof(T) * buffersize);
return *this;
}
reference_array& operator=(const reference_array &&source) {
if(pool) free(pool);
pool = source.pool;
poolsize = source.poolsize;
buffersize = source.buffersize;
source.pool = 0;
source.reset();
return *this;
}
inline T operator[](unsigned index) {
if(index >= buffersize) throw "reference_array[] out of bounds";
return *pool[index];
}
inline const T operator[](unsigned index) const {
if(index >= buffersize) throw "reference_array[] out of bounds";
return *pool[index];
}
private:
void construct() {
}
void construct(const reference_array &source) {
operator=(source);
}
void construct(const reference_array &&source) {
operator=(std::move(source));
}
template<typename... Args> void construct(T data, Args&... args) {
append(data);
construct(args...);
}
};
template<typename T> struct has_size<reference_array<T>> { enum { value = true }; };
}
#endif

View File

@ -1,239 +1,11 @@
struct OS::State {
bool initialized;
State() {
initialized = false;
}
};
struct Font::State {
bool bold;
string family;
bool italic;
unsigned size;
bool underline;
State() {
bold = false;
italic = false;
size = 8;
underline = false;
}
};
struct Window::State {
bool backgroundColor;
unsigned backgroundColorRed, backgroundColorGreen, backgroundColorBlue;
bool fullScreen;
Geometry geometry;
Layout *layout;
Font *menuFont;
bool menuVisible;
bool resizable;
Font *statusFont;
string statusText;
bool statusVisible;
string title;
bool visible;
Font *widgetFont;
State() {
backgroundColor = false;
backgroundColorRed = 0;
backgroundColorGreen = 0;
backgroundColorBlue = 0;
fullScreen = false;
geometry = { 128, 128, 256, 256 };
layout = 0;
menuFont = 0;
menuVisible = false;
resizable = true;
statusVisible = false;
visible = false;
widgetFont = 0;
}
};
struct Action::State {
bool enabled;
Window *parent;
bool visible;
State() {
enabled = true;
parent = 0;
visible = true;
}
};
struct Menu::State {
string text;
};
struct MenuItem::State {
string text;
};
struct MenuCheckItem::State {
bool checked;
string text;
State() {
checked = false;
}
};
struct MenuRadioItem::State {
bool checked;
array<MenuRadioItem*> group;
string text;
State() {
checked = true;
}
};
struct Layout::State {
Window *parent;
State() {
parent = 0;
}
};
struct Widget::State {
bool enabled;
Font *font;
Geometry geometry;
bool visible;
State() {
enabled = true;
font = 0;
geometry = { 0, 0, 0, 0 };
visible = true;
}
};
struct Button::State {
string text;
};
struct CheckBox::State {
bool checked;
string text;
State() {
checked = false;
}
};
struct ComboBox::State {
unsigned selection;
linear_vector<string> text;
State() {
selection = 0;
}
};
struct HexEdit::State {
unsigned columns;
unsigned length;
unsigned offset;
unsigned rows;
State() {
columns = 16;
length = 0;
offset = 0;
rows = 16;
}
};
struct HorizontalSlider::State {
unsigned length;
unsigned position;
State() {
length = 101;
position = 0;
}
};
struct Label::State {
string text;
};
struct LineEdit::State {
bool editable;
string text;
State() {
editable = true;
}
};
struct ListView::State {
bool checkable;
array<bool> checked;
lstring headerText;
bool headerVisible;
optional<unsigned> selection;
linear_vector<lstring> text;
State() : selection(false, 0) {
checkable = false;
headerVisible = false;
}
};
struct ProgressBar::State {
unsigned position;
State() {
position = 0;
}
};
struct RadioBox::State {
bool checked;
array<RadioBox*> group;
string text;
State() {
checked = true;
}
};
struct TextEdit::State {
unsigned cursorPosition;
bool editable;
string text;
bool wordWrap;
State() {
cursorPosition = 0;
editable = true;
wordWrap = false;
}
};
struct VerticalSlider::State {
unsigned length;
unsigned position;
State() {
length = 101;
position = 0;
}
};
#include "state.hpp"
#include "layout/fixed-layout.cpp"
#include "layout/horizontal-layout.cpp"
#include "layout/vertical-layout.cpp"
#if defined(PHOENIX_QT)
#if defined(PHOENIX_WINDOWS)
#include "../windows/windows.cpp"
#elif defined(PHOENIX_QT)
#include "../qt/qt.cpp"
#elif defined(PHOENIX_REFERENCE)
#include "../reference/reference.cpp"
@ -241,24 +13,23 @@ struct VerticalSlider::State {
Object::Object() { OS::initialize(); }
OS::State OS::state;
unsigned OS::desktopWidth() { return pOS::desktopWidth(); }
unsigned OS::desktopHeight() { return pOS::desktopHeight(); }
string OS::fileLoad_(Window &parent, const string &path, lstring &filter) { if(filter.size() == 0) filter.append("All files (*)"); return pOS::fileLoad(parent, path, filter); }
string OS::fileSave_(Window &parent, const string &path, lstring &filter) { if(filter.size() == 0) filter.append("All files (*)"); return pOS::fileSave(parent, path, filter); }
string OS::fileLoad_(Window &parent, const string &path, const lstring &filter_) { auto filter = filter_; if(filter.size() == 0) filter.append("All files (*)"); return pOS::fileLoad(parent, path, filter); }
string OS::fileSave_(Window &parent, const string &path, const lstring &filter_) { auto filter = filter_; if(filter.size() == 0) filter.append("All files (*)"); return pOS::fileSave(parent, path, filter); }
string OS::folderSelect(Window &parent, const string &path) { return pOS::folderSelect(parent, path); }
void OS::main() { return pOS::main(); }
bool OS::pending() { return pOS::pending(); }
void OS::process() { return pOS::process(); }
void OS::quit() { return pOS::quit(); }
void OS::initialize() { if(state.initialized == false) { state.initialized = true; return pOS::initialize(); } }
void OS::initialize() { static bool initialized = false; if(initialized == false) { initialized = true; return pOS::initialize(); } }
void Font::setBold(bool bold) { state.bold = bold; return p.setBold(bold); }
void Font::setFamily(const string &family) { state.family = family; return p.setFamily(family); }
void Font::setItalic(bool italic) { state.italic = italic; return p.setItalic(italic); }
void Font::setSize(unsigned size) { state.size = size; return p.setSize(size); }
void Font::setUnderline(bool underline) { state.underline = underline; return p.setUnderline(underline); }
Font::Font() : state(*new State), p(*new pFont(*this)) {}
Font::Font() : state(*new State), p(*new pFont(*this)) { p.constructor(); }
MessageWindow::Response MessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) { return pMessageWindow::information(parent, text, buttons); }
MessageWindow::Response MessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) { return pMessageWindow::question(parent, text, buttons); }
@ -266,7 +37,9 @@ MessageWindow::Response MessageWindow::warning(Window &parent, const string &tex
MessageWindow::Response MessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) { return pMessageWindow::critical(parent, text, buttons); }
Window Window::None;
void Window::append(Menu &menu) { ((Action&)menu).state.parent = this; return p.append(menu); }
void Window::append(Layout &layout) { state.layout.append(layout); return p.append(layout); }
void Window::append(Menu &menu) { state.menu.append(menu); ((Action&)menu).state.parent = this; return p.append(menu); }
void Window::append(Widget &widget) { state.widget.append(widget); return p.append(widget); }
Geometry Window::frameGeometry() { return p.frameGeometry(); }
bool Window::focused() { return p.focused(); }
Geometry Window::geometry() { return p.geometry(); }
@ -275,7 +48,6 @@ void Window::setFrameGeometry(const Geometry &geometry) { return p.setFrameGeome
void Window::setFocused() { return p.setFocused(); }
void Window::setFullScreen(bool fullScreen) { state.fullScreen = fullScreen; return p.setFullScreen(fullScreen); }
void Window::setGeometry(const Geometry &geometry) { state.geometry = geometry; return p.setGeometry(geometry); }
void Window::setLayout(Layout &layout) { layout.state.parent = this; state.layout = &layout; return p.setLayout(layout); }
void Window::setMenuFont(Font &font) { state.menuFont = &font; return p.setMenuFont(font); }
void Window::setMenuVisible(bool visible) { state.menuVisible = visible; return p.setMenuVisible(visible); }
void Window::setResizable(bool resizable) { state.resizable = resizable; return p.setResizable(resizable); }
@ -285,35 +57,31 @@ void Window::setStatusVisible(bool visible) { state.statusVisible = visible; ret
void Window::setTitle(const string &text) { state.title = text; return p.setTitle(text); }
void Window::setVisible(bool visible) { state.visible = visible; return p.setVisible(visible); }
void Window::setWidgetFont(Font &font) { state.widgetFont = &font; return p.setWidgetFont(font); }
Window::Window() : state(*new State), p(*new pWindow(*this)) {}
Window::Window() : state(*new State), p(*new pWindow(*this)) { p.constructor(); }
void Action::setEnabled(bool enabled) { state.enabled = enabled; return p.setEnabled(enabled); }
void Action::setVisible(bool visible) { state.visible = visible; return p.setVisible(visible); }
Action::Action(pAction &p) : state(*new State), p(p) {}
Action::Action(pAction &p) : state(*new State), p(p) { p.constructor(); }
void Menu::append(Action &action) { return p.append(action); }
void Menu::append(Action &action) { state.action.append(action); return p.append(action); }
void Menu::setText(const string &text) { state.text = text; return p.setText(text); }
Menu::Menu() : state(*new State), base_from_member<pMenu&>(*new pMenu(*this)), Action(base_from_member<pMenu&>::value), p(base_from_member<pMenu&>::value) {}
Menu::Menu() : state(*new State), base_from_member<pMenu&>(*new pMenu(*this)), Action(base_from_member<pMenu&>::value), p(base_from_member<pMenu&>::value) { p.constructor(); }
MenuSeparator::MenuSeparator() : base_from_member<pMenuSeparator&>(*new pMenuSeparator(*this)), Action(base_from_member<pMenuSeparator&>::value), p(base_from_member<pMenuSeparator&>::value) {}
MenuSeparator::MenuSeparator() : base_from_member<pMenuSeparator&>(*new pMenuSeparator(*this)), Action(base_from_member<pMenuSeparator&>::value), p(base_from_member<pMenuSeparator&>::value) { p.constructor(); }
void MenuItem::setText(const string &text) { state.text = text; return p.setText(text); }
MenuItem::MenuItem() : state(*new State), base_from_member<pMenuItem&>(*new pMenuItem(*this)), Action(base_from_member<pMenuItem&>::value), p(base_from_member<pMenuItem&>::value) {}
MenuItem::MenuItem() : state(*new State), base_from_member<pMenuItem&>(*new pMenuItem(*this)), Action(base_from_member<pMenuItem&>::value), p(base_from_member<pMenuItem&>::value) { p.constructor(); }
bool MenuCheckItem::checked() { return p.checked(); }
void MenuCheckItem::setChecked(bool checked) { state.checked = checked; return p.setChecked(checked); }
void MenuCheckItem::setText(const string &text) { state.text = text; return p.setText(text); }
MenuCheckItem::MenuCheckItem() : state(*new State), base_from_member<pMenuCheckItem&>(*new pMenuCheckItem(*this)), Action(base_from_member<pMenuCheckItem&>::value), p(base_from_member<pMenuCheckItem&>::value) {}
MenuCheckItem::MenuCheckItem() : state(*new State), base_from_member<pMenuCheckItem&>(*new pMenuCheckItem(*this)), Action(base_from_member<pMenuCheckItem&>::value), p(base_from_member<pMenuCheckItem&>::value) { p.constructor(); }
void MenuRadioItem::group_(const reference_array<MenuRadioItem&> &list) { foreach(item, list) item.p.setGroup(item.state.group = list); if(list.size()) list[0].setChecked(); }
bool MenuRadioItem::checked() { return p.checked(); }
void MenuRadioItem::setChecked() { foreach(item, state.group) item->state.checked = false; state.checked = true; return p.setChecked(); }
void MenuRadioItem::setGroup(const array<MenuRadioItem*> &group) { state.group = group; return p.setGroup(group); }
void MenuRadioItem::setChecked() { foreach(item, state.group) item.state.checked = false; state.checked = true; return p.setChecked(); }
void MenuRadioItem::setText(const string &text) { state.text = text; return p.setText(text); }
MenuRadioItem::MenuRadioItem() : state(*new State), base_from_member<pMenuRadioItem&>(*new pMenuRadioItem(*this)), Action(base_from_member<pMenuRadioItem&>::value), p(base_from_member<pMenuRadioItem&>::value) {}
void Layout::append(Widget &widget) { return p.append(widget); }
void Layout::setParent(Window &parent) { state.parent = &parent; }
Layout::Layout() : state(*new State), p(*new pLayout(*this)) {}
MenuRadioItem::MenuRadioItem() : state(*new State), base_from_member<pMenuRadioItem&>(*new pMenuRadioItem(*this)), Action(base_from_member<pMenuRadioItem&>::value), p(base_from_member<pMenuRadioItem&>::value) { p.constructor(); }
bool Widget::enabled() { return p.enabled(); }
void Widget::setEnabled(bool enabled) { state.enabled = enabled; return p.setEnabled(enabled); }
@ -321,77 +89,77 @@ void Widget::setFocused() { return p.setFocused(); }
void Widget::setFont(Font &font) { state.font = &font; return p.setFont(font); }
void Widget::setGeometry(const Geometry &geometry) { state.geometry = geometry; return p.setGeometry(geometry); }
void Widget::setVisible(bool visible) { state.visible = visible; return p.setVisible(visible); }
Widget::Widget(pWidget &p) : state(*new State), p(p) {}
Widget::Widget() : state(*new State), p(*new pWidget(*this)) { state.abstract = true; p.constructor(); }
Widget::Widget(pWidget &p) : state(*new State), p(p) { p.constructor(); }
void Button::setText(const string &text) { state.text = text; return p.setText(text); }
Button::Button() : state(*new State), base_from_member<pButton&>(*new pButton(*this)), Widget(base_from_member<pButton&>::value), p(base_from_member<pButton&>::value) {}
Button::Button() : state(*new State), base_from_member<pButton&>(*new pButton(*this)), Widget(base_from_member<pButton&>::value), p(base_from_member<pButton&>::value) { p.constructor(); }
bool CheckBox::checked() { return p.checked(); }
void CheckBox::setChecked(bool checked) { state.checked = checked; return p.setChecked(checked); }
void CheckBox::setText(const string &text) { state.text = text; return p.setText(text); }
CheckBox::CheckBox() : state(*new State), base_from_member<pCheckBox&>(*new pCheckBox(*this)), Widget(base_from_member<pCheckBox&>::value), p(base_from_member<pCheckBox&>::value) {}
CheckBox::CheckBox() : state(*new State), base_from_member<pCheckBox&>(*new pCheckBox(*this)), Widget(base_from_member<pCheckBox&>::value), p(base_from_member<pCheckBox&>::value) { p.constructor(); }
void ComboBox::append(const string &text) { state.text.append(text); return p.append(text); }
void ComboBox::reset() { state.selection = 0; state.text.reset(); return p.reset(); }
unsigned ComboBox::selection() { return p.selection(); }
void ComboBox::setSelection(unsigned row) { state.selection = row; return p.setSelection(row); }
ComboBox::ComboBox() : state(*new State), base_from_member<pComboBox&>(*new pComboBox(*this)), Widget(base_from_member<pComboBox&>::value), p(base_from_member<pComboBox&>::value) {}
ComboBox::ComboBox() : state(*new State), base_from_member<pComboBox&>(*new pComboBox(*this)), Widget(base_from_member<pComboBox&>::value), p(base_from_member<pComboBox&>::value) { p.constructor(); }
void HexEdit::setColumns(unsigned columns) { state.columns = columns; return p.setColumns(columns); }
void HexEdit::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void HexEdit::setOffset(unsigned offset) { state.offset = offset; return p.setOffset(offset); }
void HexEdit::setRows(unsigned rows) { state.rows = rows; return p.setRows(rows); }
void HexEdit::update() { return p.update(); }
HexEdit::HexEdit() : state(*new State), base_from_member<pHexEdit&>(*new pHexEdit(*this)), Widget(base_from_member<pHexEdit&>::value), p(base_from_member<pHexEdit&>::value) {}
HexEdit::HexEdit() : state(*new State), base_from_member<pHexEdit&>(*new pHexEdit(*this)), Widget(base_from_member<pHexEdit&>::value), p(base_from_member<pHexEdit&>::value) { p.constructor(); }
unsigned HorizontalSlider::position() { return p.position(); }
void HorizontalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void HorizontalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
HorizontalSlider::HorizontalSlider() : state(*new State), base_from_member<pHorizontalSlider&>(*new pHorizontalSlider(*this)), Widget(base_from_member<pHorizontalSlider&>::value), p(base_from_member<pHorizontalSlider&>::value) {}
HorizontalSlider::HorizontalSlider() : state(*new State), base_from_member<pHorizontalSlider&>(*new pHorizontalSlider(*this)), Widget(base_from_member<pHorizontalSlider&>::value), p(base_from_member<pHorizontalSlider&>::value) { p.constructor(); }
void Label::setText(const string &text) { state.text = text; return p.setText(text); }
Label::Label() : state(*new State), base_from_member<pLabel&>(*new pLabel(*this)), Widget(base_from_member<pLabel&>::value), p(base_from_member<pLabel&>::value) {}
Label::Label() : state(*new State), base_from_member<pLabel&>(*new pLabel(*this)), Widget(base_from_member<pLabel&>::value), p(base_from_member<pLabel&>::value) { p.constructor(); }
void LineEdit::setEditable(bool editable) { state.editable = editable; return p.setEditable(editable); }
void LineEdit::setText(const string &text) { state.text = text; return p.setText(text); }
string LineEdit::text() { return p.text(); }
LineEdit::LineEdit() : state(*new State), base_from_member<pLineEdit&>(*new pLineEdit(*this)), Widget(base_from_member<pLineEdit&>::value), p(base_from_member<pLineEdit&>::value) {}
LineEdit::LineEdit() : state(*new State), base_from_member<pLineEdit&>(*new pLineEdit(*this)), Widget(base_from_member<pLineEdit&>::value), p(base_from_member<pLineEdit&>::value) { p.constructor(); }
void ListView::append_(lstring &text) { state.text.append(text); return p.append(text); }
void ListView::append_(const lstring &text) { state.checked.append(false); state.text.append(text); return p.append(text); }
void ListView::autosizeColumns() { return p.autosizeColumns(); }
bool ListView::checked(unsigned row) { return p.checked(row); }
void ListView::modify_(unsigned row, lstring &text) { state.text[row] = text; return p.modify(row, text); }
void ListView::modify_(unsigned row, const lstring &text) { state.text[row] = text; return p.modify(row, text); }
void ListView::modify(unsigned row, unsigned column, const string &text) { state.text[row][column] = text; return p.modify(row, column, text); }
void ListView::reset() { state.checked.reset(); state.text.reset(); return p.reset(); }
optional<unsigned> ListView::selection() { return p.selection(); }
void ListView::setCheckable(bool checkable) { state.checkable = checkable; return p.setCheckable(checkable); }
void ListView::setChecked(unsigned row, bool checked) { state.checked[row] = checked; return p.setChecked(row, checked); }
void ListView::setHeaderText_(lstring &text) { state.headerText = text; return p.setHeaderText(text); }
void ListView::setHeaderText_(const lstring &text) { state.headerText = text; return p.setHeaderText(text); }
void ListView::setHeaderVisible(bool visible) { state.headerVisible = visible; return p.setHeaderVisible(visible); }
void ListView::setSelection(unsigned row) { state.selection = { true, row }; return p.setSelection(row); }
ListView::ListView() : state(*new State), base_from_member<pListView&>(*new pListView(*this)), Widget(base_from_member<pListView&>::value), p(base_from_member<pListView&>::value) {}
ListView::ListView() : state(*new State), base_from_member<pListView&>(*new pListView(*this)), Widget(base_from_member<pListView&>::value), p(base_from_member<pListView&>::value) { p.constructor(); }
void ProgressBar::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
ProgressBar::ProgressBar() : state(*new State), base_from_member<pProgressBar&>(*new pProgressBar(*this)), Widget(base_from_member<pProgressBar&>::value), p(base_from_member<pProgressBar&>::value) {}
ProgressBar::ProgressBar() : state(*new State), base_from_member<pProgressBar&>(*new pProgressBar(*this)), Widget(base_from_member<pProgressBar&>::value), p(base_from_member<pProgressBar&>::value) { p.constructor(); }
void RadioBox::group_(const reference_array<RadioBox&> &list) { foreach(item, list) item.p.setGroup(item.state.group = list); if(list.size()) list[0].setChecked(); }
bool RadioBox::checked() { return p.checked(); }
void RadioBox::setChecked() { foreach(item, state.group) item->state.checked = false; state.checked = true; return p.setChecked(); }
void RadioBox::setGroup(const array<RadioBox*> &group) { state.group = group; return p.setGroup(group); }
void RadioBox::setChecked() { foreach(item, state.group) item.state.checked = false; state.checked = true; return p.setChecked(); }
void RadioBox::setText(const string &text) { state.text = text; return p.setText(text); }
RadioBox::RadioBox() : state(*new State), base_from_member<pRadioBox&>(*new pRadioBox(*this)), Widget(base_from_member<pRadioBox&>::value), p(base_from_member<pRadioBox&>::value) {}
RadioBox::RadioBox() : state(*new State), base_from_member<pRadioBox&>(*new pRadioBox(*this)), Widget(base_from_member<pRadioBox&>::value), p(base_from_member<pRadioBox&>::value) { p.constructor(); }
void TextEdit::setCursorPosition(unsigned position) { state.cursorPosition = position; return p.setCursorPosition(position); }
void TextEdit::setEditable(bool editable) { state.editable = editable; return p.setEditable(editable); }
void TextEdit::setText(const string &text) { state.text = text; return p.setText(text); }
void TextEdit::setWordWrap(bool wordWrap) { state.wordWrap = wordWrap; return p.setWordWrap(wordWrap); }
string TextEdit::text() { return p.text(); }
TextEdit::TextEdit() : state(*new State), base_from_member<pTextEdit&>(*new pTextEdit(*this)), Widget(base_from_member<pTextEdit&>::value), p(base_from_member<pTextEdit&>::value) {}
TextEdit::TextEdit() : state(*new State), base_from_member<pTextEdit&>(*new pTextEdit(*this)), Widget(base_from_member<pTextEdit&>::value), p(base_from_member<pTextEdit&>::value) { p.constructor(); }
unsigned VerticalSlider::position() { return p.position(); }
void VerticalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void VerticalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
VerticalSlider::VerticalSlider() : state(*new State), base_from_member<pVerticalSlider&>(*new pVerticalSlider(*this)), Widget(base_from_member<pVerticalSlider&>::value), p(base_from_member<pVerticalSlider&>::value) {}
VerticalSlider::VerticalSlider() : state(*new State), base_from_member<pVerticalSlider&>(*new pVerticalSlider(*this)), Widget(base_from_member<pVerticalSlider&>::value), p(base_from_member<pVerticalSlider&>::value) { p.constructor(); }
uintptr_t Viewport::handle() { return p.handle(); }
Viewport::Viewport() : base_from_member<pViewport&>(*new pViewport(*this)), Widget(base_from_member<pViewport&>::value), p(base_from_member<pViewport&>::value) {}
Viewport::Viewport() : base_from_member<pViewport&>(*new pViewport(*this)), Widget(base_from_member<pViewport&>::value), p(base_from_member<pViewport&>::value) { p.constructor(); }

View File

@ -46,8 +46,8 @@ struct Object {
struct OS : Object {
static unsigned desktopWidth();
static unsigned desktopHeight();
template<typename... Args> static nall::string fileLoad(Window &parent, const nall::string &path, const Args&... args) { nall::lstring filter; return fileLoad_(parent, path, filter, args...); }
template<typename... Args> static nall::string fileSave(Window &parent, const nall::string &path, const Args&... args) { nall::lstring filter; return fileSave_(parent, path, filter, args...); }
template<typename... Args> static nall::string fileLoad(Window &parent, const nall::string &path, const Args&... args) { return fileLoad_(parent, path, { args... }); }
template<typename... Args> static nall::string fileSave(Window &parent, const nall::string &path, const Args&... args) { return fileSave_(parent, path, { args... }); }
static nall::string folderSelect(Window &parent, const nall::string &path);
static void main();
static bool pending();
@ -55,22 +55,11 @@ struct OS : Object {
static void quit();
OS();
struct State;
static State state;
static void initialize();
private:
static nall::string fileLoad_(Window &parent, const nall::string &path, nall::lstring &filter);
template<typename... Args> static nall::string fileLoad_(Window &parent, const nall::string &path, nall::lstring &filter, const nall::string &item, const Args&... args) {
filter.append(item);
return fileLoad_(parent, path, filter, args...);
}
static nall::string fileSave_(Window &parent, const nall::string &path, nall::lstring &filter);
template<typename... Args> static nall::string fileSave_(Window &parent, const nall::string &path, nall::lstring &filter, const nall::string &item, const Args&... args) {
filter.append(item);
return fileSave_(parent, path, filter, args...);
}
static nall::string fileLoad_(Window &parent, const nall::string &path, const nall::lstring& filter);
static nall::string fileSave_(Window &parent, const nall::string &path, const nall::lstring& filter);
};
struct Font : Object {
@ -112,7 +101,9 @@ struct Window : Object {
nall::function<void ()> onMove;
nall::function<void ()> onSize;
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Geometry frameGeometry();
bool focused();
Geometry geometry();
@ -121,7 +112,6 @@ struct Window : Object {
void setFocused();
void setFullScreen(bool fullScreen = true);
void setGeometry(const Geometry &geometry);
void setLayout(Layout &layout);
void setMenuFont(Font &font);
void setMenuVisible(bool visible = true);
void setResizable(bool resizable = true);
@ -188,12 +178,7 @@ struct MenuCheckItem : private nall::base_from_member<pMenuCheckItem&>, Action {
};
struct MenuRadioItem : private nall::base_from_member<pMenuRadioItem&>, Action {
template<typename... Args> static void group(Args&... args) {
nall::array<MenuRadioItem*> list;
group_(list, args...);
foreach(item, list) item->setGroup(list);
if(list.size()) list[0]->setChecked();
}
template<typename... Args> static void group(Args&... args) { group_({ args... }); }
nall::function<void ()> onTick;
@ -207,23 +192,13 @@ struct MenuRadioItem : private nall::base_from_member<pMenuRadioItem&>, Action {
pMenuRadioItem &p;
private:
void setGroup(const nall::array<MenuRadioItem*> &group);
static void group_(nall::array<MenuRadioItem*> &list) {}
template<typename... Args> static void group_(nall::array<MenuRadioItem*> &list, MenuRadioItem &item, Args&... args) {
list.append(&item);
group_(list, args...);
}
static void group_(const nall::reference_array<MenuRadioItem&> &list);
};
struct Layout : Object {
void append(Widget &widget);
virtual void setGeometry(Geometry &geometry) = 0;
virtual void setParent(Window &parent);
Layout();
struct State;
State &state;
pLayout &p;
virtual void setParent(Window &parent) = 0;
virtual void setVisible(bool visible = true) = 0;
};
struct Widget : Object {
@ -234,6 +209,7 @@ struct Widget : Object {
void setGeometry(const Geometry &geometry);
void setVisible(bool visible = true);
Widget();
Widget(pWidget &p);
struct State;
State &state;
@ -335,16 +311,16 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
nall::function<void ()> onChange;
nall::function<void (unsigned)> onTick;
template<typename... Args> void append(const Args&... args) { nall::lstring list; append_(list, args...); }
template<typename... Args> void append(const Args&... args) { append_({ args... }); }
void autosizeColumns();
bool checked(unsigned row);
template<typename... Args> void modify(unsigned row, const Args&... args) { nall::lstring list; modify_(row, list, args...); }
template<typename... Args> void modify(unsigned row, const Args&... args) { modify_(row, { args... }); }
void modify(unsigned row, unsigned column, const nall::string &text);
void reset();
nall::optional<unsigned> selection();
void setCheckable(bool checkable = true);
void setChecked(unsigned row, bool checked = true);
template<typename... Args> void setHeaderText(const Args&... args) { nall::lstring list; setHeaderText_(list, args...); }
template<typename... Args> void setHeaderText(const Args&... args) { setHeaderText_({ args... }); }
void setHeaderVisible(bool visible = true);
void setSelection(unsigned row);
@ -354,23 +330,9 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
pListView &p;
private:
void modify_(unsigned row, nall::lstring &list);
template<typename... Args> void modify_(unsigned row, nall::lstring &list, const nall::string &text, const Args&... args) {
list.append(text);
modify_(row, list, args...);
}
void append_(nall::lstring &list);
template<typename... Args> void append_(nall::lstring &list, const nall::string &text, const Args&... args) {
list.append(text);
append_(list, args...);
}
void setHeaderText_(nall::lstring &list);
template<typename... Args> void setHeaderText_(nall::lstring &list, const nall::string &text, const Args&... args) {
list.append(text);
setHeaderText_(list, args...);
}
void append_(const nall::lstring &list);
void modify_(unsigned row, const nall::lstring &list);
void setHeaderText_(const nall::lstring &list);
};
struct ProgressBar : private nall::base_from_member<pProgressBar&>, Widget {
@ -383,12 +345,7 @@ struct ProgressBar : private nall::base_from_member<pProgressBar&>, Widget {
};
struct RadioBox : private nall::base_from_member<pRadioBox&>, Widget {
template<typename... Args> static void group(Args&... args) {
nall::array<RadioBox*> list;
group_(list, args...);
foreach(item, list) item->setGroup(list);
if(list.size()) list[0]->setChecked();
}
template<typename... Args> static void group(Args&... args) { group_({ args... }); }
nall::function<void ()> onTick;
@ -402,12 +359,7 @@ struct RadioBox : private nall::base_from_member<pRadioBox&>, Widget {
pRadioBox &p;
private:
void setGroup(const nall::array<RadioBox*> &group);
static void group_(nall::array<RadioBox*> &list) {}
template<typename... Args> static void group_(nall::array<RadioBox*> &list, RadioBox &item, Args&... args) {
list.append(&item);
group_(list, args...);
}
static void group_(const nall::reference_array<RadioBox&> &list);
};
struct TextEdit : private nall::base_from_member<pTextEdit&>, Widget {

View File

@ -1,7 +1,6 @@
void FixedLayout::setParent(Window &parent) {
Layout::setParent(parent);
foreach(child, children) {
Layout::append(*child.widget);
parent.append(*child.widget);
child.widget->setGeometry(child.geometry);
}
}
@ -13,5 +12,9 @@ void FixedLayout::append(Widget &widget, const Geometry &geometry) {
void FixedLayout::setGeometry(Geometry &geometry) {
}
void FixedLayout::setVisible(bool visible) {
foreach(child, children) child.widget->setVisible(visible);
}
FixedLayout::FixedLayout() {
}

View File

@ -1,7 +1,8 @@
struct FixedLayout : Layout {
void setParent(Window &parent);
void setGeometry(Geometry &geometry);
void append(Widget &widget, const Geometry &geometry);
void setGeometry(Geometry &geometry);
void setParent(Window &parent);
void setVisible(bool visible);
FixedLayout();
//private:

View File

@ -1,8 +1,7 @@
void HorizontalLayout::setParent(Window &parent) {
Layout::setParent(parent);
foreach(child, children) {
if(child.layout) child.layout->setParent(parent);
if(child.widget) Layout::append(*child.widget);
if(child.widget) parent.append(*child.widget);
}
}
@ -75,6 +74,13 @@ unsigned HorizontalLayout::minimumWidth() {
return width;
}
void HorizontalLayout::setVisible(bool visible) {
foreach(child, children) {
if(child.layout) child.layout->setVisible(visible);
if(child.widget) child.widget->setVisible(visible);
}
}
HorizontalLayout::HorizontalLayout() {
margin = 0;
width = 0;

View File

@ -1,12 +1,13 @@
struct VerticalLayout;
struct HorizontalLayout : public Layout {
void setParent(Window &parent);
void setGeometry(Geometry &geometry);
void append(VerticalLayout &layout, unsigned width, unsigned height, unsigned spacing = 0);
void append(Widget &widget, unsigned width, unsigned height, unsigned spacing = 0);
void setMargin(unsigned margin);
unsigned minimumWidth();
void setGeometry(Geometry &geometry);
void setMargin(unsigned margin);
void setParent(Window &parent);
void setVisible(bool visible);
HorizontalLayout();
//private:

View File

@ -1,8 +1,7 @@
void VerticalLayout::setParent(Window &parent) {
Layout::setParent(parent);
foreach(child, children) {
if(child.layout) child.layout->setParent(parent);
if(child.widget) Layout::append(*child.widget);
if(child.widget) parent.append(*child.widget);
}
}
@ -75,6 +74,13 @@ unsigned VerticalLayout::minimumHeight() {
return height;
}
void VerticalLayout::setVisible(bool visible) {
foreach(child, children) {
if(child.layout) child.layout->setVisible(visible);
if(child.widget) child.widget->setVisible(visible);
}
}
VerticalLayout::VerticalLayout() {
margin = 0;
width = 0;

View File

@ -1,12 +1,13 @@
struct HorizontalLayout;
struct VerticalLayout : public Layout {
void setParent(Window &parent);
void setGeometry(Geometry &geometry);
void append(HorizontalLayout &layout, unsigned width, unsigned height, unsigned spacing = 0);
void append(Widget &widget, unsigned width, unsigned height, unsigned spacing = 0);
void setMargin(unsigned margin);
unsigned minimumHeight();
void setGeometry(Geometry &geometry);
void setMargin(unsigned margin);
void setParent(Window &parent);
void setVisible(bool visible);
VerticalLayout();
//private:

221
bsnes/phoenix/core/state.hpp Executable file
View File

@ -0,0 +1,221 @@
struct Font::State {
bool bold;
nall::string family;
bool italic;
unsigned size;
bool underline;
State() {
bold = false;
italic = false;
size = 8;
underline = false;
}
};
struct Window::State {
bool backgroundColor;
unsigned backgroundColorRed, backgroundColorGreen, backgroundColorBlue;
bool fullScreen;
Geometry geometry;
nall::reference_array<Layout&> layout;
nall::reference_array<Menu&> menu;
Font *menuFont;
bool menuVisible;
bool resizable;
Font *statusFont;
nall::string statusText;
bool statusVisible;
nall::string title;
bool visible;
nall::reference_array<Widget&> widget;
Font *widgetFont;
State() {
backgroundColor = false;
backgroundColorRed = 0;
backgroundColorGreen = 0;
backgroundColorBlue = 0;
fullScreen = false;
geometry = { 128, 128, 256, 256 };
menuFont = 0;
menuVisible = false;
resizable = true;
statusVisible = false;
visible = false;
widgetFont = 0;
}
};
struct Action::State {
bool enabled;
Window *parent;
bool visible;
State() {
enabled = true;
parent = 0;
visible = true;
}
};
struct Menu::State {
nall::reference_array<Action&> action;
nall::string text;
};
struct MenuItem::State {
nall::string text;
};
struct MenuCheckItem::State {
bool checked;
nall::string text;
State() {
checked = false;
}
};
struct MenuRadioItem::State {
bool checked;
nall::reference_array<MenuRadioItem&> group;
nall::string text;
State() {
checked = true;
}
};
struct Widget::State {
bool abstract;
bool enabled;
Font *font;
Geometry geometry;
bool visible;
State() {
abstract = false;
enabled = true;
font = 0;
geometry = { 0, 0, 0, 0 };
visible = true;
}
};
struct Button::State {
nall::string text;
State() {
}
};
struct CheckBox::State {
bool checked;
nall::string text;
State() {
checked = false;
}
};
struct ComboBox::State {
unsigned selection;
nall::linear_vector<nall::string> text;
State() {
selection = 0;
}
};
struct HexEdit::State {
unsigned columns;
unsigned length;
unsigned offset;
unsigned rows;
State() {
columns = 16;
length = 0;
offset = 0;
rows = 16;
}
};
struct HorizontalSlider::State {
unsigned length;
unsigned position;
State() {
length = 101;
position = 0;
}
};
struct Label::State {
nall::string text;
};
struct LineEdit::State {
bool editable;
nall::string text;
State() {
editable = true;
}
};
struct ListView::State {
bool checkable;
nall::array<bool> checked;
nall::lstring headerText;
bool headerVisible;
nall::optional<unsigned> selection;
nall::linear_vector<nall::lstring> text;
State() : selection(false, 0) {
checkable = false;
headerVisible = false;
}
};
struct ProgressBar::State {
unsigned position;
State() {
position = 0;
}
};
struct RadioBox::State {
bool checked;
nall::reference_array<RadioBox&> group;
nall::string text;
State() {
checked = true;
}
};
struct TextEdit::State {
unsigned cursorPosition;
bool editable;
nall::string text;
bool wordWrap;
State() {
cursorPosition = 0;
editable = true;
wordWrap = false;
}
};
struct VerticalSlider::State {
unsigned length;
unsigned position;
State() {
length = 101;
position = 0;
}
};

View File

@ -1,11 +1,26 @@
#include "phoenix.hpp"
using namespace nall;
#if defined(PHOENIX_WINDOWS)
#define UNICODE
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_IE 0x0600
#define NOMINMAX
#if defined(PHOENIX_QT)
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <io.h>
#include <shlobj.h>
#elif defined(PHOENIX_QT)
#include <QApplication>
#include <QtGui>
#elif defined(PHOENIX_REFERENCE)
#else
#error "phoenix: unrecognized target"
#endif
#include "phoenix.hpp"
using namespace nall;
namespace phoenix {
#include "core/core.cpp"
}

View File

@ -2,6 +2,7 @@
#include <nall/config.hpp>
#include <nall/foreach.hpp>
#include <nall/function.hpp>
#include <nall/reference_array.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#include <nall/utility.hpp>

View File

@ -12,6 +12,20 @@ void pAction::setEnabled(bool enabled) {
}
}
void pAction::setFont(Font &font) {
if(dynamic_cast<Menu*>(&action)) {
((Menu&)action).p.setFont(font);
} else if(dynamic_cast<MenuSeparator*>(&action)) {
((MenuSeparator&)action).p.qtAction->setFont(*font.p.qtFont);
} else if(dynamic_cast<MenuItem*>(&action)) {
((MenuItem&)action).p.qtAction->setFont(*font.p.qtFont);
} else if(dynamic_cast<MenuCheckItem*>(&action)) {
((MenuCheckItem&)action).p.qtAction->setFont(*font.p.qtFont);
} else if(dynamic_cast<MenuRadioItem*>(&action)) {
((MenuRadioItem&)action).p.qtAction->setFont(*font.p.qtFont);
}
}
void pAction::setVisible(bool visible) {
if(dynamic_cast<Menu*>(&action)) {
((Menu&)action).p.qtMenu->setVisible(visible);
@ -26,5 +40,5 @@ void pAction::setVisible(bool visible) {
}
}
pAction::pAction(Action &action) : action(action) {
void pAction::constructor() {
}

View File

@ -10,7 +10,7 @@ void pMenuCheckItem::setText(const string &text) {
qtAction->setText(QString::fromUtf8(text));
}
pMenuCheckItem::pMenuCheckItem(MenuCheckItem &menuCheckItem) : menuCheckItem(menuCheckItem), pAction(menuCheckItem) {
void pMenuCheckItem::constructor() {
qtAction = new QAction(0);
qtAction->setCheckable(true);
connect(qtAction, SIGNAL(triggered()), SLOT(onTick()));

View File

@ -2,7 +2,7 @@ void pMenuItem::setText(const string &text) {
qtAction->setText(QString::fromUtf8(text));
}
pMenuItem::pMenuItem(MenuItem &menuItem) : menuItem(menuItem), pAction(menuItem) {
void pMenuItem::constructor() {
qtAction = new QAction(0);
connect(qtAction, SIGNAL(triggered()), SLOT(onTick()));
}

View File

@ -5,21 +5,21 @@ bool pMenuRadioItem::checked() {
void pMenuRadioItem::setChecked() {
locked = true;
foreach(item, menuRadioItem.state.group) {
bool checkState = item->p.qtAction == qtAction;
item->state.checked = checkState;
item->p.qtAction->setChecked(checkState);
bool checkState = item.p.qtAction == qtAction;
item.state.checked = checkState;
item.p.qtAction->setChecked(checkState);
}
locked = false;
}
void pMenuRadioItem::setGroup(const array<MenuRadioItem*> &group) {
void pMenuRadioItem::setGroup(const reference_array<MenuRadioItem&> &group) {
}
void pMenuRadioItem::setText(const string &text) {
qtAction->setText(QString::fromUtf8(text));
}
pMenuRadioItem::pMenuRadioItem(MenuRadioItem &menuRadioItem) : menuRadioItem(menuRadioItem), pAction(menuRadioItem) {
void pMenuRadioItem::constructor() {
qtAction = new QAction(0);
qtGroup = new QActionGroup(0);
qtAction->setCheckable(true);

View File

@ -1,4 +1,4 @@
pMenuSeparator::pMenuSeparator(MenuSeparator &menuSeparator) : menuSeparator(menuSeparator), pAction(menuSeparator) {
void pMenuSeparator::constructor() {
qtAction = new QAction(0);
qtAction->setSeparator(true);
}

View File

@ -12,10 +12,15 @@ void pMenu::append(Action &action) {
}
}
void pMenu::setFont(Font &font) {
qtMenu->setFont(*font.p.qtFont);
foreach(item, menu.state.action) item.p.setFont(font);
}
void pMenu::setText(const string &text) {
qtMenu->setTitle(QString::fromUtf8(text));
}
pMenu::pMenu(Menu &menu) : menu(menu), pAction(menu) {
void pMenu::constructor() {
qtMenu = new QMenu;
}

View File

@ -4,7 +4,7 @@ void pFont::setItalic(bool italic) { update(); }
void pFont::setSize(unsigned size) { update(); }
void pFont::setUnderline(bool underline) { update(); }
pFont::pFont(Font &font) : font(font) {
void pFont::constructor() {
qtFont = new QFont;
}

View File

@ -1,10 +0,0 @@
void pLayout::append(Widget &widget) {
if(!widget.state.font && layout.state.parent->state.widgetFont) {
widget.p.qtWidget->setFont(*layout.state.parent->state.widgetFont->p.qtFont);
}
widget.p.qtWidget->setParent(layout.state.parent->p.qtContainer);
widget.p.qtWidget->setVisible(true);
}
pLayout::pLayout(Layout &layout) : layout(layout) {
}

View File

@ -5,7 +5,6 @@
#include "font.cpp"
#include "message-window.cpp"
#include "window.cpp"
#include "layout.cpp"
#include "action/action.cpp"
#include "action/menu.cpp"

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'qt.moc.hpp'
**
** Created: Wed Feb 16 04:07:28 2011
** Created: Fri Feb 18 07:05:10 2011
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
**
** WARNING! All changes made in this file will be lost!

View File

@ -49,7 +49,8 @@ struct pFont : public pObject {
void setSize(unsigned size);
void setUnderline(bool underline);
pFont(Font &font);
pFont(Font &font) : font(font) {}
void constructor();
void update();
};
@ -77,9 +78,10 @@ public:
QMenuBar *qtMenu;
QStatusBar *qtStatus;
QWidget *qtContainer;
Layout *layout;
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Geometry frameGeometry();
bool focused();
Geometry geometry();
@ -88,7 +90,6 @@ public:
void setFocused();
void setFullScreen(bool fullScreen);
void setGeometry(const Geometry &geometry);
void setLayout(Layout &layout);
void setMenuFont(Font &font);
void setMenuVisible(bool visible);
void setResizable(bool resizable);
@ -99,7 +100,8 @@ public:
void setVisible(bool visible);
void setWidgetFont(Font &font);
pWindow(Window &window);
pWindow(Window &window) : window(window) {}
void constructor();
void updateFrameGeometry();
};
@ -107,9 +109,11 @@ struct pAction : public pObject {
Action &action;
void setEnabled(bool enabled);
void setFont(Font &font);
void setVisible(bool visible);
pAction(Action &action);
pAction(Action &action) : action(action) {}
void constructor();
};
struct pMenu : public pAction {
@ -117,16 +121,19 @@ struct pMenu : public pAction {
QMenu *qtMenu;
void append(Action &action);
void setFont(Font &font);
void setText(const string &text);
pMenu(Menu &menu);
pMenu(Menu &menu) : pAction(menu), menu(menu) {}
void constructor();
};
struct pMenuSeparator : public pAction {
MenuSeparator &menuSeparator;
QAction *qtAction;
pMenuSeparator(MenuSeparator &menuSeparator);
pMenuSeparator(MenuSeparator &menuSeparator) : pAction(menuSeparator), menuSeparator(menuSeparator) {}
void constructor();
};
struct pMenuItem : public QObject, public pAction {
@ -138,7 +145,8 @@ public:
void setText(const string &text);
pMenuItem(MenuItem &menuItem);
pMenuItem(MenuItem &menuItem) : pAction(menuItem), menuItem(menuItem) {}
void constructor();
public slots:
void onTick();
@ -155,7 +163,8 @@ public:
void setChecked(bool checked);
void setText(const string &text);
pMenuCheckItem(MenuCheckItem &menuCheckItem);
pMenuCheckItem(MenuCheckItem &menuCheckItem) : pAction(menuCheckItem), menuCheckItem(menuCheckItem) {}
void constructor();
public slots:
void onTick();
@ -171,24 +180,16 @@ public:
bool checked();
void setChecked();
void setGroup(const array<MenuRadioItem*> &group);
void setGroup(const reference_array<MenuRadioItem&> &group);
void setText(const string &text);
pMenuRadioItem(MenuRadioItem &menuRadioItem);
pMenuRadioItem(MenuRadioItem &menuRadioItem) : pAction(menuRadioItem), menuRadioItem(menuRadioItem) {}
void constructor();
public slots:
void onTick();
};
struct pLayout : public pObject {
Layout &layout;
pWindow *parent;
void append(Widget &widget);
pLayout(Layout &layout);
};
struct pWidget : public pObject {
Widget &widget;
QWidget *qtWidget;
@ -200,7 +201,8 @@ struct pWidget : public pObject {
void setGeometry(const Geometry &geometry);
void setVisible(bool visible);
pWidget(Widget &widget);
pWidget(Widget &widget) : widget(widget) {}
void constructor();
};
struct pButton : public QObject, public pWidget {
@ -212,7 +214,8 @@ public:
void setText(const string &text);
pButton(Button &button);
pButton(Button &button) : pWidget(button), button(button) {}
void constructor();
public slots:
void onTick();
@ -229,7 +232,8 @@ public:
void setChecked(bool checked);
void setText(const string &text);
pCheckBox(CheckBox &checkBox);
pCheckBox(CheckBox &checkBox) : pWidget(checkBox), checkBox(checkBox) {}
void constructor();
public slots:
void onTick();
@ -247,7 +251,8 @@ public:
unsigned selection();
void setSelection(unsigned row);
pComboBox(ComboBox &comboBox);
pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {}
void constructor();
public slots:
void onChange();
@ -273,8 +278,9 @@ public:
void setRows(unsigned rows);
void update();
pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {}
void constructor();
void keyPressEvent(QKeyEvent*);
pHexEdit(HexEdit &hexEdit);
public slots:
void onScroll();
@ -291,7 +297,8 @@ public:
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalSlider(HorizontalSlider &horizontalSlider);
pHorizontalSlider(HorizontalSlider &horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {}
void constructor();
public slots:
void onChange();
@ -303,7 +310,8 @@ struct pLabel : public pWidget {
void setText(const string &text);
pLabel(Label &label);
pLabel(Label &label) : pWidget(label), label(label) {}
void constructor();
};
struct pLineEdit : public QObject, public pWidget {
@ -317,7 +325,8 @@ public:
void setText(const string &text);
string text();
pLineEdit(LineEdit &lineEdit);
pLineEdit(LineEdit &lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {}
void constructor();
public slots:
void onActivate();
@ -344,7 +353,8 @@ public:
void setHeaderVisible(bool visible);
void setSelection(unsigned row);
pListView(ListView &listView);
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
void constructor();
public slots:
void onActivate();
@ -358,7 +368,8 @@ struct pProgressBar : public pWidget {
void setPosition(unsigned position);
pProgressBar(ProgressBar &progressBar);
pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {}
void constructor();
};
struct pRadioBox : public QObject, public pWidget {
@ -371,10 +382,11 @@ public:
bool checked();
void setChecked();
void setGroup(const array<RadioBox*> &group);
void setGroup(const reference_array<RadioBox&> &group);
void setText(const string &text);
pRadioBox(RadioBox &radioBox);
pRadioBox(RadioBox &radioBox) : pWidget(radioBox), radioBox(radioBox) {}
void constructor();
public slots:
void onTick();
@ -393,7 +405,8 @@ public:
void setWordWrap(bool wordWrap);
string text();
pTextEdit(TextEdit &textEdit);
pTextEdit(TextEdit &textEdit) : pWidget(textEdit), textEdit(textEdit) {}
void constructor();
public slots:
void onChange();
@ -410,7 +423,8 @@ public:
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalSlider(VerticalSlider &verticalSlider);
pVerticalSlider(VerticalSlider &verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {}
void constructor();
public slots:
void onChange();
@ -421,5 +435,6 @@ struct pViewport : public pWidget {
uintptr_t handle();
pViewport(Viewport &viewport);
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
void constructor();
};

View File

@ -2,7 +2,7 @@ void pButton::setText(const string &text) {
qtButton->setText(QString::fromUtf8(text));
}
pButton::pButton(Button &button) : button(button), pWidget(button) {
void pButton::constructor() {
qtWidget = qtButton = new QPushButton;
connect(qtButton, SIGNAL(released()), SLOT(onTick()));
}

View File

@ -12,7 +12,7 @@ void pCheckBox::setText(const string &text) {
qtCheckBox->setText(QString::fromUtf8(text));
}
pCheckBox::pCheckBox(CheckBox &checkBox) : checkBox(checkBox), pWidget(checkBox) {
void pCheckBox::constructor() {
qtWidget = qtCheckBox = new QCheckBox;
connect(qtCheckBox, SIGNAL(stateChanged(int)), SLOT(onTick()));
}

View File

@ -17,7 +17,7 @@ void pComboBox::setSelection(unsigned row) {
locked = false;
}
pComboBox::pComboBox(ComboBox &comboBox) : comboBox(comboBox), pWidget(comboBox) {
void pComboBox::constructor() {
qtWidget = qtComboBox = new QComboBox;
connect(qtComboBox, SIGNAL(currentIndexChanged(int)), SLOT(onChange()));
}

View File

@ -63,7 +63,7 @@ void pHexEdit::update() {
qtHexEdit->setTextCursor(cursor);
}
pHexEdit::pHexEdit(HexEdit &hexEdit) : hexEdit(hexEdit), pWidget(hexEdit) {
void pHexEdit::constructor() {
qtWidget = qtHexEdit = new QtHexEdit(*this);
qtHexEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@ -82,13 +82,6 @@ pHexEdit::pHexEdit(HexEdit &hexEdit) : hexEdit(hexEdit), pWidget(hexEdit) {
connect(qtScroll, SIGNAL(actionTriggered(int)), SLOT(onScroll()));
}
void pHexEdit::onScroll() {
if(locked) return;
unsigned offset = qtScroll->sliderPosition();
hexEdit.state.offset = offset * hexEdit.state.columns;
update();
}
void pHexEdit::keyPressEvent(QKeyEvent *event) {
if(!hexEdit.onRead) return;
@ -161,6 +154,13 @@ void pHexEdit::keyPressEvent(QKeyEvent *event) {
}
}
void pHexEdit::onScroll() {
if(locked) return;
unsigned offset = qtScroll->sliderPosition();
hexEdit.state.offset = offset * hexEdit.state.columns;
update();
}
void pHexEdit::QtHexEdit::keyPressEvent(QKeyEvent *event) {
self.keyPressEvent(event);
}

View File

@ -12,7 +12,7 @@ void pHorizontalSlider::setPosition(unsigned position) {
qtSlider->setValue(position);
}
pHorizontalSlider::pHorizontalSlider(HorizontalSlider &horizontalSlider) : horizontalSlider(horizontalSlider), pWidget(horizontalSlider) {
void pHorizontalSlider::constructor() {
qtWidget = qtSlider = new QSlider(Qt::Horizontal);
qtSlider->setRange(0, 100);
qtSlider->setPageStep(101 >> 3);

View File

@ -2,6 +2,6 @@ void pLabel::setText(const string &text) {
qtLabel->setText(QString::fromUtf8(text));
}
pLabel::pLabel(Label &label) : label(label), pWidget(label) {
void pLabel::constructor() {
qtWidget = qtLabel = new QLabel;
}

View File

@ -10,7 +10,7 @@ string pLineEdit::text() {
return qtLineEdit->text().toUtf8().constData();
}
pLineEdit::pLineEdit(LineEdit &lineEdit) : lineEdit(lineEdit), pWidget(lineEdit) {
void pLineEdit::constructor() {
qtWidget = qtLineEdit = new QLineEdit;
connect(qtLineEdit, SIGNAL(returnPressed()), SLOT(onActivate()));
connect(qtLineEdit, SIGNAL(textEdited(const QString&)), SLOT(onChange()));

View File

@ -91,7 +91,7 @@ void pListView::setSelection(unsigned row) {
locked = false;
}
pListView::pListView(ListView &listView) : listView(listView), pWidget(listView) {
void pListView::constructor() {
qtWidget = qtListView = new QTreeWidget;
qtListView->setHeaderLabels(QStringList() << "");
qtListView->setHeaderHidden(true);

View File

@ -2,7 +2,7 @@ void pProgressBar::setPosition(unsigned position) {
qtProgressBar->setValue(position);
}
pProgressBar::pProgressBar(ProgressBar &progressBar) : progressBar(progressBar), pWidget(progressBar) {
void pProgressBar::constructor() {
qtWidget = qtProgressBar = new QProgressBar;
qtProgressBar->setRange(0, 100);
qtProgressBar->setTextVisible(false);

View File

@ -5,22 +5,22 @@ bool pRadioBox::checked() {
void pRadioBox::setChecked() {
locked = true;
foreach(item, radioBox.state.group) {
bool checkState = item->p.qtRadioBox == qtRadioBox;
item->state.checked = checkState;
item->p.qtRadioBox->setChecked(checkState);
bool checkState = item.p.qtRadioBox == qtRadioBox;
item.state.checked = checkState;
item.p.qtRadioBox->setChecked(checkState);
}
locked = false;
}
void pRadioBox::setGroup(const array<RadioBox*> &group) {
void pRadioBox::setGroup(const reference_array<RadioBox&> &group) {
locked = true;
if(qtGroup) {
delete qtGroup;
qtGroup = 0;
}
if(qtRadioBox == group[0]->p.qtRadioBox) {
if(qtRadioBox == group[0].p.qtRadioBox) {
qtGroup = new QButtonGroup;
foreach(item, group) qtGroup->addButton(item->p.qtRadioBox);
foreach(item, group) qtGroup->addButton(item.p.qtRadioBox);
setChecked();
}
locked = false;
@ -30,7 +30,7 @@ void pRadioBox::setText(const string &text) {
qtRadioBox->setText(QString::fromUtf8(text));
}
pRadioBox::pRadioBox(RadioBox &radioBox) : radioBox(radioBox), pWidget(radioBox) {
void pRadioBox::constructor() {
qtWidget = qtRadioBox = new QRadioButton;
qtGroup = new QButtonGroup;
qtGroup->addButton(qtRadioBox);

View File

@ -21,7 +21,7 @@ string pTextEdit::text() {
return qtTextEdit->toPlainText().toUtf8().constData();
}
pTextEdit::pTextEdit(TextEdit &textEdit) : textEdit(textEdit), pWidget(textEdit) {
void pTextEdit::constructor() {
qtWidget = qtTextEdit = new QTextEdit;
connect(qtTextEdit, SIGNAL(textChanged()), SLOT(onChange()));
}

View File

@ -12,7 +12,7 @@ void pVerticalSlider::setPosition(unsigned position) {
qtSlider->setValue(position);
}
pVerticalSlider::pVerticalSlider(VerticalSlider &verticalSlider) : verticalSlider(verticalSlider), pWidget(verticalSlider) {
void pVerticalSlider::constructor() {
qtWidget = qtSlider = new QSlider(Qt::Vertical);
qtSlider->setRange(0, 100);
qtSlider->setPageStep(101 >> 3);

View File

@ -2,7 +2,7 @@ uintptr_t pViewport::handle() {
return (uintptr_t)qtWidget->winId();
}
pViewport::pViewport(Viewport &viewport) : viewport(viewport), pWidget(viewport) {
void pViewport::constructor() {
qtWidget = new QWidget;
qtWidget->setAttribute(Qt::WA_PaintOnScreen, true);
qtWidget->setStyleSheet("background: #000000");

View File

@ -19,8 +19,10 @@ void pWidget::setGeometry(const Geometry &geometry) {
}
void pWidget::setVisible(bool visible) {
if(widget.state.abstract) visible = false;
qtWidget->setVisible(visible);
}
pWidget::pWidget(Widget &widget) : widget(widget) {
void pWidget::constructor() {
if(widget.state.abstract) qtWidget = new QWidget;
}

View File

@ -1,8 +1,23 @@
void pWindow::append(Layout &layout) {
layout.setParent(window);
Geometry geometry = window.state.geometry;
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
}
void pWindow::append(Menu &menu) {
if(window.state.menuFont) menu.p.qtMenu->setFont(*window.state.menuFont->p.qtFont);
qtMenu->addMenu(menu.p.qtMenu);
}
void pWindow::append(Widget &widget) {
if(!widget.state.font && window.state.widgetFont) {
widget.setFont(*window.state.widgetFont);
}
widget.p.qtWidget->setParent(qtContainer);
widget.setVisible(widget.state.visible);
}
Geometry pWindow::frameGeometry() {
if(window.state.fullScreen) return { 0, 0, OS::desktopWidth(), OS::desktopHeight() };
return {
@ -19,10 +34,10 @@ bool pWindow::focused() {
Geometry pWindow::geometry() {
if(window.state.fullScreen) {
unsigned menuHeight = window.state.menuVisible ? qtMenu->height() : 0;
unsigned statusHeight = window.state.statusVisible ? qtStatus->height() : 0;
unsigned width = OS::desktopWidth(), height = OS::desktopHeight();
if(window.state.menuVisible) height -= qtMenu->height();
if(window.state.statusVisible) height -= qtStatus->height();
return { 0, 0, width, height };
return { 0, menuHeight, width, height - menuHeight - statusHeight };
}
return window.state.geometry;
}
@ -72,24 +87,17 @@ void pWindow::setGeometry(const Geometry &geometry_) {
qtWindow->move(geometry.x - settings.frameGeometryX, geometry.y - settings.frameGeometryY);
qtWindow->adjustSize();
geometry.x = geometry.y = 0;
if(layout) layout->setGeometry(geometry);
foreach(layout, window.state.layout) {
geometry = geometry_;
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
}
locked = false;
}
void pWindow::setLayout(Layout &layout) {
this->layout = &layout;
layout.p.parent = this;
layout.setParent(window);
Geometry geometry = window.state.geometry;
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
}
void pWindow::setMenuFont(Font &font) {
qtMenu->setFont(*font.p.qtFont);
foreach(item, window.state.menu) item.p.setFont(font);
}
void pWindow::setMenuVisible(bool visible) {
@ -136,11 +144,12 @@ void pWindow::setVisible(bool visible) {
}
void pWindow::setWidgetFont(Font &font) {
foreach(item, window.state.widget) {
if(!item.state.font) item.setFont(font);
}
}
pWindow::pWindow(Window &window) : window(window) {
layout = 0;
void pWindow::constructor() {
qtWindow = new QtWindow(*this);
qtWindow->setWindowTitle(" ");
@ -204,10 +213,10 @@ void pWindow::QtWindow::resizeEvent(QResizeEvent*) {
self.window.state.geometry.height = self.qtContainer->geometry().height();
}
if(self.layout) {
foreach(layout, self.window.state.layout) {
Geometry geometry = self.geometry();
geometry.x = geometry.y = 0;
self.layout->setGeometry(geometry);
layout.setGeometry(geometry);
}
if(self.locked == false) {

View File

@ -4,5 +4,5 @@ void pAction::setEnabled(bool enabled) {
void pAction::setVisible(bool visible) {
}
pAction::pAction(Action &action) : action(action) {
void pAction::constructor() {
}

View File

@ -8,5 +8,5 @@ void pMenuCheckItem::setChecked(bool checked) {
void pMenuCheckItem::setText(const string &text) {
}
pMenuCheckItem::pMenuCheckItem(MenuCheckItem &menuCheckItem) : pAction(menuCheckItem), menuCheckItem(menuCheckItem) {
void pMenuCheckItem::constructor() {
}

View File

@ -1,5 +1,5 @@
void pMenuItem::setText(const string &text) {
}
pMenuItem::pMenuItem(MenuItem &menuItem) : pAction(menuItem), menuItem(menuItem) {
void pMenuItem::constructor() {
}

View File

@ -5,11 +5,11 @@ bool pMenuRadioItem::checked() {
void pMenuRadioItem::setChecked() {
}
void pMenuRadioItem::setGroup(const array<MenuRadioItem*> &group) {
void pMenuRadioItem::setGroup(const reference_array<MenuRadioItem&> &group) {
}
void pMenuRadioItem::setText(const string &text) {
}
pMenuRadioItem::pMenuRadioItem(MenuRadioItem &menuRadioItem) : pAction(menuRadioItem), menuRadioItem(menuRadioItem) {
void pMenuRadioItem::constructor() {
}

View File

@ -1,2 +1,2 @@
pMenuSeparator::pMenuSeparator(MenuSeparator &menuSeparator) : pAction(menuSeparator), menuSeparator(menuSeparator) {
void pMenuSeparator::constructor() {
}

View File

@ -4,5 +4,5 @@ void pMenu::append(Action &action) {
void pMenu::setText(const string &text) {
}
pMenu::pMenu(Menu &menu) : pAction(menu), menu(menu) {
void pMenu::constructor() {
}

View File

@ -13,5 +13,5 @@ void pFont::setSize(unsigned size) {
void pFont::setUnderline(bool underline) {
}
pFont::pFont(Font &font) : font(font) {
void pFont::constructor() {
}

View File

@ -1,5 +0,0 @@
void pLayout::append(Widget &widget) {
}
pLayout::pLayout(Layout &layout) : layout(layout) {
}

View File

@ -3,7 +3,6 @@
#include "font.cpp"
#include "message-window.cpp"
#include "window.cpp"
#include "layout.cpp"
#include "action/action.cpp"
#include "action/menu.cpp"

View File

@ -35,7 +35,8 @@ struct pFont : public pObject {
void setSize(unsigned size);
void setUnderline(bool underline);
pFont(Font &font);
pFont(Font &font) : font(font) {}
void constructor();
};
struct pMessageWindow : public pObject {
@ -48,7 +49,9 @@ struct pMessageWindow : public pObject {
struct pWindow : public pObject {
Window &window;
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Geometry frameGeometry();
bool focused();
Geometry geometry();
@ -57,7 +60,6 @@ struct pWindow : public pObject {
void setFocused();
void setFullScreen(bool fullScreen);
void setGeometry(const Geometry &geometry);
void setLayout(Layout &layout);
void setMenuFont(Font &font);
void setMenuVisible(bool visible);
void setResizable(bool resizable);
@ -68,7 +70,8 @@ struct pWindow : public pObject {
void setVisible(bool visible);
void setWidgetFont(Font &font);
pWindow(Window &window);
pWindow(Window &window) : window(window) {}
void constructor();
};
struct pAction : public pObject {
@ -77,7 +80,8 @@ struct pAction : public pObject {
void setEnabled(bool enabled);
void setVisible(bool visible);
pAction(Action &action);
pAction(Action &action) : action(action) {}
void constructor();
};
struct pMenu : public pAction {
@ -86,13 +90,15 @@ struct pMenu : public pAction {
void append(Action &action);
void setText(const string &text);
pMenu(Menu &menu);
pMenu(Menu &menu) : pAction(menu), menu(menu) {}
void constructor();
};
struct pMenuSeparator : public pAction {
MenuSeparator &menuSeparator;
pMenuSeparator(MenuSeparator &menuSeparator);
pMenuSeparator(MenuSeparator &menuSeparator) : pAction(menuSeparator), menuSeparator(menuSeparator) {}
void constructor();
};
struct pMenuItem : public pAction {
@ -100,7 +106,8 @@ struct pMenuItem : public pAction {
void setText(const string &text);
pMenuItem(MenuItem &menuItem);
pMenuItem(MenuItem &menuItem) : pAction(menuItem), menuItem(menuItem) {}
void constructor();
};
struct pMenuCheckItem : public pAction {
@ -110,7 +117,8 @@ struct pMenuCheckItem : public pAction {
void setChecked(bool checked);
void setText(const string &text);
pMenuCheckItem(MenuCheckItem &menuCheckItem);
pMenuCheckItem(MenuCheckItem &menuCheckItem) : pAction(menuCheckItem), menuCheckItem(menuCheckItem) {}
void constructor();
};
struct pMenuRadioItem : public pAction {
@ -118,18 +126,11 @@ struct pMenuRadioItem : public pAction {
bool checked();
void setChecked();
void setGroup(const array<MenuRadioItem*> &group);
void setGroup(const reference_array<MenuRadioItem&> &group);
void setText(const string &text);
pMenuRadioItem(MenuRadioItem &menuRadioItem);
};
struct pLayout : public pObject {
Layout &layout;
void append(Widget &widget);
pLayout(Layout &layout);
pMenuRadioItem(MenuRadioItem &menuRadioItem) : pAction(menuRadioItem), menuRadioItem(menuRadioItem) {}
void constructor();
};
struct pWidget : public pObject {
@ -142,7 +143,8 @@ struct pWidget : public pObject {
void setGeometry(const Geometry &geometry);
void setVisible(bool visible);
pWidget(Widget &widget);
pWidget(Widget &widget) : widget(widget) {}
void constructor();
};
struct pButton : public pWidget {
@ -150,7 +152,8 @@ struct pButton : public pWidget {
void setText(const string &text);
pButton(Button &button);
pButton(Button &button) : pWidget(button), button(button) {}
void constructor();
};
struct pCheckBox : public pWidget {
@ -160,7 +163,8 @@ struct pCheckBox : public pWidget {
void setChecked(bool checked);
void setText(const string &text);
pCheckBox(CheckBox &checkBox);
pCheckBox(CheckBox &checkBox) : pWidget(checkBox), checkBox(checkBox) {}
void constructor();
};
struct pComboBox : public pWidget {
@ -171,7 +175,8 @@ struct pComboBox : public pWidget {
unsigned selection();
void setSelection(unsigned row);
pComboBox(ComboBox &comboBox);
pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {}
void constructor();
};
struct pHexEdit : public pWidget {
@ -183,7 +188,8 @@ struct pHexEdit : public pWidget {
void setRows(unsigned rows);
void update();
pHexEdit(HexEdit &hexEdit);
pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {}
void constructor();
};
struct pHorizontalSlider : public pWidget {
@ -193,7 +199,8 @@ struct pHorizontalSlider : public pWidget {
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalSlider(HorizontalSlider &horizontalSlider);
pHorizontalSlider(HorizontalSlider &horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {}
void constructor();
};
struct pLabel : public pWidget {
@ -201,7 +208,8 @@ struct pLabel : public pWidget {
void setText(const string &text);
pLabel(Label &label);
pLabel(Label &label) : pWidget(label), label(label) {}
void constructor();
};
struct pLineEdit : public pWidget {
@ -211,7 +219,8 @@ struct pLineEdit : public pWidget {
void setText(const string &text);
string text();
pLineEdit(LineEdit &lineEdit);
pLineEdit(LineEdit &lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {}
void constructor();
};
struct pListView : public pWidget {
@ -230,7 +239,8 @@ struct pListView : public pWidget {
void setHeaderVisible(bool visible);
void setSelection(unsigned row);
pListView(ListView &listView);
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
void constructor();
};
struct pProgressBar : public pWidget {
@ -238,7 +248,8 @@ struct pProgressBar : public pWidget {
void setPosition(unsigned position);
pProgressBar(ProgressBar &progressBar);
pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {}
void constructor();
};
struct pRadioBox : public pWidget {
@ -246,10 +257,11 @@ struct pRadioBox : public pWidget {
bool checked();
void setChecked();
void setGroup(const array<RadioBox*> &group);
void setGroup(const reference_array<RadioBox&> &group);
void setText(const string &text);
pRadioBox(RadioBox &radioBox);
pRadioBox(RadioBox &radioBox) : pWidget(radioBox), radioBox(radioBox) {}
void constructor();
};
struct pTextEdit : public pWidget {
@ -261,7 +273,8 @@ struct pTextEdit : public pWidget {
void setWordWrap(bool wordWrap);
string text();
pTextEdit(TextEdit &textEdit);
pTextEdit(TextEdit &textEdit) : pWidget(textEdit), textEdit(textEdit) {}
void constructor();
};
struct pVerticalSlider : public pWidget {
@ -271,7 +284,8 @@ struct pVerticalSlider : public pWidget {
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalSlider(VerticalSlider &verticalSlider);
pVerticalSlider(VerticalSlider &verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {}
void constructor();
};
struct pViewport : public pWidget {
@ -279,5 +293,6 @@ struct pViewport : public pWidget {
uintptr_t handle();
pViewport(Viewport &viewport);
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
void constructor();
};

View File

@ -1,5 +1,5 @@
void pButton::setText(const string &text) {
}
pButton::pButton(Button &button) : pWidget(button), button(button) {
void pButton::constructor() {
}

View File

@ -8,5 +8,5 @@ void pCheckBox::setChecked(bool checked) {
void pCheckBox::setText(const string &text) {
}
pCheckBox::pCheckBox(CheckBox &checkBox) : pWidget(checkBox), checkBox(checkBox) {
void pCheckBox::constructor() {
}

View File

@ -11,5 +11,5 @@ unsigned pComboBox::selection() {
void pComboBox::setSelection(unsigned row) {
}
pComboBox::pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {
void pComboBox::constructor() {
}

View File

@ -13,5 +13,5 @@ void pHexEdit::setRows(unsigned rows) {
void pHexEdit::update() {
}
pHexEdit::pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {
void pHexEdit::constructor() {
}

View File

@ -8,5 +8,5 @@ void pHorizontalSlider::setLength(unsigned length) {
void pHorizontalSlider::setPosition(unsigned position) {
}
pHorizontalSlider::pHorizontalSlider(HorizontalSlider &horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {
void pHorizontalSlider::constructor() {
}

View File

@ -1,5 +1,5 @@
void pLabel::setText(const string &text) {
}
pLabel::pLabel(Label &label) : pWidget(label), label(label) {
void pLabel::constructor() {
}

View File

@ -7,5 +7,5 @@ void pLineEdit::setText(const string &text) {
string pLineEdit::text() {
}
pLineEdit::pLineEdit(LineEdit &lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {
void pLineEdit::constructor() {
}

View File

@ -35,5 +35,5 @@ void pListView::setHeaderVisible(bool visible) {
void pListView::setSelection(unsigned row) {
}
pListView::pListView(ListView &listView) : pWidget(listView), listView(listView) {
void pListView::constructor() {
}

View File

@ -1,5 +1,5 @@
void pProgressBar::setPosition(unsigned position) {
}
pProgressBar::pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {
void pProgressBar::constructor() {
}

View File

@ -5,11 +5,11 @@ bool pRadioBox::checked() {
void pRadioBox::setChecked() {
}
void pRadioBox::setGroup(const array<RadioBox*> &group) {
void pRadioBox::setGroup(const reference_array<RadioBox&> &group) {
}
void pRadioBox::setText(const string &text) {
}
pRadioBox::pRadioBox(RadioBox &radioBox) : pWidget(radioBox), radioBox(radioBox) {
void pRadioBox::constructor() {
}

View File

@ -13,5 +13,5 @@ void pTextEdit::setWordWrap(bool wordWrap) {
string pTextEdit::text() {
}
pTextEdit::pTextEdit(TextEdit &textEdit) : pWidget(textEdit), textEdit(textEdit) {
void pTextEdit::constructor() {
}

View File

@ -8,5 +8,5 @@ void pVerticalSlider::setLength(unsigned length) {
void pVerticalSlider::setPosition(unsigned position) {
}
pVerticalSlider::pVerticalSlider(VerticalSlider &verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {
void pVerticalSlider::constructor() {
}

View File

@ -2,5 +2,5 @@ uintptr_t pViewport::handle() {
return 0;
}
pViewport::pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {
void pViewport::constructor() {
}

View File

@ -17,5 +17,5 @@ void pWidget::setGeometry(const Geometry &geometry) {
void pWidget::setVisible(bool visible) {
}
pWidget::pWidget(Widget &widget) : widget(widget) {
void pWidget::constructor() {
}

View File

@ -1,6 +1,12 @@
void pWindow::append(Layout &layout) {
}
void pWindow::append(Menu &menu) {
}
void pWindow::append(Widget &widget) {
}
Geometry pWindow::frameGeometry() {
return { 0, 0, 0, 0 };
}
@ -28,9 +34,6 @@ void pWindow::setFullScreen(bool fullScreen) {
void pWindow::setGeometry(const Geometry &geometry) {
}
void pWindow::setLayout(Layout &layout) {
}
void pWindow::setMenuFont(Font &font) {
}
@ -58,5 +61,5 @@ void pWindow::setVisible(bool visible) {
void pWindow::setWidgetFont(Font &font) {
}
pWindow::pWindow(Window &window) : window(window) {
void pWindow::constructor() {
}

View File

@ -0,0 +1,12 @@
void pAction::setEnabled(bool enabled) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pAction::setVisible(bool visible) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pAction::constructor() {
parentMenu = 0;
parentWindow = 0;
}

View File

@ -0,0 +1,14 @@
bool pMenuCheckItem::checked() {
return menuCheckItem.state.checked;
}
void pMenuCheckItem::setChecked(bool checked) {
if(parentMenu) CheckMenuItem(parentMenu, id, checked ? MF_CHECKED : MF_UNCHECKED);
}
void pMenuCheckItem::setText(const string &text) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenuCheckItem::constructor() {
}

View File

@ -0,0 +1,6 @@
void pMenuItem::setText(const string &text) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenuItem::constructor() {
}

View File

@ -0,0 +1,22 @@
bool pMenuRadioItem::checked() {
return menuRadioItem.state.checked;
}
void pMenuRadioItem::setChecked() {
foreach(item, menuRadioItem.state.group) {
//CheckMenuRadioItem takes: lo, hi, id; checking only id when lo <= id <= hi
//phoenix does not force IDs to be linear, so to uncheck id, we use: lo == hi == id + 1 (out of range)
//to check id, we use: lo == hi == id (only ID, but in range)
if(item.p.parentMenu) CheckMenuRadioItem(item.p.parentMenu, item.p.id, item.p.id, item.p.id + (id != item.p.id), MF_BYCOMMAND);
}
}
void pMenuRadioItem::setGroup(const reference_array<MenuRadioItem&> &group) {
}
void pMenuRadioItem::setText(const string &text) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenuRadioItem::constructor() {
}

View File

@ -0,0 +1,2 @@
void pMenuSeparator::constructor() {
}

View File

@ -0,0 +1,46 @@
void pMenu::append(Action &action) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenu::setText(const string &text) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenu::constructor() {
hmenu = 0;
}
//Windows actions lack the ability to toggle visibility.
//To support this, menus must be destroyed and recreated when toggling any action's visibility.
void pMenu::update(Window &parentWindow, HMENU parentMenu) {
this->parentWindow = &parentWindow;
this->parentMenu = parentMenu;
if(hmenu) DestroyMenu(hmenu);
hmenu = CreatePopupMenu();
foreach(action, menu.state.action) {
action.p.parentWindow = &parentWindow;
action.p.parentMenu = hmenu;
unsigned enabled = action.state.enabled ? 0 : MF_GRAYED;
if(dynamic_cast<Menu*>(&action)) {
Menu &item = (Menu&)action;
item.p.update(parentWindow, hmenu);
AppendMenu(hmenu, MF_STRING | MF_POPUP | enabled, (UINT_PTR)item.p.hmenu, utf16_t(item.state.text));
} else if(dynamic_cast<MenuSeparator*>(&action)) {
MenuSeparator &item = (MenuSeparator&)action;
if(action.state.visible) AppendMenu(hmenu, MF_SEPARATOR | enabled, item.p.id, L"");
} else if(dynamic_cast<MenuItem*>(&action)) {
MenuItem &item = (MenuItem&)action;
if(action.state.visible) AppendMenu(hmenu, MF_STRING | enabled, item.p.id, utf16_t(item.state.text));
} else if(dynamic_cast<MenuCheckItem*>(&action)) {
MenuCheckItem &item = (MenuCheckItem&)action;
if(action.state.visible) AppendMenu(hmenu, MF_STRING | enabled, item.p.id, utf16_t(item.state.text));
if(item.state.checked) item.setChecked();
} else if(dynamic_cast<MenuRadioItem*>(&action)) {
MenuRadioItem &item = (MenuRadioItem&)action;
if(action.state.visible) AppendMenu(hmenu, MF_STRING | enabled, item.p.id, utf16_t(item.state.text));
if(item.state.checked) item.setChecked();
}
}
}

36
bsnes/phoenix/windows/font.cpp Executable file
View File

@ -0,0 +1,36 @@
static HFONT Font_createFont(const string &family, unsigned size, bool bold, bool italic, bool underline) {
return CreateFont(
-(size * 96.0 / 72.0 + 0.5),
0, 0, 0, bold == false ? FW_NORMAL : FW_BOLD, italic, underline, 0, 0, 0, 0, 0, 0,
utf16_t(family)
);
}
void pFont::setBold(bool bold) {
if(hfont) { DeleteObject(hfont); hfont = 0; }
hfont = Font_createFont(font.state.family, font.state.size, font.state.bold, font.state.italic, font.state.underline);
}
void pFont::setFamily(const string &family) {
if(hfont) { DeleteObject(hfont); hfont = 0; }
hfont = Font_createFont(font.state.family, font.state.size, font.state.bold, font.state.italic, font.state.underline);
}
void pFont::setItalic(bool italic) {
if(hfont) { DeleteObject(hfont); hfont = 0; }
hfont = Font_createFont(font.state.family, font.state.size, font.state.bold, font.state.italic, font.state.underline);
}
void pFont::setSize(unsigned size) {
if(hfont) { DeleteObject(hfont); hfont = 0; }
hfont = Font_createFont(font.state.family, font.state.size, font.state.bold, font.state.italic, font.state.underline);
}
void pFont::setUnderline(bool underline) {
if(hfont) { DeleteObject(hfont); hfont = 0; }
hfont = Font_createFont(font.state.family, font.state.size, font.state.bold, font.state.italic, font.state.underline);
}
void pFont::constructor() {
hfont = 0;
}

View File

@ -0,0 +1,41 @@
static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons buttons, UINT response) {
if(response == IDOK) return MessageWindow::Response::Ok;
if(response == IDCANCEL) return MessageWindow::Response::Cancel;
if(response == IDYES) return MessageWindow::Response::Yes;
if(response == IDNO) 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) {
UINT flags = MB_ICONINFORMATION;
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
}
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
UINT flags = MB_ICONQUESTION;
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
}
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
UINT flags = MB_ICONWARNING;
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
}
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
UINT flags = MB_ICONERROR;
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
}

View File

@ -0,0 +1,13 @@
array<pObject*> pObject::objects;
pObject::pObject() {
static unsigned uniqueId = 100;
objects.append(this);
id = uniqueId++;
locked = false;
}
pObject* pObject::find(unsigned id) {
foreach(item, objects) if(item->id == id) return item;
return 0;
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="phoenix" version="1.0.0.0" processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
</assembly>

View File

@ -0,0 +1 @@
1 24 "phoenix.Manifest"

View File

@ -0,0 +1,15 @@
void pButton::setText(const string &text) {
SetWindowText(hwnd, utf16_t(text));
}
void pButton::constructor() {
setParent(Window::None);
}
void pButton::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(L"BUTTON", L"", WS_CHILD | WS_TABSTOP | WS_VISIBLE, 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&button);
setDefaultFont();
setText(button.state.text);
}

View File

@ -0,0 +1,27 @@
bool pCheckBox::checked() {
return SendMessage(hwnd, BM_GETCHECK, 0, 0);
}
void pCheckBox::setChecked(bool checked) {
SendMessage(hwnd, BM_SETCHECK, (WPARAM)checked, 0);
}
void pCheckBox::setText(const string &text) {
SetWindowText(hwnd, utf16_t(text));
}
void pCheckBox::constructor() {
setParent(Window::None);
}
void pCheckBox::setParent(Window &parent) {
hwnd = CreateWindow(
L"BUTTON", L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_CHECKBOX,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&checkBox);
setDefaultFont();
if(checkBox.state.checked) setChecked(true);
setText(checkBox.state.text);
}

View File

@ -0,0 +1,34 @@
void pComboBox::append(const string &text) {
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)(wchar_t*)utf16_t(text));
if(SendMessage(hwnd, CB_GETCOUNT, 0, 0) == 1) setSelection(0);
}
void pComboBox::reset() {
SendMessage(hwnd, CB_RESETCONTENT, 0, 0);
}
unsigned pComboBox::selection() {
return SendMessage(hwnd, CB_GETCURSEL, 0, 0);
}
void pComboBox::setSelection(unsigned row) {
SendMessage(hwnd, CB_SETCURSEL, row, 0);
}
void pComboBox::constructor() {
setParent(Window::None);
}
void pComboBox::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(
L"COMBOBOX", L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
0, 0, 0, 0,
parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&comboBox);
setDefaultFont();
foreach(text, comboBox.state.text) append(text);
setSelection(comboBox.state.selection);
}

View File

@ -0,0 +1,131 @@
static LRESULT CALLBACK HexEdit_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
HexEdit &hexEdit = *(HexEdit*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(msg == WM_CHAR) {
if(hexEdit.p.keyPress(wparam)) return 0;
}
return hexEdit.p.windowProc(hwnd, msg, wparam, lparam);
}
void pHexEdit::setColumns(unsigned columns) {
update();
}
void pHexEdit::setLength(unsigned length) {
update();
}
void pHexEdit::setOffset(unsigned offset) {
update();
}
void pHexEdit::setRows(unsigned rows) {
update();
}
void pHexEdit::update() {
if(!hexEdit.onRead) {
SetWindowText(hwnd, L"");
return;
}
unsigned cursorPosition = Edit_GetSel(hwnd);
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("\r\n");
}
SetWindowText(hwnd, utf16_t(output));
Edit_SetSel(hwnd, LOWORD(cursorPosition), HIWORD(cursorPosition));
}
void pHexEdit::constructor() {
setParent(Window::None);
}
bool pHexEdit::keyPress(unsigned scancode) {
if(!hexEdit.onRead) return false;
unsigned position = LOWORD(Edit_GetSel(hwnd));
unsigned lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 2;
unsigned cursorY = position / lineWidth;
unsigned cursorX = position % lineWidth;
//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;
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 or byte
position++;
if(cursorNibble && cursorX != hexEdit.state.columns - 1) position++;
Edit_SetSel(hwnd, position, position);
//refresh output to reflect modified data
update();
}
}
}
return true;
}
void pHexEdit::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | ES_READONLY | ES_MULTILINE | ES_WANTRETURN,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&hexEdit);
setDefaultFont();
update();
windowProc = (LRESULT CALLBACK (*)(HWND, UINT, LPARAM, WPARAM))GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)HexEdit_windowProc);
}

View File

@ -0,0 +1,29 @@
unsigned pHorizontalSlider::position() {
return SendMessage(hwnd, TBM_GETPOS, 0, 0);
}
void pHorizontalSlider::setLength(unsigned length) {
length += (length == 0);
SendMessage(hwnd, TBM_SETRANGE, (WPARAM)true, (LPARAM)MAKELONG(0, length - 1));
SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)(length >> 3));
horizontalSlider.setPosition(0);
}
void pHorizontalSlider::setPosition(unsigned position) {
SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)position);
}
void pHorizontalSlider::constructor() {
setParent(Window::None);
}
void pHorizontalSlider::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(
TRACKBAR_CLASS, L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP | TBS_NOTICKS | TBS_BOTH | TBS_HORZ,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&horizontalSlider);
setLength(horizontalSlider.state.length);
setPosition(horizontalSlider.state.position);
}

View File

@ -0,0 +1,45 @@
void pLabel::setText(const string &text) {
SetWindowText(hwnd, utf16_t(text));
InvalidateRect(hwnd, 0, false);
}
void pLabel::constructor() {
setParent(Window::None);
}
void pLabel::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(L"phoenix_label", L"", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&label);
setDefaultFont();
setText(label.state.text);
}
static LRESULT CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
Window *window = (Window*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
Label *label = (Label*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(!window || !label) return DefWindowProc(hwnd, msg, wparam, lparam);
if(msg == WM_PAINT) {
PAINTSTRUCT ps;
RECT rc;
BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
FillRect(ps.hdc, &rc, window->p.brush ? window->p.brush : GetSysColorBrush(COLOR_3DFACE));
SetBkColor(ps.hdc, window->p.brush ? window->p.brushColor : GetSysColor(COLOR_3DFACE));
SelectObject(ps.hdc, ((Widget*)label)->state.font ? ((Widget*)label)->state.font->p.hfont : pOS::state->defaultFont.p.hfont);
unsigned length = GetWindowTextLength(hwnd);
wchar_t text[length + 1];
GetWindowText(hwnd, text, length + 1);
text[length] = 0;
DrawText(ps.hdc, text, -1, &rc, DT_CALCRECT | DT_END_ELLIPSIS);
unsigned height = rc.bottom;
GetClientRect(hwnd, &rc);
rc.top = (rc.bottom - height) / 2;
rc.bottom = rc.top + height;
DrawText(ps.hdc, text, -1, &rc, DT_LEFT | DT_END_ELLIPSIS);
EndPaint(hwnd, &ps);
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}

View File

@ -0,0 +1,34 @@
void pLineEdit::setEditable(bool editable) {
SendMessage(hwnd, EM_SETREADONLY, editable == false, 0);
}
void pLineEdit::setText(const string &text) {
locked = true;
SetWindowText(hwnd, utf16_t(text));
locked = false;
}
string pLineEdit::text() {
unsigned length = GetWindowTextLength(hwnd);
wchar_t text[length + 1];
GetWindowText(hwnd, text, length + 1);
text[length] = 0;
return utf8_t(text);
}
void pLineEdit::constructor() {
setParent(Window::None);
}
void pLineEdit::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&lineEdit);
setDefaultFont();
setEditable(lineEdit.state.editable);
setText(lineEdit.state.text);
}

View File

@ -0,0 +1,121 @@
void pListView::append(const lstring &list) {
wchar_t empty[] = L"";
unsigned row = ListView_GetItemCount(hwnd);
LVITEM item;
item.mask = LVIF_TEXT;
item.iItem = row;
item.iSubItem = 0;
item.pszText = empty;
locked = true;
ListView_InsertItem(hwnd, &item);
locked = false;
foreach(text, list, n) {
utf16_t wtext(text);
ListView_SetItemText(hwnd, row, n, wtext);
}
//workaround: when there is only one column, the horizontal scrollbar will always appear without this
if(listView.state.headerText.size() <= 1) ListView_SetColumnWidth(hwnd, 0, LVSCW_AUTOSIZE_USEHEADER);
}
void pListView::autosizeColumns() {
for(unsigned n = 0; n < listView.state.headerText.size(); n++) {
ListView_SetColumnWidth(hwnd, n, LVSCW_AUTOSIZE_USEHEADER);
}
}
bool pListView::checked(unsigned row) {
return ListView_GetCheckState(hwnd, row);
}
void pListView::modify(unsigned row, const lstring &list) {
foreach(text, list, n) {
utf16_t wtext(text);
ListView_SetItemText(hwnd, row, n, wtext);
}
if(listView.state.headerText.size() <= 1) ListView_SetColumnWidth(hwnd, 0, LVSCW_AUTOSIZE_USEHEADER);
}
void pListView::modify(unsigned row, unsigned column, const string &text) {
utf16_t wtext(text);
ListView_SetItemText(hwnd, row, column, wtext);
if(listView.state.headerText.size() <= 1) ListView_SetColumnWidth(hwnd, 0, LVSCW_AUTOSIZE_USEHEADER);
}
void pListView::reset() {
ListView_DeleteAllItems(hwnd);
}
optional<unsigned> pListView::selection() {
unsigned count = ListView_GetItemCount(hwnd);
for(unsigned n = 0; n < count; n++) {
if(ListView_GetItemState(hwnd, n, LVIS_SELECTED)) return { true, n };
}
return { false, 0 };
}
void pListView::setCheckable(bool checkable) {
ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT | (checkable ? LVS_EX_CHECKBOXES : 0));
}
void pListView::setChecked(unsigned row, bool checked) {
locked = true;
ListView_SetCheckState(hwnd, row, checked);
locked = false;
}
void pListView::setHeaderText(const lstring &list) {
while(ListView_DeleteColumn(hwnd, 0));
lstring headers = list;
if(headers.size() == 0) headers.append(""); //must have at least one column
foreach(text, headers, n) {
LVCOLUMN column;
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
column.fmt = LVCFMT_LEFT;
column.iSubItem = n;
utf16_t headerText(text);
column.pszText = headerText;
ListView_InsertColumn(hwnd, n, &column);
}
autosizeColumns();
}
void pListView::setHeaderVisible(bool visible) {
SetWindowLong(
hwnd, GWL_STYLE,
(GetWindowLong(hwnd, GWL_STYLE) & ~LVS_NOCOLUMNHEADER) |
(visible ? 0 : LVS_NOCOLUMNHEADER)
);
}
void pListView::setSelection(unsigned row) {
unsigned count = ListView_GetItemCount(hwnd);
for(unsigned n = 0; n < count; n++) {
ListView_SetItemState(hwnd, n, LVIS_FOCUSED, (n == row ? LVIS_FOCUSED : 0));
ListView_SetItemState(hwnd, n, LVIS_SELECTED, (n == row ? LVIS_SELECTED : 0));
}
}
void pListView::constructor() {
lostFocus = false;
setParent(Window::None);
}
void pListView::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | LVS_NOCOLUMNHEADER,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&listView);
setDefaultFont();
setHeaderText(listView.state.headerText);
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();
}

View File

@ -0,0 +1,16 @@
void pProgressBar::setPosition(unsigned position) {
SendMessage(hwnd, PBM_SETPOS, (WPARAM)position, 0);
}
void pProgressBar::constructor() {
setParent(Window::None);
}
void pProgressBar::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(PROGRESS_CLASS, L"", WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&progressBar);
SendMessage(hwnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
SendMessage(hwnd, PBM_SETSTEP, MAKEWPARAM(1, 0), 0);
setPosition(progressBar.state.position);
}

View File

@ -0,0 +1,32 @@
bool pRadioBox::checked() {
return SendMessage(hwnd, BM_GETCHECK, 0, 0);
}
void pRadioBox::setChecked() {
foreach(item, radioBox.state.group) {
SendMessage(item.p.hwnd, BM_SETCHECK, (WPARAM)(&item == &radioBox), 0);
}
}
void pRadioBox::setGroup(const reference_array<RadioBox&> &group) {
}
void pRadioBox::setText(const string &text) {
SetWindowText(hwnd, utf16_t(text));
}
void pRadioBox::constructor() {
setParent(Window::None);
}
void pRadioBox::setParent(Window &parent) {
hwnd = CreateWindow(
L"BUTTON", L"",
WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_RADIOBUTTON,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&radioBox);
setDefaultFont();
if(radioBox.state.checked) setChecked();
setText(radioBox.state.text);
}

View File

@ -0,0 +1,53 @@
void pTextEdit::setCursorPosition(unsigned position) {
Edit_SetSel(hwnd, position, position);
}
void pTextEdit::setEditable(bool editable) {
SendMessage(hwnd, EM_SETREADONLY, editable == false, (LPARAM)0);
}
void pTextEdit::setText(const string &text) {
locked = true;
string output = text;
output.replace("\r", "");
output.replace("\n", "\r\n");
SetWindowText(hwnd, utf16_t(output));
locked = false;
}
void pTextEdit::setWordWrap(bool wordWrap) {
//ES_AUTOHSCROLL cannot be changed after widget creation.
//As a result, we must destroy and re-create widget to change this setting.
HWND hwndParent = GetParent(hwnd);
Object *object = (Object*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
if(object == 0) return;
if(dynamic_cast<Window*>(object)) setParent(((Window&)*object));
}
string pTextEdit::text() {
unsigned length = GetWindowTextLength(hwnd);
wchar_t buffer[length + 1];
GetWindowText(hwnd, buffer, length + 1);
buffer[length] = 0;
string text = utf8_t(buffer);
text.replace("\r", "");
return text;
}
void pTextEdit::constructor() {
setParent(Window::None);
}
void pTextEdit::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_VISIBLE | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN | (textEdit.state.wordWrap == false ? ES_AUTOHSCROLL : 0),
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&textEdit);
setDefaultFont();
setCursorPosition(textEdit.state.cursorPosition);
setEditable(textEdit.state.editable);
setText(textEdit.state.text);
}

View File

@ -0,0 +1,29 @@
unsigned pVerticalSlider::position() {
return SendMessage(hwnd, TBM_GETPOS, 0, 0);
}
void pVerticalSlider::setLength(unsigned length) {
length += (length == 0);
SendMessage(hwnd, TBM_SETRANGE, (WPARAM)true, (LPARAM)MAKELONG(0, length - 1));
SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)(length >> 3));
verticalSlider.setPosition(0);
}
void pVerticalSlider::setPosition(unsigned position) {
SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)position);
}
void pVerticalSlider::constructor() {
setParent(Window::None);
}
void pVerticalSlider::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(
TRACKBAR_CLASS, L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP | TBS_NOTICKS | TBS_BOTH | TBS_HORZ,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&verticalSlider);
setLength(verticalSlider.state.length);
setPosition(verticalSlider.state.position);
}

View File

@ -0,0 +1,16 @@
uintptr_t pViewport::handle() {
return (uintptr_t)hwnd;
}
void pViewport::constructor() {
setParent(Window::None);
}
void pViewport::setParent(Window &parent) {
hwnd = CreateWindow(L"phoenix_viewport", L"", WS_CHILD | WS_VISIBLE | WS_DISABLED, 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&viewport);
}
static LRESULT CALLBACK Viewport_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
return DefWindowProc(hwnd, msg, wparam, lparam);
}

View File

@ -0,0 +1,34 @@
bool pWidget::enabled() {
return false;
}
void pWidget::setEnabled(bool enabled) {
}
void pWidget::setFocused() {
}
void pWidget::setFont(Font &font) {
}
void pWidget::setGeometry(const Geometry &geometry) {
SetWindowPos(hwnd, NULL, geometry.x, geometry.y, geometry.width, geometry.height, SWP_NOZORDER);
}
void pWidget::setVisible(bool visible) {
}
void pWidget::constructor() {
hwnd = 0;
}
void pWidget::setDefaultFont() {
if(widget.state.font) {
SendMessage(hwnd, WM_SETFONT, (WPARAM)widget.state.font->p.hfont, 0);
} else {
SendMessage(hwnd, WM_SETFONT, (WPARAM)pOS::state->defaultFont.p.hfont, 0);
}
}
void pWidget::setParent(Window &parent) {
}

162
bsnes/phoenix/windows/window.cpp Executable file
View File

@ -0,0 +1,162 @@
static const unsigned FixedStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER;
static const unsigned ResizableStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME;
void pWindow::append(Layout &layout) {
layout.setParent(window);
Geometry geom = window.state.geometry;
geom.x = geom.y = 0;
layout.setGeometry(geom);
}
void pWindow::append(Menu &menu) {
updateMenu();
}
void pWindow::append(Widget &widget) {
widget.p.setParent(window);
}
Geometry pWindow::frameGeometry() {
RECT rc;
GetWindowRect(hwnd, &rc);
return { rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top };
}
bool pWindow::focused() {
return (GetForegroundWindow() == hwnd);
}
Geometry pWindow::geometry() {
Geometry margin = frameMargin();
RECT rc;
GetWindowRect(hwnd, &rc);
signed x = rc.left + margin.x;
signed y = rc.top + margin.y;
unsigned width = (rc.right - rc.left) - margin.width;
unsigned height = (rc.bottom - rc.top) - margin.height;
return { x, y, width, height };
}
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
if(brush) DeleteObject(brush);
brushColor = RGB(red, green, blue);
brush = CreateSolidBrush(brushColor);
}
void pWindow::setFrameGeometry(const Geometry &geometry) {
Geometry margin = frameMargin();
window.setGeometry({
geometry.x + margin.x, geometry.y + margin.y,
geometry.width - margin.width, geometry.height - margin.height
});
}
void pWindow::setFocused() {
if(window.state.visible == false) setVisible(true);
SetFocus(hwnd);
}
void pWindow::setFullScreen(bool fullScreen) {
}
void pWindow::setGeometry(const Geometry &geometry) {
locked = true;
Geometry margin = frameMargin();
SetWindowPos(
hwnd, NULL,
geometry.x - margin.x, geometry.y - margin.y,
geometry.width + margin.width, geometry.height + margin.height,
SWP_NOZORDER | SWP_FRAMECHANGED
);
SetWindowPos(hstatus, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_FRAMECHANGED);
foreach(layout, window.state.layout) {
Geometry geom = this->geometry();
geom.x = geom.y = 0;
layout.setGeometry(geom);
}
locked = false;
}
void pWindow::setMenuFont(Font &font) {
}
void pWindow::setMenuVisible(bool visible) {
locked = true;
SetMenu(hwnd, visible ? hmenu : 0);
setGeometry(window.state.geometry);
locked = false;
}
void pWindow::setResizable(bool resizable) {
SetWindowLongPtr(hwnd, GWL_STYLE, window.state.resizable ? ResizableStyle : FixedStyle);
setGeometry(window.state.geometry);
}
void pWindow::setStatusFont(Font &font) {
SendMessage(hwnd, WM_SETFONT, (WPARAM)font.p.hfont, 0);
}
void pWindow::setStatusText(const string &text) {
SendMessage(hstatus, SB_SETTEXT, 0, (LPARAM)(wchar_t*)utf16_t(text));
}
void pWindow::setStatusVisible(bool visible) {
locked = true;
ShowWindow(hstatus, visible ? SW_SHOWNORMAL : SW_HIDE);
setGeometry(window.state.geometry);
locked = false;
}
void pWindow::setTitle(const string &text) {
SetWindowText(hwnd, utf16_t(text));
}
void pWindow::setVisible(bool visible) {
ShowWindow(hwnd, visible ? SW_SHOWNORMAL : SW_HIDE);
}
void pWindow::setWidgetFont(Font &font) {
foreach(widget, window.state.widget) {
if(!widget.state.font) widget.setFont(font);
}
}
void pWindow::constructor() {
brush = 0;
hwnd = CreateWindow(L"phoenix_window", L"", ResizableStyle, 128, 128, 256, 256, 0, 0, GetModuleHandle(0), 0);
hmenu = CreateMenu();
hstatus = CreateWindow(STATUSCLASSNAME, L"", WS_CHILD, 0, 0, 0, 0, hwnd, 0, GetModuleHandle(0), 0);
//status bar will be capable of receiving tab focus if it is not disabled
SetWindowLongPtr(hstatus, GWL_STYLE, GetWindowLong(hstatus, GWL_STYLE) | WS_DISABLED);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&window);
setGeometry({ 128, 128, 256, 256 });
}
Geometry pWindow::frameMargin() {
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect(&rc, window.state.resizable ? ResizableStyle : FixedStyle, window.state.menuVisible);
unsigned statusHeight = 0;
if(window.state.statusVisible) {
RECT src;
GetClientRect(hstatus, &src);
statusHeight = src.bottom - src.top;
}
return { abs(rc.left), abs(rc.top), (rc.right - rc.left) - 640, (rc.bottom - rc.top) + statusHeight - 480 };
}
void pWindow::updateMenu() {
if(hmenu) DestroyMenu(hmenu);
hmenu = CreateMenu();
foreach(menu, window.state.menu) {
menu.p.update(window, hmenu);
AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT_PTR)menu.p.hmenu, utf16_t(menu.state.text));
}
SetMenu(hwnd, window.state.menuVisible ? hmenu : 0);
}

413
bsnes/phoenix/windows/windows.cpp Executable file
View File

@ -0,0 +1,413 @@
#include "windows.hpp"
#include "object.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"
static void OS_keyboardProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK OS_windowProc(HWND, UINT, WPARAM, LPARAM);
pOS::State *pOS::state = 0;
unsigned pOS::desktopWidth() {
return GetSystemMetrics(SM_CXSCREEN);
}
unsigned pOS::desktopHeight() {
return GetSystemMetrics(SM_CYSCREEN);
}
static string pOS_fileDialog(bool save, Window &parent, const string &path, const lstring &filter) {
string dir = path;
dir.replace("/", "\\");
string filterList;
foreach(filterItem, filter) {
lstring part;
part.split("(", filterItem);
if(part.size() != 2) { print("--", filterItem, "\n"); continue; }
part[1].rtrim<1>(")");
part[1].replace(" ", "");
part[1].transform(",", ";");
filterList.append(string(filterItem, "\t", part[1], "\t"));
}
utf16_t wfilter(filterList);
utf16_t wdir(dir);
wchar_t wfilename[PATH_MAX + 1] = L"";
wchar_t *p = wfilter;
while(*p != L'\0') {
if(*p == L'\t') *p = L'\0';
p++;
}
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = &parent != &Window::None ? parent.p.hwnd : 0;
ofn.lpstrFilter = wfilter;
ofn.lpstrInitialDir = wdir;
ofn.lpstrFile = wfilename;
ofn.nMaxFile = PATH_MAX;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = L"";
bool result = (save == false ? GetOpenFileName(&ofn) : GetSaveFileName(&ofn));
if(result == false) return "";
string name = utf8_t(wfilename);
name.transform("\\", "/");
return name;
}
string pOS::fileLoad(Window &parent, const string &path, const lstring &filter) {
return pOS_fileDialog(false, parent, path, filter);
}
string pOS::fileSave(Window &parent, const string &path, const lstring &filter) {
return pOS_fileDialog(true, parent, path, filter);
}
string pOS::folderSelect(Window &parent, const string &path) {
wchar_t wfilename[PATH_MAX + 1] = L"";
BROWSEINFO bi;
bi.hwndOwner = &parent != &Window::None ? parent.p.hwnd : 0;
bi.pidlRoot = NULL;
bi.pszDisplayName = wfilename;
bi.lpszTitle = L"";
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
bool result = false;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if(pidl) {
if(SHGetPathFromIDList(pidl, wfilename)) {
result = true;
IMalloc *imalloc = 0;
if(SUCCEEDED(SHGetMalloc(&imalloc))) {
imalloc->Free(pidl);
imalloc->Release();
}
}
}
if(result == false) return "";
string name = utf8_t(wfilename);
if(name == "") return "";
name.transform("\\", "/");
if(name.endswith("/") == false) name.append("/");
return name;
}
void pOS::main() {
MSG msg;
while(GetMessage(&msg, 0, 0, 0)) {
if(msg.message == WM_KEYDOWN || msg.message == WM_KEYUP) {
OS_keyboardProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
}
if(!IsDialogMessage(GetParent(msg.hwnd) ? GetParent(msg.hwnd) : msg.hwnd, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
bool pOS::pending() {
MSG msg;
return PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
}
void pOS::process() {
while(pending()) {
MSG msg;
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
if(msg.message == WM_KEYDOWN || msg.message == WM_KEYUP) {
OS_keyboardProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
}
if(!IsDialogMessage(GetParent(msg.hwnd) ? GetParent(msg.hwnd) : msg.hwnd, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
void pOS::quit() {
PostQuitMessage(0);
}
void pOS::initialize() {
CoInitialize(0);
InitCommonControls();
state = new State;
state->defaultFont.setFamily("Tahoma");
state->defaultFont.setSize(8);
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2));
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = OS_windowProc;
wc.lpszClassName = L"phoenix_window";
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = Label_windowProc;
wc.lpszClassName = L"phoenix_label";
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = Viewport_windowProc;
wc.lpszClassName = L"phoenix_viewport";
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
}
static void OS_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
if(msg == WM_KEYDOWN) {
GUITHREADINFO info;
memset(&info, 0, sizeof(GUITHREADINFO));
info.cbSize = sizeof(GUITHREADINFO);
GetGUIThreadInfo(GetCurrentThreadId(), &info);
Object *object = (Object*)GetWindowLongPtr(info.hwndFocus, GWLP_USERDATA);
if(object == 0) return;
if(dynamic_cast<ListView*>(object)) {
ListView &listView = (ListView&)*object;
if(wparam == VK_RETURN) {
if(listView.onActivate) listView.onActivate();
}
} else if(dynamic_cast<LineEdit*>(object)) {
LineEdit &lineEdit = (LineEdit&)*object;
if(wparam == VK_RETURN) {
if(lineEdit.onActivate) lineEdit.onActivate();
}
}
}
}
static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
Object *object = (Object*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(!object || !dynamic_cast<Window*>(object)) return DefWindowProc(hwnd, msg, wparam, lparam);
Window &window = (Window&)*object;
switch(msg) {
case WM_CLOSE: {
if(window.onClose) window.onClose();
window.setVisible(false);
return TRUE;
}
case WM_MOVE: {
if(window.p.locked) break;
Geometry geometry = window.geometry();
window.state.geometry.x = geometry.x;
window.state.geometry.y = geometry.y;
if(window.onMove) window.onMove();
break;
}
case WM_SIZE: {
if(window.p.locked) break;
SetWindowPos(window.p.hstatus, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_FRAMECHANGED);
Geometry geometry = window.geometry();
window.state.geometry.width = geometry.width;
window.state.geometry.height = geometry.height;
foreach(layout, window.state.layout) {
Geometry geom = window.geometry();
geom.x = geom.y = 0;
layout.setGeometry(geom);
}
if(window.onSize) window.onSize();
break;
}
case WM_GETMINMAXINFO: {
MINMAXINFO *mmi = (MINMAXINFO*)lparam;
//mmi->ptMinTrackSize.x = 256 + window.p.frameMargin().width;
//mmi->ptMinTrackSize.y = 256 + window.p.frameMargin().height;
//return TRUE;
}
case WM_ERASEBKGND: {
if(window.p.brush == 0) break;
RECT rc;
GetClientRect(window.p.hwnd, &rc);
PAINTSTRUCT ps;
BeginPaint(window.p.hwnd, &ps);
FillRect(ps.hdc, &rc, window.p.brush);
EndPaint(window.p.hwnd, &ps);
return TRUE;
}
case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC: {
Object *object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
if(object && window.p.brush) {
HDC hdc = (HDC)wparam;
SetBkColor((HDC)wparam, window.p.brushColor);
return (INT_PTR)window.p.brush;
}
}
case WM_COMMAND: {
unsigned id = LOWORD(wparam);
HWND control = GetDlgItem(window.p.hwnd, id);
if(control == 0) {
pObject *object = (pObject*)pObject::find(id);
if(!object) break;
if(dynamic_cast<pMenuItem*>(object)) {
MenuItem &menuItem = ((pMenuItem*)object)->menuItem;
if(menuItem.onTick) menuItem.onTick();
} else if(dynamic_cast<pMenuCheckItem*>(object)) {
MenuCheckItem &menuCheckItem = ((pMenuCheckItem*)object)->menuCheckItem;
menuCheckItem.setChecked(!menuCheckItem.state.checked);
if(menuCheckItem.onTick) menuCheckItem.onTick();
} else if(dynamic_cast<pMenuRadioItem*>(object)) {
MenuRadioItem &menuRadioItem = ((pMenuRadioItem*)object)->menuRadioItem;
if(menuRadioItem.state.checked == false) {
menuRadioItem.setChecked();
if(menuRadioItem.onTick) menuRadioItem.onTick();
}
}
} else {
Object *object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
if(!object) break;
if(dynamic_cast<Button*>(object)) {
Button &button = (Button&)*object;
if(button.onTick) button.onTick();
} else if(dynamic_cast<CheckBox*>(object)) {
CheckBox &checkBox = (CheckBox&)*object;
checkBox.setChecked(!checkBox.state.checked);
if(checkBox.onTick) checkBox.onTick();
} else if(dynamic_cast<ComboBox*>(object)) {
ComboBox &comboBox = (ComboBox&)*object;
if(HIWORD(wparam) == CBN_SELCHANGE) {
if(comboBox.state.selection != comboBox.selection()) {
comboBox.state.selection = comboBox.selection();
if(comboBox.onChange) comboBox.onChange();
}
}
} else if(dynamic_cast<LineEdit*>(object)) {
LineEdit &lineEdit = (LineEdit&)*object;
if(HIWORD(wparam) == EN_CHANGE) {
if(lineEdit.p.locked == false && lineEdit.onChange) lineEdit.onChange();
}
} else if(dynamic_cast<RadioBox*>(object)) {
RadioBox &radioBox = (RadioBox&)*object;
if(radioBox.state.checked == false) {
radioBox.setChecked();
if(radioBox.onTick) radioBox.onTick();
}
} else if(dynamic_cast<TextEdit*>(object)) {
TextEdit &textEdit = (TextEdit&)*object;
if(HIWORD(wparam) == EN_CHANGE) {
if(textEdit.p.locked == false && textEdit.onChange) textEdit.onChange();
}
}
}
}
case WM_NOTIFY: {
unsigned id = LOWORD(wparam);
HWND control = GetDlgItem(window.p.hwnd, id);
if(control == 0) break;
Object *object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
if(object == 0) break;
if(dynamic_cast<ListView*>(object)) {
ListView &listView = (ListView&)*object;
LPNMHDR nmhdr = (LPNMHDR)lparam;
LPNMLISTVIEW nmlistview = (LPNMLISTVIEW)lparam;
if(nmhdr->code == LVN_ITEMCHANGED && (nmlistview->uChanged & LVIF_STATE)) {
unsigned imagemask = ((nmlistview->uNewState & LVIS_STATEIMAGEMASK) >> 12) - 1;
if(imagemask == 0 || imagemask == 1) {
if(listView.p.locked == false && listView.onTick) listView.onTick(nmlistview->iItem);
} else if((nmlistview->uOldState & LVIS_FOCUSED) && !(nmlistview->uNewState & LVIS_FOCUSED)) {
listView.p.lostFocus = true;
} else {
if(!(nmlistview->uOldState & LVIS_SELECTED) && (nmlistview->uNewState & LVIS_SELECTED)) {
if(listView.onChange) listView.onChange();
} else if(listView.p.lostFocus == false && listView.selection() == false) {
if(listView.onChange) listView.onChange();
}
listView.p.lostFocus = false;
}
} else if(nmhdr->code == LVN_ITEMACTIVATE) {
if(listView.onActivate) listView.onActivate();
}
}
}
case WM_HSCROLL:
case WM_VSCROLL: {
unsigned id = LOWORD(wparam);
HWND control = GetDlgItem(window.p.hwnd, id);
if(control == 0) break;
Object *object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
if(object == 0) break;
if(dynamic_cast<HorizontalSlider*>(object)) {
HorizontalSlider &horizontalSlider = (HorizontalSlider&)*object;
if(horizontalSlider.state.position != horizontalSlider.position()) {
horizontalSlider.state.position = horizontalSlider.position();
if(horizontalSlider.onChange) horizontalSlider.onChange();
}
} else if(dynamic_cast<VerticalSlider*>(object)) {
VerticalSlider &verticalSlider = (VerticalSlider&)*object;
if(verticalSlider.state.position != verticalSlider.position()) {
verticalSlider.state.position = verticalSlider.position();
if(verticalSlider.onChange) verticalSlider.onChange();
}
}
}
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}

336
bsnes/phoenix/windows/windows.hpp Executable file
View File

@ -0,0 +1,336 @@
struct pFont;
struct pWindow;
struct pMenu;
struct pLayout;
struct pWidget;
struct pObject {
unsigned id;
bool locked;
static array<pObject*> objects;
pObject();
static pObject* find(unsigned id);
virtual void unused() {}
};
struct pOS : public pObject {
struct State {
Font defaultFont;
};
static State *state;
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;
HFONT hfont;
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;
HWND hwnd;
HMENU hmenu;
HWND hstatus;
HBRUSH brush;
COLORREF brushColor;
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();
Geometry frameMargin();
void updateMenu();
};
struct pAction : public pObject {
Action &action;
HMENU parentMenu;
Window *parentWindow;
void setEnabled(bool enabled);
void setVisible(bool visible);
pAction(Action &action) : action(action) {}
void constructor();
};
struct pMenu : public pAction {
Menu &menu;
HMENU hmenu;
void append(Action &action);
void setText(const string &text);
pMenu(Menu &menu) : pAction(menu), menu(menu) {}
void constructor();
void update(Window &parentWindow, HMENU parentMenu);
};
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;
HWND hwnd;
bool enabled();
void setEnabled(bool enabled);
void setFocused();
void setFont(Font &font);
void setGeometry(const Geometry &geometry);
void setVisible(bool visible);
pWidget(Widget &widget) : widget(widget) {}
void constructor();
void setDefaultFont();
virtual void setParent(Window &parent);
};
struct pButton : public pWidget {
Button &button;
void setText(const string &text);
pButton(Button &button) : pWidget(button), button(button) {}
void constructor();
void setParent(Window &parent);
};
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();
void setParent(Window &parent);
};
struct pComboBox : public pWidget {
ComboBox &comboBox;
void append(const string &text);
void reset();
unsigned selection();
void setSelection(unsigned row);
pComboBox(ComboBox &comboBox) : pWidget(comboBox), comboBox(comboBox) {}
void constructor();
void setParent(Window &parent);
};
struct pHexEdit : public pWidget {
HexEdit &hexEdit;
LRESULT CALLBACK (*windowProc)(HWND, UINT, LPARAM, WPARAM);
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();
bool keyPress(unsigned key);
void setParent(Window &parent);
};
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();
void setParent(Window &parent);
};
struct pLabel : public pWidget {
Label &label;
void setText(const string &text);
pLabel(Label &label) : pWidget(label), label(label) {}
void constructor();
void setParent(Window &parent);
};
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();
void setParent(Window &parent);
};
struct pListView : public pWidget {
ListView &listView;
bool lostFocus;
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 setParent(Window &parent);
};
struct pProgressBar : public pWidget {
ProgressBar &progressBar;
void setPosition(unsigned position);
pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {}
void constructor();
void setParent(Window &parent);
};
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();
void setParent(Window &parent);
};
struct pTextEdit : public pWidget {
TextEdit &textEdit;
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();
void setParent(Window &parent);
};
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();
void setParent(Window &parent);
};
struct pViewport : public pWidget {
Viewport &viewport;
uintptr_t handle();
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
void constructor();
void setParent(Window &parent);
};

View File

@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "075.13";
static const char Version[] = "075.14";
static const unsigned SerializerVersion = 18;
}
}

View File

@ -80,7 +80,7 @@ void MainWindow::create() {
help.append(helpAbout);
layout.append(viewport, { 0, 0, 160 * 2, 144 * 2 });
setLayout(layout);
append(layout);
setGeometry({ 128, 128, 160 * 2, 144 * 2 });
setMenuVisible(true);

View File

@ -16,7 +16,7 @@ void Application::main(int argc, char **argv) {
proportionalFontBold.setSize(8);
proportionalFontBold.setBold();
monospaceFont.setFamily("Courier New");
monospaceFont.setFamily("Lucida Console");
monospaceFont.setSize(8);
#else
proportionalFont.setFamily("Sans");

View File

@ -25,7 +25,7 @@ void Console::create() {
layout.append(controlLayout, 120, 0);
setGeometry({ 0, 0, layout.minimumWidth() + 580, 350 });
setLayout(layout);
append(layout);
onClose = []() {
debugger.showConsole.setChecked(false);

View File

@ -19,7 +19,7 @@ void CPUDebugger::create() {
layout.append(controlLayout, 80, 0);
setGeometry({ 0, 0, layout.minimumWidth() + 300, 220 });
setLayout(layout);
append(layout);
onClose = []() {
debugger.showCPUDebugger.setChecked(false);

View File

@ -37,7 +37,7 @@ void Debugger::create() {
layout.append(showMemoryEditor, 0, Style::CheckBoxHeight);
setGeometry({ 0, 0, 256, layout.minimumHeight() });
setLayout(layout);
append(layout);
//windows shown by default
showConsole.setChecked();

View File

@ -19,7 +19,7 @@ void SMPDebugger::create() {
layout.append(controlLayout, 80, 0);
setGeometry({ 0, 0, layout.minimumWidth() + 300, 220 });
setLayout(layout);
append(layout);
onClose = []() {
debugger.showSMPDebugger.setChecked(false);

View File

@ -30,7 +30,7 @@ void BreakpointEditor::create() {
}
setGeometry({ 0, 0, 310, layout.minimumHeight() });
setLayout(layout);
append(layout);
onClose = []() {
debugger.showBreakpointEditor.setChecked(false);

View File

@ -22,7 +22,7 @@ void MemoryEditor::create() {
layout.append(controlLayout, 80, 0);
setGeometry({ 0, 0, layout.minimumWidth() + 475, 230 });
setLayout(layout);
append(layout);
onClose = []() {
debugger.showMemoryEditor.setChecked(false);

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