From 35ed2427c15747fddc948d8e575fec9d72441f0c Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sat, 28 Jul 2018 22:22:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=B6=88=E6=81=AF=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=96=B9=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Input.cpp | 46 ++-------------- core/Base/Window.cpp | 16 ++++-- core/Common/Scene.cpp | 6 +-- core/Event/KeyEvent.cpp | 2 +- core/Event/MouseEvent.cpp | 35 +++++++++---- core/Node/Button.cpp | 104 ++++++++++++++++++------------------- core/Node/Node.cpp | 76 +++++---------------------- core/Node/ToggleButton.cpp | 8 +-- core/e2dbase.h | 26 ++-------- core/e2dcommon.h | 20 +++++-- core/e2dnode.h | 21 +++++--- 11 files changed, 149 insertions(+), 211 deletions(-) diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index 1654b14d..71a1fccb 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -13,9 +13,7 @@ e2d::Input::Input() CoInitialize(nullptr); ZeroMemory(_keyBuffer, sizeof(_keyBuffer)); - ZeroMemory(_keyRecordBuffer, sizeof(_keyRecordBuffer)); ZeroMemory(&_mouseState, sizeof(_mouseState)); - ZeroMemory(&_mouseRecordState, sizeof(_mouseRecordState)); // 初始化接口对象 HRESULT hr = DirectInput8Create( @@ -116,7 +114,6 @@ void e2d::Input::update() } else { - strcpy_s(_keyRecordBuffer, 256, _keyBuffer); _keyboardDevice->GetDeviceState(sizeof(_keyBuffer), (void**)&_keyBuffer); } } @@ -132,7 +129,6 @@ void e2d::Input::update() } else { - _mouseRecordState = _mouseState; _mouseDevice->GetDeviceState(sizeof(_mouseState), (void**)&_mouseState); } } @@ -145,22 +141,6 @@ bool e2d::Input::isDown(KeyCode key) return false; } -bool e2d::Input::isPress(KeyCode key) -{ - if ((_keyBuffer[static_cast(key)] & 0x80) && - !(_keyRecordBuffer[static_cast(key)] & 0x80)) - return true; - return false; -} - -bool e2d::Input::isRelease(KeyCode key) -{ - if (!(_keyBuffer[static_cast(key)] & 0x80) && - (_keyRecordBuffer[static_cast(key)] & 0x80)) - return true; - return false; -} - bool e2d::Input::isDown(MouseCode code) { if (_mouseState.rgbButtons[static_cast(code)] & 0x80) @@ -168,22 +148,6 @@ bool e2d::Input::isDown(MouseCode code) return false; } -bool e2d::Input::isPress(MouseCode code) -{ - if ((_mouseState.rgbButtons[static_cast(code)] & 0x80) && - !(_mouseRecordState.rgbButtons[static_cast(code)] & 0x80)) - return true; - return false; -} - -bool e2d::Input::isRelease(MouseCode code) -{ - if (!(_mouseState.rgbButtons[static_cast(code)] & 0x80) && - (_mouseRecordState.rgbButtons[static_cast(code)] & 0x80)) - return true; - return false; -} - float e2d::Input::getMouseX() { return getMousePos().x; @@ -196,14 +160,14 @@ float e2d::Input::getMouseY() e2d::Point e2d::Input::getMousePos() { - HWND hWnd = Window::getInstance()->getHWnd(); + auto window = Window::getInstance(); POINT mousePos; - GetCursorPos(&mousePos); - ScreenToClient(hWnd, &mousePos); + ::GetCursorPos(&mousePos); + ::ScreenToClient(window->getHWnd(), &mousePos); - UINT ret = ::GetDpiForWindow(hWnd); - return Point(mousePos.x * 96.f / ret, mousePos.y * 96.f / ret); + float dpi = window->getDpi(); + return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi); } float e2d::Input::getMouseDeltaX() diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index d1ee83b6..43585eff 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -11,6 +11,7 @@ e2d::Window::Window() , _size(640, 480) , _title(L"Easy2D Game") , _iconID(0) + , _dpi(0.f) { } @@ -164,6 +165,8 @@ HWND e2d::Window::__create() HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE); ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); } + // 获取 DPI + _dpi = static_cast(::GetDpiForWindow(hWnd)); } else { @@ -196,6 +199,11 @@ e2d::Size e2d::Window::getSize() return _size; } +float e2d::Window::getDpi() +{ + return _dpi; +} + e2d::String e2d::Window::getTitle() { return _title; @@ -410,7 +418,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar case WM_MOUSEMOVE: case WM_MOUSEWHEEL: { - SceneManager::getInstance()->dispatch(MouseEvent(message, wParam, lParam)); + SceneManager::getInstance()->dispatch(MouseEvent(hWnd, message, wParam, lParam)); } result = 0; hasHandled = true; @@ -420,7 +428,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar case WM_KEYDOWN: case WM_KEYUP: { - SceneManager::getInstance()->dispatch(KeyEvent(message, wParam, lParam)); + SceneManager::getInstance()->dispatch(KeyEvent(hWnd, message, wParam, lParam)); } result = 0; hasHandled = true; @@ -434,8 +442,8 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar if (wParam == SIZE_RESTORED) { - UINT dpi = ::GetDpiForWindow(hWnd); - _instance->_size = Size(width * 96.f / dpi, height * 96.f / dpi); + _instance->_size.width = width * 96.f / _instance->_dpi; + _instance->_size.height = height * 96.f / _instance->_dpi; } // 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染 diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index a5935558..1341b6a7 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -37,14 +37,14 @@ void e2d::Scene::update() { if (_autoUpdate) { - this->onUpdate(); + onUpdate(); } _root->_update(); } void e2d::Scene::dispatch(const MouseEvent & e) { - if (this->onMouseEvent(e)) + if (onMouseEvent(e)) { _root->dispatch(e); } @@ -52,7 +52,7 @@ void e2d::Scene::dispatch(const MouseEvent & e) void e2d::Scene::dispatch(const KeyEvent & e) { - if (this->onKeyEvent(e)) + if (onKeyEvent(e)) { _root->dispatch(e); } diff --git a/core/Event/KeyEvent.cpp b/core/Event/KeyEvent.cpp index 7ab30a63..cb854367 100644 --- a/core/Event/KeyEvent.cpp +++ b/core/Event/KeyEvent.cpp @@ -1,7 +1,7 @@ #include "..\e2dcommon.h" -e2d::KeyEvent::KeyEvent(UINT message, WPARAM wParam, LPARAM lParam) +e2d::KeyEvent::KeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) : _code(KeyCode(wParam)) , _type(Type(message)) , _count(static_cast((DWORD)lParam & 0x0000FFFF)) diff --git a/core/Event/MouseEvent.cpp b/core/Event/MouseEvent.cpp index dfa38390..1a77275d 100644 --- a/core/Event/MouseEvent.cpp +++ b/core/Event/MouseEvent.cpp @@ -1,13 +1,15 @@ #include "..\e2dcommon.h" +#include "..\e2dbase.h" - -e2d::MouseEvent::MouseEvent(UINT message, WPARAM wParam, LPARAM lParam) - : _pos(LOWORD(lParam), HIWORD(lParam)) - , _shiftDown(GET_KEYSTATE_WPARAM(wParam) == MK_SHIFT) - , _ctrlDown(GET_KEYSTATE_WPARAM(wParam) == MK_CONTROL) - , _wheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)) +e2d::MouseEvent::MouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) + : _message(message) + , _wParam(wParam) + , _lParam(lParam) , _type(Type(message)) { + float dpi = Window::getInstance()->getDpi(); + _pos.x = ((float)(short)LOWORD(lParam)) * 96.f / dpi; + _pos.y = ((float)(short)HIWORD(lParam)) * 96.f / dpi; } float e2d::MouseEvent::getX() const @@ -27,17 +29,32 @@ e2d::Point e2d::MouseEvent::getPos() const bool e2d::MouseEvent::isShiftDown() const { - return _shiftDown; + return GET_KEYSTATE_WPARAM(_wParam) == MK_SHIFT; } bool e2d::MouseEvent::isCtrlDown() const { - return _ctrlDown; + return GET_KEYSTATE_WPARAM(_wParam) == MK_CONTROL; } float e2d::MouseEvent::getWheelDelta() const { - return _wheelDelta; + return static_cast(GET_WHEEL_DELTA_WPARAM(_wParam)); +} + +bool e2d::MouseEvent::isLButtonDown() const +{ + return GET_KEYSTATE_WPARAM(_wParam) == MK_LBUTTON; +} + +bool e2d::MouseEvent::isRButtonDown() const +{ + return GET_KEYSTATE_WPARAM(_wParam) == MK_RBUTTON; +} + +bool e2d::MouseEvent::isMButtonDown() const +{ + return GET_KEYSTATE_WPARAM(_wParam) == MK_MBUTTON; } e2d::MouseEvent::Type e2d::MouseEvent::getType() const diff --git a/core/Node/Button.cpp b/core/Node/Button.cpp index d739a9b3..cbea2340 100644 --- a/core/Node/Button.cpp +++ b/core/Node/Button.cpp @@ -6,7 +6,7 @@ e2d::Button::Button() : _func(nullptr) - , _state(ButtonState::Normal) + , _status(Status::Normal) , _enabled(true) , _isSelected(false) , _normal(nullptr) @@ -18,7 +18,7 @@ e2d::Button::Button() e2d::Button::Button(Node * normal, const Function& func) : _func(nullptr) - , _state(ButtonState::Normal) + , _status(Status::Normal) , _enabled(true) , _isSelected(false) , _normal(nullptr) @@ -32,7 +32,7 @@ e2d::Button::Button(Node * normal, const Function& func) e2d::Button::Button(Node * normal, Node * selected, const Function& func) : _func(nullptr) - , _state(ButtonState::Normal) + , _status(Status::Normal) , _enabled(true) , _isSelected(false) , _normal(nullptr) @@ -47,7 +47,7 @@ e2d::Button::Button(Node * normal, Node * selected, const Function& func) e2d::Button::Button(Node * normal, Node * mouseover, Node * selected, const Function& func) : _func(nullptr) - , _state(ButtonState::Normal) + , _status(Status::Normal) , _enabled(true) , _isSelected(false) , _normal(nullptr) @@ -63,7 +63,7 @@ e2d::Button::Button(Node * normal, Node * mouseover, Node * selected, const Func e2d::Button::Button(Node * normal, Node * mouseover, Node * selected, Node * disabled, const Function& func) : _func(nullptr) - , _state(ButtonState::Normal) + , _status(Status::Normal) , _enabled(true) , _isSelected(false) , _normal(nullptr) @@ -188,69 +188,65 @@ void e2d::Button::setPivot(float pivotX, float pivotY) SAFE_SET(_disabled, setPivot, pivotX, pivotY); } -void e2d::Button::_update() +void e2d::Button::dispatch(const MouseEvent & e) { - Node::_update(); - - if (SceneManager::getInstance()->isTransitioning()) - return; - - auto input = Input::getInstance(); - auto window = Window::getInstance(); - if (_enabled && _visible && _normal) { - if (input->isRelease(MouseCode::Left)) + bool contains = _normal->containsPoint(e.getPos()); + if (e.getType() == MouseEvent::Type::LeftUp && _isSelected && contains) { - // 鼠标左键抬起时,判断鼠标坐标是否在按钮内部 - if (_isSelected && - _normal->containsPoint(input->getMousePos())) + _isSelected = false; + _runCallback(); + _setStatus(Status::Normal); + } + else if (e.getType() == MouseEvent::Type::LeftDown) + { + _isSelected = contains; + _setStatus(contains ? Status::Selected : Status::Normal); + } + else if (e.getType() == MouseEvent::Type::LeftUp) + { + _isSelected = false; + } + else if (e.getType() == MouseEvent::Type::Move && _isSelected && contains) + { + _setStatus(Status::Selected); + } + else + { + if (!e.isLButtonDown() && _isSelected) { _isSelected = false; - _runCallback(); } + _setStatus(contains ? Status::Mouseover : Status::Normal); } - - if (input->isPress(MouseCode::Left)) - { - if (_normal->containsPoint(input->getMousePos())) - { - // 鼠标左键按下,且位于按钮内时,标记 _isSelected 为 true - _isSelected = true; - return; - } - } - - if (_isSelected && input->isDown(MouseCode::Left)) - { - if (_normal->containsPoint(input->getMousePos())) - { - _setState(ButtonState::Selected); - window->setCursor(Window::Cursor::Hand); - return; - } - } - else if (_normal->containsPoint(input->getMousePos())) - { - _setState(ButtonState::Mouseover); - window->setCursor(Window::Cursor::Hand); - return; - } - - _setState(ButtonState::Normal); } - if (_visible && !_enabled && _normal && _normal->containsPoint(input->getMousePos())) + Node::dispatch(e); +} + +void e2d::Button::_render() +{ + Node::_render(); + + if (_visible && + !_enabled && + _normal && + _normal->containsPoint(Input::getInstance()->getMousePos())) { - window->setCursor(Window::Cursor::No); + Window::getInstance()->setCursor(Window::Cursor::No); + } + else if (_status == Status::Mouseover || _status == Status::Selected) + { + Window::getInstance()->setCursor(Window::Cursor::Hand); } } -void e2d::Button::_setState(ButtonState state) +void e2d::Button::_setStatus(Status status) { - if (_state != state) + if (_status != status) { - _state = state; + _status = status; _updateVisible(); } } @@ -264,11 +260,11 @@ void e2d::Button::_updateVisible() if (_enabled) { - if (_state == ButtonState::Selected && _selected) + if (_status == Status::Selected && _selected) { _selected->setVisible(true); } - else if (_state == ButtonState::Mouseover && _mouseover) + else if (_status == Status::Mouseover && _mouseover) { _mouseover->setVisible(true); } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 97822f46..ce7d4b87 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -304,79 +304,31 @@ void e2d::Node::updateTransform() } } -bool e2d::Node::dispatch(const MouseEvent & e) +void e2d::Node::dispatch(const MouseEvent & e) { - if (_children.empty()) + if (!onMouseEvent(e)) + return; + + if (!_children.empty()) { - return onMouseEvent(e); - } - else - { - size_t i; - for (i = 0; i < _children.size(); ++i) + for (auto child : _children) { - auto child = _children[i]; - if (child->getOrder() < 0) - { - if (!child->dispatch(e)) - { - return false; - } - } - else - { - break; - } + child->dispatch(e); } - - if (!onMouseEvent(e)) - { - return false; - } - - for (; i < _children.size(); ++i) - if (!_children[i]->dispatch(e)) - return false; - - return true; } } -bool e2d::Node::dispatch(const KeyEvent & e) +void e2d::Node::dispatch(const KeyEvent & e) { - if (_children.empty()) + if (!onKeyEvent(e)) + return; + + if (!_children.empty()) { - return onKeyEvent(e); - } - else - { - size_t i; - for (i = 0; i < _children.size(); ++i) + for (auto child : _children) { - auto child = _children[i]; - if (child->getOrder() < 0) - { - if (!child->dispatch(e)) - { - return false; - } - } - else - { - break; - } + child->dispatch(e); } - - if (!onKeyEvent(e)) - { - return false; - } - - for (; i < _children.size(); ++i) - if (!_children[i]->dispatch(e)) - return false; - - return true; } } diff --git a/core/Node/ToggleButton.cpp b/core/Node/ToggleButton.cpp index 90c7421a..d824b4d6 100644 --- a/core/Node/ToggleButton.cpp +++ b/core/Node/ToggleButton.cpp @@ -12,7 +12,7 @@ this->addChild(New); \ } \ Old = New; \ - _updateState(); \ + _updateStatus(); \ _updateVisible(); \ } \ @@ -117,7 +117,7 @@ void e2d::ToggleButton::setChecked(bool checked) if (_checked != checked) { _checked = checked; - _updateState(); + _updateStatus(); _updateVisible(); } } @@ -176,7 +176,7 @@ void e2d::ToggleButton::setPivot(float pivotX, float pivotY) SAFE_SET(_disabledOff, setPivot, pivotX, pivotY); } -void e2d::ToggleButton::_updateState() +void e2d::ToggleButton::_updateStatus() { if (_checked) { @@ -207,7 +207,7 @@ void e2d::ToggleButton::_updateState() void e2d::ToggleButton::_runCallback() { _checked = !_checked; - _updateState(); + _updateStatus(); if (_func) { diff --git a/core/e2dbase.h b/core/e2dbase.h index aad0844c..c7df7890 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -230,6 +230,9 @@ public: // 获取窗体大小 Size getSize(); + // 获取窗口 DPI + float getDpi(); + // 获取窗口句柄 HWND getHWnd(); @@ -279,6 +282,7 @@ private: Size _size; String _title; int _iconID; + float _dpi; static Window * _instance; }; @@ -299,31 +303,11 @@ public: KeyCode key ); - // 检测键盘某按键是否被点击 - bool isPress( - KeyCode key - ); - - // 检测键盘某按键是否正在松开 - bool isRelease( - KeyCode key - ); - // 检测鼠标按键是否正被按下 bool isDown( MouseCode code ); - // 检测鼠标按键是否被点击 - bool isPress( - MouseCode code - ); - - // 检测鼠标按键是否正在松开 - bool isRelease( - MouseCode code - ); - // 获得鼠标X轴坐标值 float getMouseX(); @@ -357,9 +341,7 @@ private: IDirectInputDevice8W* _keyboardDevice; IDirectInputDevice8W* _mouseDevice; DIMOUSESTATE _mouseState; - DIMOUSESTATE _mouseRecordState; char _keyBuffer[256]; - char _keyRecordBuffer[256]; static Input * _instance; }; diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 64d42ec3..66ad39c5 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -586,6 +586,7 @@ public: public: explicit KeyEvent( + HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam @@ -634,15 +635,19 @@ public: public: explicit MouseEvent( + HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); + // 获取鼠标横坐标 float getX() const; + // 获取鼠标纵坐标 float getY() const; + // 获取鼠标坐标 Point getPos() const; // 获取事件类型 @@ -650,6 +655,15 @@ public: float getWheelDelta() const; + // 鼠标左键是否按下 + bool isLButtonDown() const; + + // 鼠标右键是否按下 + bool isRButtonDown() const; + + // 鼠标中键是否按下 + bool isMButtonDown() const; + // Shift 键是否按下 bool isShiftDown() const; @@ -657,9 +671,9 @@ public: bool isCtrlDown() const; protected: - bool _shiftDown; - bool _ctrlDown; - float _wheelDelta; + UINT _message; + WPARAM _wParam; + LPARAM _lParam; Point _pos; MouseEvent::Type _type; }; diff --git a/core/e2dnode.h b/core/e2dnode.h index 83042934..7e11dde3 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -402,12 +402,12 @@ public: void updateTransform(); // 分发鼠标消息 - bool dispatch( + virtual void dispatch( const MouseEvent& e ); // 分发按键消息 - bool dispatch( + virtual void dispatch( const KeyEvent& e ); @@ -827,17 +827,22 @@ public: float pivotY ) override; + // 分发鼠标消息 + virtual void dispatch( + const MouseEvent& e + ) override; + protected: E2D_DISABLE_COPY(Button); // 按钮状态枚举 - enum class ButtonState { Normal, Mouseover, Selected }; + enum class Status { Normal, Mouseover, Selected }; - // 更新节点 - virtual void _update() override; + // 渲染节点 + virtual void _render() override; // 设置按钮状态 - virtual void _setState(ButtonState state); + virtual void _setStatus(Status status); // 刷新按钮显示 virtual void _updateVisible(); @@ -852,7 +857,7 @@ protected: Node * _disabled; bool _enabled; bool _isSelected; - ButtonState _state; + Status _status; Function _func; }; @@ -958,7 +963,7 @@ protected: E2D_DISABLE_COPY(ToggleButton); // 刷新按钮开关 - virtual void _updateState(); + virtual void _updateStatus(); // 执行按钮函数对象 virtual void _runCallback() override;