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 harpOverlay =
new QImage(
":/img/overlay_harpoon.png");
150 painter.setBrush(palette().brush(QPalette::Window));
151 painter.drawRect(0, 0,
width(), height());
152 float oXScale = scale / 9.f, oYScale = scale / 9.f;
153 float x = (xpos + offX) * scale,
y = (ypos + offY) * scale;
154 int w = overlay->width() * oXScale, h = overlay->height() * oYScale;
157 int iW = round(w), iH = round(h);
158 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));
162 painter.setBrush(QBrush(bgColor));
163 painter.drawRect(0, 0,
width(), height());
172 painter.setPen(QPen(highlightColor, 0.5));
173 QColor bColor = highlightColor;
174 bColor.setAlpha(128);
175 painter.setBrush(QBrush(bColor));
176 painter.drawRect(x1, y1, x2 - x1, y2 - y1);
180 QPixmap keyBG(wWidth * ratio, wHeight * ratio);
181 keyBG.fill(QColor(0, 0, 0, 0));
182 QPainter bgPainter(&keyBG);
183 bgPainter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
184 bgPainter.setPen(Qt::NoPen);
185 QHashIterator<QString, Key> k(
keyMap);
190 const Key&
key = k.value();
191 float x = key.
x + offX - key.
width / 2.f + 1.f;
192 float y = key.
y + offY - key.
height / 2.f + 1.f;
193 float w = key.
width - 2.f;
194 float h = key.
height - 2.f;
200 bgPainter.setOpacity(1.);
201 if(highlight.testBit(i)){
203 bgPainter.setBrush(QBrush(highlightAnimColor));
205 bgPainter.setBrush(QBrush(highlightColor));
207 bgPainter.setBrush(QBrush(animColor));
209 if(!strcmp(key.
name,
"sniper"))
211 bgPainter.setBrush(QBrush(sniperColor));
214 bgPainter.setBrush(QBrush(thumbColor));
215 else if(!strcmp(key.
name,
"lsidel") || !strcmp(key.
name,
"rsidel") || !strcmp(key.
name,
"logo"))
217 bgPainter.setBrush(QBrush(transparentColor));
219 bgPainter.setBrush(QBrush(keyColor));
221 bgPainter.setOpacity(0.7);
225 || !strcmp(key.
name,
"light") || !strcmp(key.
name,
"lock") || (model ==
KeyMap::K65 && !strcmp(key.
name,
"mute")))){
231 bgPainter.drawEllipse(QRectF(x * scale, y * scale, w * scale, h * scale));
233 if(!strcmp(key.
name,
"enter")){
238 bgPainter.drawRect(QRectF((x + w - 13.f) * scale, y * scale, 13.f * scale, 22.f * scale));
244 }
else if(!strcmp(key.
name,
"rshift") || !strcmp(key.
name,
"stop")){
248 }
else if(!strcmp(key.
name,
"caps") || !strcmp(key.
name,
"lshift") || !strcmp(key.
name,
"next")){
251 bgPainter.drawRect(QRectF(x * scale, y * scale, w * scale, h * scale));
256 QPixmap decoration(wWidth * ratio, wHeight * ratio);
257 decoration.fill(QColor(0, 0, 0, 0));
258 QPainter decPainter(&decoration);
259 decPainter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
262 QHashIterator<QString, Key> k(
keyMap);
267 const Key&
key = k.value();
270 float x = key.
x + offX - 1.8f;
271 float y = key.
y + offY - 1.8f;
276 decPainter.setPen(QPen(QColor(255, 248, 136), 1.5));
278 decPainter.setPen(QPen(QColor(255, 255, 255), 1.5));
289 color =
monoRgb(qRed(color), qGreen(color), qBlue(color));
291 decPainter.setBrush(QBrush(color));
293 float kx = key.
x + offX - key.
width / 2.f + 1.f;
294 float ky = key.
y + offY - key.
height / 2.f + 1.f;
295 float kw = key.
width - 2.f;
296 float kh = key.
height - 2.f;
297 decPainter.setPen(QPen(QColor(255, 255, 255), 1.2));
298 if(!strcmp(key.
name,
"logo")) {
299 float lx = key.
x + offX - key.
width / 2.f + 2.f;
300 float ly = key.
y + offY - key.
height / 2.f + 2.f;
301 float lw = key.
width - 4.f;
302 float lh = key.
height - 4.f;
304 logo.moveTo(lx*scale,(ly+lh)*scale);
305 logo.quadTo((lx+2.f)*scale,(ly+lh/2.f)*scale,lx*scale,ly*scale);
306 logo.quadTo((lx+lw)*scale,ly*scale,(lx+lw)*scale,(ly+lh)*scale);
307 logo.quadTo((lx+lw/2.f)*scale,(ly+lh-4.f)*scale,lx*scale,(ly+lh)*scale);
308 decPainter.drawPath(logo);
311 }
else if(!strcmp(key.
name,
"lsidel") || !strcmp(key.
name,
"rsidel")) {
312 QRadialGradient gradient(QPointF(wWidth/2.f * ratio, wHeight/2.f * ratio), wWidth/2.f * ratio);
313 gradient.setColorAt(0, color);
314 gradient.setColorAt(0.9, color);
315 gradient.setColorAt(1, bgColor);
316 decPainter.setBrush(QBrush(gradient));
317 decPainter.setPen(QPen(keyColor, 1.2));
318 decPainter.drawRect(QRectF(kx * scale, ky * scale - 12 , kw * scale, kh * scale+24));
320 decPainter.setPen(QPen(QColor(0,0,0,0), 1));
321 decPainter.drawRect(QRectF((kx+2.f) * scale, (ky+2.f) * scale, (kw-4.f) * scale, (kh-4.f) * scale));
323 decPainter.drawEllipse(QRectF((x-1.f) * scale, (y-1.f) * scale, (w+2.f) * scale, (h+2.f) * scale));
325 decPainter.drawEllipse(QRectF(x * scale, y * scale, w * scale, h * scale));
329 decPainter.setBrush(Qt::NoBrush);
330 QFont font = painter.font();
332 font.setPixelSize(5.25f * scale);
334 QHashIterator<QString, Key> k(
keyMap);
339 const Key&
key = k.value();
342 float x = key.
x + offX - key.
width / 2.f + 1.f;
343 float y = key.
y + offY - key.
height / 2.f;
344 float w = key.
width - 2.f;
349 name = name.split(
" ").last();
351 const char* keyName, *displayName;
353 {
"light",
"☼"}, {
"lock",
"☒"}, {
"mute",
"◖⊘"}, {
"volup",
keyMap.
model() ==
KeyMap::K65 ?
"◖))" :
"▲"}, {
"voldn",
keyMap.
model() ==
KeyMap::K65 ?
"◖)" :
"▼"},
354 {
"prtscn",
"PrtScn\nSysRq"}, {
"scroll",
"Scroll\nLock"}, {
"pause",
"Pause\nBreak"}, {
"stop",
"▪"}, {
"prev",
"|◂◂"}, {
"play",
"▸||"}, {
"next",
"▸▸|"},
355 {
"pgup",
"Page\nUp"}, {
"pgdn",
"Page\nDown"}, {
"numlock",
"Num\nLock"},
356 {
"caps",
"Caps"}, {
"lshift",
"Shift"}, {
"rshift",
"Shift"},
358 {
"lctrl",
"⌃"}, {
"rctrl",
"⌃"}, {
"lwin",
"⌘"}, {
"rwin",
"⌘"}, {
"lalt",
"⌥"}, {
"ralt",
"⌥"},
360 {
"lctrl",
"Ctrl"}, {
"rctrl",
"Ctrl"}, {
"lwin",
"❖"}, {
"rwin",
"❖"}, {
"lalt",
"Alt"}, {
"ralt",
"Alt"},
362 {
"rmenu",
"▤"}, {
"up",
"▲"}, {
"left",
"◀"}, {
"down",
"▼"}, {
"right",
"▶"}, {
"fn",
"Fn"},
363 {
"mouse1",
""}, {
"mouse2",
""}, {
"mouse3",
"∙"}, {
"dpiup",
"▲"}, {
"dpidn",
"▼"}, {
"wheelup",
"▲"}, {
"wheeldn",
"▼"}, {
"dpi",
"◉"}, {
"mouse5",
"▲"}, {
"mouse4",
"▼"}, {
"sniper",
"⊕"}
365 for(uint k = 0; k <
sizeof(names) /
sizeof(names[0]); k++){
366 if(keyName == names[k].keyName){
367 name = names[k].displayName;
373 if(keyName ==
"mr" || keyName ==
"m1" || keyName ==
"m2" || keyName ==
"m3" || keyName ==
"up" || keyName ==
"down" || keyName ==
"left" || keyName ==
"right")
375 font.setPixelSize(font.pixelSize() * 0.75);
376 else if(keyName ==
"end")
378 font.setPixelSize(font.pixelSize() * 0.65);
379 else if(keyName ==
"light"
381 || keyName ==
"lwin" || keyName ==
"rwin"
385 font.setPixelSize(font.pixelSize() * 1.3);
390 decPainter.setFont(font);
391 QRectF rect(x * scale, y * scale - 1, w * scale, h * scale);
392 int flags = Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap;
393 QRectF bounds = decPainter.boundingRect(rect, flags, name);
394 while((bounds.height() >= rect.height() - 8. || bounds.width() >= rect.width() - 2.) && font.pixelSize() >= 5){
396 font.setPixelSize(font.pixelSize() - 2);
397 decPainter.setFont(font);
398 bounds = decPainter.boundingRect(rect, flags, name);
405 decPainter.setPen(QColor(255, 136, 136));
408 decPainter.setPen(QColor(255, 224, 192));
411 decPainter.setPen(QColor(128, 224, 255));
414 decPainter.setPen(QColor(160, 255, 168));
417 decPainter.setPen(QColor(255, 255, 255));
420 decPainter.setPen(QColor(255, 248, 128));
421 decPainter.drawText(rect, flags, name);
426 QGraphicsDropShadowEffect* bgEffect =
new QGraphicsDropShadowEffect;
427 bgEffect->setBlurRadius(2.);
428 bgEffect->setColor(QColor(0, 0, 0, 32));
429 bgEffect->setOffset(0, 1);
430 QGraphicsDropShadowEffect* decEffect =
new QGraphicsDropShadowEffect;
431 decEffect->setBlurRadius(4.);
432 decEffect->setColor(QColor(0, 0, 0, 104));
433 decEffect->setOffset(0, 1);
435 QGraphicsPixmapItem* bgItem =
new QGraphicsPixmapItem(keyBG);
436 bgItem->setGraphicsEffect(bgEffect);
437 QGraphicsPixmapItem* decItem =
new QGraphicsPixmapItem(decoration);
438 decItem->setGraphicsEffect(decEffect);
440 QGraphicsScene* scene =
new QGraphicsScene;
441 scene->addItem(bgItem);
442 scene->addItem(decItem);
444 QPixmap
final(wWidth * ratio, wHeight * ratio);
445 final.fill(QColor(0, 0, 0, 0));
446 QPainter finalPainter(&
final);
447 scene->render(&finalPainter, QRectF(0, 0, wWidth * ratio, wHeight * ratio), QRectF(0, 0, wWidth * ratio, wHeight * ratio));
449 #if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
450 final.setDevicePixelRatio(ratio);
452 painter.drawPixmap(QPointF(0., 0.),
final);
457 mouseDownMode = (
event->modifiers() & Qt::AltModifier) ?
SUBTRACT : (event->modifiers() & Qt::ShiftModifier) ?
ADD : (event->modifiers() & Qt::ControlModifier) ?
TOGGLE :
SET;
461 float scale, offX, offY;
464 QHashIterator<QString, Key> k(
keyMap);
469 const Key&
key = k.value();
473 if(fabs(key.
x - mx) <= key.
width / 2.f - 1.f && fabs(key.
y - my) <= key.
height / 2.f - 1.f){
475 if(!strcmp(key.
name,
"lsidel") || !strcmp(key.
name,
"rsidel")){
494 float scale, offX, offY;
497 float mx1, mx2, my1, my2;
516 QHashIterator<QString, Key> k(
keyMap);
521 const Key&
key = k.value();
526 if(fabs(key.
x - mx) <= key.
width / 2.f - 1.f && fabs(key.
y - my) <= key.
height / 2.f - 1.f
527 && tooltip.isEmpty())
532 float kx1 = key.
x - key.
width / 2.f + 1.f;
533 float ky1 = key.
y - key.
height / 2.f + 1.f;
534 float kx2 = kx1 + key.
width - 2.f;
535 float ky2 = ky1 + key.
height - 2.f;
537 if(!(mx1 >= kx2 || kx1 >= mx2)
538 && !(my1 >= ky2 || ky1 >= my2)
572 QStringList selectedNames;
576 selectedNames << key;
585 foreach(
const QString&
key, keys){
586 int index = allNames.indexOf(key);
600 QStringList selectedNames;
603 if(strcmp(key.
name,
"lsidel") && strcmp(key.
name,
"rsidel")
606 selectedNames << key.
name;
628 foreach(
const QString&
key, keys){
630 if(!strcmp(key.toLatin1(),
"lsidel") || !strcmp(key.toLatin1(),
"rsidel"))
632 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)
QString defaultAction(const QString &key)
QHash< QString, QRgb > QColorMap
QList< Key > positions() const