forked from Mirrors/openclonk
Allow using mouse keys and key combinations from the control assignment configuration dialogue (#1693, #1692)
parent
417d10ed97
commit
b115641685
|
@ -23,6 +23,7 @@
|
|||
#include "graphics/C4Draw.h"
|
||||
#include "graphics/C4GraphicsResource.h"
|
||||
#include "gui/C4MouseControl.h"
|
||||
#include "gui/C4KeyboardInput.h"
|
||||
#include "gui/C4StartupMainDlg.h"
|
||||
#include "network/C4Network2.h"
|
||||
#include "platform/C4GamePadCon.h"
|
||||
|
@ -147,7 +148,17 @@ C4StartupOptionsDlg::KeySelDialog::KeySelDialog(const C4PlayerControlAssignment
|
|||
: C4GUI::MessageDialog(GetDlgMessage(assignment, assignment_set).getData(), LoadResStr("IDS_MSG_DEFINEKEY"), C4GUI::MessageDialog::btnAbort | C4GUI::MessageDialog::btnReset, GetDlgIcon(assignment_set), C4GUI::MessageDialog::dsRegular),
|
||||
key(KEY_Undefined), assignment(assignment), assignment_set(assignment_set)
|
||||
{
|
||||
pKeyListener = new C4KeyBinding(C4KeyCodeEx(KEY_Any, KEYS_None), "DefineKey", KEYSCOPE_Gui, new C4GUI::DlgKeyCBPassKey<C4StartupOptionsDlg::KeySelDialog>(*this, &C4StartupOptionsDlg::KeySelDialog::KeyDown), C4CustomKey::PRIO_PlrControl);
|
||||
pKeyListener = new C4KeyBinding(
|
||||
C4KeyCodeEx(KEY_Any, KEYS_None),
|
||||
"DefineKey",
|
||||
KEYSCOPE_Gui,
|
||||
new C4GUI::DlgKeyCBPassKey<C4StartupOptionsDlg::KeySelDialog>(
|
||||
*this,
|
||||
&C4StartupOptionsDlg::KeySelDialog::KeyDown,
|
||||
&C4StartupOptionsDlg::KeySelDialog::KeyUp
|
||||
),
|
||||
C4CustomKey::PRIO_PlrControl
|
||||
);
|
||||
}
|
||||
|
||||
StdStrBuf C4StartupOptionsDlg::KeySelDialog::GetDlgMessage(const C4PlayerControlAssignment *assignment, const C4PlayerControlAssignmentSet *assignment_set)
|
||||
|
@ -183,7 +194,61 @@ C4StartupOptionsDlg::KeySelDialog::~KeySelDialog()
|
|||
delete pKeyListener;
|
||||
}
|
||||
|
||||
bool C4StartupOptionsDlg::KeySelDialog::KeyDown(const C4KeyCodeEx &key)
|
||||
void C4StartupOptionsDlg::KeySelDialog::MouseInput(C4GUI::CMouse& rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
|
||||
{
|
||||
// Original action
|
||||
C4GUI::MessageDialog::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
|
||||
|
||||
// Find out to where the input was made (code duplication with C4GUI::Window::MouseInput)
|
||||
// get client pos
|
||||
C4Rect &rcClientRect = GetClientRect(), &rcBounds = GetBounds();
|
||||
iX -= rcClientRect.x - rcBounds.x; iY -= rcClientRect.y - rcBounds.y;
|
||||
// forward to topmost child element
|
||||
for (Element *pChild = pLast; pChild; pChild = pChild->GetPrev())
|
||||
if (pChild->fVisible && pChild->GetBounds().Contains(iX, iY))
|
||||
{
|
||||
if (dynamic_cast<C4GUI::Label*>(pChild))
|
||||
break;
|
||||
else
|
||||
return;
|
||||
}
|
||||
// Only process the input event if the user certainly didn't click a button or anything…
|
||||
|
||||
// Logic duplication of C4PlayerControl::DoMouseInput (and C4MouseControl::Move for the wheel_dir.) There has to be a better way. :(
|
||||
uint8_t mouseevent_code;
|
||||
int wheel_dir = 0;
|
||||
if (iButton == C4MC_Button_Wheel) wheel_dir = (short)(dwKeyParam >> 16);
|
||||
switch (iButton)
|
||||
{
|
||||
case C4MC_Button_LeftUp:
|
||||
case C4MC_Button_RightUp:
|
||||
case C4MC_Button_MiddleUp:
|
||||
case C4MC_Button_X1Up:
|
||||
case C4MC_Button_X2Up:
|
||||
case C4MC_Button_None:
|
||||
return;
|
||||
case C4MC_Button_LeftDown: mouseevent_code = KEY_MOUSE_ButtonLeft; break;
|
||||
case C4MC_Button_LeftDouble: mouseevent_code = KEY_MOUSE_ButtonLeftDouble; break;
|
||||
case C4MC_Button_RightDown: mouseevent_code = KEY_MOUSE_ButtonRight; break;
|
||||
case C4MC_Button_RightDouble: mouseevent_code = KEY_MOUSE_ButtonRightDouble; break;
|
||||
case C4MC_Button_MiddleDown: mouseevent_code = KEY_MOUSE_ButtonMiddle; break;
|
||||
case C4MC_Button_MiddleDouble: mouseevent_code = KEY_MOUSE_ButtonMiddleDouble; break;
|
||||
case C4MC_Button_X1Down: mouseevent_code = KEY_MOUSE_ButtonX1; break;
|
||||
case C4MC_Button_X1Double: mouseevent_code = KEY_MOUSE_ButtonX1Double; break;
|
||||
case C4MC_Button_X2Down: mouseevent_code = KEY_MOUSE_ButtonX2; break;
|
||||
case C4MC_Button_X2Double: mouseevent_code = KEY_MOUSE_ButtonX2Double; break;
|
||||
case C4MC_Button_Wheel:
|
||||
if (!wheel_dir) return;
|
||||
mouseevent_code = (wheel_dir > 0) ? KEY_MOUSE_Wheel1Up : KEY_MOUSE_Wheel1Down; break;
|
||||
}
|
||||
C4KeyCodeEx key{KEY_Mouse(0, mouseevent_code), KEYS_None};
|
||||
if (dwKeyParam & MK_CONTROL) key.dwShift |= KEYS_Control;
|
||||
if (dwKeyParam & MK_SHIFT) key.dwShift |= KEYS_Shift;
|
||||
if (dwKeyParam & MK_ALT) key.dwShift |= KEYS_Alt;
|
||||
KeyDown(key);
|
||||
}
|
||||
|
||||
bool C4StartupOptionsDlg::KeySelDialog::KeyPress(const C4KeyCodeEx &key, bool fDown)
|
||||
{
|
||||
// safety
|
||||
if (!assignment || !assignment_set) return false;
|
||||
|
@ -200,6 +265,13 @@ bool C4StartupOptionsDlg::KeySelDialog::KeyDown(const C4KeyCodeEx &key)
|
|||
{
|
||||
if (!assignment_set->HasKeyboard()) return false;
|
||||
}
|
||||
// FIXME: There doesn't seem to be any kind of KEY_IsModifier function…
|
||||
switch (key.Key) {
|
||||
case K_CONTROL_L: case K_SHIFT_L: case K_ALT_L:
|
||||
case K_CONTROL_R: case K_SHIFT_R: case K_ALT_R:
|
||||
if (fDown)
|
||||
return false;
|
||||
}
|
||||
// okay, use it
|
||||
this->key=key;
|
||||
Close(true);
|
||||
|
|
|
@ -165,7 +165,10 @@ private:
|
|||
static C4GUI::Icons GetDlgIcon(const class C4PlayerControlAssignmentSet *assignment_set);
|
||||
|
||||
protected:
|
||||
bool KeyDown(const C4KeyCodeEx &key);
|
||||
bool KeyDown(const C4KeyCodeEx &key) { return KeyPress(key, true); };
|
||||
bool KeyUp(const C4KeyCodeEx &key) { return KeyPress(key, false); };
|
||||
bool KeyPress(const C4KeyCodeEx &key, bool fDown);
|
||||
void MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override;
|
||||
public:
|
||||
KeySelDialog(const class C4PlayerControlAssignment *assignment, const class C4PlayerControlAssignmentSet *assignment_set);
|
||||
~KeySelDialog() override;
|
||||
|
|
Loading…
Reference in New Issue