From dec78acc19d762d294ec11cc49839d6c27f4f242 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 26 Dec 2022 08:41:01 +0200 Subject: [PATCH] Very simple GUI stub --- GUI/GUITools.cpp | 52 ++++ GUI/GraphicalUserInterface.cpp | 334 ++++++++++++++++++++++++++ GUI/Widgets.cpp | 31 +++ GUI/Window.cpp | 420 +++++++++++++++++++++++++++++++++ include/gui.hpp | 202 ++++++++++++++++ 5 files changed, 1039 insertions(+) create mode 100644 GUI/GUITools.cpp create mode 100644 GUI/GraphicalUserInterface.cpp create mode 100644 GUI/Widgets.cpp create mode 100644 GUI/Window.cpp create mode 100644 include/gui.hpp diff --git a/GUI/GUITools.cpp b/GUI/GUITools.cpp new file mode 100644 index 0000000..3524965 --- /dev/null +++ b/GUI/GUITools.cpp @@ -0,0 +1,52 @@ +#include + +#include "../kernel.h" + +namespace GraphicalUserInterface +{ + void PutRect(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color) + { + for (uint32_t i = 0; i < Width; i++) + for (uint32_t j = 0; j < Height; j++) + Display->SetPixel(X + i, Y + j, Color, 200); + } + + void PutBorder(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color) + { + for (uint32_t i = 0; i < Width; i++) + { + Display->SetPixel(X + i, Y, Color, 200); + Display->SetPixel(X + i, Y + Height - 1, Color, 200); + } + for (uint32_t i = 0; i < Height; i++) + { + Display->SetPixel(X, Y + i, Color, 200); + Display->SetPixel(X + Width - 1, Y + i, Color, 200); + } + } + + void PutBorderWithShadow(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color) + { + uint32_t ShadowColor = (Color ? (Color / 2) : 0x000000); + for (uint32_t i = 0; i < Width; i++) + { + Display->SetPixel(X + i, Y, Color, 200); + Display->SetPixel(X + i, Y + Height - 1, Color, 200); + } + for (uint32_t i = 0; i < Height; i++) + { + Display->SetPixel(X, Y + i, Color, 200); + Display->SetPixel(X + Width - 1, Y + i, Color, 200); + } + for (uint32_t i = 0; i < Width; i++) + { + Display->SetPixel(X + i, Y + 1, ShadowColor, 200); + Display->SetPixel(X + i, Y + Height - 2, ShadowColor, 200); + } + for (uint32_t i = 0; i < Height; i++) + { + Display->SetPixel(X + 1, Y + i, ShadowColor, 200); + Display->SetPixel(X + Width - 2, Y + i, ShadowColor, 200); + } + } +} diff --git a/GUI/GraphicalUserInterface.cpp b/GUI/GraphicalUserInterface.cpp new file mode 100644 index 0000000..c2f0743 --- /dev/null +++ b/GUI/GraphicalUserInterface.cpp @@ -0,0 +1,334 @@ +#include +#include +#include +#include + +#include "../kernel.h" +#include "../DAPI.hpp" +#include "../Fex.hpp" + +namespace GraphicalUserInterface +{ + char CursorArrow[] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 12x19 + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, // + 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, // + 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, // + 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, // + 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, // + 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, // + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, // + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, // + 1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0, 0, // + 1, 2, 2, 1, 0, 1, 2, 2, 1, 0, 0, 0, // + 1, 2, 1, 0, 0, 1, 2, 2, 1, 0, 0, 0, // + 1, 1, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, // + 1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, // + }; + + char CursorHand[] = { + 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x24 + 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 0, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 0, // + 0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, // + 1, 1, 1, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, // + 1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, // + 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, // + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, // + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, // + 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, // + 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char CursorWait[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 13x22 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, // + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // + 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, // + 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, // + 0, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 0, // + 0, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 0, // + 0, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 0, // + 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 0, 0, // + 0, 0, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 0, // + 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, // + 0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0, 0, // + 0, 0, 1, 1, 2, 2, 1, 2, 2, 1, 1, 0, 0, // + 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, // + 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 0, // + 0, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 0, // + 0, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 0, // + 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, // + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, // + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // + }; + + char CursorIBeam[] = { + 1, 1, 1, 0, 1, 1, 1, // 7x17 + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 1, 0, 0, 0, // + 1, 1, 1, 0, 1, 1, 1, // + }; + + char CursorResizeAll[] ={ + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, // 23x23 + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,1,1,1,1,2,1,1,1,1,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,0,0,0,0, // + 0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0, // + 0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0, // + 0,1,2,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,0, // + 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, // + 0,1,2,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,0, // + 0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0, // + 0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0, // + 0,0,0,0,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, // + }; + + void GUI::PaintDesktop() + { + PutRect(0, 0, Display->GetBuffer(200)->Width, Display->GetBuffer(200)->Height, 0x282828); + } + + void GUI::PaintWindows() + { + foreach (auto wnd in this->Windows) + wnd->Paint(); + } + + void GUI::PaintCursor() + { + KernelCallback callback; + if (DriverManager->GetDrivers().size() > 0) + { + foreach (auto Driver in DriverManager->GetDrivers()) + { + if (((FexExtended *)((uintptr_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Input) + { + memset(&callback, 0, sizeof(KernelCallback)); + callback.Reason = FetchReason; + DriverManager->IOCB(Driver->DriverUID, (void *)&callback); + // TODO: I think I should check somehow what driver is the one that is mouse and not keyboard + Mouse.X = (callback.InputCallback.Mouse.X * Display->GetBuffer(200)->Width) / 0xFFFF; // VMWARE mouse + Mouse.Y = (callback.InputCallback.Mouse.Y * Display->GetBuffer(200)->Height) / 0xFFFF; // VMWARE mouse + Mouse.Z = (callback.InputCallback.Mouse.Z); + Mouse.Left = callback.InputCallback.Mouse.Buttons.Left; + Mouse.Right = callback.InputCallback.Mouse.Buttons.Right; + Mouse.Middle = callback.InputCallback.Mouse.Buttons.Middle; + break; + } + } + } + + uint32_t CursorColorInner = 0xFFFFFFFF; + uint32_t CursorColorOuter = 0x00000000; + + switch (this->Cursor) + { + case CursorType::Visible: + { + CursorVisible = true; + break; + } + case CursorType::Hidden: + { + CursorVisible = false; + break; + } + default: + fixme("Unknown cursor type %d", this->Cursor); + [[fallthrough]]; + case CursorType::Arrow: + { + if (CursorVisible) + for (int i = 0; i < 19; i++) + { + for (int j = 0; j < 12; j++) + { + if (CursorArrow[i * 12 + j] == 1) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); + } + else if (CursorArrow[i * 12 + j] == 2) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); + } + } + } + break; + } + case CursorType::Hand: + { + if (CursorVisible) + for (int i = 0; i < 24; i++) + { + for (int j = 0; j < 17; j++) + { + if (CursorHand[i * 17 + j] == 1) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); + } + else if (CursorHand[i * 17 + j] == 2) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); + } + } + } + break; + } + case CursorType::Wait: + { + if (CursorVisible) + for (int i = 0; i < 22; i++) + { + for (int j = 0; j < 13; j++) + { + if (CursorWait[i * 13 + j] == 1) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); + } + else if (CursorWait[i * 13 + j] == 2) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); + } + } + } + break; + } + case CursorType::IBeam: + { + if (CursorVisible) + for (int i = 0; i < 22; i++) + { + for (int j = 0; j < 13; j++) + { + if (CursorIBeam[i * 13 + j] == 1) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); + } + else if (CursorIBeam[i * 13 + j] == 2) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); + } + } + } + break; + } + case CursorType::ResizeAll: + { + if (CursorVisible) + for (int i = 0; i < 23; i++) + { + for (int j = 0; j < 23; j++) + { + if (CursorResizeAll[i * 23 + j] == 1) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); + } + else if (CursorResizeAll[i * 23 + j] == 2) + { + Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); + } + } + } + break; + } + } + + foreach (auto wnd in this->Windows) + { + Event ev; + ev.Type = EventType::MouseEvent; + ev.Mouse.X = Mouse.X; + ev.Mouse.Y = Mouse.Y; + ev.Mouse.Z = Mouse.Z; + ev.Mouse.Left = Mouse.Left; + ev.Mouse.Right = Mouse.Right; + ev.Mouse.Middle = Mouse.Middle; + ev.LastMouse.X = LastMouse.X; + ev.LastMouse.Y = LastMouse.Y; + ev.LastMouse.Z = LastMouse.Z; + ev.LastMouse.Left = LastMouse.Left; + ev.LastMouse.Right = LastMouse.Right; + ev.LastMouse.Middle = LastMouse.Middle; + wnd->HandleEvent(&ev); + } + + LastMouse = Mouse; + } + + void GUI::Loop() + { + while (IsRunning) + { + PaintDesktop(); + PaintWindows(); + PaintCursor(); + Display->SetBuffer(200); + } + } + + void GUI::AddWindow(Window *window) + { + this->Windows.push_back(window); + } + + GUI::GUI() + { + this->mem = new Memory::MemMgr; + Display->CreateBuffer(0, 0, 200); + this->IsRunning = true; + } + + GUI::~GUI() + { + delete this->mem; + Display->DeleteBuffer(200); + for (size_t i = 0; i < this->Windows.size(); i++) + this->Windows.remove(i); + } +} diff --git a/GUI/Widgets.cpp b/GUI/Widgets.cpp new file mode 100644 index 0000000..0da32bb --- /dev/null +++ b/GUI/Widgets.cpp @@ -0,0 +1,31 @@ +#include + +#include +#include +#include +#include + +#include "../kernel.h" +#include "../DAPI.hpp" +#include "../Fex.hpp" + +namespace GraphicalUserInterface +{ + void Widget::Paint() + { + } + + void Widget::HandleEvent(Event *e) + { + } + + Widget::Widget(void *ParentWindow) + { + this->mem = new Memory::MemMgr; + } + + Widget::~Widget() + { + delete this->mem; + } +} diff --git a/GUI/Window.cpp b/GUI/Window.cpp new file mode 100644 index 0000000..9b68020 --- /dev/null +++ b/GUI/Window.cpp @@ -0,0 +1,420 @@ +#include + +#include +#include +#include +#include + +#include "../kernel.h" +#include "../DAPI.hpp" +#include "../Fex.hpp" + +namespace GraphicalUserInterface +{ + char CloseButton[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char MinimizeButton[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char MaximizeButtonNormal[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char MaximizeButtonMaximized[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char ResizeHint[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + uint32_t CloseButtonFade[] = { + 0x404040, + 0x770000, + 0x990000, + 0xBB0000, + 0xDD0000, + 0xFF0000, + }; + + uint32_t MaximizeMinimizeButtonFade[] = { + 0x404040, + 0x454545, + 0x505050, + 0x5F5F5F, + }; + + void Window::Paint() + { + // Window background + PutRect(this->Left, this->Top + 20, this->Width, this->Height, 0x121212); + // Title bar + PutRect(this->Left, this->Top, this->Width, 20, 0x404040); + // Title bar buttons (close, minimize, maximize) on the right + static int CloseButtonIteration = 0; + static int MaximizeButtonIteration = 0; + static int MinimizeButtonIteration = 0; + if (CloseButtonFocused) + { + PutRect(this->Left + this->Width - 20, this->Top, 20, 20, CloseButtonFade[CloseButtonIteration]); + if (CloseButtonIteration < 5) + CloseButtonIteration++; + } + else + { + PutRect(this->Left + this->Width - 20, this->Top, 20, 20, CloseButtonFade[CloseButtonIteration]); + if (CloseButtonIteration > 0) + CloseButtonIteration--; + } + + if (MaximizeButtonFocused) + { + PutRect(this->Left + this->Width - 40, this->Top, 20, 20, MaximizeMinimizeButtonFade[MaximizeButtonIteration]); + if (MaximizeButtonIteration < 3) + MaximizeButtonIteration++; + } + else + { + PutRect(this->Left + this->Width - 40, this->Top, 20, 20, MaximizeMinimizeButtonFade[MaximizeButtonIteration]); + if (MaximizeButtonIteration > 0) + MaximizeButtonIteration--; + } + + if (MinimizeButtonFocused) + { + PutRect(this->Left + this->Width - 60, this->Top, 20, 20, MaximizeMinimizeButtonFade[MinimizeButtonIteration]); + if (MinimizeButtonIteration < 3) + MinimizeButtonIteration++; + } + else + { + PutRect(this->Left + this->Width - 60, this->Top, 20, 20, MaximizeMinimizeButtonFade[MinimizeButtonIteration]); + if (MinimizeButtonIteration > 0) + MinimizeButtonIteration--; + } + + // Title bar icons (close, minimize, maximize) on the right + for (int i = 0; i < 20; i++) + { + for (int j = 0; j < 20; j++) + { + if (CloseButton[i * 20 + j] == 1) + { + Display->SetPixel(this->Left + this->Width - 20 + j, this->Top + i, 0xFFFFFF, 200); + } + if ((MaximizeButtonMaximized[i * 20 + j] == 1) && !this->Maximized) + { + Display->SetPixel(this->Left + this->Width - 40 + j, this->Top + i, 0xFFFFFF, 200); + } + else if ((MaximizeButtonNormal[i * 20 + j] == 1) && this->Maximized) + { + Display->SetPixel(this->Left + this->Width - 40 + j, this->Top + i, 0xFFFFFF, 200); + } + if (MinimizeButton[i * 20 + j] == 1) + { + Display->SetPixel(this->Left + this->Width - 60 + j, this->Top + i, 0xFFFFFF, 200); + } + } + } + + // Resize hint + for (int i = 0; i < 20; i++) + { + for (int j = 0; j < 20; j++) + { + if (ResizeHint[i * 20 + j] == 1) + { + Display->SetPixel(this->Left + this->Width - 20 + j, this->Top + this->Height + i, 0xFFFFFF, 200); + } + } + } + + // Title bar border + PutBorder(this->Left, this->Top, this->Width, 20, 0x000000); + // Window border + PutBorder(this->Left, this->Top + 20, this->Width, this->Height, 0x000000); + // Title bar text + Display->DrawString(this->Title, this->Left + 5, this->Top + 5, 200); + + // Window content + foreach (auto var in this->Widgets) + { + var->Paint(); + } + + if (!this->Maximized) + { + char buf[100]; + sprintf_(buf, "Left:\eAA11FF%ld\eFFFFFF Top:\eAA11FF%ld\eFFFFFF W:\eAA11FF%ld\eFFFFFF H:\eAA11FF%ld\eFFFFFF", this->Left, this->Top, this->Width, this->Height); + Display->DrawString(buf, this->Left + 20, this->Top + 25, 200); + } + } + + void Window::Close() + { + fixme("Window::Close() not implemented"); + } + + void Window::Maximize() + { + if (!Maximized) + { + this->Last_Left = this->Left; + this->Last_Top = this->Top; + this->Last_Width = this->Width; + this->Last_Height = this->Height; + this->Left = 0; + this->Top = 0; + this->Width = Display->GetBuffer(200)->Width; + this->Height = Display->GetBuffer(200)->Height; + Maximized = true; + } + else + { + this->Left = this->Last_Left; + this->Top = this->Last_Top; + this->Width = this->Last_Width; + this->Height = this->Last_Height; + Maximized = false; + } + } + + void Window::Minimize() + { + fixme("Window::Minimize() not implemented"); + } + + void Window::HandleEvent(Event *e) + { + if (e->Type == EventType::MouseEvent) + { + // close button + if (!WindowDragging && + e->Mouse.X >= this->Left + this->Width - 20 && + e->Mouse.X <= this->Left + this->Width && + e->Mouse.Y >= this->Top && + e->Mouse.Y <= this->Top + 20) + { + if (e->Mouse.Left) + { + this->Close(); + } + CloseButtonFocused = true; + } + else + CloseButtonFocused = false; + + // maximize button + if (!WindowDragging && + e->Mouse.X >= this->Left + this->Width - 40 && + e->Mouse.X <= this->Left + this->Width - 20 && + e->Mouse.Y >= this->Top && + e->Mouse.Y <= this->Top + 20) + { + if (e->Mouse.Left) + { + this->Maximize(); + } + MaximizeButtonFocused = true; + } + else + MaximizeButtonFocused = false; + + // minimize button + if (!WindowDragging && + e->Mouse.X >= this->Left + this->Width - 60 && + e->Mouse.X <= this->Left + this->Width - 40 && + e->Mouse.Y >= this->Top && + e->Mouse.Y <= this->Top + 20) + { + if (e->Mouse.Left) + { + this->Minimize(); + } + MinimizeButtonFocused = true; + } + else + MinimizeButtonFocused = false; + + // window dragging + if (e->Mouse.X >= this->Left && + e->Mouse.X <= this->Left + this->Width && + e->Mouse.Y >= this->Top && + e->Mouse.Y <= this->Top + 20) + { + if (e->Mouse.Left && + !Maximized) + { + long X = (long)this->Left + (long)e->Mouse.X - (long)e->LastMouse.X; + long Y = (long)this->Top + (long)e->Mouse.Y - (long)e->LastMouse.Y; + + if (X < 0) + X = 0; + else if (X + this->Width > Display->GetBuffer(200)->Width) + X = Display->GetBuffer(200)->Width - this->Width; + + if (Y < 0) + Y = 0; + else if (Y + this->Height + 20 > Display->GetBuffer(200)->Height) + Y = Display->GetBuffer(200)->Height - this->Height - 20; + + this->Left = X; + this->Top = Y; + WindowDragging = true; + } + else + WindowDragging = false; + } + + // resize + if (!WindowDragging && + e->Mouse.X >= this->Left + this->Width - 20 && + e->Mouse.X <= this->Left + this->Width && + e->Mouse.Y >= this->Top + this->Height && + e->Mouse.Y <= this->Top + this->Height + 20) + { + if (e->Mouse.Left) + { + long X = this->Width + (long)e->Mouse.X - (long)e->LastMouse.X; + long Y = this->Height + (long)e->Mouse.Y - (long)e->LastMouse.Y; + if (X < 250) + X = 250; + if (Y < 150) + Y = 150; + this->Width = X; + this->Height = Y; + } + ((GUI *)this->ParentGUI)->SetCursorType(CursorType::ResizeAll); + } + else + { + ((GUI *)this->ParentGUI)->SetCursorType(CursorType::Arrow); + } + } + } + + void Window::AddWidget(Widget *widget) + { + this->Widgets.push_back(widget); + } + + Window::Window(void *ParentGUI, uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Title) + { + this->mem = new Memory::MemMgr; + this->ParentGUI = ParentGUI; + this->Left = Left; + this->Top = Top; + this->Width = Width; + this->Height = Height; + strcpy(this->Title, Title); + this->Maximized = false; + this->Minimized = false; + this->CloseButtonFocused = false; + this->MaximizeButtonFocused = false; + this->MinimizeButtonFocused = false; + this->WindowDragging = false; + } + + Window::~Window() + { + delete this->mem; + } +} diff --git a/include/gui.hpp b/include/gui.hpp new file mode 100644 index 0000000..d9dc84e --- /dev/null +++ b/include/gui.hpp @@ -0,0 +1,202 @@ +#ifndef __FENNIX_KERNEL_GUI_H__ +#define __FENNIX_KERNEL_GUI_H__ + +#include +#include +#include + +namespace GraphicalUserInterface +{ + typedef uintptr_t Handle; + + struct MouseData + { + uint32_t X; + uint32_t Y; + uint32_t Z; + bool Left; + bool Right; + bool Middle; + }; + + enum CursorType + { + Visible = 0, + Hidden, + Arrow, + Hand, + Wait, + IBeam, + ResizeHorizontal, + ResizeVertical, + ResizeDiagonalLeft, + ResizeDiagonalRight, + ResizeAll, + Cross, + Help, + No, + AppStarting, + }; + + enum EventType + { + MouseEvent, + KeyboardEvent, + FocusEvent, + WidgetEvent + }; + + struct Event + { + EventType Type; + Handle Source; + Handle Target; + MouseData Mouse; + MouseData LastMouse; + + struct + { + bool MouseMove; + bool MouseClick; + bool MouseDoubleClick; + bool MouseDown; + bool MouseUp; + bool MouseWheel; + bool MouseEnter; + bool MouseLeave; + bool MouseHover; + bool MouseDrag; + bool MouseDragStart; + bool MouseDragEnd; + bool MouseDragEnter; + bool MouseDragLeave; + bool MouseDragHover; + bool MouseDragDrop; + bool MouseDragDropEnter; + bool MouseDragDropLeave; + bool MouseDragDropHover; + bool MouseDragDropEnd; + bool MouseDragDropStart; + bool MouseDragDropCancel; + bool MouseDragDropComplete; + bool MouseDragDropAbort; + } MouseEventData; + + struct + { + bool KeyDown; + bool KeyUp; + bool KeyPress; + } KeyboardEventData; + + struct + { + bool FocusEnter; + bool FocusLeave; + bool FocusHover; + } FocusEventData; + + struct + { + bool Resize; + bool Move; + bool Show; + bool Hide; + bool Close; + bool Destroy; + bool Paint; + bool PaintBackground; + bool PaintForeground; + bool PaintBorder; + bool PaintShadow; + bool PaintOverlay; + bool PaintAll; + bool PaintChildren; + bool PaintChildrenBackground; + bool PaintChildrenForeground; + bool PaintChildrenBorder; + bool PaintChildrenShadow; + bool PaintChildrenOverlay; + bool PaintChildrenAll; + } WidgetEventData; + }; + + void PutRect(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color); + void PutBorder(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color); + void PutBorderWithShadow(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color); + + class Widget + { + private: + Memory::MemMgr *mem; + + public: + void Paint(); + Handle CreatePanel(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateButton(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateLabel(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateTextBox(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateCheckBox(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateRadioButton(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateComboBox(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateListBox(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateProgressBar(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreateContextMenu(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + void HandleEvent(Event *e); + Widget(void /* Window */ *ParentWindow); + ~Widget(); + }; + + class Window + { + private: + Memory::MemMgr *mem; + void *ParentGUI; + long Left, Top, Width, Height; + long Last_Left, Last_Top, Last_Width, Last_Height; + char Title[256]; + Vector Widgets; + bool Maximized; + bool Minimized; + + bool CloseButtonFocused; + bool MaximizeButtonFocused; + bool MinimizeButtonFocused; + bool WindowDragging; + + public: + void Close(); + void Maximize(); + void Minimize(); + void HandleEvent(Event *e); + void Paint(); + void AddWidget(Widget *widget); + Window(void *ParentGUI, uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Title); + ~Window(); + }; + + class GUI + { + private: + MouseData Mouse; + MouseData LastMouse; + Memory::MemMgr *mem; + Vector Windows; + bool IsRunning; + CursorType Cursor = CursorType::Arrow; + bool CursorVisible = true; + + void PaintDesktop(); + void PaintWindows(); + void PaintCursor(); + + public: + void SetCursorType(CursorType Type = CursorType::Visible) { this->Cursor = Type; } + void Loop(); + void AddWindow(Window *window); + GUI(); + ~GUI(); + }; +} + +#endif // !__FENNIX_KERNEL_GUI_H__