From 9ade0e2d4b9cedd661229cb84b979626b4dbb67f Mon Sep 17 00:00:00 2001 From: James Grogan Date: Mon, 14 Nov 2022 14:57:50 +0000 Subject: [PATCH] Starting resize support. --- apps/sample-gui/gui-main.cpp | 2 +- src/core/Color.cpp | 8 ++--- src/core/Color.h | 21 ++++++++++--- src/graphics/DrawingSurface.h | 2 +- src/graphics/opengl/OpenGlPainter.cpp | 22 +++++++++----- src/image/Image.cpp | 6 ++-- src/mesh/TriFace.cpp | 15 ++++++++++ src/mesh/TriFace.h | 8 +++++ src/mesh/TriMesh.cpp | 18 +++++++++++ src/mesh/TriMesh.h | 4 +++ src/ui_elements/CMakeLists.txt | 2 ++ src/ui_elements/desktop_elements/Window.cpp | 6 ++++ src/ui_elements/desktop_elements/Window.h | 2 ++ src/ui_elements/ui_events/PaintEvent.h | 1 - src/ui_elements/ui_events/ResizeEvent.cpp | 20 +++++++++++++ src/ui_elements/ui_events/ResizeEvent.h | 30 +++++++++++++++++++ src/ui_elements/ui_events/UiEvent.h | 3 +- src/visual_elements/RectangleNode.cpp | 3 ++ src/windows/managers/DesktopManager.cpp | 7 +++++ src/windows/managers/WindowManager.cpp | 5 ++++ src/windows/managers/WindowManager.h | 3 ++ .../ui_interfaces/x11/XcbGlInterface.cpp | 2 ++ .../ui_interfaces/x11/XcbInterface.cpp | 28 +++++++++++++++-- .../ui_interfaces/x11/XcbLayerInterface.cpp | 14 ++------- .../ui_interfaces/x11/XcbLayerInterface.h | 6 +--- .../ui_interfaces/x11/XcbTextInterface.cpp | 3 +- 26 files changed, 197 insertions(+), 44 deletions(-) create mode 100644 src/ui_elements/ui_events/ResizeEvent.cpp create mode 100644 src/ui_elements/ui_events/ResizeEvent.h diff --git a/apps/sample-gui/gui-main.cpp b/apps/sample-gui/gui-main.cpp index 9a964a6..700ff9a 100644 --- a/apps/sample-gui/gui-main.cpp +++ b/apps/sample-gui/gui-main.cpp @@ -12,7 +12,7 @@ int main(int argc, char *argv[]) // Start the gui app auto app = MediaTool(std::move(args)); - app.setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER); + //app.setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER); app.run(); return 0; diff --git a/src/core/Color.cpp b/src/core/Color.cpp index 649dd03..3a53e4d 100644 --- a/src/core/Color.cpp +++ b/src/core/Color.cpp @@ -26,22 +26,22 @@ std::unique_ptr Color::Create(const Color& color) return std::make_unique(color); } -unsigned Color::GetR() const +unsigned Color::getR() const { return mR; } -unsigned Color::GetG() const +unsigned Color::getG() const { return mG; } -unsigned Color::GetB() const +unsigned Color::getB() const { return mB; } -double Color::GetAlpha() const +double Color::getAlpha() const { return mAlpha; } diff --git a/src/core/Color.h b/src/core/Color.h index 567ba95..b1af736 100644 --- a/src/core/Color.h +++ b/src/core/Color.h @@ -1,5 +1,8 @@ #pragma once + #include +#include +#include class Color { @@ -10,10 +13,10 @@ public: static std::unique_ptr Create(unsigned r, unsigned g, unsigned b, double a = 1.0); static std::unique_ptr Create(const Color& color); - unsigned GetR() const; - unsigned GetG() const; - unsigned GetB() const; - double GetAlpha() const; + unsigned getR() const; + unsigned getG() const; + unsigned getB() const; + double getAlpha() const; bool operator==(const Color& rhs) const { @@ -28,6 +31,16 @@ public: return !operator==(rhs); } + std::vector getAsVectorDouble() const + { + return {mR/255.0, mG/255.0, mB/255.0, mAlpha/255.0}; + } + + uint32_t getAsUInt32() const + { + return mB + (mG<<8) + (mR<<16); + } + private: unsigned mR{0}; unsigned mG{0}; diff --git a/src/graphics/DrawingSurface.h b/src/graphics/DrawingSurface.h index 9093ed0..c89a1e9 100644 --- a/src/graphics/DrawingSurface.h +++ b/src/graphics/DrawingSurface.h @@ -13,7 +13,7 @@ public: static std::unique_ptr Create(); - void setSize(unsigned width, unsigned height); + virtual void setSize(unsigned width, unsigned height); unsigned getWidth() const; diff --git a/src/graphics/opengl/OpenGlPainter.cpp b/src/graphics/opengl/OpenGlPainter.cpp index 92c301f..11fda56 100644 --- a/src/graphics/opengl/OpenGlPainter.cpp +++ b/src/graphics/opengl/OpenGlPainter.cpp @@ -21,35 +21,43 @@ void OpenGlPainter::paint(DrawingContext* context) const auto num_mesh = context->getScene()->getNumMeshes(); - glClearColor(0.4, 0.4, 0.4, 0.4); + glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + //glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); for (std::size_t idx=0; idxgetScene()->getMesh(idx); const auto faces = mesh->getFaceVertices(); + const auto colors = mesh->getFaceVectorAttributes("Color"); - glColor3f(1.0, 0.0, 1.0); - + std::size_t counter{0}; for (const auto& face : faces) { + const auto r = colors[counter][0]; + const auto g = colors[counter][1]; + const auto b = colors[counter][2]; + + glColor3f(r, g, b); + glBegin(GL_TRIANGLES); double x0 = 2.0*face[0].getX() / width - 1.0; - double y0 = 2.0*face[0].getY() / height - 1.0; + double y0 = 1.0 - 2.0*face[0].getY() / height; double x1 = 2.0*face[1].getX() / width - 1.0; - double y1 = 2.0*face[1].getY() / height - 1.0; + double y1 = 1.0 - 2.0*face[1].getY() / height; double x2 = 2.0*face[2].getX() / width - 1.0; - double y2 = 2.0*face[2].getY() / height - 1.0; + double y2 = 1.0 - 2.0*face[2].getY() / height; glVertex3f(x0, y0, 0); glVertex3f(x1, y1, 0); glVertex3f(x2, y2, 0); glEnd(); + + counter++; } } diff --git a/src/image/Image.cpp b/src/image/Image.cpp index 27d2802..daea989 100644 --- a/src/image/Image.cpp +++ b/src/image/Image.cpp @@ -30,9 +30,9 @@ void Image::setPixelValue(unsigned idx, unsigned jdx, const Color& color) initialize(); } - mData[jdx*getBytesPerRow() + idx*3] = static_cast(color.GetR()); - mData[jdx*getBytesPerRow() + idx*3 + 1] = static_cast(color.GetG()); - mData[jdx*getBytesPerRow() + idx*3 + 2] = static_cast(color.GetB()); + mData[jdx*getBytesPerRow() + idx*3] = static_cast(color.getR()); + mData[jdx*getBytesPerRow() + idx*3 + 1] = static_cast(color.getG()); + mData[jdx*getBytesPerRow() + idx*3 + 2] = static_cast(color.getB()); } template diff --git a/src/mesh/TriFace.cpp b/src/mesh/TriFace.cpp index efe0b44..fd8d4cb 100644 --- a/src/mesh/TriFace.cpp +++ b/src/mesh/TriFace.cpp @@ -25,3 +25,18 @@ std::vector TriFace::getNodeIds() const { return {mEdge0->getNode0Id(), mEdge0->getNode1Id(), mEdge1->getNode1Id()}; } + +void TriFace::addVectorAttribute(const std::string& tag, const std::vector& values) +{ + mVectorAttributes[tag] = values; +} + +std::vector TriFace::getVectorAttribute(const std::string& tag) const +{ + auto iter = mVectorAttributes.find(tag); + if (iter != mVectorAttributes.end()) + { + return iter->second; + } + return {}; +} diff --git a/src/mesh/TriFace.h b/src/mesh/TriFace.h index 43aa17d..12412a2 100644 --- a/src/mesh/TriFace.h +++ b/src/mesh/TriFace.h @@ -2,6 +2,8 @@ #include #include +#include +#include class Edge; @@ -14,8 +16,14 @@ public: static std::unique_ptr Create(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0); std::vector getNodeIds() const; + + void addVectorAttribute(const std::string& tag, const std::vector& values); + + std::vector getVectorAttribute(const std::string& tag) const; + private: unsigned mId{0}; + std::unordered_map > mVectorAttributes; Edge* mEdge0{nullptr}; Edge* mEdge1{nullptr}; Edge* mEdge2{nullptr}; diff --git a/src/mesh/TriMesh.cpp b/src/mesh/TriMesh.cpp index 1046f22..22264d6 100644 --- a/src/mesh/TriMesh.cpp +++ b/src/mesh/TriMesh.cpp @@ -27,3 +27,21 @@ std::vector > TriMesh::getFaceVertices() const } return verts; } + +std::vector > TriMesh::getFaceVectorAttributes(const std::string& tag) +{ + std::vector > attribs(mFaces.size()); + for(std::size_t idx=0; idxgetVectorAttribute(tag)}; + } + return attribs; +} + +void TriMesh::addConstantFaceVectorAttribute(const std::string& tag, const std::vector& values) +{ + for (const auto& face : mFaces) + { + face->addVectorAttribute(tag, values); + } +} diff --git a/src/mesh/TriMesh.h b/src/mesh/TriMesh.h index 989761f..1bc1d02 100644 --- a/src/mesh/TriMesh.h +++ b/src/mesh/TriMesh.h @@ -29,6 +29,10 @@ public: std::vector > getFaceVertices() const; + void addConstantFaceVectorAttribute(const std::string& tag, const std::vector& values); + + std::vector > getFaceVectorAttributes(const std::string& tag); + private: VecNodes mNodes; VecEdges mEdges; diff --git a/src/ui_elements/CMakeLists.txt b/src/ui_elements/CMakeLists.txt index 4504637..61ced1e 100644 --- a/src/ui_elements/CMakeLists.txt +++ b/src/ui_elements/CMakeLists.txt @@ -12,6 +12,8 @@ list(APPEND ui_elements_LIB_INCLUDES ui_events/MouseEvent.h ui_events/UiEvent.h ui_events/PaintEvent.h + ui_events/ResizeEvent.h + ui_events/ResizeEvent.cpp widgets/Widget.cpp widgets/Button.cpp widgets/Label.cpp diff --git a/src/ui_elements/desktop_elements/Window.cpp b/src/ui_elements/desktop_elements/Window.cpp index 540f326..0823b8c 100644 --- a/src/ui_elements/desktop_elements/Window.cpp +++ b/src/ui_elements/desktop_elements/Window.cpp @@ -37,6 +37,12 @@ std::unique_ptr Window::Create() return std::make_unique(); } +void Window::setSize(unsigned width, unsigned height) +{ + DrawingSurface::setSize(width, height); + mWidget->setBounds(width, height); +} + void Window::clearPlatformWindow() { mPlatformWindow.reset(); diff --git a/src/ui_elements/desktop_elements/Window.h b/src/ui_elements/desktop_elements/Window.h index c7c0d21..8d7e41a 100644 --- a/src/ui_elements/desktop_elements/Window.h +++ b/src/ui_elements/desktop_elements/Window.h @@ -55,6 +55,8 @@ public: void clearPlatformWindow(); + void setSize(unsigned width, unsigned height) override; + private: WidgetPtr mWidget {nullptr}; IPlatformWindowPtr mPlatformWindow {nullptr}; diff --git a/src/ui_elements/ui_events/PaintEvent.h b/src/ui_elements/ui_events/PaintEvent.h index b64f988..f377b60 100644 --- a/src/ui_elements/ui_events/PaintEvent.h +++ b/src/ui_elements/ui_events/PaintEvent.h @@ -7,7 +7,6 @@ class PaintEvent : public UiEvent { public: - PaintEvent(); ~PaintEvent(); diff --git a/src/ui_elements/ui_events/ResizeEvent.cpp b/src/ui_elements/ui_events/ResizeEvent.cpp new file mode 100644 index 0000000..5b84462 --- /dev/null +++ b/src/ui_elements/ui_events/ResizeEvent.cpp @@ -0,0 +1,20 @@ +#include "ResizeEvent.h" + +ResizeEvent::ResizeEvent(unsigned width, unsigned height) + : UiEvent(), + mWidth(), + mHeight() +{ + mType = UiEvent::Type::Resize; +} + +ResizeEvent::~ResizeEvent() +{ + +} + +std::unique_ptr ResizeEvent::Create(unsigned width, unsigned height) +{ + return std::make_unique(width, height); +} + diff --git a/src/ui_elements/ui_events/ResizeEvent.h b/src/ui_elements/ui_events/ResizeEvent.h new file mode 100644 index 0000000..bd79312 --- /dev/null +++ b/src/ui_elements/ui_events/ResizeEvent.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include "UiEvent.h" + +class ResizeEvent : public UiEvent +{ +public: + ResizeEvent(unsigned width, unsigned height); + + ~ResizeEvent(); + + static std::unique_ptr Create(unsigned width, unsigned height); + + unsigned getWidth() const + { + return mWidth; + } + + unsigned getHeight() const + { + return mHeight; + } + +private: + unsigned mWidth{0}; + unsigned mHeight{0}; +}; +using ResizeEventPtr = std::unique_ptr; diff --git a/src/ui_elements/ui_events/UiEvent.h b/src/ui_elements/ui_events/UiEvent.h index 0423fe9..be12840 100644 --- a/src/ui_elements/ui_events/UiEvent.h +++ b/src/ui_elements/ui_events/UiEvent.h @@ -10,7 +10,8 @@ public: Unknown, Paint, Mouse, - Keyboard + Keyboard, + Resize }; protected: diff --git a/src/visual_elements/RectangleNode.cpp b/src/visual_elements/RectangleNode.cpp index 8a01240..5679148 100644 --- a/src/visual_elements/RectangleNode.cpp +++ b/src/visual_elements/RectangleNode.cpp @@ -38,5 +38,8 @@ void RectangleNode::updateMesh() const auto rect = Rectangle(mLocation, mWidth, mHeight); auto mesh = MeshPrimitives::build(rect); + auto color = getFillColor(); + + mesh->addConstantFaceVectorAttribute("Color", color.getAsVectorDouble()); mMesh = std::move(mesh); } diff --git a/src/windows/managers/DesktopManager.cpp b/src/windows/managers/DesktopManager.cpp index 68cb364..2284b62 100644 --- a/src/windows/managers/DesktopManager.cpp +++ b/src/windows/managers/DesktopManager.cpp @@ -67,6 +67,13 @@ void DesktopManager::onUiEvent(UiEventUPtr eventUPtr) mModified = true; break; } + case (UiEvent::Type::Resize): + { + auto resize_event = dynamic_cast(event); + mWindowManager->onResizeEvent(resize_event); + //mModified = true; + break; + } case (UiEvent::Type::Mouse): { auto mouseEvent = dynamic_cast(event); diff --git a/src/windows/managers/WindowManager.cpp b/src/windows/managers/WindowManager.cpp index 8ec0be2..b470ffc 100644 --- a/src/windows/managers/WindowManager.cpp +++ b/src/windows/managers/WindowManager.cpp @@ -26,6 +26,11 @@ void WindowManager::onMouseEvent(const MouseEvent* event) getMainWindow()->onMouseEvent(event); } +void WindowManager::onResizeEvent(const ResizeEvent* event) +{ + getMainWindow()->setSize(event->getWidth(), event->getHeight()); +} + void WindowManager::onKeyboardEvent(const KeyboardEvent* event) { getMainWindow()->onKeyboardEvent(event); diff --git a/src/windows/managers/WindowManager.h b/src/windows/managers/WindowManager.h index 2a22e7b..4e48c13 100644 --- a/src/windows/managers/WindowManager.h +++ b/src/windows/managers/WindowManager.h @@ -6,6 +6,7 @@ #include "Window.h" #include "PaintEvent.h" #include "MouseEvent.h" +#include "ResizeEvent.h" #include "KeyboardEvent.h" class WindowManager @@ -27,6 +28,8 @@ public: void onKeyboardEvent(const KeyboardEvent* event); + void onResizeEvent(const ResizeEvent* event); + void clearPlatformWindows(); std::size_t getNumWindows() const diff --git a/src/windows/ui_interfaces/x11/XcbGlInterface.cpp b/src/windows/ui_interfaces/x11/XcbGlInterface.cpp index 02cbc09..bf4e7a1 100644 --- a/src/windows/ui_interfaces/x11/XcbGlInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbGlInterface.cpp @@ -9,11 +9,13 @@ XcbGlInterface::XcbGlInterface(Display* display, int default_screen) mContext(), mConfig() { + MLOG_INFO("Creating XcbGlInterface"); setupContext(default_screen); } XcbGlInterface::~XcbGlInterface() { + MLOG_INFO("Destroying XcbGlInterface"); destroyContext(); } diff --git a/src/windows/ui_interfaces/x11/XcbInterface.cpp b/src/windows/ui_interfaces/x11/XcbInterface.cpp index a5fe332..d2da4b5 100644 --- a/src/windows/ui_interfaces/x11/XcbInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbInterface.cpp @@ -7,17 +7,20 @@ #include #include "PaintEvent.h" +#include "ResizeEvent.h" #include "Screen.h" #include "XcbScreen.h" +#include "Color.h" #include "UiEvent.h" #include "VisualLayer.h" #include "XcbKeyboard.h" #include "XcbWindow.h" -#include "XcbLayerInterface.h" #include "XcbEventInterface.h" #include "XcbGlInterface.h" #include "FileLogger.h" +#include + XcbInterface::XcbInterface(DesktopManager* desktopManager, bool useHardware) : AbstractUIInterface(desktopManager, useHardware), @@ -120,7 +123,8 @@ void XcbInterface::createGraphicsContext() auto gc = xcb_generate_id(mConnection); xcb_drawable_t window = xcb_screen->GetNativeScreen()->root; uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; - uint32_t values[2] = {XcbLayerInterface::getColor(240, 240, 240), 0}; + auto color = Color(240, 240, 240); + uint32_t values[2] = {color.getAsUInt32(), 0}; xcb_create_gc(mConnection, gc, window, mask, values); xcb_screen->SetGraphicsContext(gc); } @@ -140,7 +144,8 @@ uint32_t XcbInterface::getEventMask() return XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_EXPOSURE; + XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_RESIZE_REDIRECT; } void XcbInterface::addWindow(mt::Window* window) @@ -205,6 +210,23 @@ void XcbInterface::loop() mDesktopManager->onUiEvent(std::move(ui_event)); break; } + case XCB_RESIZE_REQUEST: + { + auto resize = (xcb_resize_request_event_t*) event; + int width = 1; + int height = 1; + if (resize->width > 0) + { + width = resize->width; + } + if (resize->height > 0) + { + height = resize->height; + } + auto ui_event = std::make_unique(width, height); + mDesktopManager->onUiEvent(std::move(ui_event)); + break; + } default: /* Unknown event type, ignore it */ break; diff --git a/src/windows/ui_interfaces/x11/XcbLayerInterface.cpp b/src/windows/ui_interfaces/x11/XcbLayerInterface.cpp index 8261ff2..e0b9e9c 100644 --- a/src/windows/ui_interfaces/x11/XcbLayerInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbLayerInterface.cpp @@ -6,20 +6,10 @@ #include -uint32_t XcbLayerInterface::getColor(const Color* color) -{ - return XcbLayerInterface::getColor(color->GetR(), color->GetG(), color->GetB()); -} - -uint32_t XcbLayerInterface::getColor(int r, int g, int b) -{ - return b + (g<<8) + (r<<16); -} - -void XcbLayerInterface::modifyGcColor(xcb_connection_t* connection, xcb_gcontext_t gc, const Color* color) +void XcbLayerInterface::modifyGcColor(xcb_connection_t* connection, xcb_gcontext_t gc, const Color& color) { uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; - uint32_t values[2] = {XcbLayerInterface::getColor(color), 0}; + uint32_t values[2] = {color.getAsUInt32(), 0}; xcb_change_gc(connection, gc, mask, values); } diff --git a/src/windows/ui_interfaces/x11/XcbLayerInterface.h b/src/windows/ui_interfaces/x11/XcbLayerInterface.h index 7277928..d56ec0f 100644 --- a/src/windows/ui_interfaces/x11/XcbLayerInterface.h +++ b/src/windows/ui_interfaces/x11/XcbLayerInterface.h @@ -8,11 +8,7 @@ class VisualLayer; class XcbLayerInterface { public: - static uint32_t getColor(const Color* color); - - static uint32_t getColor(int r, int g, int b); - - static void modifyGcColor(xcb_connection_t* connection, xcb_gcontext_t gc, const Color* color); + static void modifyGcColor(xcb_connection_t* connection, xcb_gcontext_t gc, const Color& color); static void addLayer(xcb_connection_t* connection, xcb_screen_t* screen, xcb_window_t window, xcb_gcontext_t gc, VisualLayer* layer); }; diff --git a/src/windows/ui_interfaces/x11/XcbTextInterface.cpp b/src/windows/ui_interfaces/x11/XcbTextInterface.cpp index b2b93eb..27b1f01 100644 --- a/src/windows/ui_interfaces/x11/XcbTextInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbTextInterface.cpp @@ -1,6 +1,5 @@ #include "XcbTextInterface.h" -#include "XcbLayerInterface.h" #include "VisualLayer.h" #include "Color.h" @@ -16,7 +15,7 @@ xcb_gcontext_t XcbTextInterface::GetFontGC(xcb_connection_t *connection, /* create graphics context */ xcb_gcontext_t gc = xcb_generate_id(connection); uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - auto fillColor = XcbLayerInterface::getColor(&textElement->getFillColor()); + auto fillColor = textElement->getFillColor().getAsUInt32(); uint32_t value_list[3] = {screen->black_pixel, fillColor, font }; xcb_create_gc(connection, gc, window, mask, value_list);