Add win32 mouse button events.

This commit is contained in:
jmsgrogan 2023-01-17 08:34:48 +00:00
parent 2bc53186bc
commit 78a4fa99ff
20 changed files with 141 additions and 53 deletions

View file

@ -6,8 +6,6 @@
#include "TransformNode.h" #include "TransformNode.h"
#include "CircleNode.h" #include "CircleNode.h"
#include <iostream>
CanvasDrawingArea::~CanvasDrawingArea() CanvasDrawingArea::~CanvasDrawingArea()
{ {
@ -40,14 +38,14 @@ void CanvasDrawingArea::doPaint(const PaintEvent* event)
void CanvasDrawingArea::onMyMouseEvent(const MouseEvent* event) void CanvasDrawingArea::onMyMouseEvent(const MouseEvent* event)
{ {
if(event->GetAction() == MouseEvent::Action::Pressed) if(event->getAction() == MouseEvent::Action::Pressed)
{ {
} }
else if(event->GetAction() == MouseEvent::Action::Released) else if(event->getAction() == MouseEvent::Action::Released)
{ {
auto client_loc = event->GetClientLocation(); auto client_loc = event->getClientLocation();
auto screen_loc = event->GetScreenLocation(); auto screen_loc = event->getScreenLocation();
addShapeAt(client_loc.getX(), client_loc.getY()); addShapeAt(client_loc.getX(), client_loc.getY());
} }

View file

@ -48,3 +48,8 @@ uint32_t Color::getAsUInt32() const
{ {
return static_cast<uint32_t>(mB + (mG << 8) + (mR << 16)); return static_cast<uint32_t>(mB + (mG << 8) + (mR << 16));
} }
std::string Color::toString() const
{
return std::to_string(static_cast<int>(mR)) + "," + std::to_string(static_cast<int>(mG)) + "," + std::to_string(static_cast<int>(mB));
}

View file

@ -2,6 +2,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <string>
class Color class Color
{ {
@ -20,6 +21,8 @@ public:
uint32_t getAsUInt32() const; uint32_t getAsUInt32() const;
std::string toString() const;
bool operator==(const Color& rhs) const bool operator==(const Color& rhs) const
{ {
return (mR == rhs.mR) return (mR == rhs.mR)

View file

@ -1,20 +1,28 @@
set(MODULE_NAME database)
set(SQLite3_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/third_party/sqlite3") set(SQLite3_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/third_party/sqlite3")
set(SQLite3_SOURCE_FILE "${CMAKE_SOURCE_DIR}/src/third_party/sqlite3/sqlite3.c") set(SQLite3_SOURCE_FILE "${CMAKE_SOURCE_DIR}/src/third_party/sqlite3/sqlite3.c")
list(APPEND database_LIB_INCLUDES list(APPEND HEADERS
Database.h
DatabaseManager.h
database_interfaces/SqliteInterface.h
${SQLite3_SOURCE_FILE})
list(APPEND LIB_INCLUDES
Database.cpp Database.cpp
DatabaseManager.cpp DatabaseManager.cpp
database_interfaces/SqliteInterface.cpp database_interfaces/SqliteInterface.cpp
${SQLite3_SOURCE_FILE}) ${SQLite3_SOURCE_FILE})
add_library(database SHARED ${database_LIB_INCLUDES}) add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES} ${HEADERS})
target_include_directories(database PUBLIC target_include_directories(${MODULE_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/database_interfaces ${CMAKE_CURRENT_SOURCE_DIR}/database_interfaces
${SQLite3_INCLUDE_DIR} ${SQLite3_INCLUDE_DIR}
) )
target_link_libraries(database core) target_link_libraries(${MODULE_NAME} core)
set_property(TARGET database PROPERTY FOLDER src) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src)
set_target_properties( database PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )

View file

@ -35,7 +35,7 @@ void DirectX2dPainter::paint(SceneModel* model)
const auto loc = model->getTransform().getLocation(); const auto loc = model->getTransform().getLocation();
const auto scale_x = model->getTransform().getScaleX(); const auto scale_x = model->getTransform().getScaleX();
const auto scale_y = model->getTransform().getScaleY(); const auto scale_y = model->getTransform().getScaleY();
D2D1_RECT_F d2d_rect{ static_cast<float>(loc.getX()), static_cast<float>(loc.getY() + scale_x), static_cast<float>(loc.getX() + scale_y), static_cast<float>(loc.getY()) }; D2D1_RECT_F d2d_rect{ static_cast<float>(loc.getX()), static_cast<float>(loc.getY() + scale_y), static_cast<float>(loc.getX() + scale_x), static_cast<float>(loc.getY()) };
if (model->hasFillColor()) if (model->hasFillColor())
{ {

View file

@ -48,7 +48,7 @@ void Win32WebRequest::resizeBuffer(unsigned size)
std::string Win32WebRequest::getUrlFromRequest() const std::string Win32WebRequest::getUrlFromRequest() const
{ {
return UnicodeUtils::utf16ToUtf8String(mHandle->CookedUrl.pFullUrl); return UnicodeUtils::utf16ToUtf8String(mHandle->CookedUrl.pAbsPath);
} }
HttpRequest Win32WebRequest::getRequest() const HttpRequest Win32WebRequest::getRequest() const

View file

@ -9,7 +9,6 @@ Win32WebResponse::Win32WebResponse(const HttpResponse& response)
{ {
RtlZeroMemory((&mResponse), sizeof(*(&mResponse))); RtlZeroMemory((&mResponse), sizeof(*(&mResponse)));
mResponse.StatusCode = response.getStatusCode(); mResponse.StatusCode = response.getStatusCode();
mResponseReason = response.getResponseReason(); mResponseReason = response.getResponseReason();
@ -32,16 +31,14 @@ void Win32WebResponse::populateBody(const HttpResponse& response)
if (!mBody.empty()) if (!mBody.empty())
{ {
mContentLength = std::to_string(mBody.size()); mContentLength = std::to_string(mBody.size());
mResponse.Headers.KnownHeaders[HttpHeaderContentLength].pRawValue = mContentLength.c_str();
mResponse.Headers.KnownHeaders[HttpHeaderContentLength].RawValueLength = (USHORT)strlen(mContentLength.c_str());
HTTP_DATA_CHUNK dataChunk; mDataChunk.DataChunkType = HttpDataChunkFromMemory;
dataChunk.DataChunkType = HttpDataChunkFromMemory; char test[] = "test";
dataChunk.FromMemory.pBuffer = mBody.data(); mDataChunk.FromMemory.pBuffer = mBody.data();
dataChunk.FromMemory.BufferLength = (ULONG)strlen(mBody.data()); mDataChunk.FromMemory.BufferLength = (ULONG)strlen(mBody.data());
mResponse.EntityChunkCount = 1; mResponse.EntityChunkCount = 1;
mResponse.pEntityChunks = &dataChunk; mResponse.pEntityChunks = &mDataChunk;
} }
} }

View file

@ -38,4 +38,5 @@ private:
std::string mContentLength; std::string mContentLength;
HTTP_RESPONSE mResponse; HTTP_RESPONSE mResponse;
HTTP_DATA_CHUNK mDataChunk;
}; };

View file

@ -149,7 +149,7 @@ bool Win32WebServer::sendHttpResponse(const Win32WebRequest& request, const Http
Win32WebResponse response(appResponse); Win32WebResponse response(appResponse);
DWORD bytesSent; DWORD bytesSent;
const auto result = ::HttpSendHttpResponse(mWorkingQueue, request.getHandle()->RequestId, 0, &(response.getResponse()), NULL, &bytesSent, NULL, 0, NULL, NULL); const auto result = ::HttpSendHttpResponse(mWorkingQueue, request.getHandle()->RequestId, 0, &response.getResponse(), nullptr, &bytesSent, nullptr, 0, nullptr, nullptr);
if (result != NO_ERROR) if (result != NO_ERROR)
{ {
MLOG_ERROR("Http response failed with error: " << result); MLOG_ERROR("Http response failed with error: " << result);
@ -196,6 +196,8 @@ bool Win32WebServer::sendHttpPostResponse(const Win32WebRequest& request, const
void Win32WebServer::run() void Win32WebServer::run()
{ {
MLOG_INFO("Running web server on: " << mListenUrl);
Win32WebRequest request; Win32WebRequest request;
if (!request.isValid()) if (!request.isValid())
{ {

View file

@ -19,32 +19,32 @@ std::unique_ptr<MouseEvent> MouseEvent::Create()
return std::make_unique<MouseEvent>(); return std::make_unique<MouseEvent>();
} }
void MouseEvent::SetClientLocation(Pixel location) void MouseEvent::setClientLocation(Pixel location)
{ {
mClientLocation = location; mClientLocation = location;
} }
void MouseEvent::SetScreenLocation(Pixel location) void MouseEvent::setScreenLocation(Pixel location)
{ {
mScreenLocation = location; mScreenLocation = location;
} }
void MouseEvent::SetAction(MouseEvent::Action action) void MouseEvent::setAction(MouseEvent::Action action)
{ {
mAction = action; mAction = action;
} }
Pixel MouseEvent::GetClientLocation() const Pixel MouseEvent::getClientLocation() const
{ {
return mClientLocation; return mClientLocation;
} }
Pixel MouseEvent::GetScreenLocation() const Pixel MouseEvent::getScreenLocation() const
{ {
return mScreenLocation; return mScreenLocation;
} }
MouseEvent::Action MouseEvent::GetAction() const MouseEvent::Action MouseEvent::getAction() const
{ {
return mAction; return mAction;
} }

View file

@ -14,11 +14,6 @@ public:
Released Released
}; };
private:
Pixel mClientLocation;
Pixel mScreenLocation;
Action mAction;
public: public:
MouseEvent(); MouseEvent();
@ -27,16 +22,21 @@ public:
static std::unique_ptr<MouseEvent> Create(); static std::unique_ptr<MouseEvent> Create();
void SetClientLocation(Pixel location); Pixel getClientLocation() const;
void SetScreenLocation(Pixel location); Pixel getScreenLocation() const;
void SetAction(Action action); Action getAction() const;
Pixel GetClientLocation() const; void setClientLocation(Pixel location);
Pixel GetScreenLocation() const; void setScreenLocation(Pixel location);
Action GetAction() const; void setAction(Action action);
private:
Pixel mClientLocation;
Pixel mScreenLocation;
Action mAction;
}; };
using MouseEventUPtr = std::unique_ptr<MouseEvent>; using MouseEventUPtr = std::unique_ptr<MouseEvent>;

View file

@ -5,8 +5,7 @@
#include "TransformNode.h" #include "TransformNode.h"
#include "MouseEvent.h" #include "MouseEvent.h"
#include "FileLogger.h"
#include <iostream>
Button::Button() Button::Button()
: Widget(), : Widget(),
@ -44,7 +43,8 @@ void Button::setLabel(const std::string& text)
void Button::onMyMouseEvent(const MouseEvent* event) void Button::onMyMouseEvent(const MouseEvent* event)
{ {
if(event->GetAction() == MouseEvent::Action::Pressed) MLOG_INFO("Widget mouse event");
if(event->getAction() == MouseEvent::Action::Pressed)
{ {
mCachedColor = mBackgroundColor; mCachedColor = mBackgroundColor;
setBackgroundColor(mClickedColor); setBackgroundColor(mClickedColor);
@ -53,7 +53,7 @@ void Button::onMyMouseEvent(const MouseEvent* event)
mClickFunc(this); mClickFunc(this);
} }
} }
else if(event->GetAction() == MouseEvent::Action::Released) else if(event->getAction() == MouseEvent::Action::Released)
{ {
setBackgroundColor(mCachedColor); setBackgroundColor(mCachedColor);
} }

View file

@ -11,6 +11,7 @@
#include "RootNode.h" #include "RootNode.h"
#include "Window.h" #include "Window.h"
#include "FileLogger.h"
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
@ -293,7 +294,7 @@ bool Widget::onMouseEvent(const MouseEvent* event)
} }
if(!inChild) if(!inChild)
{ {
if(mVisible && contains(event->GetClientLocation())) if(mVisible && contains(event->getClientLocation()))
{ {
onMyMouseEvent(event); onMyMouseEvent(event);
return true; return true;
@ -308,13 +309,13 @@ bool Widget::onMouseEvent(const MouseEvent* event)
void Widget::onMyMouseEvent(const MouseEvent* event) void Widget::onMyMouseEvent(const MouseEvent* event)
{ {
MLOG_INFO("Widget mouse event");
} }
void Widget::updateBackground(const PaintEvent* event) void Widget::updateBackground(const PaintEvent* event)
{ {
unsigned locX = mLocation.getX() + mMargin.mLeft; unsigned locX = mLocation.getX() + mMargin.mLeft;
unsigned locY = mLocation.getX() + mMargin.mTop; unsigned locY = mLocation.getY() + mMargin.mTop;
unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight; unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom; unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
@ -335,6 +336,8 @@ void Widget::updateBackground(const PaintEvent* event)
if (mMaterialDirty) if (mMaterialDirty)
{ {
mBackgroundNode->setFillColor(mBackgroundColor); mBackgroundNode->setFillColor(mBackgroundColor);
mBackgroundNode->setStrokeColor(mBorderColor);
mBackgroundNode->setStrokeThickness(mBorderThickness);
} }
if (mVisibilityDirty) if (mVisibilityDirty)

View file

@ -141,8 +141,6 @@ protected:
virtual bool isDirty() const; virtual bool isDirty() const;
void setParent(Widget* parent); void setParent(Widget* parent);
Widget* getParent() const; Widget* getParent() const;

View file

@ -60,7 +60,7 @@ void GeometryNode::updateMaterial()
mBackgroundItem->setFillColor(mFillColor); mBackgroundItem->setFillColor(mFillColor);
} }
if (mHasStrokeColor) if (mHasStrokeColor && mStrokeThickness > 0)
{ {
mBackgroundItem->setOutlineColor(mStrokeColor); mBackgroundItem->setOutlineColor(mStrokeColor);
mBackgroundItem->setOutlineThickness(mStrokeThickness); mBackgroundItem->setOutlineThickness(mStrokeThickness);

View file

@ -29,7 +29,7 @@ void SvgShapeElement::setFill(const Color& fill)
auto attr = std::make_unique<XmlAttribute>("fill"); auto attr = std::make_unique<XmlAttribute>("fill");
std::stringstream sstr; std::stringstream sstr;
sstr << "rgb(" << fill.getR() << "," << fill.getG() << "," << fill.getB() << ")"; sstr << "rgb(" << fill.toString() << ")";
attr->setValue(sstr.str()); attr->setValue(sstr.str());
addAttribute(std::move(attr)); addAttribute(std::move(attr));
@ -48,7 +48,7 @@ void SvgShapeElement::setStrokeColor(const Color& stroke)
auto attr = std::make_unique<XmlAttribute>("stroke"); auto attr = std::make_unique<XmlAttribute>("stroke");
std::stringstream sstr; std::stringstream sstr;
sstr << "rgb(" << stroke.getR() << "," << stroke.getG() << "," << stroke.getB() << ")"; sstr << "rgb(" << stroke.toString() << ")";
attr->setValue(sstr.str()); attr->setValue(sstr.str());
addAttribute(std::move(attr)); addAttribute(std::move(attr));

View file

@ -14,6 +14,7 @@
#include "DesktopManager.h" #include "DesktopManager.h"
#include <WinUser.h> #include <WinUser.h>
#include <windowsx.h>
LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -90,6 +91,24 @@ void Win32Window::onPaintMessage()
mWindow->doPaint(nullptr); mWindow->doPaint(nullptr);
} }
void Win32Window::onMouseDownMessage(int x, int y)
{
auto event = MouseEvent::Create();
event->setClientLocation({ static_cast<unsigned>(x), static_cast<unsigned>(y) });
event->setAction(MouseEvent::Action::Pressed);
mDesktopManager->onUiEvent(std::move(event));
MLOG_INFO("Mouse down at: " << x << " , " << y);
}
void Win32Window::onMouseUpMessage(int x, int y)
{
auto event = MouseEvent::Create();
event->setClientLocation({ static_cast<unsigned>(x), static_cast<unsigned>(y) });
event->setAction(MouseEvent::Action::Released);
mDesktopManager->onUiEvent(std::move(event));
MLOG_INFO("Mouse up at: " << x << " , " << y);
}
LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{ {
switch (message) switch (message)
@ -114,6 +133,20 @@ LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lPa
onPaintMessage(); onPaintMessage();
return 0; return 0;
} }
case WM_LBUTTONDOWN :
{
const auto x = GET_X_LPARAM(lParam);
const auto y = GET_Y_LPARAM(lParam);
onMouseDownMessage(x, y);
return 0;
}
case WM_LBUTTONUP:
{
const auto x = GET_X_LPARAM(lParam);
const auto y = GET_Y_LPARAM(lParam);
onMouseUpMessage(x, y);
return 0;
}
case WM_SIZE: case WM_SIZE:
{ {
auto width = LOWORD(lParam); auto width = LOWORD(lParam);

View file

@ -50,6 +50,10 @@ public:
void afterPaint(mt::Screen* screen); void afterPaint(mt::Screen* screen);
private: private:
void onMouseDownMessage(int x, int y);
void onMouseUpMessage(int x, int y);
void onPaintMessage(); void onPaintMessage();
HWND mHandle{ 0 }; HWND mHandle{ 0 };

View file

@ -1,9 +1,14 @@
#include "TestUiApplication.h" #include "TestUiApplication.h"
#include "TestFramework.h" #include "TestFramework.h"
#include "TestRenderUtils.h"
#include "TestUtils.h"
#include "RectangleNode.h" #include "RectangleNode.h"
#include "TextNode.h" #include "TextNode.h"
#include "Button.h"
#include "TransformNode.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -22,3 +27,29 @@ TEST_CASE(TestD2dRendering, "graphics")
scene->update(); scene->update();
gui_app->run(); gui_app->run();
}; };
TEST_CASE(TestD2dWidgetRendering, "graphics")
{
auto gui_app = TestCaseRunner::getInstance().getTestApplication();
auto scene = gui_app->getMainWindowScene();
Widget widget;
widget.setBackgroundColor({ 0, 200, 0 });
widget.setBounds(300, 300);
auto button = Button::Create();
button->setBackgroundColor({ 200, 0, 0 });
button->setLabel("Test Button");
button->setMaxWidth(100);
widget.addWidget(std::move(button));
widget.onPaintEvent(nullptr);
scene->addNode(widget.getRootNode());
scene->update();
TestRenderer::writeSvg(TestUtils::getTestOutputDir(__FILE__) / "TestD2dWidgetRendering.svg", scene);
gui_app->run();
};

View file

@ -41,9 +41,14 @@ public:
} }
void writeSvg(const Path& path) void writeSvg(const Path& path)
{
writeSvg(path, mSurface->getScene());
}
static void writeSvg(const Path& path, Scene* scene)
{ {
SvgConverter converter; SvgConverter converter;
auto svg_document = converter.convert(mSurface->getScene()); auto svg_document = converter.convert(scene);
SvgWriter writer; SvgWriter writer;
auto svg_content = writer.toString(svg_document.get()); auto svg_content = writer.toString(svg_document.get());