summaryrefslogtreecommitdiffhomepage
path: root/opentrack/shortcuts.h
blob: 8fe1a39b21f3f146ac360b38a540f458c7e00e8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#pragma once
#include <QWidget>
#include <QElapsedTimer>
#include <QThread>
#include <QMessageBox>
#include <QCheckBox>
#include <QComboBox>
#include <QSettings>

#include "qxt-mini/QxtGlobalShortcut"
#include "opentrack/plugin-support.h"
#include "opentrack/options.hpp"
#include "ui_ftnoir_keyboardshortcuts.h"

using namespace options;

extern QList<QString> global_key_sequences;

struct key_opts {
    value<int> key_index;
    value<bool> ctrl, alt, shift;

    key_opts(pbundle b, const QString& name) :
        key_index(b,  QString("key-index-%1").arg(name), 0),
        ctrl(b,  QString("key-ctrl-%1").arg(name), 0),
        alt(b,  QString("key-alt-%1").arg(name), 0),
        shift(b,  QString("key-shift-%1").arg(name), 0)
    {}
};

#if defined(_WIN32)
extern QList<int> global_windows_key_sequences;
#   undef DIRECTINPUT_VERSION
#   define DIRECTINPUT_VERSION 0x0800
#   include <windows.h>
#   include <dinput.h>

struct Key {
    BYTE keycode;
    bool shift;
    bool ctrl;
    bool alt;
    bool ever_pressed;
    QElapsedTimer timer;
public:
    Key() : keycode(0), shift(false), ctrl(false), alt(false), ever_pressed(false)
    {
    }
};
#else
typedef unsigned char BYTE;
struct Key { int foo; };
#endif

struct KeybindingWorker : public QThread {
    Q_OBJECT
#ifdef _WIN32
private:
    LPDIRECTINPUT8 din;
    LPDIRECTINPUTDEVICE8 dinkeyboard;
    Key kCenter;
    Key kToggle;
public:
    volatile bool should_quit;
    ~KeybindingWorker();
    KeybindingWorker(Key keyCenter, Key keyToggle, WId handle);
	void run();
#else
public:
    KeybindingWorker(Key, Key, WId) {}
	void run() {}
#endif
signals:
    void center();
    void toggle();
};


struct Shortcuts {
    using K =
#ifndef _WIN32
    ptr<QxtGlobalShortcut>
#else
    Key
#endif
    ;
    
    K keyCenter;
    K keyToggle;

    WId handle;
#ifdef _WIN32
    ptr<KeybindingWorker> keybindingWorker;
#endif
    
    struct settings {
        pbundle b;
        key_opts center, toggle;
        settings() :
            b(bundle("keyboard-shortcuts")),
            center(b, "center"),
            toggle(b, "toggle")
        {}
    } s;

    Shortcuts(WId handle) : handle(handle)
    {
        reload();
    }

    void reload()
    {
#ifndef _WIN32
        if (keyCenter)
        {
            keyCenter->setShortcut(QKeySequence::UnknownKey);
            keyCenter->setEnabled(false);
        }
        if (keyToggle)
        {
            keyToggle->setShortcut(QKeySequence::UnknownKey);
            keyToggle->setEnabled(false);
        }
#endif
        bind_keyboard_shortcut(keyCenter, s.center);
        bind_keyboard_shortcut(keyToggle, s.toggle);
#ifdef _WIN32
        keybindingWorker = nullptr;
        keybindingWorker = std::make_shared<KeybindingWorker>(keyCenter, keyToggle, handle);
        keybindingWorker->start();
#endif        
    }
private:
    void bind_keyboard_shortcut(K &key, key_opts& k);
};

class KeyboardShortcutDialog: public QWidget
{
    Q_OBJECT
public:
    KeyboardShortcutDialog();
private:
    Ui::UICKeyboardShortcutDialog ui;
    Shortcuts::settings s;
    ptr<Shortcuts> sc;
signals:
    void reload();
private slots:
	void doOK();
	void doCancel();
};