Massive refactoring of xenia::ui and GL swap behavior.
This seems to dramatically improve most games (especially with --vsync=false), though it may cause swap issues with others. New code should be easier to port, and enables elemental-forms to be drawn for any emulator UI.
This commit is contained in:
@@ -10,10 +10,13 @@
|
||||
#ifndef XENIA_UI_WINDOW_H_
|
||||
#define XENIA_UI_WINDOW_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "el/element.h"
|
||||
#include "el/graphics/renderer.h"
|
||||
#include "xenia/base/delegate.h"
|
||||
#include "xenia/ui/control.h"
|
||||
#include "xenia/ui/graphics_context.h"
|
||||
#include "xenia/ui/loop.h"
|
||||
#include "xenia/ui/menu_item.h"
|
||||
#include "xenia/ui/ui_event.h"
|
||||
@@ -21,14 +24,22 @@
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
|
||||
template <typename T>
|
||||
class Window : public T {
|
||||
public:
|
||||
~Window() override = default;
|
||||
typedef void* NativeWindowHandle;
|
||||
|
||||
virtual bool Initialize() { return true; }
|
||||
class Window {
|
||||
public:
|
||||
static std::unique_ptr<Window> Create(Loop* loop, const std::wstring& title);
|
||||
|
||||
virtual ~Window();
|
||||
|
||||
Loop* loop() const { return loop_; }
|
||||
virtual NativeWindowHandle native_handle() const = 0;
|
||||
|
||||
MenuItem* main_menu() const { return main_menu_.get(); }
|
||||
void set_main_menu(std::unique_ptr<MenuItem> main_menu) {
|
||||
main_menu_ = std::move(main_menu);
|
||||
OnMainMenuChange();
|
||||
}
|
||||
|
||||
const std::wstring& title() const { return title_; }
|
||||
virtual bool set_title(const std::wstring& title) {
|
||||
@@ -39,65 +50,124 @@ class Window : public T {
|
||||
return true;
|
||||
}
|
||||
|
||||
MenuItem* menu() const { return menu_; }
|
||||
void set_menu(MenuItem* menu) {
|
||||
if (menu == menu_) {
|
||||
return;
|
||||
}
|
||||
menu_ = menu;
|
||||
OnSetMenu(menu);
|
||||
}
|
||||
|
||||
void Close() {
|
||||
auto e = UIEvent(this);
|
||||
on_closing(e);
|
||||
|
||||
OnClose();
|
||||
|
||||
e = UIEvent(this);
|
||||
on_closed(e);
|
||||
}
|
||||
|
||||
virtual bool is_fullscreen() const { return false; }
|
||||
virtual void ToggleFullscreen(bool fullscreen) {}
|
||||
|
||||
bool has_focus() const { return has_focus_; }
|
||||
virtual void set_focus(bool value) { has_focus_ = value; }
|
||||
|
||||
bool is_cursor_visible() const { return is_cursor_visible_; }
|
||||
virtual void set_cursor_visible(bool value) { is_cursor_visible_ = value; }
|
||||
|
||||
int32_t width() const { return width_; }
|
||||
int32_t height() const { return height_; }
|
||||
virtual void Resize(int32_t width, int32_t height) = 0;
|
||||
virtual void Resize(int32_t left, int32_t top, int32_t right,
|
||||
int32_t bottom) = 0;
|
||||
|
||||
GraphicsContext* context() const { return context_.get(); }
|
||||
el::graphics::Renderer* renderer() const { return renderer_.get(); }
|
||||
el::Element* root_element() const { return root_element_.get(); }
|
||||
|
||||
virtual bool Initialize() { return true; }
|
||||
void set_context(std::unique_ptr<GraphicsContext> context) {
|
||||
context_ = std::move(context);
|
||||
}
|
||||
virtual bool MakeReady();
|
||||
|
||||
bool LoadLanguage(std::string filename);
|
||||
bool LoadSkin(std::string filename);
|
||||
|
||||
void Layout();
|
||||
virtual void Invalidate();
|
||||
|
||||
virtual void Close() = 0;
|
||||
|
||||
public:
|
||||
Delegate<UIEvent> on_shown;
|
||||
Delegate<UIEvent> on_hidden;
|
||||
Delegate<UIEvent> on_closing;
|
||||
Delegate<UIEvent> on_closed;
|
||||
|
||||
Delegate<int> on_command;
|
||||
|
||||
Delegate<UIEvent> on_resize;
|
||||
Delegate<UIEvent> on_layout;
|
||||
Delegate<UIEvent> on_painting;
|
||||
Delegate<UIEvent> on_paint;
|
||||
Delegate<UIEvent> on_painted;
|
||||
|
||||
Delegate<UIEvent> on_visible;
|
||||
Delegate<UIEvent> on_hidden;
|
||||
|
||||
Delegate<UIEvent> on_got_focus;
|
||||
Delegate<UIEvent> on_lost_focus;
|
||||
|
||||
Delegate<KeyEvent> on_key_down;
|
||||
Delegate<KeyEvent> on_key_up;
|
||||
Delegate<KeyEvent> on_key_char;
|
||||
|
||||
Delegate<MouseEvent> on_mouse_down;
|
||||
Delegate<MouseEvent> on_mouse_move;
|
||||
Delegate<MouseEvent> on_mouse_up;
|
||||
Delegate<MouseEvent> on_mouse_wheel;
|
||||
|
||||
protected:
|
||||
Window(Loop* loop, const std::wstring& title)
|
||||
: T(0), loop_(loop), title_(title) {}
|
||||
Window(Loop* loop, const std::wstring& title);
|
||||
|
||||
void OnShow() {
|
||||
if (is_visible_) {
|
||||
return;
|
||||
}
|
||||
is_visible_ = true;
|
||||
auto e = UIEvent(this);
|
||||
on_shown(e);
|
||||
}
|
||||
bool InitializeElemental(Loop* loop, el::graphics::Renderer* renderer);
|
||||
|
||||
void OnHide() {
|
||||
if (!is_visible_) {
|
||||
return;
|
||||
}
|
||||
is_visible_ = false;
|
||||
auto e = UIEvent(this);
|
||||
on_hidden(e);
|
||||
}
|
||||
virtual bool OnCreate();
|
||||
virtual void OnMainMenuChange();
|
||||
virtual void OnClose();
|
||||
virtual void OnDestroy();
|
||||
|
||||
virtual void OnClose() {}
|
||||
virtual void OnResize(UIEvent& e);
|
||||
virtual void OnLayout(UIEvent& e);
|
||||
virtual void OnPaint(UIEvent& e);
|
||||
|
||||
virtual void OnSetMenu(MenuItem* menu) {}
|
||||
virtual void OnVisible(UIEvent& e);
|
||||
virtual void OnHidden(UIEvent& e);
|
||||
|
||||
virtual void OnCommand(int id) {}
|
||||
virtual void OnGotFocus(UIEvent& e);
|
||||
virtual void OnLostFocus(UIEvent& e);
|
||||
|
||||
virtual void OnKeyDown(KeyEvent& e);
|
||||
virtual void OnKeyUp(KeyEvent& e);
|
||||
virtual void OnKeyChar(KeyEvent& e);
|
||||
|
||||
virtual void OnMouseDown(MouseEvent& e);
|
||||
virtual void OnMouseMove(MouseEvent& e);
|
||||
virtual void OnMouseUp(MouseEvent& e);
|
||||
virtual void OnMouseWheel(MouseEvent& e);
|
||||
|
||||
el::ModifierKeys GetModifierKeys();
|
||||
void OnKeyPress(KeyEvent& e, bool is_down, bool is_char);
|
||||
bool CheckShortcutKey(KeyEvent& e, el::SpecialKey special_key, bool is_down);
|
||||
|
||||
Loop* loop_ = nullptr;
|
||||
std::unique_ptr<MenuItem> main_menu_;
|
||||
std::wstring title_;
|
||||
MenuItem* menu_ = nullptr;
|
||||
int32_t width_ = 0;
|
||||
int32_t height_ = 0;
|
||||
bool has_focus_ = true;
|
||||
bool is_cursor_visible_ = true;
|
||||
|
||||
std::unique_ptr<GraphicsContext> context_;
|
||||
std::unique_ptr<el::graphics::Renderer> renderer_;
|
||||
std::unique_ptr<el::Element> root_element_;
|
||||
|
||||
uint32_t frame_count_ = 0;
|
||||
uint32_t fps_ = 0;
|
||||
uint64_t fps_update_time_ = 0;
|
||||
uint64_t fps_frame_count_ = 0;
|
||||
|
||||
bool modifier_shift_pressed_ = false;
|
||||
bool modifier_cntrl_pressed_ = false;
|
||||
bool modifier_alt_pressed_ = false;
|
||||
bool modifier_super_pressed_ = false;
|
||||
uint64_t last_click_time_ = 0;
|
||||
int last_click_x_ = 0;
|
||||
int last_click_y_ = 0;
|
||||
int last_click_counter_ = 0;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
Reference in New Issue
Block a user