diff --git a/src/xenia/debug/ui/main_window.cc b/src/xenia/debug/ui/main_window.cc index 1e4890a01..85e571f2a 100644 --- a/src/xenia/debug/ui/main_window.cc +++ b/src/xenia/debug/ui/main_window.cc @@ -9,6 +9,8 @@ #include "xenia/debug/ui/main_window.h" +#include "el/animation_manager.h" +#include "el/util/debug.h" #include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/platform.h" @@ -96,9 +98,60 @@ bool MainWindow::Initialize() { Resize(1440, 1200); + BuildUI(); + return true; } +void MainWindow::BuildUI() { + using namespace el::dsl; + el::AnimationBlocker animation_blocker; + + auto root_element = control_->root_element(); + window_ = std::make_unique(); + window_->set_settings(el::WindowSettings::kFullScreen); + root_element->AddChild(window_.get()); + + auto root_node = + LayoutBoxNode() + .gravity(Gravity::kAll) + .distribution(LayoutDistribution::kAvailable) + .axis(Axis::kY) + .child(LayoutBoxNode() + .id("toolbar_box") + .gravity(Gravity::kTop | Gravity::kLeftRight) + .distribution(LayoutDistribution::kAvailable) + .child(LabelNode("toolbar"))) + .child( + SplitContainerNode() + .id("split_container") + .gravity(Gravity::kAll) + .axis(Axis::kX) + .fixed_pane(FixedPane::kSecond) + .min(128) + .value(250) + .pane(TabContainerNode() + .id("tab_container") + .gravity(Gravity::kAll) + .align(Align::kTop)) + .pane(LayoutBoxNode().id("log_box").gravity(Gravity::kAll))); + + window_->LoadNodeTree(root_node); + window_->GetElementsById({ + {TBIDC("split_container"), &ui_.split_container}, + {TBIDC("toolbar_box"), &ui_.toolbar_box}, + {TBIDC("tab_container"), &ui_.tab_container}, + }); + + ui_.tab_container->tab_bar()->LoadNodeTree(ButtonNode(cpu_view_.name())); + ui_.tab_container->content_root()->AddChild(cpu_view_.BuildUI()); + + ui_.tab_container->tab_bar()->LoadNodeTree(ButtonNode(gpu_view_.name())); + ui_.tab_container->content_root()->AddChild(gpu_view_.BuildUI()); + + el::util::ShowDebugInfoSettingsWindow(root_element); +} + void MainWindow::OnClose() { app_->Quit(); } void MainWindow::OnCommand(int id) { diff --git a/src/xenia/debug/ui/main_window.h b/src/xenia/debug/ui/main_window.h index 2aded1926..5c17c168d 100644 --- a/src/xenia/debug/ui/main_window.h +++ b/src/xenia/debug/ui/main_window.h @@ -12,7 +12,10 @@ #include +#include "el/elements.h" #include "xenia/debug/ui/application.h" +#include "xenia/debug/ui/views/cpu/cpu_view.h" +#include "xenia/debug/ui/views/gpu/gpu_view.h" #include "xenia/ui/elemental_control.h" #include "xenia/ui/platform.h" #include "xenia/ui/window.h" @@ -30,13 +33,26 @@ class MainWindow : public xe::ui::PlatformWindow { bool Initialize(); + // void NavigateToCpuView(uint32_t address); + private: + void BuildUI(); + void OnClose() override; void OnCommand(int id) override; Application* app_ = nullptr; xe::ui::PlatformMenu main_menu_; std::unique_ptr control_; + + std::unique_ptr window_; + struct { + el::SplitContainer* split_container; + el::LayoutBox* toolbar_box; + el::TabContainer* tab_container; + } ui_ = {0}; + views::cpu::CpuView cpu_view_; + views::gpu::GpuView gpu_view_; }; } // namespace ui diff --git a/src/xenia/debug/ui/view.h b/src/xenia/debug/ui/view.h new file mode 100644 index 000000000..fb36ae6d3 --- /dev/null +++ b/src/xenia/debug/ui/view.h @@ -0,0 +1,42 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_DEBUG_UI_VIEW_H_ +#define XENIA_DEBUG_UI_VIEW_H_ + +#include +#include + +#include "el/elements.h" + +namespace xe { +namespace debug { +namespace ui { + +class View { + public: + virtual ~View() = default; + + std::string name() const { return name_; } + el::LayoutBox* root_element() { return &root_element_; } + + virtual el::Element* BuildUI() = 0; + + protected: + View(std::string name) : name_(name) {} + + std::string name_; + el::LayoutBox root_element_; +}; + +} // namespace ui +} // namespace debug +} // namespace xe + +#endif // XENIA_DEBUG_UI_VIEW_H_ diff --git a/src/xenia/debug/ui/views/cpu/cpu_view.cc b/src/xenia/debug/ui/views/cpu/cpu_view.cc new file mode 100644 index 000000000..88d9ded07 --- /dev/null +++ b/src/xenia/debug/ui/views/cpu/cpu_view.cc @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "el/animation_manager.h" +#include "xenia/debug/ui/views/cpu/cpu_view.h" + +namespace xe { +namespace debug { +namespace ui { +namespace views { +namespace cpu { + +CpuView::CpuView() : View("CPU") {} + +CpuView::~CpuView() = default; + +el::Element* CpuView::BuildUI() { + using namespace el::dsl; + el::AnimationBlocker animation_blocker; + + auto functions_node = + LayoutBoxNode() + .gravity(Gravity::kAll) + .distribution(LayoutDistribution::kAvailable) + .axis(Axis::kY) + .child( + LayoutBoxNode() + .gravity(Gravity::kTop | Gravity::kLeftRight) + .distribution(LayoutDistribution::kAvailable) + .axis(Axis::kX) + .skin("button_group") + .child(ButtonNode("?")) + .child( + DropDownButtonNode().item("Module").item("Module").item( + "Module"))) + .child(ListBoxNode() + .gravity(Gravity::kAll) + .item("fn") + .item("fn") + .item("fn") + .item("fn")) + .child(LayoutBoxNode() + .gravity(Gravity::kBottom | Gravity::kLeftRight) + .distribution(LayoutDistribution::kAvailable) + .axis(Axis::kX) + .child(TextBoxNode() + .type(EditType::kSearch) + .placeholder("Filter"))); + + auto source_code_node = + LayoutBoxNode() + .gravity(Gravity::kAll) + .distribution(LayoutDistribution::kAvailable) + .axis(Axis::kY) + .child( + LayoutBoxNode() + .gravity(Gravity::kTop | Gravity::kLeftRight) + .distribution(LayoutDistribution::kGravity) + .distribution_position(LayoutDistributionPosition::kLeftTop) + .axis(Axis::kX) + .child(ButtonNode("A"))) + .child(TextBoxNode("source!") + .gravity(Gravity::kAll) + .is_multiline(true) + .is_read_only(true)); + + auto register_list_node = ListBoxNode() + .gravity(Gravity::kAll) + .item("A") + .item("A") + .item("A") + .item("A"); + auto source_registers_node = + TabContainerNode() + .gravity(Gravity::kAll) + .tab(ButtonNode("GPR"), CloneNode(register_list_node)) + .tab(ButtonNode("FPR"), CloneNode(register_list_node)) + .tab(ButtonNode("VMX"), CloneNode(register_list_node)); + + auto source_tools_node = + TabContainerNode() + .gravity(Gravity::kAll) + .align(Align::kLeft) + .tab(ButtonNode("Stack"), LabelNode("STACK")) + .tab(ButtonNode("BPs"), LabelNode("BREAKPOINTS")); + + auto source_pane_node = + LayoutBoxNode() + .gravity(Gravity::kAll) + .distribution(LayoutDistribution::kAvailable) + .axis(Axis::kY) + .child( + LayoutBoxNode() + .id("source_toolbar") + .gravity(Gravity::kTop | Gravity::kLeftRight) + .distribution(LayoutDistribution::kGravity) + .distribution_position(LayoutDistributionPosition::kLeftTop) + .axis(Axis::kX) + .child(ButtonNode("button")) + .child(ButtonNode("button")) + .child(ButtonNode("button"))) + .child(LayoutBoxNode() + .gravity(Gravity::kAll) + .distribution(LayoutDistribution::kAvailable) + .child(SplitContainerNode() + .gravity(Gravity::kAll) + .axis(Axis::kX) + .fixed_pane(FixedPane::kSecond) + .value(128) + .pane(SplitContainerNode() + .gravity(Gravity::kAll) + .axis(Axis::kY) + .fixed_pane(FixedPane::kSecond) + .value(180) + .pane(source_code_node) + .pane(source_registers_node)) + .pane(source_tools_node))); + + auto memory_pane_node = LabelNode("MEMORY"); + + auto node = SplitContainerNode() + .gravity(Gravity::kAll) + .axis(Axis::kY) + .min(128) + .max(512) + .value(128) + .pane(functions_node) + .pane(SplitContainerNode() + .gravity(Gravity::kAll) + .axis(Axis::kY) + .value(800) + .pane(source_pane_node) + .pane(memory_pane_node)); + + root_element_.set_gravity(Gravity::kAll); + root_element_.set_layout_distribution(LayoutDistribution::kAvailable); + root_element_.LoadNodeTree(node); + root_element_.GetElementsById({ + // + }); + return &root_element_; +} + +} // namespace cpu +} // namespace views +} // namespace ui +} // namespace debug +} // namespace xe diff --git a/src/xenia/debug/ui/views/cpu/cpu_view.h b/src/xenia/debug/ui/views/cpu/cpu_view.h new file mode 100644 index 000000000..1962eee77 --- /dev/null +++ b/src/xenia/debug/ui/views/cpu/cpu_view.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_DEBUG_UI_VIEWS_CPU_CPU_VIEW_H_ +#define XENIA_DEBUG_UI_VIEWS_CPU_CPU_VIEW_H_ + +#include +#include + +#include "xenia/debug/ui/view.h" + +namespace xe { +namespace debug { +namespace ui { +namespace views { +namespace cpu { + +class CpuView : public View { + public: + CpuView(); + ~CpuView() override; + + el::Element* BuildUI() override; + + protected: +}; + +} // namespace cpu +} // namespace views +} // namespace ui +} // namespace debug +} // namespace xe + +#endif // XENIA_DEBUG_UI_VIEWS_CPU_CPU_VIEW_H_ diff --git a/src/xenia/debug/ui/views/gpu/gpu_view.cc b/src/xenia/debug/ui/views/gpu/gpu_view.cc new file mode 100644 index 000000000..f91dbbbdb --- /dev/null +++ b/src/xenia/debug/ui/views/gpu/gpu_view.cc @@ -0,0 +1,42 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "el/animation_manager.h" +#include "xenia/debug/ui/views/gpu/gpu_view.h" + +namespace xe { +namespace debug { +namespace ui { +namespace views { +namespace gpu { + +GpuView::GpuView() : View("GPU") {} + +GpuView::~GpuView() = default; + +el::Element* GpuView::BuildUI() { + using namespace el::dsl; + el::AnimationBlocker animation_blocker; + + auto node = LabelNode("TODO"); + + root_element_.set_gravity(Gravity::kAll); + root_element_.set_layout_distribution(LayoutDistribution::kAvailable); + root_element_.LoadNodeTree(node); + root_element_.GetElementsById({ + // + }); + return &root_element_; +} + +} // namespace gpu +} // namespace views +} // namespace ui +} // namespace debug +} // namespace xe diff --git a/src/xenia/debug/ui/views/gpu/gpu_view.h b/src/xenia/debug/ui/views/gpu/gpu_view.h new file mode 100644 index 000000000..d53263a92 --- /dev/null +++ b/src/xenia/debug/ui/views/gpu/gpu_view.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_DEBUG_UI_VIEWS_GPU_GPU_VIEW_H_ +#define XENIA_DEBUG_UI_VIEWS_GPU_GPU_VIEW_H_ + +#include +#include + +#include "xenia/debug/ui/view.h" + +namespace xe { +namespace debug { +namespace ui { +namespace views { +namespace gpu { + +class GpuView : public View { + public: + GpuView(); + ~GpuView() override; + + el::Element* BuildUI() override; + + protected: +}; + +} // namespace gpu +} // namespace views +} // namespace ui +} // namespace debug +} // namespace xe + +#endif // XENIA_DEBUG_UI_VIEWS_GPU_GPU_VIEW_H_ diff --git a/src/xenia/debug/ui/xe-debug-ui.vcxproj b/src/xenia/debug/ui/xe-debug-ui.vcxproj index 85779cd4e..632353b68 100644 --- a/src/xenia/debug/ui/xe-debug-ui.vcxproj +++ b/src/xenia/debug/ui/xe-debug-ui.vcxproj @@ -77,11 +77,16 @@ + + + + + diff --git a/src/xenia/debug/ui/xe-debug-ui.vcxproj.filters b/src/xenia/debug/ui/xe-debug-ui.vcxproj.filters index bb91f41c8..971c75985 100644 --- a/src/xenia/debug/ui/xe-debug-ui.vcxproj.filters +++ b/src/xenia/debug/ui/xe-debug-ui.vcxproj.filters @@ -19,6 +19,15 @@ {f0ac4999-4700-4b41-b73d-c6dc8b23c5e6} + + {5601b0a2-a720-4d89-9fca-df1637fce0b1} + + + {5b186e9a-1fef-42f5-b06b-2ac0b10a8a5b} + + + {c66e9a6b-0947-4610-9b2b-29db99c08e91} + @@ -30,6 +39,15 @@ src\xenia\debug\ui + + src\xenia\debug\ui + + + src\xenia\debug\ui\views\gpu + + + src\xenia\debug\ui\views\cpu + @@ -44,6 +62,12 @@ src\xenia\debug\ui + + src\xenia\debug\ui\views\gpu + + + src\xenia\debug\ui\views\cpu + diff --git a/src/xenia/ui/elemental_control.cc b/src/xenia/ui/elemental_control.cc index bfa4688b9..5a3251876 100644 --- a/src/xenia/ui/elemental_control.cc +++ b/src/xenia/ui/elemental_control.cc @@ -141,15 +141,6 @@ bool ElementalControl::Create() { root_element_->set_background_skin(TBIDC("background")); root_element_->set_rect({0, 0, 1000, 1000}); - // Block animations during init. - el::AnimationBlocker anim_blocker; - - // TODO(benvanik): dummy UI. - auto message_window = new el::MessageWindow(root_element(), TBIDC("")); - message_window->Show("Title", "Hello!"); - - el::util::ShowDebugInfoSettingsWindow(root_element()); - return true; } @@ -257,106 +248,106 @@ void ElementalControl::OnKeyPress(KeyEvent& e, bool is_down, bool is_char) { auto special_key = el::SpecialKey::kUndefined; if (!is_char) { switch (e.key_code()) { - case 38: - special_key = el::SpecialKey::kUp; - break; - case 39: - special_key = el::SpecialKey::kRight; - break; - case 40: - special_key = el::SpecialKey::kDown; - break; - case 37: - special_key = el::SpecialKey::kLeft; - break; - case 112: - special_key = el::SpecialKey::kF1; - break; - case 113: - special_key = el::SpecialKey::kF2; - break; - case 114: - special_key = el::SpecialKey::kF3; - break; - case 115: - special_key = el::SpecialKey::kF4; - break; - case 116: - special_key = el::SpecialKey::kF5; - break; - case 117: - special_key = el::SpecialKey::kF6; - break; - case 118: - special_key = el::SpecialKey::kF7; - break; - case 119: - special_key = el::SpecialKey::kF8; - break; - case 120: - special_key = el::SpecialKey::kF9; - break; - case 121: - special_key = el::SpecialKey::kF10; - break; - case 122: - special_key = el::SpecialKey::kF11; - break; - case 123: - special_key = el::SpecialKey::kF12; - break; - case 33: - special_key = el::SpecialKey::kPageUp; - break; - case 34: - special_key = el::SpecialKey::kPageDown; - break; - case 36: - special_key = el::SpecialKey::kHome; - break; - case 35: - special_key = el::SpecialKey::kEnd; - break; - case 45: - special_key = el::SpecialKey::kInsert; - break; - case 9: - special_key = el::SpecialKey::kTab; - break; - case 46: - special_key = el::SpecialKey::kDelete; - break; - case 8: - special_key = el::SpecialKey::kBackspace; - break; - case 13: - special_key = el::SpecialKey::kEnter; - break; - case 27: - special_key = el::SpecialKey::kEsc; - break; - case 93: - if (!is_down && el::Element::focused_element) { - el::Event ev(el::EventType::kContextMenu); - ev.modifierkeys = GetModifierKeys(); - el::Element::focused_element->InvokeEvent(ev); - e.set_handled(true); - return; - } - break; - case 16: - modifier_shift_pressed_ = is_down; - break; - case 17: - modifier_cntrl_pressed_ = is_down; - break; - // case xx: - // // alt ?? - // modifier_alt_pressed_ = is_down; - // break; - case 91: - modifier_super_pressed_ = is_down; - break; + case 38: + special_key = el::SpecialKey::kUp; + break; + case 39: + special_key = el::SpecialKey::kRight; + break; + case 40: + special_key = el::SpecialKey::kDown; + break; + case 37: + special_key = el::SpecialKey::kLeft; + break; + case 112: + special_key = el::SpecialKey::kF1; + break; + case 113: + special_key = el::SpecialKey::kF2; + break; + case 114: + special_key = el::SpecialKey::kF3; + break; + case 115: + special_key = el::SpecialKey::kF4; + break; + case 116: + special_key = el::SpecialKey::kF5; + break; + case 117: + special_key = el::SpecialKey::kF6; + break; + case 118: + special_key = el::SpecialKey::kF7; + break; + case 119: + special_key = el::SpecialKey::kF8; + break; + case 120: + special_key = el::SpecialKey::kF9; + break; + case 121: + special_key = el::SpecialKey::kF10; + break; + case 122: + special_key = el::SpecialKey::kF11; + break; + case 123: + special_key = el::SpecialKey::kF12; + break; + case 33: + special_key = el::SpecialKey::kPageUp; + break; + case 34: + special_key = el::SpecialKey::kPageDown; + break; + case 36: + special_key = el::SpecialKey::kHome; + break; + case 35: + special_key = el::SpecialKey::kEnd; + break; + case 45: + special_key = el::SpecialKey::kInsert; + break; + case 9: + special_key = el::SpecialKey::kTab; + break; + case 46: + special_key = el::SpecialKey::kDelete; + break; + case 8: + special_key = el::SpecialKey::kBackspace; + break; + case 13: + special_key = el::SpecialKey::kEnter; + break; + case 27: + special_key = el::SpecialKey::kEsc; + break; + case 93: + if (!is_down && el::Element::focused_element) { + el::Event ev(el::EventType::kContextMenu); + ev.modifierkeys = GetModifierKeys(); + el::Element::focused_element->InvokeEvent(ev); + e.set_handled(true); + return; + } + break; + case 16: + modifier_shift_pressed_ = is_down; + break; + case 17: + modifier_cntrl_pressed_ = is_down; + break; + // case xx: + // // alt ?? + // modifier_alt_pressed_ = is_down; + // break; + case 91: + modifier_super_pressed_ = is_down; + break; } } diff --git a/third_party/elemental-forms b/third_party/elemental-forms index a03a30899..a95e9a198 160000 --- a/third_party/elemental-forms +++ b/third_party/elemental-forms @@ -1 +1 @@ -Subproject commit a03a3089954862677e2d30f85824b978a45eba22 +Subproject commit a95e9a1984029382ae8e35260725d5697a702f8b