2 #include <QGraphicsDropShadowEffect>
3 #include <QGraphicsPixmapItem>
4 #include <QGraphicsScene>
15 extern QRgb
monoRgb(
float r,
float g,
float b);
18 QWidget(parent), mouseDownX(-1), mouseDownY(-1), mouseCurrentX(-1), mouseCurrentY(-1), mouseDownMode(NONE), _rgbMode(rgbMode), _monochrome(false)
20 setMouseTracking(
true);
21 setAutoFillBackground(
false);
39 setFixedSize(width, height);
44 int w = width() * ratio, h = height() * ratio;
47 scale = fmin(xScale, yScale);
71 const QColor bgColor(68, 64, 64);
72 const QColor keyColor(112, 110, 110);
73 const QColor sniperColor(130, 90, 90);
74 const QColor thumbColor(34, 32, 32);
75 const QColor transparentColor(0, 0, 0, 0);
76 const QColor highlightColor(136, 176, 240);
77 const QColor highlightAnimColor(136, 200, 240);
78 const QColor animColor(112, 200, 110);
99 QPainter painter(
this);
100 #if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
101 int ratio = painter.device()->devicePixelRatio();
105 int wWidth = width(), wHeight = height();
108 float scale, offX, offY;
111 painter.setPen(Qt::NoPen);
112 painter.setRenderHint(QPainter::Antialiasing,
true);
116 const QImage* overlay = 0;
117 float xpos = 0.f, ypos = 0.f;
120 m65Overlay =
new QImage(
":/img/overlay_m65.png");
126 sabOverlay =
new QImage(
":/img/overlay_sabre.png");
132 scimOverlay =
new QImage(
":/img/overlay_scimitar.png");
138 painter.setBrush(palette().brush(QPalette::Window));
139 painter.drawRect(0, 0, width(), height());
140 float oXScale = scale / 9.f, oYScale = scale / 9.f;
141 float x = (xpos + offX) * scale, y = (ypos + offY) * scale;
142 int w = overlay->width() * oXScale, h = overlay->height() * oYScale;
145 int iW = round(w), iH = round(h);
146 painter.drawImage(QRectF((x - (iW - w) / 2.f) / ratio, (y - (iH - h) / 2.f) / ratio, iW / ratio, iH / ratio), overlay->scaled(iW, iH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
150 painter.setBrush(QBrush(bgColor));
151 painter.drawRect(0, 0, width(), height());
160 painter.setPen(QPen(highlightColor, 0.5));
161 QColor bColor = highlightColor;
162 bColor.setAlpha(128);
163 painter.setBrush(QBrush(bColor));
164 painter.drawRect(x1, y1, x2 - x1, y2 - y1);
168 QPixmap keyBG(wWidth * ratio, wHeight * ratio);
169 keyBG.fill(QColor(0, 0, 0, 0));
170 QPainter bgPainter(&keyBG);
171 bgPainter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
172 bgPainter.setPen(Qt::NoPen);
173 QHashIterator<QString, Key> k(
keyMap);
178 const Key& key = k.value();
179 float x = key.
x + offX - key.
width / 2.f + 1.f;
180 float y = key.
y + offY - key.
height / 2.f + 1.f;
181 float w = key.
width - 2.f;
182 float h = key.
height - 2.f;
188 bgPainter.setOpacity(1.);
189 if(highlight.testBit(i)){
191 bgPainter.setBrush(QBrush(highlightAnimColor));
193 bgPainter.setBrush(QBrush(highlightColor));
195 bgPainter.setBrush(QBrush(animColor));
197 if(!strcmp(key.
name,
"sniper"))
199 bgPainter.setBrush(QBrush(sniperColor));
202 bgPainter.setBrush(QBrush(thumbColor));
203 else if(!strcmp(key.
name,
"lsidel") || !strcmp(key.
name,
"rsidel") || !strcmp(key.
name,
"logo"))
205 bgPainter.setBrush(QBrush(transparentColor));
207 bgPainter.setBrush(QBrush(keyColor));
209 bgPainter.setOpacity(0.7);
213 || !strcmp(key.
name,
"light") || !strcmp(key.
name,
"lock") || (model ==
KeyMap::K65 && !strcmp(key.
name,
"mute")))){
219 bgPainter.drawEllipse(QRectF(x * scale, y * scale, w * scale, h * scale));
221 if(!strcmp(key.
name,
"enter")){
226 bgPainter.drawRect(QRectF((x + w - 13.f) * scale, y * scale, 13.f * scale, 22.f * scale));
232 }
else if(!strcmp(key.
name,
"rshift") || !strcmp(key.
name,
"stop")){
236 }
else if(!strcmp(key.
name,
"caps") || !strcmp(key.
name,
"lshift") || !strcmp(key.
name,
"next")){
239 bgPainter.drawRect(QRectF(x * scale, y * scale, w * scale, h * scale));
244 QPixmap decoration(wWidth * ratio, wHeight * ratio);
245 decoration.fill(QColor(0, 0, 0, 0));
246 QPainter decPainter(&decoration);
247 decPainter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
250 QHashIterator<QString, Key> k(
keyMap);
255 const Key& key = k.value();
258 float x = key.
x + offX - 1.8f;
259 float y = key.
y + offY - 1.8f;
264 decPainter.setPen(QPen(QColor(255, 248, 136), 1.5));
266 decPainter.setPen(QPen(QColor(255, 255, 255), 1.5));
277 color =
monoRgb(qRed(color), qGreen(color), qBlue(color));
279 decPainter.setBrush(QBrush(color));
281 float kx = key.
x + offX - key.
width / 2.f + 1.f;
282 float ky = key.
y + offY - key.
height / 2.f + 1.f;
283 float kw = key.
width - 2.f;
284 float kh = key.
height - 2.f;
285 decPainter.setPen(QPen(QColor(255, 255, 255), 1.2));
286 if(!strcmp(key.
name,
"logo")) {
287 float lx = key.
x + offX - key.
width / 2.f + 2.f;
288 float ly = key.
y + offY - key.
height / 2.f + 2.f;
289 float lw = key.
width - 4.f;
290 float lh = key.
height - 4.f;
292 logo.moveTo(lx*scale,(ly+lh)*scale);
293 logo.quadTo((lx+2.f)*scale,(ly+lh/2.f)*scale,lx*scale,ly*scale);
294 logo.quadTo((lx+lw)*scale,ly*scale,(lx+lw)*scale,(ly+lh)*scale);
295 logo.quadTo((lx+lw/2.f)*scale,(ly+lh-4.f)*scale,lx*scale,(ly+lh)*scale);
296 decPainter.drawPath(logo);
299 }
else if(!strcmp(key.
name,
"lsidel") || !strcmp(key.
name,
"rsidel")) {
300 QRadialGradient gradient(QPointF(wWidth/2.f * ratio, wHeight/2.f * ratio), wWidth/2.f * ratio);
301 gradient.setColorAt(0, color);
302 gradient.setColorAt(0.9, color);
303 gradient.setColorAt(1, bgColor);
304 decPainter.setBrush(QBrush(gradient));
305 decPainter.setPen(QPen(keyColor, 1.2));
306 decPainter.drawRect(QRectF(kx * scale, ky * scale - 12 , kw * scale, kh * scale+24));
308 decPainter.setPen(QPen(QColor(0,0,0,0), 1));
309 decPainter.drawRect(QRectF((kx+2.f) * scale, (ky+2.f) * scale, (kw-4.f) * scale, (kh-4.f) * scale));
311 decPainter.drawEllipse(QRectF((x-1.f) * scale, (y-1.f) * scale, (w+2.f) * scale, (h+2.f) * scale));
313 decPainter.drawEllipse(QRectF(x * scale, y * scale, w * scale, h * scale));
317 decPainter.setBrush(Qt::NoBrush);
318 QFont font = painter.font();
320 font.setPixelSize(5.25f * scale);
322 QHashIterator<QString, Key> k(
keyMap);
327 const Key& key = k.value();
330 float x = key.
x + offX - key.
width / 2.f + 1.f;
331 float y = key.
y + offY - key.
height / 2.f;
332 float w = key.
width - 2.f;
337 name = name.split(
" ").last();
339 const char* keyName, *displayName;
341 {
"light",
"☼"}, {
"lock",
"☒"}, {
"mute",
"◖⊘"}, {
"volup",
keyMap.
model() ==
KeyMap::K65 ?
"◖))" :
"▲"}, {
"voldn",
keyMap.
model() ==
KeyMap::K65 ?
"◖)" :
"▼"},
342 {
"prtscn",
"PrtScn\nSysRq"}, {
"scroll",
"Scroll\nLock"}, {
"pause",
"Pause\nBreak"}, {
"stop",
"▪"}, {
"prev",
"|◂◂"}, {
"play",
"▸||"}, {
"next",
"▸▸|"},
343 {
"pgup",
"Page\nUp"}, {
"pgdn",
"Page\nDown"}, {
"numlock",
"Num\nLock"},
344 {
"caps",
"Caps"}, {
"lshift",
"Shift"}, {
"rshift",
"Shift"},
346 {
"lctrl",
"⌃"}, {
"rctrl",
"⌃"}, {
"lwin",
"⌘"}, {
"rwin",
"⌘"}, {
"lalt",
"⌥"}, {
"ralt",
"⌥"},
348 {
"lctrl",
"Ctrl"}, {
"rctrl",
"Ctrl"}, {
"lwin",
"❖"}, {
"rwin",
"❖"}, {
"lalt",
"Alt"}, {
"ralt",
"Alt"},
350 {
"rmenu",
"▤"}, {
"up",
"▲"}, {
"left",
"◀"}, {
"down",
"▼"}, {
"right",
"▶"}, {
"fn",
"Fn"},
351 {
"mouse1",
""}, {
"mouse2",
""}, {
"mouse3",
"∙"}, {
"dpiup",
"▲"}, {
"dpidn",
"▼"}, {
"wheelup",
"▲"}, {
"wheeldn",
"▼"}, {
"dpi",
"◉"}, {
"mouse5",
"▲"}, {
"mouse4",
"▼"}, {
"sniper",
"⊕"}
353 for(uint k = 0; k <
sizeof(names) /
sizeof(names[0]); k++){
354 if(keyName == names[k].keyName){
355 name = names[k].displayName;
361 if(keyName ==
"mr" || keyName ==
"m1" || keyName ==
"m2" || keyName ==
"m3" || keyName ==
"up" || keyName ==
"down" || keyName ==
"left" || keyName ==
"right")
363 font.setPixelSize(font.pixelSize() * 0.75);
364 else if(keyName ==
"end")
366 font.setPixelSize(font.pixelSize() * 0.65);
367 else if(keyName ==
"light"
369 || keyName ==
"lwin" || keyName ==
"rwin"
373 font.setPixelSize(font.pixelSize() * 1.3);
378 decPainter.setFont(font);
379 QRectF rect(x * scale, y * scale - 1, w * scale, h * scale);
380 int flags = Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap;
381 QRectF bounds = decPainter.boundingRect(rect, flags, name);
382 while((bounds.height() >= rect.height() - 8. || bounds.width() >= rect.width() - 2.) && font.pixelSize() >= 5){
384 font.setPixelSize(font.pixelSize() - 2);
385 decPainter.setFont(font);
386 bounds = decPainter.boundingRect(rect, flags, name);
393 decPainter.setPen(QColor(255, 136, 136));
396 decPainter.setPen(QColor(255, 224, 192));
399 decPainter.setPen(QColor(128, 224, 255));
402 decPainter.setPen(QColor(160, 255, 168));
405 decPainter.setPen(QColor(255, 255, 255));
408 decPainter.setPen(QColor(255, 248, 128));
409 decPainter.drawText(rect, flags, name);
414 QGraphicsDropShadowEffect* bgEffect =
new QGraphicsDropShadowEffect;
415 bgEffect->setBlurRadius(2.);
416 bgEffect->setColor(QColor(0, 0, 0, 32));
417 bgEffect->setOffset(0, 1);
418 QGraphicsDropShadowEffect* decEffect =
new QGraphicsDropShadowEffect;
419 decEffect->setBlurRadius(4.);
420 decEffect->setColor(QColor(0, 0, 0, 104));
421 decEffect->setOffset(0, 1);
423 QGraphicsPixmapItem* bgItem =
new QGraphicsPixmapItem(keyBG);
424 bgItem->setGraphicsEffect(bgEffect);
425 QGraphicsPixmapItem* decItem =
new QGraphicsPixmapItem(decoration);
426 decItem->setGraphicsEffect(decEffect);
428 QGraphicsScene* scene =
new QGraphicsScene;
429 scene->addItem(bgItem);
430 scene->addItem(decItem);
432 QPixmap
final(wWidth * ratio, wHeight * ratio);
433 final.fill(QColor(0, 0, 0, 0));
434 QPainter finalPainter(&
final);
435 scene->render(&finalPainter, QRectF(0, 0, wWidth * ratio, wHeight * ratio), QRectF(0, 0, wWidth * ratio, wHeight * ratio));
437 #if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
438 final.setDevicePixelRatio(ratio);
440 painter.drawPixmap(QPointF(0., 0.),
final);
445 mouseDownMode = (
event->modifiers() & Qt::AltModifier) ?
SUBTRACT : (event->modifiers() & Qt::ShiftModifier) ?
ADD : (event->modifiers() & Qt::ControlModifier) ?
TOGGLE :
SET;
449 float scale, offX, offY;
452 QHashIterator<QString, Key> k(
keyMap);
457 const Key& key = k.value();
461 if(fabs(key.
x - mx) <= key.
width / 2.f - 1.f && fabs(key.
y - my) <= key.
height / 2.f - 1.f){
463 if(!strcmp(key.
name,
"lsidel") || !strcmp(key.
name,
"rsidel")){
482 float scale, offX, offY;
485 float mx1, mx2, my1, my2;
504 QHashIterator<QString, Key> k(
keyMap);
509 const Key& key = k.value();
514 if(fabs(key.
x - mx) <= key.
width / 2.f - 1.f && fabs(key.
y - my) <= key.
height / 2.f - 1.f
515 && tooltip.isEmpty())
520 float kx1 = key.
x - key.
width / 2.f + 1.f;
521 float ky1 = key.
y - key.
height / 2.f + 1.f;
522 float kx2 = kx1 + key.
width - 2.f;
523 float ky2 = ky1 + key.
height - 2.f;
525 if(!(mx1 >= kx2 || kx1 >= mx2)
526 && !(my1 >= ky2 || ky1 >= my2)
560 QStringList selectedNames;
564 selectedNames << key;
573 foreach(
const QString& key, keys){
574 int index = allNames.indexOf(key);
588 QStringList selectedNames;
591 if(strcmp(key.
name,
"lsidel") && strcmp(key.
name,
"rsidel")
594 selectedNames << key.
name;
616 foreach(
const QString& key, keys){
618 if(!strcmp(key.toLatin1(),
"lsidel") || !strcmp(key.toLatin1(),
"rsidel"))
620 int index = allNames.indexOf(key);
static bool isMouse(Model model)
static QString globalRemap(const QString &key)
QString friendlyName(bool os=true) const
QRgb * colorForName(const char *name)
static QString defaultAction(const QString &key)
QHash< QString, QRgb > QColorMap
QList< Key > positions() const