OBSProxyStyle.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include "OBSProxyStyle.hpp"
  2. #include <QStyleOption>
  3. #include "moc_OBSProxyStyle.cpp"
  4. static inline uint qt_intensity(uint r, uint g, uint b)
  5. {
  6. /* 30% red, 59% green, 11% blue */
  7. return (77 * r + 150 * g + 28 * b) / 255;
  8. }
  9. /* The constants in the default QT styles don't dim the icons enough in
  10. * disabled mode
  11. *
  12. * https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#6429
  13. */
  14. QPixmap OBSContextBarProxyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
  15. const QStyleOption *option) const
  16. {
  17. if (iconMode == QIcon::Disabled) {
  18. QImage im = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
  19. /* Create a colortable based on the background
  20. * (black -> bg -> white) */
  21. QColor bg = option->palette.color(QPalette::Disabled, QPalette::Window);
  22. int red = bg.red();
  23. int green = bg.green();
  24. int blue = bg.blue();
  25. uchar reds[256], greens[256], blues[256];
  26. for (int i = 0; i < 128; ++i) {
  27. reds[i] = uchar((red * (i << 1)) >> 8);
  28. greens[i] = uchar((green * (i << 1)) >> 8);
  29. blues[i] = uchar((blue * (i << 1)) >> 8);
  30. }
  31. for (int i = 0; i < 128; ++i) {
  32. reds[i + 128] = uchar(qMin(red + (i << 1), 255));
  33. greens[i + 128] = uchar(qMin(green + (i << 1), 255));
  34. blues[i + 128] = uchar(qMin(blue + (i << 1), 255));
  35. }
  36. /* High intensity colors needs dark shifting in the color
  37. * table, while low intensity colors needs light shifting. This
  38. * is to increase the perceived contrast. */
  39. int intensity = qt_intensity(red, green, blue);
  40. const int factor = 191;
  41. if ((red - factor > green && red - factor > blue) || (green - factor > red && green - factor > blue) ||
  42. (blue - factor > red && blue - factor > green))
  43. qMin(255, intensity + 20);
  44. else if (intensity <= 128)
  45. intensity += 100;
  46. for (int y = 0; y < im.height(); ++y) {
  47. QRgb *scanLine = (QRgb *)im.scanLine(y);
  48. for (int x = 0; x < im.width(); ++x) {
  49. QRgb pixel = *scanLine;
  50. /* Calculate color table index, taking
  51. * intensity adjustment and a magic offset into
  52. * account. */
  53. uint ci = uint(qGray(pixel) / 3 + (130 - intensity / 3));
  54. *scanLine = qRgba(reds[ci], greens[ci], blues[ci], qAlpha(pixel));
  55. ++scanLine;
  56. }
  57. }
  58. return QPixmap::fromImage(im);
  59. }
  60. return QProxyStyle::generatedIconPixmap(iconMode, pixmap, option);
  61. }
  62. int OBSProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
  63. QStyleHintReturn *returnData) const
  64. {
  65. if (hint == SH_ComboBox_AllowWheelScrolling)
  66. return 0;
  67. #ifdef __APPLE__
  68. if (hint == SH_ComboBox_UseNativePopup)
  69. return 1;
  70. #endif
  71. return QProxyStyle::styleHint(hint, option, widget, returnData);
  72. }