From e884201a90d621bdb94c1cbe741dd2b5bfdc60bb Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Fri, 13 Jul 2012 12:33:09 +0300 Subject: [PATCH] Added support for custom cursors (based on @brianferguson's work) Also refactored mouse action code to remove duplicate code. --- Library/Library.vcxproj | 4 + Library/Library.vcxproj.filters | 6 + Library/Meter.cpp | 23 +-- Library/Meter.h | 32 +---- Library/MeterWindow.cpp | 238 +++++++------------------------- Library/MeterWindow.h | 40 ++---- Library/Mouse.cpp | 206 +++++++++++++++++++++++++++ Library/Mouse.h | 93 +++++++++++++ 8 files changed, 376 insertions(+), 266 deletions(-) create mode 100644 Library/Mouse.cpp create mode 100644 Library/Mouse.h diff --git a/Library/Library.vcxproj b/Library/Library.vcxproj index 79720eb4..24ff780e 100644 --- a/Library/Library.vcxproj +++ b/Library/Library.vcxproj @@ -286,6 +286,9 @@ Use + + Use + @@ -422,6 +425,7 @@ + diff --git a/Library/Library.vcxproj.filters b/Library/Library.vcxproj.filters index bb74fd35..3e815360 100644 --- a/Library/Library.vcxproj.filters +++ b/Library/Library.vcxproj.filters @@ -318,6 +318,9 @@ Source Files + + Source Files + @@ -545,6 +548,9 @@ Lua\Lua + + Header Files + diff --git a/Library/Meter.cpp b/Library/Meter.cpp index 872df058..c826c64e 100644 --- a/Library/Meter.cpp +++ b/Library/Meter.cpp @@ -57,7 +57,6 @@ CMeter::CMeter(CMeterWindow* meterWindow, const WCHAR* name) : m_MeterWindow(met m_ToolTipHidden(meterWindow->GetMeterToolTipHidden()), m_ToolTipHandle(), m_HasMouseAction(false), - m_MouseActionCursor(meterWindow->GetMeterMouseActionCursor()), m_MouseOver(false), m_RelativeX(POSITION_ABSOLUTE), m_RelativeY(POSITION_ABSOLUTE), @@ -351,24 +350,14 @@ void CMeter::ReadOptions(CConfigParser& parser, const WCHAR* section) m_SolidColor2 = parser.ReadColor(section, L"SolidColor2", m_SolidColor.GetValue()); m_SolidAngle = (Gdiplus::REAL)parser.ReadFloat(section, L"GradientAngle", 0.0); - m_LeftMouseDownAction = parser.ReadString(section, L"LeftMouseDownAction", L"", false); - m_RightMouseDownAction = parser.ReadString(section, L"RightMouseDownAction", L"", false); - m_MiddleMouseDownAction = parser.ReadString(section, L"MiddleMouseDownAction", L"", false); - m_LeftMouseUpAction = parser.ReadString(section, L"LeftMouseUpAction", L"", false); - m_RightMouseUpAction = parser.ReadString(section, L"RightMouseUpAction", L"", false); - m_MiddleMouseUpAction = parser.ReadString(section, L"MiddleMouseUpAction", L"", false); - m_LeftMouseDoubleClickAction = parser.ReadString(section, L"LeftMouseDoubleClickAction", L"", false); - m_RightMouseDoubleClickAction = parser.ReadString(section, L"RightMouseDoubleClickAction", L"", false); - m_MiddleMouseDoubleClickAction = parser.ReadString(section, L"MiddleMouseDoubleClickAction", L"", false); - m_MouseOverAction = parser.ReadString(section, L"MouseOverAction", L"", false); - m_MouseLeaveAction = parser.ReadString(section, L"MouseLeaveAction", L"", false); - - m_MouseActionCursor = 0!=parser.ReadInt(section, L"MouseActionCursor", m_MeterWindow->GetMeterMouseActionCursor()); + m_Mouse.ReadOptions(parser, section, m_MeterWindow); m_HasMouseAction = - ( !m_LeftMouseUpAction.empty() || !m_LeftMouseDownAction.empty() || !m_LeftMouseDoubleClickAction.empty() - || !m_MiddleMouseUpAction.empty() || !m_MiddleMouseDownAction.empty() || !m_MiddleMouseDoubleClickAction.empty() - || !m_RightMouseUpAction.empty() || !m_RightMouseDownAction.empty() || !m_RightMouseDoubleClickAction.empty() ); + !(m_Mouse.GetLeftUpAction().empty() && m_Mouse.GetLeftDownAction().empty() && + m_Mouse.GetLeftDoubleClickAction().empty() && m_Mouse.GetMiddleUpAction().empty() && + m_Mouse.GetMiddleDownAction().empty() && m_Mouse.GetMiddleDoubleClickAction().empty() && + m_Mouse.GetRightUpAction().empty() && m_Mouse.GetRightDownAction().empty() && + m_Mouse.GetRightDoubleClickAction().empty()); m_ToolTipText = parser.ReadString(section, L"ToolTipText", L""); m_ToolTipTitle = parser.ReadString(section, L"ToolTipTitle", L""); diff --git a/Library/Meter.h b/Library/Meter.h index 2978bd5f..c8851fee 100644 --- a/Library/Meter.h +++ b/Library/Meter.h @@ -60,17 +60,8 @@ public: void SetX(int x) { m_X = x; m_RelativeX = POSITION_ABSOLUTE; } void SetY(int y) { m_Y = y; m_RelativeY = POSITION_ABSOLUTE; } - const std::wstring& GetRightMouseDownAction() { return m_RightMouseDownAction; } - const std::wstring& GetRightMouseUpAction() { return m_RightMouseUpAction; } - const std::wstring& GetRightMouseDoubleClickAction() { return m_RightMouseDoubleClickAction; } - const std::wstring& GetLeftMouseDownAction() { return m_LeftMouseDownAction; } - const std::wstring& GetLeftMouseUpAction() { return m_LeftMouseUpAction; } - const std::wstring& GetLeftMouseDoubleClickAction() { return m_LeftMouseDoubleClickAction; } - const std::wstring& GetMiddleMouseDownAction() { return m_MiddleMouseDownAction; } - const std::wstring& GetMiddleMouseUpAction() { return m_MiddleMouseUpAction; } - const std::wstring& GetMiddleMouseDoubleClickAction() { return m_MiddleMouseDoubleClickAction; } - const std::wstring& GetMouseOverAction() { return m_MouseOverAction; } - const std::wstring& GetMouseLeaveAction() { return m_MouseLeaveAction; } + const CMouse& GetMouse() { return m_Mouse; } + bool HasMouseAction() { return m_HasMouseAction; } const std::wstring& GetToolTipText() { return m_ToolTipText; } bool HasToolTip() { return m_ToolTipHandle != NULL; } @@ -78,9 +69,6 @@ public: void CreateToolTip(CMeterWindow* meterWindow); void UpdateToolTip(); - bool HasMouseAction() { return m_HasMouseAction; } - bool HasMouseActionCursor() { return m_MouseActionCursor; } - virtual void Hide(); virtual void Show(); bool IsHidden() { return m_Hidden; } @@ -166,22 +154,10 @@ protected: HWND m_ToolTipHandle; - std::wstring m_LeftMouseDownAction; - std::wstring m_RightMouseDownAction; - std::wstring m_MiddleMouseDownAction; - std::wstring m_LeftMouseUpAction; - std::wstring m_RightMouseUpAction; - std::wstring m_MiddleMouseUpAction; - std::wstring m_LeftMouseDoubleClickAction; - std::wstring m_RightMouseDoubleClickAction; - std::wstring m_MiddleMouseDoubleClickAction; - std::wstring m_MouseOverAction; - std::wstring m_MouseLeaveAction; - + CMouse m_Mouse; bool m_HasMouseAction; - bool m_MouseActionCursor; - bool m_MouseOver; + METER_POSITION m_RelativeX; METER_POSITION m_RelativeY; diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index a04912ca..b2d4ede4 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -140,7 +140,6 @@ CMeterWindow::CMeterWindow(const std::wstring& folderPath, const std::wstring& f m_UpdateCounter(), m_MouseMoveCounter(), m_FontCollection(), - m_MouseActionCursor(true), m_ToolTipHidden(false) { if (!c_DwmInstance && CSystem::GetOSPlatform() >= OSPLATFORM_VISTA) @@ -2015,23 +2014,13 @@ bool CMeterWindow::ReadSkin() } } - m_LeftMouseDownAction = m_Parser.ReadString(L"Rainmeter", L"LeftMouseDownAction", L"", false); - m_RightMouseDownAction = m_Parser.ReadString(L"Rainmeter", L"RightMouseDownAction", L"", false); - m_MiddleMouseDownAction = m_Parser.ReadString(L"Rainmeter", L"MiddleMouseDownAction", L"", false); - m_LeftMouseUpAction = m_Parser.ReadString(L"Rainmeter", L"LeftMouseUpAction", L"", false); - m_RightMouseUpAction = m_Parser.ReadString(L"Rainmeter", L"RightMouseUpAction", L"", false); - m_MiddleMouseUpAction = m_Parser.ReadString(L"Rainmeter", L"MiddleMouseUpAction", L"", false); - m_LeftMouseDoubleClickAction = m_Parser.ReadString(L"Rainmeter", L"LeftMouseDoubleClickAction", L"", false); - m_RightMouseDoubleClickAction = m_Parser.ReadString(L"Rainmeter", L"RightMouseDoubleClickAction", L"", false); - m_MiddleMouseDoubleClickAction = m_Parser.ReadString(L"Rainmeter", L"MiddleMouseDoubleClickAction", L"", false); - m_MouseOverAction = m_Parser.ReadString(L"Rainmeter", L"MouseOverAction", L"", false); - m_MouseLeaveAction = m_Parser.ReadString(L"Rainmeter", L"MouseLeaveAction", L"", false); + m_Mouse.ReadOptions(m_Parser, L"Rainmeter", this); + m_OnRefreshAction = m_Parser.ReadString(L"Rainmeter", L"OnRefreshAction", L"", false); m_OnCloseAction = m_Parser.ReadString(L"Rainmeter", L"OnCloseAction", L"", false); m_WindowUpdate = m_Parser.ReadInt(L"Rainmeter", L"Update", INTERVAL_METER); m_TransitionUpdate = m_Parser.ReadInt(L"Rainmeter", L"TransitionUpdate", INTERVAL_TRANSITION); - m_MouseActionCursor = 0 != m_Parser.ReadInt(L"Rainmeter", L"MouseActionCursor", 1); m_ToolTipHidden = 0 != m_Parser.ReadInt(L"Rainmeter", L"ToolTipHidden", 0); if (CSystem::GetOSPlatform() >= OSPLATFORM_VISTA) @@ -3136,7 +3125,7 @@ bool CMeterWindow::HitTest(int x, int y) void CMeterWindow::HandleButtons(POINT pos, BUTTONPROC proc, bool execute) { bool redraw = false; - bool drawCursor = false; + HCURSOR cursor = NULL; std::list::const_reverse_iterator j = m_Meters.rbegin(); for ( ; j != m_Meters.rend(); ++j) @@ -3168,12 +3157,12 @@ void CMeterWindow::HandleButtons(POINT pos, BUTTONPROC proc, bool execute) } } - if (!drawCursor) + if (!cursor && + ((*j)->HasMouseAction() || button) && + (*j)->GetMouse().GetCursorType() != MOUSECURSOR_ARROW && + (*j)->HitTest(pos.x, pos.y)) { - if ((*j)->HasMouseActionCursor() && (*j)->HitTest(pos.x, pos.y)) - { - drawCursor = ((*j)->HasMouseAction() || button); - } + cursor = (*j)->GetMouse().GetCursor(); } } @@ -3182,8 +3171,12 @@ void CMeterWindow::HandleButtons(POINT pos, BUTTONPROC proc, bool execute) Redraw(); } - // Set cursor - SetCursor(LoadCursor(NULL, drawCursor ? IDC_HAND : IDC_ARROW)); + if (!cursor) + { + cursor = LoadCursor(NULL, IDC_ARROW); + } + + SetCursor(cursor); } /* @@ -4155,8 +4148,10 @@ LRESULT CMeterWindow::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam) ** If the test is true, the action is not executed. ** */ -bool CMeterWindow::DoAction(int x, int y, MOUSE mouse, bool test) +bool CMeterWindow::DoAction(int x, int y, MOUSEACTION action, bool test) { + const WCHAR* command = NULL; + // Check if the hitpoint was over some meter std::list::const_reverse_iterator j = m_Meters.rbegin(); for ( ; j != m_Meters.rend(); ++j) @@ -4164,162 +4159,27 @@ bool CMeterWindow::DoAction(int x, int y, MOUSE mouse, bool test) // Hidden meters are ignored if ((*j)->IsHidden()) continue; - if ((*j)->HitTest(x, y)) + const WCHAR* meterCommand = (*j)->GetMouse().GetActionCommand(action); + if (meterCommand && (*j)->HitTest(x, y)) { - switch (mouse) - { - case MOUSE_LMB_DOWN: - if (!((*j)->GetLeftMouseDownAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetLeftMouseDownAction().c_str(), this); - return true; - } - break; - - case MOUSE_LMB_UP: - if (!((*j)->GetLeftMouseUpAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetLeftMouseUpAction().c_str(), this); - return true; - } - break; - - case MOUSE_LMB_DBLCLK: - if (!((*j)->GetLeftMouseDoubleClickAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetLeftMouseDoubleClickAction().c_str(), this); - return true; - } - break; - - case MOUSE_RMB_DOWN: - if (!((*j)->GetRightMouseDownAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetRightMouseDownAction().c_str(), this); - return true; - } - break; - - case MOUSE_RMB_UP: - if (!((*j)->GetRightMouseUpAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetRightMouseUpAction().c_str(), this); - return true; - } - break; - - case MOUSE_RMB_DBLCLK: - if (!((*j)->GetRightMouseDoubleClickAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetRightMouseDoubleClickAction().c_str(), this); - return true; - } - break; - - case MOUSE_MMB_DOWN: - if (!((*j)->GetMiddleMouseDownAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetMiddleMouseDownAction().c_str(), this); - return true; - } - break; - - case MOUSE_MMB_UP: - if (!((*j)->GetMiddleMouseUpAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetMiddleMouseUpAction().c_str(), this); - return true; - } - break; - - case MOUSE_MMB_DBLCLK: - if (!((*j)->GetMiddleMouseDoubleClickAction().empty())) - { - if (!test) Rainmeter->ExecuteCommand((*j)->GetMiddleMouseDoubleClickAction().c_str(), this); - return true; - } - break; - } + command = meterCommand; + break; } } - if (HitTest(x, y)) + if (!command && HitTest(x, y)) { - // If no meters caused actions, do the default actions - switch (mouse) + command = m_Mouse.GetActionCommand(action); + } + + if (command) + { + if (!test) { - case MOUSE_LMB_DOWN: - if (!m_LeftMouseDownAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_LeftMouseDownAction.c_str(), this); - return true; - } - break; - - case MOUSE_LMB_UP: - if (!m_LeftMouseUpAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_LeftMouseUpAction.c_str(), this); - return true; - } - break; - - case MOUSE_LMB_DBLCLK: - if (!m_LeftMouseDoubleClickAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_LeftMouseDoubleClickAction.c_str(), this); - return true; - } - break; - - case MOUSE_RMB_DOWN: - if (!m_RightMouseDownAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_RightMouseDownAction.c_str(), this); - return true; - } - break; - - case MOUSE_RMB_UP: - if (!m_RightMouseUpAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_RightMouseUpAction.c_str(), this); - return true; - } - break; - - case MOUSE_RMB_DBLCLK: - if (!m_RightMouseDoubleClickAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_RightMouseDoubleClickAction.c_str(), this); - return true; - } - break; - - case MOUSE_MMB_DOWN: - if (!m_MiddleMouseDownAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_MiddleMouseDownAction.c_str(), this); - return true; - } - break; - - case MOUSE_MMB_UP: - if (!m_MiddleMouseUpAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_MiddleMouseUpAction.c_str(), this); - return true; - } - break; - - case MOUSE_MMB_DBLCLK: - if (!m_MiddleMouseDoubleClickAction.empty()) - { - if (!test) Rainmeter->ExecuteCommand(m_MiddleMouseDoubleClickAction.c_str(), this); - return true; - } - break; + Rainmeter->ExecuteCommand(command, this); } + + return true; } return false; @@ -4329,7 +4189,7 @@ bool CMeterWindow::DoAction(int x, int y, MOUSE mouse, bool test) ** Executes the action if such are defined. Returns true, if meter/window which should be processed still may exist. ** */ -bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) +bool CMeterWindow::DoMoveAction(int x, int y, MOUSEACTION action) { bool buttonFound = false; @@ -4339,7 +4199,7 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) { if (!(*j)->IsHidden() && (*j)->HitTest(x, y)) { - if (mouse == MOUSE_OVER) + if (action == MOUSE_OVER) { if (!m_MouseOver) { @@ -4348,10 +4208,10 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) m_MouseOver = true; SetMouseLeaveEvent(false); - if (!m_MouseOverAction.empty()) + if (!m_Mouse.GetOverAction().empty()) { UINT currCounter = m_MouseMoveCounter; - Rainmeter->ExecuteCommand(m_MouseOverAction.c_str(), this); + Rainmeter->ExecuteCommand(m_Mouse.GetOverAction().c_str(), this); return (currCounter == m_MouseMoveCounter); } } @@ -4377,17 +4237,17 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) if (!(*j)->IsMouseOver()) { - if (!((*j)->GetMouseOverAction().empty()) || - !((*j)->GetMouseLeaveAction().empty()) || + if (!((*j)->GetMouse().GetOverAction().empty()) || + !((*j)->GetMouse().GetLeaveAction().empty()) || button) { //LogWithArgs(LOG_DEBUG, L"MeterEnter: %s - [%s]", m_FolderPath.c_str(), (*j)->GetName()); (*j)->SetMouseOver(true); - if (!((*j)->GetMouseOverAction().empty())) + if (!((*j)->GetMouse().GetOverAction().empty())) { UINT currCounter = m_MouseMoveCounter; - Rainmeter->ExecuteCommand((*j)->GetMouseOverAction().c_str(), this); + Rainmeter->ExecuteCommand((*j)->GetMouse().GetOverAction().c_str(), this); return (currCounter == m_MouseMoveCounter); } } @@ -4396,7 +4256,7 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) } else { - if (mouse == MOUSE_LEAVE) + if (action == MOUSE_LEAVE) { if ((*j)->IsMouseOver()) { @@ -4410,9 +4270,9 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) //LogWithArgs(LOG_DEBUG, L"MeterLeave: %s - [%s]", m_FolderPath.c_str(), (*j)->GetName()); (*j)->SetMouseOver(false); - if (!((*j)->GetMouseLeaveAction().empty())) + if (!((*j)->GetMouse().GetLeaveAction().empty())) { - Rainmeter->ExecuteCommand((*j)->GetMouseLeaveAction().c_str(), this); + Rainmeter->ExecuteCommand((*j)->GetMouse().GetLeaveAction().c_str(), this); return true; } } @@ -4423,7 +4283,7 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) if (HitTest(x, y)) { // If no meters caused actions, do the default actions - if (mouse == MOUSE_OVER) + if (action == MOUSE_OVER) { if (!m_MouseOver) { @@ -4431,10 +4291,10 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) m_MouseOver = true; SetMouseLeaveEvent(false); - if (!m_MouseOverAction.empty()) + if (!m_Mouse.GetOverAction().empty()) { UINT currCounter = m_MouseMoveCounter; - Rainmeter->ExecuteCommand(m_MouseOverAction.c_str(), this); + Rainmeter->ExecuteCommand(m_Mouse.GetOverAction().c_str(), this); return (currCounter == m_MouseMoveCounter); } } @@ -4442,18 +4302,18 @@ bool CMeterWindow::DoMoveAction(int x, int y, MOUSE mouse) } else { - if (mouse == MOUSE_LEAVE) + if (action == MOUSE_LEAVE) { - // Mouse leave happens when the mouse is outside the window + // Mouse leave happens when the action is outside the window if (m_MouseOver) { //LogWithArgs(LOG_DEBUG, L"Leave: %s", m_FolderPath.c_str()); m_MouseOver = false; SetMouseLeaveEvent(true); - if (!m_MouseLeaveAction.empty()) + if (!m_Mouse.GetLeaveAction().empty()) { - Rainmeter->ExecuteCommand(m_MouseLeaveAction.c_str(), this); + Rainmeter->ExecuteCommand(m_Mouse.GetLeaveAction().c_str(), this); return true; } } diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index a469e728..368089c3 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -26,6 +26,7 @@ #include #include "ConfigParser.h" #include "Group.h" +#include "Mouse.h" #define BEGIN_MESSAGEPROC switch (uMsg) { #define MESSAGE(handler, msg) case msg: return window->handler(uMsg, wParam, lParam); @@ -42,21 +43,6 @@ typedef HRESULT (WINAPI * FPDWMGETCOLORIZATIONCOLOR)(DWORD* pcrColorization, BOO typedef HRESULT (WINAPI * FPDWMSETWINDOWATTRIBUTE)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); typedef HRESULT (WINAPI * FPDWMISCOMPOSITIONENABLED)(BOOL* pfEnabled); -enum MOUSE -{ - MOUSE_LMB_DOWN, - MOUSE_LMB_UP, - MOUSE_LMB_DBLCLK, - MOUSE_RMB_DOWN, - MOUSE_RMB_UP, - MOUSE_RMB_DBLCLK, - MOUSE_MMB_DOWN, - MOUSE_MMB_UP, - MOUSE_MMB_DBLCLK, - MOUSE_OVER, - MOUSE_LEAVE -}; - enum BUTTONPROC { BUTTONPROC_DOWN, @@ -238,7 +224,8 @@ public: int GetTransitionUpdate() { return m_TransitionUpdate; } bool GetMeterToolTipHidden() { return m_ToolTipHidden; } - bool GetMeterMouseActionCursor() { return m_MouseActionCursor; } + + const CMouse& GetMouse() { return m_Mouse; } void MakePathAbsolute(std::wstring& path); @@ -336,8 +323,8 @@ private: void SetSnapEdges(bool b); void SetWindowHide(HIDEMODE hide); void SetWindowZPosition(ZPOSITION zpos); - bool DoAction(int x, int y, MOUSE mouse, bool test); - bool DoMoveAction(int x, int y, MOUSE mouse); + bool DoAction(int x, int y, MOUSEACTION action, bool test); + bool DoMoveAction(int x, int y, MOUSEACTION action); bool ResizeWindow(bool reset); void IgnoreAeroPeek(); void AddWindowExStyle(LONG_PTR flag); @@ -364,22 +351,12 @@ private: HWND m_Window; - std::wstring m_LeftMouseDownAction; - std::wstring m_RightMouseDownAction; - std::wstring m_MiddleMouseDownAction; - std::wstring m_LeftMouseUpAction; - std::wstring m_RightMouseUpAction; - std::wstring m_MiddleMouseUpAction; - std::wstring m_LeftMouseDoubleClickAction; - std::wstring m_RightMouseDoubleClickAction; - std::wstring m_MiddleMouseDoubleClickAction; - std::wstring m_MouseOverAction; - std::wstring m_MouseLeaveAction; + CMouse m_Mouse; + bool m_MouseOver; + std::wstring m_OnRefreshAction; std::wstring m_OnCloseAction; - bool m_MouseOver; - std::wstring m_SkinGroup; std::wstring m_BackgroundName; RECT m_BackgroundMargins; @@ -456,7 +433,6 @@ private: Gdiplus::PrivateFontCollection* m_FontCollection; - bool m_MouseActionCursor; bool m_ToolTipHidden; static int c_InstanceCount; diff --git a/Library/Mouse.cpp b/Library/Mouse.cpp new file mode 100644 index 00000000..7a4a65ae --- /dev/null +++ b/Library/Mouse.cpp @@ -0,0 +1,206 @@ +/* + Copyright (C) 2012 Rainmeter Team + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "StdAfx.h" +#include "ConfigParser.h" +#include "MeterWindow.h" +#include "System.h" +#include "Litestep.h" +#include "Mouse.h" + +CMouse::CMouse() : + m_CursorType(MOUSECURSOR_HAND), + m_CustomCursor() +{ +} + +CMouse::~CMouse() +{ + DestroyCustomCursor(); +} + +void CMouse::ReadOptions(CConfigParser& parser, const WCHAR* section, CMeterWindow* meterWindow) +{ + DestroyCustomCursor(); + + m_LeftDownAction = parser.ReadString(section, L"LeftMouseDownAction", L"", false); + m_RightDownAction = parser.ReadString(section, L"RightMouseDownAction", L"", false); + m_MiddleDownAction = parser.ReadString(section, L"MiddleMouseDownAction", L"", false); + m_LeftUpAction = parser.ReadString(section, L"LeftMouseUpAction", L"", false); + m_RightUpAction = parser.ReadString(section, L"RightMouseUpAction", L"", false); + m_MiddleUpAction = parser.ReadString(section, L"MiddleMouseUpAction", L"", false); + m_LeftDoubleClickAction = parser.ReadString(section, L"LeftMouseDoubleClickAction", L"", false); + m_RightDoubleClickAction = parser.ReadString(section, L"RightMouseDoubleClickAction", L"", false); + m_MiddleDoubleClickAction = parser.ReadString(section, L"MiddleMouseDoubleClickAction", L"", false); + m_OverAction = parser.ReadString(section, L"MouseOverAction", L"", false); + m_LeaveAction = parser.ReadString(section, L"MouseLeaveAction", L"", false); + + const WCHAR* mouseCursor = parser.ReadString(section, L"MouseActionCursor", L"").c_str(); + if (_wcsicmp(mouseCursor, L"HAND") == 0 || + wcscmp(mouseCursor, L"1") == 0) // For backwards compatibility + { + m_CursorType = MOUSECURSOR_HAND; + } + else if (_wcsicmp(mouseCursor, L"ARROW") == 0 || + wcscmp(mouseCursor, L"0") == 0) // For backwards compatibility + { + m_CursorType = MOUSECURSOR_ARROW; + } + else if (_wcsicmp(mouseCursor, L"TEXT") == 0) + { + m_CursorType = MOUSECURSOR_TEXT; + } + else if (_wcsicmp(mouseCursor, L"HELP") == 0) + { + m_CursorType = MOUSECURSOR_HELP; + } + else if (_wcsicmp(mouseCursor, L"BUSY") == 0) + { + m_CursorType = MOUSECURSOR_BUSY; + } + else if (_wcsicmp(mouseCursor, L"CROSS") == 0) + { + m_CursorType = MOUSECURSOR_CROSS; + } + else if (_wcsicmp(mouseCursor, L"PEN") == 0) + { + m_CursorType = MOUSECURSOR_PEN; + } + else if (*mouseCursor) + { + // Load custom cursor + std::wstring cursorPath = meterWindow->GetResourcesPath(); + cursorPath += L"Cursors\\"; + cursorPath += mouseCursor; + m_CustomCursor = LoadCursorFromFile(cursorPath.c_str()); + if (m_CustomCursor) + { + m_CursorType = MOUSECURSOR_CUSTOM; + } + else + { + m_CursorType = MOUSECURSOR_ARROW; + LogWithArgs(LOG_ERROR, L"Invalid cursor: %s", cursorPath.c_str()); + } + } + else + { + m_CursorType = meterWindow->GetMouse().m_CursorType; + if (meterWindow->GetMouse().m_CustomCursor) + { + m_CustomCursor = CopyCursor(meterWindow->GetMouse().m_CustomCursor); + } + } +} + +HCURSOR CMouse::GetCursor() const +{ + LPCWSTR name = IDC_ARROW; + switch (m_CursorType) + { + case MOUSECURSOR_HAND: + name = IDC_HAND; + break; + + case MOUSECURSOR_TEXT: + name = IDC_IBEAM; + break; + + case MOUSECURSOR_HELP: + name = IDC_HELP; + break; + + case MOUSECURSOR_BUSY: + name = IDC_APPSTARTING; + break; + + case MOUSECURSOR_CROSS: + name = IDC_CROSS; + break; + + case MOUSECURSOR_PEN: + name = MAKEINTRESOURCE(32631); + break; + + case MOUSECURSOR_CUSTOM: + { + if (m_CustomCursor) + { + return m_CustomCursor; + } + } + break; + } + + return LoadCursor(NULL, name); +} + +const WCHAR* CMouse::GetActionCommand(MOUSEACTION action) const +{ + const WCHAR* command = NULL; + + switch (action) + { + case MOUSE_LMB_DOWN: + command = m_LeftDownAction.c_str(); + break; + + case MOUSE_LMB_UP: + command = m_LeftUpAction.c_str(); + break; + + case MOUSE_LMB_DBLCLK: + command = m_LeftDoubleClickAction.c_str(); + break; + + case MOUSE_RMB_DOWN: + command = m_RightDownAction.c_str(); + break; + + case MOUSE_RMB_UP: + command = m_RightUpAction.c_str(); + break; + + case MOUSE_RMB_DBLCLK: + command = m_RightDoubleClickAction.c_str(); + break; + + case MOUSE_MMB_DOWN: + command = m_MiddleDownAction.c_str(); + break; + + case MOUSE_MMB_UP: + command = m_MiddleUpAction.c_str(); + break; + + case MOUSE_MMB_DBLCLK: + command = m_MiddleDoubleClickAction.c_str(); + break; + } + + return *command ? command : NULL; +} + +void CMouse::DestroyCustomCursor() +{ + if (m_CustomCursor) + { + DestroyCursor(m_CustomCursor); + m_CustomCursor = NULL; + } +} \ No newline at end of file diff --git a/Library/Mouse.h b/Library/Mouse.h new file mode 100644 index 00000000..e46ee5e5 --- /dev/null +++ b/Library/Mouse.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2012 Rainmeter Team + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MOUSE_H__ +#define __MOUSE_H__ + +enum MOUSEACTION +{ + MOUSE_LMB_DOWN, + MOUSE_LMB_UP, + MOUSE_LMB_DBLCLK, + MOUSE_RMB_DOWN, + MOUSE_RMB_UP, + MOUSE_RMB_DBLCLK, + MOUSE_MMB_DOWN, + MOUSE_MMB_UP, + MOUSE_MMB_DBLCLK, + MOUSE_OVER, + MOUSE_LEAVE +}; + +enum MOUSECURSOR +{ + MOUSECURSOR_ARROW, + MOUSECURSOR_HAND, + MOUSECURSOR_TEXT, + MOUSECURSOR_HELP, + MOUSECURSOR_BUSY, + MOUSECURSOR_CROSS, + MOUSECURSOR_PEN, + MOUSECURSOR_CUSTOM +}; + +class CMouse +{ +public: + CMouse(); + ~CMouse(); + + void ReadOptions(CConfigParser& parser, const WCHAR* section, CMeterWindow* meterWindow); + + MOUSECURSOR GetCursorType() const { return m_CursorType; } + HCURSOR GetCursor() const; + + void DestroyCustomCursor(); + + const WCHAR* GetActionCommand(MOUSEACTION action) const; + + const std::wstring& GetRightDownAction() const { return m_RightDownAction; } + const std::wstring& GetRightUpAction() const { return m_RightUpAction; } + const std::wstring& GetRightDoubleClickAction() const { return m_RightDoubleClickAction; } + const std::wstring& GetLeftDownAction() const { return m_LeftDownAction; } + const std::wstring& GetLeftUpAction() const { return m_LeftUpAction; } + const std::wstring& GetLeftDoubleClickAction() const { return m_LeftDoubleClickAction; } + const std::wstring& GetMiddleDownAction() const { return m_MiddleDownAction; } + const std::wstring& GetMiddleUpAction() const { return m_MiddleUpAction; } + const std::wstring& GetMiddleDoubleClickAction() const { return m_MiddleDoubleClickAction; } + const std::wstring& GetOverAction() const { return m_OverAction; } + const std::wstring& GetLeaveAction() const { return m_LeaveAction; } + +private: + std::wstring m_LeftDownAction; + std::wstring m_RightDownAction; + std::wstring m_MiddleDownAction; + std::wstring m_LeftUpAction; + std::wstring m_RightUpAction; + std::wstring m_MiddleUpAction; + std::wstring m_LeftDoubleClickAction; + std::wstring m_RightDoubleClickAction; + std::wstring m_MiddleDoubleClickAction; + std::wstring m_OverAction; + std::wstring m_LeaveAction; + + MOUSECURSOR m_CursorType; + HCURSOR m_CustomCursor; +}; + +#endif