Initial popup window.

This commit is contained in:
James Grogan 2022-12-02 13:44:52 +00:00
parent f16dd7c0d9
commit 70220fc6e9
22 changed files with 253 additions and 15 deletions

View file

@ -4,13 +4,15 @@ list(APPEND TARGET_HEADERS
TopBar.h TopBar.h
StatusBar.h StatusBar.h
GuiApplication.h GuiApplication.h
TabbedPanelWidget.h) TabbedPanelWidget.h
TopBarMenu.h)
list(APPEND TARGET_SOURCES list(APPEND TARGET_SOURCES
TopBar.cpp TopBar.cpp
StatusBar.cpp StatusBar.cpp
GuiApplication.cpp GuiApplication.cpp
TabbedPanelWidget.cpp) TabbedPanelWidget.cpp
TopBarMenu.cpp)
add_library(${MODULE_NAME} SHARED ${TARGET_SOURCES} ${TARGET_HEADERS}) add_library(${MODULE_NAME} SHARED ${TARGET_SOURCES} ${TARGET_HEADERS})

View file

@ -7,6 +7,7 @@
#include "FontsManager.h" #include "FontsManager.h"
#include "MainApplication.h" #include "MainApplication.h"
#include "AbstractUiInterface.h" #include "AbstractUiInterface.h"
#include "Widget.h"
#include "FileLogger.h" #include "FileLogger.h"

View file

@ -21,6 +21,11 @@ public:
void run(); void run();
AbstractUIInterface* getUiInterface() const override
{
return mUiInterface.get();
}
void setUiInterfaceBackend(UiInterfaceFactory::Backend backend); void setUiInterfaceBackend(UiInterfaceFactory::Backend backend);
protected: protected:

View file

@ -1,10 +1,36 @@
#include "TopBar.h" #include "TopBar.h"
#include "Color.h" #include "Color.h"
#include "Theme.h"
#include "Button.h"
#include "TopBarMenu.h"
TopBar::TopBar() TopBar::TopBar()
{ {
setBackgroundColor(Color(50, 50, 50)); setBackgroundColor(Theme::getBackgroundPrimary());
auto fileButton = Button::Create();
fileButton->setLabel("File");
fileButton->setBackgroundColor(Theme::getBackgroundPrimary());
fileButton->setMargin(2);
fileButton->setMaxWidth(60);
auto onClick = [this](Widget* self){
if(this)
{
auto menu = std::make_unique<TopBarMenu>();
auto window = getTopLevelWindow();
window->addPopup(std::move(menu));
};
};
fileButton->setOnClickFunction(onClick);
addWidget(std::move(fileButton));
}
TopBar::~TopBar()
{
} }
std::unique_ptr<TopBar> TopBar::Create() std::unique_ptr<TopBar> TopBar::Create()

View file

@ -2,12 +2,15 @@
#include "Widget.h" #include "Widget.h"
class TopBarMenu;
class TopBar : public Widget class TopBar : public Widget
{ {
public: public:
TopBar(); TopBar();
~TopBar();
static std::unique_ptr<TopBar> Create(); static std::unique_ptr<TopBar> Create();
}; };

View file

16
src/client/TopBarMenu.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include "Widget.h"
#include "Window.h"
class TopBarMenu : public Widget
{
public:
void popupFrom(Widget* parent)
{
auto window = parent->getTopLevelWindow();
}
};

View file

@ -30,6 +30,7 @@ Window::Window()
mWidth = 800; mWidth = 800;
mHeight = 600; mHeight = 600;
mWidget->setBounds(mWidth, mHeight); mWidget->setBounds(mWidth, mHeight);
mWidget->setWindow(this);
} }
Window::~Window() Window::~Window()
@ -81,6 +82,7 @@ void Window::setWidget(WidgetPtr widget)
} }
mWidget = std::move(widget); mWidget = std::move(widget);
mWidget->setBounds(mWidth, mHeight); mWidget->setBounds(mWidth, mHeight);
mWidget->setWindow(this);
} }
IPlatformWindow* Window::getPlatformWindow() const IPlatformWindow* Window::getPlatformWindow() const

View file

@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <functional>
class PaintEvent; class PaintEvent;
class MouseEvent; class MouseEvent;
@ -30,6 +31,8 @@ class Window : public DrawingSurface
public: public:
using onPopupFunc = std::function<void(mt::Window* parent, std::unique_ptr<Widget> popup)>;
Window(); Window();
~Window(); ~Window();
@ -72,11 +75,37 @@ public:
return mTitle; return mTitle;
} }
void addPopup(std::unique_ptr<Widget> popupWidget)
{
if (mPopupFunc)
{
mPopupFunc(this, std::move(popupWidget));
}
}
void setPopupHandler(onPopupFunc func)
{
mPopupFunc = func;
}
void setParent(Window* parent)
{
mParent = parent;
}
Window* getParent() const
{
return mParent;
}
private: private:
WidgetPtr mWidget {nullptr}; WidgetPtr mWidget {nullptr};
std::string mTitle; std::string mTitle;
IPlatformWindowPtr mPlatformWindow {nullptr}; IPlatformWindowPtr mPlatformWindow {nullptr};
std::unique_ptr<DrawingContext> mDrawingContext; std::unique_ptr<DrawingContext> mDrawingContext;
onPopupFunc mPopupFunc;
Window* mParent{nullptr};
}; };
} }

View file

@ -2,7 +2,7 @@
Color Theme::getBackgroundPrimary() Color Theme::getBackgroundPrimary()
{ {
return {217, 217, 217}; return {245, 245, 245};
} }
Color Theme::getBannerBackground() Color Theme::getBannerBackground()

View file

@ -18,6 +18,11 @@ Button::Button()
mName = "Button"; mName = "Button";
} }
Button::~Button()
{
}
std::unique_ptr<Button> Button::Create() std::unique_ptr<Button> Button::Create()
{ {
return std::make_unique<Button>(); return std::make_unique<Button>();

View file

@ -17,6 +17,8 @@ public:
Button(); Button();
~Button();
static std::unique_ptr<Button> Create(); static std::unique_ptr<Button> Create();
void setLabel(const std::string& text); void setLabel(const std::string& text);

View file

@ -10,6 +10,8 @@
#include "TransformNode.h" #include "TransformNode.h"
#include "RootNode.h" #include "RootNode.h"
#include "Window.h"
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <iostream> #include <iostream>
@ -41,6 +43,8 @@ std::unique_ptr<Widget> Widget::Create()
void Widget::addWidget(WidgetUPtr widget) void Widget::addWidget(WidgetUPtr widget)
{ {
widget->setParent(this);
mPendingChildNodes.push_back(widget->getRootNode()); mPendingChildNodes.push_back(widget->getRootNode());
mChildren.push_back(std::move(widget)); mChildren.push_back(std::move(widget));
} }
@ -99,6 +103,16 @@ void Widget::setPadding(const BoundaryOffset& padding)
void Widget::setBounds(unsigned width, unsigned height) void Widget::setBounds(unsigned width, unsigned height)
{ {
if (mSize.mMaxWidth > 0 && width > mSize.mMaxWidth)
{
width = mSize.mMaxWidth;
}
if (mSize.mMaxHeight > 0 && height > mSize.mMaxHeight)
{
height = mSize.mMaxHeight;
}
if (width != mSize.mWidth || height != mSize.mHeight) if (width != mSize.mWidth || height != mSize.mHeight)
{ {
mTransformDirty = true; mTransformDirty = true;
@ -161,6 +175,15 @@ bool Widget::needsUpdate() const
return false; return false;
} }
void Widget::setMaxWidth(unsigned maxWidth)
{
if (mSize.mMaxWidth != maxWidth)
{
mTransformDirty = true;
mSize.mMaxWidth = maxWidth;
}
}
void Widget::doPaint(const PaintEvent* event) void Widget::doPaint(const PaintEvent* event)
{ {
updateBackground(event); updateBackground(event);
@ -319,3 +342,51 @@ void Widget::updateBackground(const PaintEvent* event)
mBackgroundNode->setIsVisible(mVisible); mBackgroundNode->setIsVisible(mVisible);
} }
} }
mt::Window* Widget::getTopLevelWindow() const
{
if(mWindow)
{
return mWindow;
}
std::cout << "I am " << getName() << std::endl;
auto lastParent = mParent;
auto nextParent = mParent;
while(nextParent)
{
lastParent = nextParent;
nextParent = lastParent->getParent();
std::cout << "Checking if " << lastParent->getName() << std::endl;
if (nextParent)
{
std::cout << "Next is " << nextParent->getName() << std::endl;
}
else
{
std::cout << "no next" << std::endl;
}
}
return lastParent->getTopLevelWindow();
}
Widget* Widget::getParent() const
{
return mParent;
}
mt::Window* Widget::getWindow() const
{
return mWindow;
}
void Widget::setParent(Widget* parent)
{
mParent = parent;
}
void Widget::setWindow(mt::Window* window)
{
mWindow = window;
}

View file

@ -16,6 +16,11 @@ class AbstractVisualNode;
class TransformNode; class TransformNode;
class RectangleNode; class RectangleNode;
namespace mt
{
class Window;
}
class Widget class Widget
{ {
public: public:
@ -93,6 +98,8 @@ public:
void setSize(const BoundedSize& size); void setSize(const BoundedSize& size);
void setMaxWidth(unsigned maxWidth);
void setMargin(unsigned margin); void setMargin(unsigned margin);
void setMargin(const BoundaryOffset& margin); void setMargin(const BoundaryOffset& margin);
@ -110,13 +117,17 @@ public:
mName = name; mName = name;
} }
const std::string& getName() const std::string& getName() const
{ {
return mName; return mName;
} }
bool needsUpdate() const; bool needsUpdate() const;
void setWindow(mt::Window* window);
mt::Window* getTopLevelWindow() const;
protected: protected:
virtual bool onMyKeyboardEvent(const KeyboardEvent* event); virtual bool onMyKeyboardEvent(const KeyboardEvent* event);
@ -130,6 +141,14 @@ protected:
virtual bool isDirty() const; virtual bool isDirty() const;
void setParent(Widget* parent);
Widget* getParent() const;
mt::Window* getWindow() const;
DiscretePoint mLocation; DiscretePoint mLocation;
BoundedSize mSize; BoundedSize mSize;
BoundaryOffset mPadding; BoundaryOffset mPadding;
@ -152,6 +171,8 @@ protected:
std::vector<TransformNode*> mPendingChildNodes; std::vector<TransformNode*> mPendingChildNodes;
FontItem mDefaultFont; FontItem mDefaultFont;
Widget* mParent{nullptr};
mt::Window* mWindow{nullptr};
}; };
using WidgetUPtr = std::unique_ptr<Widget>; using WidgetUPtr = std::unique_ptr<Widget>;

View file

@ -4,6 +4,8 @@
#include "AbstractApp.h" #include "AbstractApp.h"
class AbstractUIInterface;
class AbstractDesktopApp class AbstractDesktopApp
{ {
public: public:
@ -11,6 +13,8 @@ public:
virtual ~AbstractDesktopApp() = default; virtual ~AbstractDesktopApp() = default;
virtual AbstractApp* getMainApplication() const = 0; virtual AbstractApp* getMainApplication() const = 0;
virtual AbstractUIInterface* getUiInterface() const = 0;
}; };
using AbstractDesktopAppPtr = std::shared_ptr<AbstractDesktopApp>; using AbstractDesktopAppPtr = std::shared_ptr<AbstractDesktopApp>;

View file

@ -1,17 +1,20 @@
#include "DesktopManager.h" #include "DesktopManager.h"
#include "AbstractDesktopApp.h" #include "AbstractDesktopApp.h"
#include "AbstractUiInterface.h"
#include "FileLogger.h" #include "FileLogger.h"
#include "Widget.h"
#include <iostream>
DesktopManager::DesktopManager(AbstractDesktopApp* application) DesktopManager::DesktopManager(AbstractDesktopApp* application)
: mScreens(), : mScreens(),
mWindowManager(WindowManager::Create()),
mKeyboard(Keyboard::Create()), mKeyboard(Keyboard::Create()),
mUiApplication(application), mUiApplication(application),
mEventManager(EventManager::Create()) mEventManager(EventManager::Create())
{ {
mWindowManager = WindowManager::Create(this);
} }
DesktopManager::~DesktopManager() DesktopManager::~DesktopManager()
@ -115,6 +118,16 @@ WindowManager* DesktopManager::getWindowManager() const
return mWindowManager.get(); return mWindowManager.get();
} }
void DesktopManager::addWindow(mt::Window* window)
{
if (auto ui_interface = mUiApplication->getUiInterface())
{
std::cout << "Adding popup window" << std::endl;
ui_interface->addWindow(window);
ui_interface->showWindow(window);
}
}
void DesktopManager::onLoopIteration() void DesktopManager::onLoopIteration()
{ {
auto defaultScreen = getDefaultScreen(); auto defaultScreen = getDefaultScreen();

View file

@ -51,6 +51,8 @@ public:
void onLoopIteration(); void onLoopIteration();
void addWindow(mt::Window* window);
private: private:
std::vector<ScreenPtr> mScreens; std::vector<ScreenPtr> mScreens;
WindowManagerUPtr mWindowManager; WindowManagerUPtr mWindowManager;

View file

@ -1,9 +1,13 @@
#include "WindowManager.h" #include "WindowManager.h"
#include "DesktopManager.h"
#include "Widget.h"
#include <iostream> #include <iostream>
WindowManager::WindowManager() WindowManager::WindowManager(DesktopManager* desktopManager)
: mWindows() : mWindows(),
mDesktopManager(desktopManager)
{ {
addWindow(mt::Window::Create()); addWindow(mt::Window::Create());
} }
@ -13,9 +17,9 @@ WindowManager::~WindowManager()
} }
std::unique_ptr<WindowManager> WindowManager::Create() std::unique_ptr<WindowManager> WindowManager::Create(DesktopManager* desktopManager)
{ {
return std::make_unique<WindowManager>(); return std::make_unique<WindowManager>(desktopManager);
} }
void WindowManager::onPaintEvent(const PaintEvent* event) void WindowManager::onPaintEvent(const PaintEvent* event)
@ -40,9 +44,25 @@ void WindowManager::onKeyboardEvent(const KeyboardEvent* event)
void WindowManager::addWindow(WindowUPtr window) void WindowManager::addWindow(WindowUPtr window)
{ {
auto popup_handler = [this](mt::Window* parent, std::unique_ptr<Widget> popup){
onAddPopupWindow(parent, std::move(popup));
};
window->setPopupHandler(popup_handler);
mWindows.push_back(std::move(window)); mWindows.push_back(std::move(window));
} }
void WindowManager::onAddPopupWindow(mt::Window* parent, std::unique_ptr<Widget> widget)
{
auto popup = mt::Window::Create();
popup->setWidget(std::move(widget));
popup->setParent(parent);
auto popup_raw = popup.get();
addWindow(std::move(popup));
mDesktopManager->addWindow(popup_raw);
}
void WindowManager::clearPlatformWindows() void WindowManager::clearPlatformWindows()
{ {
for (auto& window : mWindows) for (auto& window : mWindows)

View file

@ -9,14 +9,17 @@
#include "ResizeEvent.h" #include "ResizeEvent.h"
#include "KeyboardEvent.h" #include "KeyboardEvent.h"
class Widget;
class DesktopManager;
class WindowManager class WindowManager
{ {
public: public:
WindowManager(); WindowManager(DesktopManager* desktopManager);
~WindowManager(); ~WindowManager();
static std::unique_ptr<WindowManager> Create(); static std::unique_ptr<WindowManager> Create(DesktopManager* desktopManager);
void addWindow(WindowUPtr window); void addWindow(WindowUPtr window);
@ -44,8 +47,11 @@ public:
void onLoopIteration(mt::Screen* screen); void onLoopIteration(mt::Screen* screen);
void onAddPopupWindow(mt::Window* parent, std::unique_ptr<Widget> widget);
private: private:
std::vector<WindowUPtr> mWindows; std::vector<WindowUPtr> mWindows;
DesktopManager* mDesktopManager{nullptr};
}; };
using WindowManagerUPtr = std::unique_ptr<WindowManager>; using WindowManagerUPtr = std::unique_ptr<WindowManager>;

View file

@ -14,6 +14,7 @@
#include "NullUiInterface.h" #include "NullUiInterface.h"
#include "FontsManager.h" #include "FontsManager.h"
#include "Widget.h"
std::unique_ptr<AbstractUIInterface> UiInterfaceFactory::create(DesktopManager* desktopManager, Backend backend) std::unique_ptr<AbstractUIInterface> UiInterfaceFactory::create(DesktopManager* desktopManager, Backend backend)
{ {

View file

@ -17,6 +17,7 @@
#include "Screen.h" #include "Screen.h"
#include "XcbScreen.h" #include "XcbScreen.h"
#include "Color.h" #include "Color.h"
#include "Widget.h"
#include "UiEvent.h" #include "UiEvent.h"
#include "XcbKeyboard.h" #include "XcbKeyboard.h"
#include "XcbWindow.h" #include "XcbWindow.h"

View file

@ -1,6 +1,7 @@
#include "XcbWindow.h" #include "XcbWindow.h"
#include "Window.h" #include "Window.h"
#include "Widget.h"
#include "XcbScreen.h" #include "XcbScreen.h"
#include "XcbImage.h" #include "XcbImage.h"
#include "Screen.h" #include "Screen.h"
@ -40,10 +41,17 @@ void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen
const auto hwnd = xcb_generate_id(connection); const auto hwnd = xcb_generate_id(connection);
const uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; const uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
const uint32_t values[2] = {xcb_screen->GetNativeScreen()->white_pixel, eventMask}; const uint32_t values[2] = {xcb_screen->GetNativeScreen()->white_pixel, eventMask};
xcb_window_t parent_hwnd = xcb_screen->GetNativeScreen()->root;
if (auto parent = window->getParent())
{
parent_hwnd = dynamic_cast<XcbWindow*>(parent->getPlatformWindow())->getHandle();
}
xcb_create_window (connection, /* connection */ xcb_create_window (connection, /* connection */
XCB_COPY_FROM_PARENT, /* depth */ XCB_COPY_FROM_PARENT, /* depth */
hwnd, /* window Id */ hwnd, /* window Id */
xcb_screen->GetNativeScreen()->root, /* parent window */ parent_hwnd, /* parent window */
0, 0, /* x, y */ 0, 0, /* x, y */
window->getWidth(), window->getHeight(), /* width, height */ window->getWidth(), window->getHeight(), /* width, height */
10, /* border_width */ 10, /* border_width */