Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F133952
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
90 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/CloneDialog.cpp b/src/CloneDialog.cpp
index a7de176..9dacf42 100644
--- a/src/CloneDialog.cpp
+++ b/src/CloneDialog.cpp
@@ -1,138 +1,143 @@
#include "CloneDialog.h"
#include "ui_CloneDialog.h"
#include "common/misc.h"
#include "common/joinpath.h"
#include "BasicMainWindow.h"
#include "SearchFromGitHubDialog.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QThread>
enum SearchRepository {
None,
GitHub,
};
struct CloneDialog::Private {
QString url;
QString repo_name;
QString default_working_dir;
bool ok = false;
QString errmsg;
CloneDialog::Action action = CloneDialog::Action::Clone;
};
CloneDialog::CloneDialog(BasicMainWindow *parent, QString const &url, QString const &defworkdir)
: QDialog(parent)
, ui(new Ui::CloneDialog)
, m(new Private)
{
ui->setupUi(this);
Qt::WindowFlags flags = windowFlags();
flags &= ~Qt::WindowContextHelpButtonHint;
setWindowFlags(flags);
m->default_working_dir = defworkdir;
ui->lineEdit_working_dir->setText(m->default_working_dir);
ui->lineEdit_repo_location->setText(url);
ui->comboBox->addItem(tr("Search"));
ui->comboBox->addItem(tr("GitHub"));
+
+
+#ifdef Q_OS_MACX
+ ui->comboBox->setMinimumWidth(100);
+#endif
}
CloneDialog::~CloneDialog()
{
delete m;
delete ui;
}
CloneDialog::Action CloneDialog::action() const
{
return m->action;
}
BasicMainWindow *CloneDialog::mainwindow()
{
return qobject_cast<BasicMainWindow *>(parent());
}
QString CloneDialog::url()
{
return ui->lineEdit_repo_location->text();
}
QString CloneDialog::dir()
{
return ui->lineEdit_working_dir->text();
}
void CloneDialog::on_lineEdit_repo_location_textChanged(QString const &text)
{
QString path;
int i = text.lastIndexOf('/');
int j = text.lastIndexOf('\\');
if (i < j) i = j;
j = text.size();
if (text.endsWith(".git")) {
j -= 4;
}
if (i >= 0 && i < j) {
path = text.mid(i, j - i);
}
m->repo_name = path;
path = m->default_working_dir / m->repo_name;
path = misc::normalizePathSeparator(path);
ui->lineEdit_working_dir->setText(path);
}
void CloneDialog::on_comboBox_currentIndexChanged(int index)
{
if (index == GitHub) {
SearchFromGitHubDialog dlg(this, mainwindow());
if (dlg.exec() == QDialog::Accepted) {
ui->lineEdit_repo_location->setText(dlg.url());
}
}
ui->comboBox->setCurrentIndex(0);
}
void CloneDialog::on_pushButton_test_clicked()
{
mainwindow()->testRemoteRepositoryValidity(url());
}
void CloneDialog::on_pushButton_browse_clicked()
{
QString path = ui->lineEdit_working_dir->text();
path = QFileDialog::getExistingDirectory(this, tr("Checkout into"), path);
if (!path.isEmpty()) {
m->default_working_dir = path;
path = m->default_working_dir / m->repo_name;
path = misc::normalizePathSeparator(path);
ui->lineEdit_working_dir->setText(path);
}
}
void CloneDialog::on_pushButton_open_existing_clicked()
{
QString dir = mainwindow()->defaultWorkingDir();
dir = QFileDialog::getExistingDirectory(this, tr("Open existing directory"), dir);
if (QFileInfo(dir).isDir()) {
QString url;
GitPtr g = mainwindow()->git(dir);
QList<Git::Remote> vec;
if (g->isValidWorkingCopy()) {
g->getRemoteURLs(&vec);
}
for (Git::Remote const &r : vec) {
if (r.purpose == "push" || url.isEmpty()) {
url = r.url;
}
}
ui->lineEdit_repo_location->setText(url);
ui->lineEdit_working_dir->setText(dir);
m->action = CloneDialog::Action::AddExisting;
done(Accepted);
}
}
diff --git a/src/CloneDialog.ui b/src/CloneDialog.ui
index 990dcf7..d82f778 100644
--- a/src/CloneDialog.ui
+++ b/src/CloneDialog.ui
@@ -1,175 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CloneDialog</class>
<widget class="QDialog" name="CloneDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>545</width>
- <height>115</height>
+ <height>140</height>
</rect>
</property>
<property name="windowTitle">
<string>Clone</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Remote</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="RepositoryLineEdit" name="lineEdit_repo_location">
<property name="minimumSize">
<size>
<width>320</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_test">
<property name="text">
<string>&Test</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Local</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="DirectoryLineEdit" name="lineEdit_working_dir"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_browse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="comboBox"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_open_existing">
<property name="text">
<string>Open existing local directory...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Clone</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RepositoryLineEdit</class>
<extends>QLineEdit</extends>
<header>RepositoryLineEdit.h</header>
</customwidget>
<customwidget>
<class>DirectoryLineEdit</class>
<extends>QLineEdit</extends>
<header>DirectoryLineEdit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>lineEdit_repo_location</tabstop>
<tabstop>pushButton_test</tabstop>
<tabstop>lineEdit_working_dir</tabstop>
<tabstop>pushButton</tabstop>
<tabstop>pushButton_2</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>CloneDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>152</x>
<y>269</y>
</hint>
<hint type="destinationlabel">
<x>104</x>
<y>320</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton_2</sender>
<signal>clicked()</signal>
<receiver>CloneDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>244</x>
<y>270</y>
</hint>
<hint type="destinationlabel">
<x>238</x>
<y>317</y>
</hint>
</hints>
</connection>
</connections>
</ui>
diff --git a/src/darktheme/DarkStyle.cpp b/src/darktheme/DarkStyle.cpp
index 2e9db83..321158e 100644
--- a/src/darktheme/DarkStyle.cpp
+++ b/src/darktheme/DarkStyle.cpp
@@ -1,2548 +1,2571 @@
#include "DarkStyle.h"
#include "NinePatch.h"
#include "TraditionalWindowsStyleTreeControl.h"
#include <QApplication>
#include <QComboBox>
#include <QDebug>
#include <QDialogButtonBox>
#include <QDockWidget>
#include <QInputDialog>
#include <QListView>
#include <QMessageBox>
#include <QPixmapCache>
#include <QStyleOptionComplex>
#include <QStyleOptionFrameV3>
#include <QTableWidget>
#include <QTextLayout>
#include <QToolTip>
#include <cmath>
#include <cstdint>
#define MBI_NORMAL 1
#define MBI_HOT 2
#define MBI_PUSHED 3
#define MBI_DISABLED 4
namespace {
const int windowsItemFrame = 2; // menu item frame width
const int windowsItemHMargin = 3; // menu item hor text margin
const int windowsItemVMargin = 4; // menu item ver text margin
const int windowsArrowHMargin = 6; // arrow horizontal margin
const int windowsRightBorder = 15; // right border on windows
void drawFrame(QPainter *pr, int x, int y, int w, int h, QColor color_topleft, QColor color_bottomright)
{
if (w < 3 || h < 3) {
if (w > 0 && h > 0) {
pr->fillRect(x, y, w, h, color_topleft);
}
} else {
if (!color_topleft.isValid()) color_topleft = Qt::black;
if (!color_bottomright.isValid()) color_bottomright = color_topleft;
pr->fillRect(x, y, w - 1, 1, color_topleft);
pr->fillRect(x, y + 1, 1, h -1, color_topleft);
pr->fillRect(x + w - 1, y, 1, h -1, color_bottomright);
pr->fillRect(x + 1, y + h - 1, w - 1, 1, color_bottomright);
}
}
void drawFrame(QPainter *pr, QRect const &r, QColor const &color_topleft, QColor const &color_bottomright)
{
return drawFrame(pr, r.x(), r.y(), r.width(), r.height(), color_topleft, color_bottomright);
}
struct TextureCacheItem {
QString key;
QPixmap pm;
};
QString pixmapkey(QString const &name, QString const &role, QSize const &size, QColor const &color)
{
QString key = "%1:%2:%3:%4:%5";
key = key.arg(name).arg(role).arg(size.width()).arg(size.height()).arg(QString().sprintf("%02X%02X%02X", color.red(), color.green(), color.blue()));
return key;
}
void drawRaisedFrame(QPainter *p, const QRect &rect, const QPalette &palette)
{
p->save();
int x = rect.x();
int y = rect.y();
int w = rect.width();
int h = rect.height();
p->setClipRect(x, y, w, h);
p->fillRect(x, y, w, h, palette.color(QPalette::Window));
p->fillRect(x, y, w - 1, 1, palette.color(QPalette::Light));
p->fillRect(x, y, 1, h - 1, palette.color(QPalette::Light));
// p->fillRect(x + 1, y + h - 2, w - 2, 1, palette.color(QPalette::Dark));
// p->fillRect(x + w - 2, y + 1, 1, h - 2, palette.color(QPalette::Dark));
p->fillRect(x, y + h - 1, w, 1, palette.color(QPalette::Shadow));
p->fillRect(x + w - 1, y, 1, h, palette.color(QPalette::Shadow));
p->restore();
}
QImage loadImage(QString const &path, QString const &role = QString())
{
QImage image(path);
image.setText("name", path);
image.setText("role", role);
return image;
}
QRgb colorize(QRgb color, int light, int alpha)
{
int r, g, b;
r = g = b = 0;
if (alpha != 0) {
r = qRed(color);
g = qGreen(color);
b = qBlue(color);
if (light < 128) {
r = r * light / 127;
g = g * light / 127;
b = b * light / 127;
} else {
int u = 255 - light;
r = 255 - (255 - r) * u / 127;
g = 255 - (255 - g) * u / 127;
b = 255 - (255 - b) * u / 127;
}
}
return qRgba(r, g, b, alpha);
}
} // namespace
// DarkStyle
static const int TEXTURE_CACHE_SIZE = 100;
struct DarkStyle::Private {
QColor base_color;
bool images_loaded = false;
ScrollBarTextures hsb;
ScrollBarTextures vsb;
int scroll_bar_extent = -1;
QImage button_normal;
QImage button_press;
QImage progress_horz;
QImage progress_vert;
TraditionalWindowsStyleTreeControl legacy_windows;
};
DarkStyle::DarkStyle(QColor const &base_color)
: m(new Private)
{
setBaseColor(base_color);
}
DarkStyle::~DarkStyle()
{
delete m;
}
QColor DarkStyle::getBaseColor()
{
return m->base_color;
}
void DarkStyle::setBaseColor(QColor const &color)
{
m->base_color = color;
m->images_loaded = false;
}
QColor DarkStyle::color(int level, int alpha) const
{
QColor c = m->base_color.lighter(level * 100 / 255);
c.setAlpha(alpha);
return c;
}
void DarkStyle::setScrollBarExtent(int n)
{
m->scroll_bar_extent = n;
}
QImage DarkStyle::colorizeImage(QImage image)
{
int w = image.width();
int h = image.height();
if (w > 0 && h > 0) {
QColor c = color(128);
QRgb rgb = c.rgb();
Q_ASSERT(image.format() == QImage::Format_ARGB32);
for (int y = 0; y < h; y++) {
QRgb *p = reinterpret_cast<QRgb *>(image.scanLine(y));
for (int x = 0; x < w; x++) {
p[x] = colorize(rgb, qGray(p[x]), qAlpha(p[x]));
}
}
}
return image;
}
QImage DarkStyle::loadColorizedImage(QString const &path, QString const &role)
{
QImage image = loadImage(path);
image = colorizeImage(image);
image.setText("name", path);
image.setText("role", role);
return image;
}
namespace {
class Lighten {
private:
int lut[256];
public:
Lighten()
{
#if 0
const double x = 0.75;
for (int i = 0; i < 256; i++) {
lut[i] = (int)(pow(i / 255.0, x) * 255);
}
#else
for (int i = 0; i < 256; i++) {
lut[i] = 255 - (255 - i) * 192 / 256;
}
#endif
}
int operator [] (int i)
{
return lut[i];
}
};
}
DarkStyle::ButtonImages DarkStyle::generateButtonImages(QString const &path)
{
QImage source = loadImage(path);
ButtonImages buttons;
int w = source.width();
int h = source.height();
if (w > 4 && h > 4) {
QColor c = color(128);
QRgb rgb = c.rgb();
Lighten lighten;
buttons.im_normal = source;
buttons.im_hover = source;
w -= 4;
h -= 4;
for (int y = 0; y < h; y++) {
QRgb *src1 = reinterpret_cast<QRgb *>(source.scanLine(y + 1));
QRgb *src2 = reinterpret_cast<QRgb *>(source.scanLine(y + 2));
QRgb *src3 = reinterpret_cast<QRgb *>(source.scanLine(y + 3));
QRgb *dst0 = reinterpret_cast<QRgb *>(buttons.im_normal.scanLine(y + 2)) + 2;
QRgb *dst1 = reinterpret_cast<QRgb *>(buttons.im_hover.scanLine(y + 2)) + 2;
for (int x = 0; x < w; x++) {
int v = (int)qAlpha(src3[x + 3]) - (int)qAlpha(src1[x + 1]);
v = (v + 256) / 2;
int alpha = qAlpha(src2[x + 2]);
dst0[x] = colorize(rgb, v, alpha);
v = lighten[v];
dst1[x] = colorize(rgb, v, alpha);
}
}
buttons.im_normal.setText("name", source.text("name"));
buttons.im_hover.setText("name", source.text("name"));
buttons.im_normal.setText("role", "normal");
buttons.im_hover.setText("role", "hover");
}
return buttons;
}
QImage DarkStyle::generateHoverImage(QImage const &source)
{
QImage newimage;
int w = source.width();
int h = source.height();
if (w > 2 && h > 2) {
QColor c = color(128);
QRgb rgb = c.rgb();
Lighten lighten;
newimage = source;
Q_ASSERT(newimage.format() == QImage::Format_ARGB32);
w -= 2;
h -= 2;
for (int y = 0; y < h; y++) {
QRgb *ptr = reinterpret_cast<QRgb *>(newimage.scanLine(y + 1)) + 1;
for (int x = 0; x < w; x++) {
int v = qGray(ptr[x]);
v = lighten[v];
ptr[x] = colorize(rgb, v, qAlpha(ptr[x]));
}
}
newimage.setText("role", "hover");
}
return newimage;
}
void DarkStyle::loadImages()
{
if (m->images_loaded) return;
if (!m->base_color.isValid()) {
setBaseColor(Qt::white);
}
m->button_normal = loadColorizedImage(QLatin1String(":/darktheme/button/button_normal.png"), QLatin1String("normal"));
m->button_press = loadColorizedImage(QLatin1String(":/darktheme/button/button_press.png"), QLatin1String("press"));
m->hsb.sub_line = generateButtonImages(QLatin1String(":/darktheme/hsb/hsb_sub_line.png"));
m->hsb.add_line = generateButtonImages(QLatin1String(":/darktheme/hsb/hsb_add_line.png"));
m->hsb.page_bg = loadColorizedImage(QLatin1String(":/darktheme/hsb/hsb_page_bg.png"));
m->hsb.slider.im_normal = loadColorizedImage(QLatin1String(":/darktheme/hsb/hsb_slider.png"));
m->hsb.slider.im_hover = generateHoverImage(m->hsb.slider.im_normal);
m->vsb.sub_line = generateButtonImages(QLatin1String(":/darktheme/vsb/vsb_sub_line.png"));
m->vsb.add_line = generateButtonImages(QLatin1String(":/darktheme/vsb/vsb_add_line.png"));
m->vsb.page_bg = loadColorizedImage(QLatin1String(":/darktheme/vsb/vsb_page_bg.png"));
m->vsb.slider.im_normal = loadColorizedImage(QLatin1String(":/darktheme/vsb/vsb_slider.png"));
m->vsb.slider.im_hover = generateHoverImage(m->vsb.slider.im_normal);
m->progress_horz = loadImage(QLatin1String(":/darktheme/progress/horz.png"));
m->progress_vert = loadImage(QLatin1String(":/darktheme/progress/vert.png"));
m->images_loaded = true;
}
QPixmap DarkStyle::pixmapFromImage(const QImage &image, QSize size) const
{
QString key = pixmapkey(image.text("name"), image.text("role"), size, m->base_color);
QPixmap *pm = QPixmapCache::find(key);
if (pm) return *pm;
TextureCacheItem t;
t.key = key;
t.pm = QPixmap::fromImage(image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
QPixmapCache::insert(key, t.pm);
return t.pm;
}
QColor DarkStyle::selectionColor() const
{
// return QColor(128, 192, 255);
return QColor(80, 160, 255);
}
QColor DarkStyle::colorForItemView(QStyleOption const *opt) const
{
#ifdef Q_OS_WIN
return opt->palette.color(QPalette::Base);
#else
return opt->palette.color(QPalette::Dark);
#endif
}
void DarkStyle::drawNinePatchImage(QPainter *p, const QImage &image, const QRect &r, int w, int h) const
{
QImage im = createImageFromNinePatchImage(image, w, h);
im.setText("name", image.text("name"));
im.setText("role", image.text("role"));
QPixmap pm = pixmapFromImage(im, r.size());
p->drawPixmap(r.x(), r.y(), pm);
}
void DarkStyle::polish(QPalette &palette)
{
if (!m->base_color.isValid()) {
setBaseColor(Qt::white);
}
loadImages();
palette = QPalette(color(64));
palette.setColor(QPalette::Disabled, QPalette::Text, color(160));
palette.setColor(QPalette::Normal, QPalette::Highlight, selectionColor().lighter(75));
palette.setColor(QPalette::Disabled, QPalette::ButtonText, color(128));
#ifndef Q_OS_WIN
palette.setColor(QPalette::ToolTipText, Qt::black); // ツールチップの文字色
#endif
}
void DarkStyle::drawGutter(QPainter *p, const QRect &r) const
{
int x = r.x();
int y = r.y();
int w = r.width();
int h = r.height();
QColor dark = color(32);
QColor lite = color(128);
if (w < h) {
x += (w - 1) / 2;
p->fillRect(x, y, 1, h, dark);
p->fillRect(x + 1, y, 1, h, lite);
} else if (w > h) {
y += (h - 1) / 2;
p->fillRect(x, y, w, 1, dark);
p->fillRect(x, y + 1, w, 1, lite);
}
}
void DarkStyle::drawSelectedItemFrame(QPainter *p, QRect rect, bool focus) const
{
QColor color = focus ? selectionColor() : QColor(128, 128, 128);
int x, y, w, h;
x = rect.x();
y = rect.y();
w = rect.width();
h = rect.height();
QString key = QString::asprintf("selection_frame:%02x%02x%02x:%dx%d", color.red(), color.green(), color.blue(), w, h);
QPixmap pixmap;
if (!QPixmapCache::find(key, &pixmap)) {
pixmap = QPixmap(w, h);
pixmap.fill(Qt::transparent);
QPainter pr(&pixmap);
pr.setRenderHint(QPainter::Antialiasing);
QColor pencolor = color;
pencolor.setAlpha(128);
pr.setPen(pencolor);
pr.setBrush(Qt::NoBrush);
QPainterPath path;
path.addRoundedRect(1.5, 1.5, w - 1.5, h - 1.5, 3, 3);
pr.drawPath(path);
pr.setClipPath(path);
int a = color.alpha();
QColor color0 = color;
QColor color1 = color;
color0.setAlpha(128 * a / 255);
color1.setAlpha(64 * a / 255);
QLinearGradient gr(QPointF(0, 0), QPointF(0, h));
gr.setColorAt(0, color0);
gr.setColorAt(1, color1);
QBrush br(gr);
pr.fillRect(0, 0, w, h, br);
pr.end();
QPixmapCache::insert(key, pixmap);
}
p->drawPixmap(x, y, w, h, pixmap);
}
void DarkStyle::drawFocusFrame(QPainter *p, QRect const &rect, int margin) const
{
p->save();
p->setRenderHint(QPainter::Antialiasing);
QColor color = selectionColor();
p->setPen(color);
p->setBrush(Qt::NoBrush);
double m = margin + 0.5;
p->drawRoundedRect(((QRectF)rect).adjusted(m, m, -m, -m), 3, 3);
p->restore();
}
void DarkStyle::drawButton(QPainter *p, const QStyleOption *option, bool mac_margin) const
{
QRect rect = option->rect;
int w = rect.width();
int h = rect.height();
#ifdef Q_OS_MAC
if (mac_margin) {
int margin = pixelMetric(PM_ButtonMargin, option, nullptr);
if (margin > 0) {
int n = std::min(w, h);
if (n > margin * 2) {
n = (n - margin * 2) / 2;
if (n > margin) n = margin;
rect = rect.adjusted(n, n, -n, -n);
w = rect.width();
h = rect.height();
}
}
}
#else
(void)mac_margin;
#endif
bool pressed = (option->state & (State_Sunken | State_On));
bool hover = (option->state & State_MouseOver);
if (pressed) {
drawNinePatchImage(p, m->button_press, rect, w, h);
} else {
drawNinePatchImage(p, m->button_normal, rect, w, h);
}
{
QPainterPath path;
path.addRoundedRect(rect, 6, 6); // 角丸四角形のパス
p->save();
p->setRenderHint(QPainter::Antialiasing);
p->setClipPath(path);
int x = rect.x();
int y = rect.y();
int w = rect.width();
int h = rect.height();
QColor color0, color1;
#ifdef Q_OS_MAC
if (pressed) {
color0 = Qt::black;
color1 = Qt::black;
color0.setAlpha(48);
color1.setAlpha(144);
} else {
color0 = Qt::black;
color1 = Qt::black;
color0.setAlpha(32);
color1.setAlpha(128);
}
#else
if (pressed) {
color0 = Qt::black;
color1 = Qt::black;
color0.setAlpha(32);
color1.setAlpha(128);
} else if (hover) {
color0 = Qt::black;
color1 = Qt::black;
color0.setAlpha(16);
color1.setAlpha(96);
} else {
color0 = Qt::black;
color1 = Qt::black;
color0.setAlpha(32);
color1.setAlpha(128);
}
#endif
QLinearGradient gr(QPointF(x, y), QPointF(x, y + h));
gr.setColorAt(0, color0);
gr.setColorAt(1, color1);
QBrush br(gr);
p->fillRect(x, y, w, h, br);
if (option->state & State_HasFocus) {
#if 1
drawFocusFrame(p, rect, 3);
#else
p->fillRect(x, y, w, h, QColor(80, 160, 255, 32));
#endif
}
p->restore();
}
}
void DarkStyle::drawToolButton(QPainter *p, const QStyleOption *option) const
{
p->save();
bool hover = (option->state & State_MouseOver);
bool pressed = (option->state & State_Sunken);
#ifdef Q_OS_MAC
hover = false;
#endif
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width();
int h = option->rect.height();
QColor color0, color1;
#ifdef Q_OS_MAC
if (pressed) {
color0 = color(72);
color1 = color(40);
} else {
color0 = color(80);
color1 = color(48);
}
#else
if (pressed) {
color0 = color(80);
color1 = color(48);
} else if (hover) {
color0 = color(96);
color1 = color(64);
} else {
color0 = color(80);
color1 = color(48);
}
#endif
QLinearGradient gr(QPointF(x, y), QPointF(x, y + h));
gr.setColorAt(0, color0);
gr.setColorAt(1, color1);
QBrush br(gr);
p->fillRect(x, y, w, h, br);
if (option->state & State_Raised) {
drawFrame(p, option->rect, color(96), color(32));
} else if (option->state & State_Sunken) {
drawFrame(p, option->rect, color(48), color(48));
}
p->restore();
}
void DarkStyle::drawMenuBarBG(QPainter *p, const QStyleOption *option, QWidget const *widget) const
{
int x = option->rect.x();
int y = widget->y();
int w = option->rect.width();
int h = widget->height();
QLinearGradient gradient;
gradient.setStart(x, y);
gradient.setFinalStop(x, y + h / 2.0);
gradient.setColorAt(0, option->palette.color(QPalette::Light));
gradient.setColorAt(1, option->palette.color(QPalette::Window));
p->fillRect(x, y, w, h, gradient);
p->fillRect(x, y + h - 1, w, 1, option->palette.color(QPalette::Dark));
}
int DarkStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
{
if (metric == PM_ScrollBarExtent) {
if (m->scroll_bar_extent > 0) {
return m->scroll_bar_extent;
}
}
if (metric == PM_SliderLength) {
return std::min(widget->width(), widget->height());
}
return QProxyStyle::pixelMetric(metric, option, widget);
}
QRect DarkStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const
{
if (cc == CC_Slider && sc == SC_SliderGroove) {
return widget->rect();
}
if (cc == CC_Slider && sc == SC_SliderHandle) {
if (auto const *o = qstyleoption_cast<QStyleOptionSlider const *>(option)) {
QRect rect;
int extent = std::min(widget->width(), widget->height());
int span = pixelMetric(PM_SliderLength, o, widget);
bool horizontal = o->orientation == Qt::Horizontal;
int sliderPos = sliderPositionFromValue(o->minimum, o->maximum,
o->sliderPosition,
(horizontal ? o->rect.width()
: o->rect.height()) - span,
o->upsideDown);
if (horizontal) {
rect.setRect(o->rect.x() + sliderPos, o->rect.y(), span, extent);
} else {
rect.setRect(o->rect.x(), o->rect.y() + sliderPos, extent, span);
}
return rect;
}
}
if (cc == CC_GroupBox) {
QRect ret;
if (auto const *o = qstyleoption_cast<QStyleOptionGroupBox const *>(option)) {
switch (sc) {
case SC_GroupBoxFrame:
case SC_GroupBoxContents:
{
int topMargin = 0;
int topHeight = 0;
int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, o, widget);
#ifdef Q_OS_MACX
verticalAlignment |= Qt::AlignVCenter;
#endif
if (o->text.size() || (o->subControls & QStyle::SC_GroupBoxCheckBox)) {
topHeight = o->fontMetrics.height();
if (verticalAlignment & Qt::AlignVCenter) {
topMargin = topHeight / 2;
} else if (verticalAlignment & Qt::AlignTop) {
topMargin = topHeight;
}
}
QRect frameRect = o->rect;
frameRect.setTop(topMargin);
if (sc == SC_GroupBoxFrame) {
ret = frameRect;
break;
}
int frameWidth = 0;
if ((o->features & QStyleOptionFrame::Flat) == 0) {
frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, o, widget);
}
ret = frameRect.adjusted(frameWidth, frameWidth + topHeight - topMargin, -frameWidth, -frameWidth);
}
break;
case SC_GroupBoxCheckBox:
case SC_GroupBoxLabel:
{
QFontMetrics fontMetrics = o->fontMetrics;
int h = fontMetrics.height();
int tw = fontMetrics.size(Qt::TextShowMnemonic, o->text + QLatin1Char(' ')).width();
int marg = (o->features & QStyleOptionFrame::Flat) ? 0 : 8;
ret = o->rect.adjusted(marg, 0, -marg, 0);
ret.setHeight(h);
int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, option, widget) - 1;
bool hasCheckBox = o->subControls & QStyle::SC_GroupBoxCheckBox;
int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
// Adjusted rect for label + indicatorWidth + indicatorSpace
QRect totalRect = alignedRect(o->direction, o->textAlignment, QSize(tw + checkBoxSize, h), ret);
// Adjust totalRect if checkbox is set
if (hasCheckBox) {
bool ltr = o->direction == Qt::LeftToRight;
int left = 0;
// Adjust for check box
if (sc == SC_GroupBoxCheckBox) {
int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
int top = totalRect.top() + qMax(0, fontMetrics.height() - indicatorHeight) / 2;
totalRect.setRect(left, top, indicatorWidth, indicatorHeight);
// Adjust for label
} else {
left = ltr ? (totalRect.left() + checkBoxSize - 2) : totalRect.left();
totalRect.setRect(left, totalRect.top(), totalRect.width() - checkBoxSize, totalRect.height());
}
}
ret = totalRect;
}
break;
}
return ret;
}
}
return QProxyStyle::subControlRect(cc, option, sc, widget);
}
int DarkStyle::styleHint(QStyle::StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const
{
if (stylehint == SH_Table_GridLineColor) {
return static_cast<int>(color(32).rgb());
}
return QProxyStyle::styleHint(stylehint, opt, widget, returnData);
}
#if 0
static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
{
qreal height = 0;
qreal widthUsed = 0;
textLayout.beginLayout();
while (true) {
QTextLine line = textLayout.createLine();
if (!line.isValid())
break;
line.setLineWidth(lineWidth);
line.setPosition(QPointF(0, height));
height += line.height();
widthUsed = qMax(widthUsed, line.naturalTextWidth());
}
textLayout.endLayout();
return QSizeF(widthUsed, height);
}
void DarkStyle::drawItemViewText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const
{
const QWidget *widget = option->widget;
const int textMargin = pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
const bool wrapText = option->features & QStyleOptionViewItem::WrapText;
QTextOption textOption;
textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
textOption.setTextDirection(option->direction);
textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment));
QTextLayout textLayout(option->text, option->font);
textLayout.setTextOption(textOption);
viewItemTextLayout(textLayout, textRect.width());
const QRectF boundingRect = textLayout.boundingRect();
const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment, boundingRect.size().toSize(), textRect);
const QPointF position = layoutRect.topLeft();
const int lineCount = textLayout.lineCount();
qreal height = 0;
for (int i = 0; i < lineCount; ++i) {
const QTextLine line = textLayout.lineAt(i);
height += line.height();
// above visible rect
if (height + layoutRect.top() <= textRect.top()) continue;
const int start = line.textStart();
const int length = line.textLength();
const bool drawElided = line.naturalTextWidth() > textRect.width();
bool elideLastVisibleLine = false;
if (!drawElided && i + 1 < lineCount) {
const QTextLine nextLine = textLayout.lineAt(i + 1);
const int nextHeight = height + nextLine.height() / 2;
// elide when less than the next half line is visible
if (nextHeight + layoutRect.top() > textRect.height() + textRect.top()) {
elideLastVisibleLine = true;
}
}
if (drawElided || elideLastVisibleLine) {
QString text = textLayout.text().mid(start, length);
if (elideLastVisibleLine) {
text += QChar(0x2026);
}
// const QStackTextEngine engine(text, option->font);
const QString elidedText = text;//engine.elidedText(option->textElideMode, textRect.width());
const QPointF pos(position.x() + line.x(), position.y() + line.y() + line.ascent());
p->save();
p->setFont(option->font);
p->drawText(pos, elidedText);
p->restore();
} else {
line.draw(p, position);
}
// below visible text, can stop
if (height + layoutRect.top() >= textRect.bottom()) {
break;
}
}
}
#else
void DarkStyle::drawItemViewText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect, bool abbreviation) const
{
bool enabled = (option->state & State_Enabled);
p->save();
p->setFont(option->font);
QString text = option->text;
if (abbreviation) {
int n = text.size();
if (n > 1) {
QFontMetrics fm = p->fontMetrics();
int w = rect.width();
while (1) {
if (fm.size(0, text).width() <= w) break;
n--;
text = text.mid(0, n);
text += "...";
}
}
}
drawItemText(p, rect, option->displayAlignment, option->palette, enabled, text, QPalette::NoRole);
p->restore();
}
#endif
void DarkStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, const QWidget *widget) const
{
// qDebug() << pe;
#ifndef Q_OS_MAC
if (pe == PE_FrameFocusRect) {
// if (auto const *w = qobject_cast<QTableView const *>(widget)) {
// if (w->selectionBehavior() == QAbstractItemView::SelectRows) {
// if (auto const *v = w->viewport()) {
// QRect r(0, option->rect.y(), v->width(), option->rect.height());
// return;
// }
// }
// }
drawFocusFrame(p, option->rect, 0);
return;
}
#endif
if (pe == PE_IndicatorArrowDown) {
switch (pe) {
case PE_IndicatorArrowUp:
case PE_IndicatorArrowDown:
case PE_IndicatorArrowRight:
case PE_IndicatorArrowLeft:
{
if (option->rect.width() <= 1 || option->rect.height() <= 1) {
break;
}
QRect r = option->rect.adjusted(-10, -10, 0, 10);
int size = qMin(r.height(), r.width());
QPixmap pixmap;
if (1) {
int border = size / 5;
int sqsize = 2 * (size / 2);
QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied);
image.fill(0);
QPainter imagePainter(&image);
QPolygon a;
switch (pe) {
case PE_IndicatorArrowUp:
a.setPoints(3, border, sqsize / 2, sqsize / 2, border, sqsize - border, sqsize / 2);
break;
case PE_IndicatorArrowDown:
a.setPoints(3, border, sqsize / 2, sqsize / 2, sqsize - border, sqsize - border, sqsize / 2);
break;
case PE_IndicatorArrowRight:
a.setPoints(3, sqsize - border, sqsize / 2, sqsize / 2, border, sqsize / 2, sqsize - border);
break;
case PE_IndicatorArrowLeft:
a.setPoints(3, border, sqsize / 2, sqsize / 2, border, sqsize / 2, sqsize - border);
break;
default:
break;
}
int bsx = 0;
int bsy = 0;
if (option->state & State_Sunken) {
bsx = pixelMetric(PM_ButtonShiftHorizontal, option, widget);
bsy = pixelMetric(PM_ButtonShiftVertical, option, widget);
}
QRect bounds = a.boundingRect();
int sx = sqsize / 2 - bounds.center().x() - 1;
int sy = sqsize / 2 - bounds.center().y() - 1;
imagePainter.translate(sx + bsx, sy + bsy);
imagePainter.setPen(option->palette.buttonText().color());
imagePainter.setBrush(option->palette.buttonText());
imagePainter.setRenderHint(QPainter::Qt4CompatiblePainting);
if (!(option->state & State_Enabled)) {
imagePainter.translate(1, 1);
imagePainter.setBrush(option->palette.light().color());
imagePainter.setPen(option->palette.light().color());
imagePainter.drawPolygon(a);
imagePainter.translate(-1, -1);
imagePainter.setBrush(option->palette.mid().color());
imagePainter.setPen(option->palette.mid().color());
}
imagePainter.drawPolygon(a);
imagePainter.end();
pixmap = QPixmap::fromImage(image);
}
int xOffset = r.x() + (r.width() - size)/2;
int yOffset = r.y() + (r.height() - size)/2;
p->drawPixmap(xOffset, yOffset, pixmap);
}
}
return;
}
if (pe == PE_PanelMenu) {
+#ifdef Q_OS_MACX
+ if (qobject_cast<const QComboBox *>(widget->parent())) {
+ p->fillRect(option->rect, option->palette.color(QPalette::Light));
+ return;
+ }
+#endif
QRect r = option->rect;
drawFrame(p, r, Qt::black, Qt::black);
r = r.adjusted(1, 1, -1, -1);
drawFrame(p, r, color(128), color(64));
r = r.adjusted(1, 1, -1, -1);
p->fillRect(r, color(80));
return;
}
if (pe == PE_FrameMenu) {
return;
}
if (pe == PE_PanelButtonBevel) {
drawButton(p, option);
return;
}
if (pe == PE_PanelStatusBar) {
p->fillRect(option->rect, option->palette.color(QPalette::Window));
return;
}
if (pe == PE_FrameTabWidget) {
if (auto const *o = qstyleoption_cast<QStyleOptionTabWidgetFrame const *>(option)) {
int x = o->rect.x();
int y = o->rect.y();
int w = o->rect.width();
int h = o->rect.height();
#ifdef Q_OS_WIN
switch (o->shape) {
case QTabBar::RoundedNorth:
break;
case QTabBar::RoundedSouth:
h -= 1;
break;
case QTabBar::RoundedWest:
break;
case QTabBar::RoundedEast:
w -= 2;
break;
}
#endif
drawRaisedFrame(p, QRect(x, y, w, h), o->palette);
return;
}
}
if (pe == PE_PanelLineEdit) {
if (auto const *panel = qstyleoption_cast<QStyleOptionFrame const *>(option)) {
p->fillRect(option->rect, colorForItemView(option));
if (panel->lineWidth > 0) {
drawFrame(p, option->rect, option->palette.color(QPalette::Shadow), option->palette.color(QPalette::Light));
}
}
return;
}
if (pe == PE_FrameGroupBox) {
p->save();
p->setRenderHint(QPainter::Antialiasing);
QRectF r = option->rect;
r = r.adjusted(1.5, 1.5, -0.5, -0.5);
p->setPen(option->palette.color(QPalette::Light));
p->drawRoundedRect(r, 5, 5);
r = r.adjusted(-1, -1, -1, -1);
p->setPen(option->palette.color(QPalette::Dark));
p->drawRoundedRect(r, 5, 5);
p->restore();
return;
}
if (pe == PE_PanelItemViewRow) {
// p->drawEllipse(option->rect);
// return;
#ifdef Q_OS_WIN
// thru
#else
return;
#endif
}
if (pe == PE_PanelItemViewItem) {
// p->fillRect(option->rect, colorForItemView(option)); // 選択枠を透過描画させるので背景は描かない
auto DrawSelectionFrame = [&](QRect const &r){
bool focus = widget && widget->hasFocus();
drawSelectedItemFrame(p, r, focus);
};
if (auto const *tableview = qobject_cast<QTableView const *>(widget)) {
#if 0
Qt::PenStyle grid_pen_style = Qt::NoPen;
if (tableview->showGrid()) {
grid_pen_style = tableview->gridStyle();
}
if (grid_pen_style != Qt::NoPen) {
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width();
int h = option->rect.height();
p->fillRect(x + w - 1, y, 1, h, option->palette.color(QPalette::Dark));
p->fillRect(x, y + h - 1, w, 1, option->palette.color(QPalette::Dark));
}
#endif
QAbstractItemView::SelectionBehavior selection_behavior = tableview->selectionBehavior();
if (option->state & State_Selected) {
p->save();
p->setClipRect(option->rect);
QRect r = widget->rect();
if (selection_behavior == QAbstractItemView::SelectionBehavior::SelectRows) {
r = QRect(r.x(), option->rect.y(), r.width(), option->rect.height());
} else if (selection_behavior == QAbstractItemView::SelectionBehavior::SelectRows) {
r = QRect(option->rect.x(), r.y(), option->rect.y(), r.height());
}
DrawSelectionFrame(r);
p->restore();
}
} else {
if (option->state & State_Selected) {
DrawSelectionFrame(option->rect);
}
}
return;
}
if (pe == QStyle::PE_IndicatorBranch) {
QColor bg = option->palette.color(QPalette::Base);
p->fillRect(option->rect, bg);
if (m->legacy_windows.drawPrimitive(pe, option, p, widget)) {
return;
}
}
if (pe == QStyle::PE_Widget) { // bg for messagebox
const QDialogButtonBox *buttonBox = nullptr;
if (qobject_cast<const QMessageBox *> (widget))
buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
#ifndef QT_NO_INPUTDIALOG
else if (qobject_cast<const QInputDialog *> (widget))
buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
#endif // QT_NO_INPUTDIALOG
if (buttonBox) {
int y = buttonBox->geometry().top();
QRect r(option->rect.x(), y, option->rect.width(), 1);
p->fillRect(r, option->palette.color(QPalette::Light));
r.translate(0, -1);
p->fillRect(r, option->palette.color(QPalette::Dark));
}
return;
}
#ifndef Q_OS_WIN
if (pe == QStyle::PE_PanelTipLabel) {
// ツールチップの背景パネル
p->fillRect(option->rect, QColor(255, 255, 192));
drawFrame(p, option->rect, Qt::black, Qt::black);
return;
}
#endif
// qDebug() << pe;
QProxyStyle::drawPrimitive(pe, option, p, widget);
}
void DarkStyle::drawControl(ControlElement ce, const QStyleOption *option, QPainter *p, const QWidget *widget) const
{
// qDebug() << ce;
bool disabled = !(option->state & State_Enabled);
#ifdef Q_OS_MAC
if (ce == CE_ToolBar) {
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width();
int h = option->rect.height();
p->fillRect(x, y + h - 1, w, 1, color(32));
return;
}
#endif
#ifdef Q_OS_LINUX
if (ce == CE_ToolBar) {
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width();
int h = option->rect.height();
QColor color = option->palette.color(QPalette::Window);
p->fillRect(x, y + h - 1, w, 1, color);
return;
}
if (ce == CE_PushButtonLabel) {
if (auto const *o = qstyleoption_cast<QStyleOptionButton const *>(option)) {
QRect ir = o->rect;
uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
QPoint buttonShift;
if (option->state & State_Sunken) {
buttonShift = QPoint(pixelMetric(PM_ButtonShiftHorizontal, option, widget), proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
}
if (proxy()->styleHint(SH_UnderlineShortcut, o, widget)) {
tf |= Qt::TextShowMnemonic;
} else {
tf |= Qt::TextHideMnemonic;
}
if (!o->icon.isNull()) {
//Center both icon and text
QPoint point;
QIcon::Mode mode = o->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
if (mode == QIcon::Normal && o->state & State_HasFocus) {
mode = QIcon::Active;
}
QIcon::State state = QIcon::Off;
if (o->state & State_On) {
state = QIcon::On;
}
QPixmap pixmap = o->icon.pixmap(o->iconSize, mode, state);
int w = pixmap.width();
int h = pixmap.height();
if (!o->text.isEmpty()) {
w += o->fontMetrics.boundingRect(option->rect, tf, o->text).width() + 4;
}
point = QPoint(ir.x() + ir.width() / 2 - w / 2, ir.y() + ir.height() / 2 - h / 2);
if (o->direction == Qt::RightToLeft) {
point.rx() += pixmap.width();
}
p->drawPixmap(visualPos(o->direction, o->rect, point + buttonShift), pixmap);
if (o->direction == Qt::RightToLeft) {
ir.translate(-point.x() - 2, 0);
} else {
ir.translate(point.x() + pixmap.width() + 2, 0);
}
// left-align text if there is
if (!o->text.isEmpty()) {
tf |= Qt::AlignLeft;
}
} else {
tf |= Qt::AlignHCenter;
}
ir.translate(buttonShift);
if (o->features & QStyleOptionButton::HasMenu) {
ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, o, widget), 0);
}
drawItemText(p, ir, tf, option->palette, (o->state & State_Enabled), o->text, QPalette::ButtonText);
return;
}
}
if (ce == CE_RadioButton || ce == CE_CheckBox) {
if (auto const *o = qstyleoption_cast<QStyleOptionButton const *>(option)) {
bool isRadio = (ce == CE_RadioButton);
QStyleOptionButton subopt = *o;
subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, o, widget);
proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, &subopt, p, widget);
subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents : SE_CheckBoxContents, o, widget);
drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
if (o->state & State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*o);
fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect, o, widget);
drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
return;
}
}
if (ce == CE_RadioButtonLabel || ce == CE_CheckBoxLabel) {
if (auto const *o = qstyleoption_cast<QStyleOptionButton const *>(option)) {
uint alignment = visualAlignment(o->direction, Qt::AlignLeft | Qt::AlignVCenter);
if (!styleHint(SH_UnderlineShortcut, o, widget)) {
alignment |= Qt::TextHideMnemonic;
}
QPixmap pix;
QRect textRect = o->rect;
if (!o->icon.isNull()) {
pix = o->icon.pixmap(o->iconSize, o->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
drawItemPixmap(p, o->rect, alignment, pix);
if (o->direction == Qt::RightToLeft) {
textRect.setRight(textRect.right() - o->iconSize.width() - 4);
} else {
textRect.setLeft(textRect.left() + o->iconSize.width() + 4);
}
}
if (!o->text.isEmpty()){
drawItemText(p, textRect, alignment | Qt::TextShowMnemonic, o->palette, o->state & State_Enabled, o->text, QPalette::ButtonText);
}
return;
}
}
if (ce == CE_ComboBoxLabel) {
if (auto const *o = qstyleoption_cast<QStyleOptionComboBox const *>(option)) {
QRect editRect = subControlRect(CC_ComboBox, o, SC_ComboBoxEditField, widget);
uint alignment = Qt::AlignLeft | Qt::AlignVCenter;
if (!styleHint(SH_UnderlineShortcut, o, widget)) {
alignment |= Qt::TextHideMnemonic;
}
QPixmap pix;
QRect iconRect(editRect);
QIcon icon = o->currentIcon;
QString text = o->currentText;
if (!icon.isNull()) {
pix = icon.pixmap(o->iconSize, o->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
drawItemPixmap(p, iconRect, alignment, pix);
if (o->direction == Qt::RightToLeft) {
editRect.setRight(editRect.right() - o->iconSize.width() - 4);
} else {
editRect.setLeft(editRect.left() + o->iconSize.width() + 4);
}
}
if (!text.isEmpty()){
drawItemText(p, editRect, alignment, o->palette, o->state & State_Enabled, text, QPalette::ButtonText);
}
return;
}
}
#endif
if (ce == CE_ShapedFrame) {
if (auto const *o = qstyleoption_cast<QStyleOptionFrameV3 const *>(option)) {
int lw = o->lineWidth;
if (lw > 0) {
QRect r = o->rect;
if (o->frameShape == QFrame::Panel || o->frameShape == QFrame::HLine || o->frameShape == QFrame::VLine) {
if (o->state & (State_Sunken | State_Raised)) {
if (r.width() < r.height()) {
if (r.width() > 2) {
r.adjust(0, 0, -1, 0);
}
} else {
if (r.height() > 2) {
r.adjust(0, 0, 0, -1);
}
}
int x = r.x();
int y = r.y();
int w = r.width();
int h = r.height();
QColor color_topleft = o->palette.color(QPalette::Dark);
QColor color_bottomright = o->palette.color(QPalette::Light);
if (o->state & State_Raised) {
std::swap(color_topleft, color_bottomright);
}
int t = lw;
if (o->frameShape == QFrame::HLine) {
y = h / 2 - t;
h = t * 2;
} else if (o->frameShape == QFrame::VLine) {
x = w / 2 - t;
w = t * 2;
}
p->fillRect(x, y, w - t, t, color_topleft);
p->fillRect(x, y + t, t, h - t, color_topleft);
p->fillRect(x + w - t, y, t, h - t, color_bottomright);
p->fillRect(x + t, y + h - t, w - t, t, color_bottomright);
} else {
if (r.width() < r.height()) {
if (lw < r.width()) {
r = QRect(r.x() + (r.width() - lw) / 2, r.y(), lw, r.height());
}
} else {
if (lw < r.height()) {
r = QRect(r.x(), r.y() + (r.height() - lw) / 2, r.width(), lw);
}
}
int x = r.x();
int y = r.y();
int w = r.width();
int h = r.height();
QColor color = o->palette.color(QPalette::Shadow);
p->fillRect(x, y, w, h, color);
}
} else if (o->frameShape == QFrame::Box) {
int x = r.x();
int y = r.y();
int w = r.width();
int h = r.height();
if (w > 1) w--;
if (h > 1) h--;
QColor color_topleft = o->palette.color(QPalette::Dark);
QColor color_bottomright = o->palette.color(QPalette::Light);
if (o->state & State_Raised) {
std::swap(color_topleft, color_bottomright);
}
drawFrame(p, x + 1, y + 1, w, h, color_bottomright, color_bottomright);
drawFrame(p, x, y, w, h, color_topleft, color_topleft);
} else if (o->frameShape == QFrame::StyledPanel) {
QColor color = o->palette.color(QPalette::Midlight);
int x = r.x();
int y = r.y();
int w = r.width();
int h = r.height();
drawFrame(p, x, y, w, h, color, color);
}
}
}
return;
}
if (ce == CE_PushButtonBevel) {
if (auto const *o = qstyleoption_cast<QStyleOptionButton const *>(option)) {
if (o->features & QStyleOptionButton::Flat) {
// nop
} else {
drawButton(p, option);
}
if (o->features & QStyleOptionButton::HasMenu) {
+#ifdef Q_OS_MAC
+ QStyleOptionButton newBtn = *o;
+ QRect rect = option->rect;
+ {
+ int margin = pixelMetric(PM_ButtonMargin, option, nullptr);
+ if (margin > 0) {
+ int n = rect.height();
+ if (n > margin * 2) {
+ n = (n - margin * 2) / 2;
+ if (n > margin) n = margin;
+ rect = rect.adjusted(n, n, -n, -n);
+ }
+ }
+ }
+ int mbi = pixelMetric(PM_IndicatorWidth, o, widget);
+ rect = QRect(rect.x() + rect.width() - mbi, rect.y(), mbi - 4, rect.height());
+ newBtn.rect = rect;
+ drawPrimitive(PE_IndicatorSpinDown, &newBtn, p, widget);
+#else
+ QStyleOptionButton newBtn = *o;
int mbiw = 0, mbih = 0;
QRect r = subElementRect(SE_PushButtonContents, option, nullptr);
- QStyleOptionButton newBtn = *o;
- r = QRect(r.right() - mbiw - 2, option->rect.top() + (option->rect.height()/2) - (mbih/2), mbiw + 1, mbih + 1);
+ r = QRect(r.right() - mbiw - 2, option->rect.top() + (option->rect.height() / 2) - (mbih / 2), mbiw + 1, mbih + 1);
newBtn.rect = QStyle::visualRect(option->direction, option->rect, r);
drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+#endif
}
}
return;
}
if (ce == CE_MenuBarEmptyArea) {
drawMenuBarBG(p, option, widget);
return;
}
if (ce == CE_MenuBarItem) {
drawMenuBarBG(p, option, widget);
if (option->state & State_Selected) {
drawSelectedItemFrame(p, option->rect, true);
}
if (auto const *o = qstyleoption_cast<QStyleOptionMenuItem const *>(option)) {
QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
QPixmap pix = o->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
if (!styleHint(SH_UnderlineShortcut, o, widget)) {
alignment |= Qt::TextHideMnemonic;
}
if (!pix.isNull()) {
drawItemPixmap(p, o->rect, alignment, pix);
} else {
drawItemText(p, o->rect, alignment, o->palette, o->state & State_Enabled, o->text, textRole);
}
}
return;
}
if (ce == CE_MenuEmptyArea) {
return;
}
if (ce == CE_MenuItem) {
if (auto const *o = qstyleoption_cast<QStyleOptionMenuItem const *>(option)) {
#ifdef Q_OS_MAC
int checkcol = 15;
#else
// windows always has a check column, regardless whether we have an icon or not
int checkcol = 25;// / QWindowsXPStylePrivate::devicePixelRatio(widget);
#endif
const int gutterWidth = 3;// / QWindowsXPStylePrivate::devicePixelRatio(widget);
QRect rect = option->rect;
bool ignoreCheckMark = false;
if (qobject_cast<const QComboBox*>(widget)) {
- { // bg
- int x = option->rect.x();
- int y = option->rect.y();
- int w = option->rect.width();
- int h = option->rect.height();
- p->fillRect(x, y, w, h, option->palette.color(QPalette::Light));
- }
+ // bg
+ p->fillRect(option->rect, option->palette.color(QPalette::Light));
+#ifndef Q_OS_MACX
ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
+#endif
}
//draw vertical menu line
if (option->direction == Qt::LeftToRight) {
checkcol += rect.x();
}
int x, y, w, h;
o->rect.getRect(&x, &y, &w, &h);
int tab = o->tabWidth;
bool dis = !(o->state & State_Enabled);
bool checked = (o->checkType != QStyleOptionMenuItem::NotCheckable) && o->checked;
bool act = o->state & State_Selected;
if (o->menuItemType == QStyleOptionMenuItem::Separator) {
QRect r = option->rect.adjusted(2, 0, -2, 0);
drawGutter(p, r);
return;
}
#ifdef Q_OS_MAC
// qDebug() << pixelMetric(PM_SmallIconSize, option, widget);
QRect vCheckRect = visualRect(option->direction, o->rect, QRect(o->rect.x(), o->rect.y(), 20 - (gutterWidth + o->rect.x()), o->rect.height()));
#else
QRect vCheckRect = visualRect(option->direction, o->rect, QRect(o->rect.x(), o->rect.y(), checkcol - (gutterWidth + o->rect.x()), o->rect.height()));
#endif
if (act) {
drawSelectedItemFrame(p, option->rect, true);
}
int xm = windowsItemFrame + checkcol + windowsItemHMargin + (gutterWidth - o->rect.x()) - 1;
int xpos = o->rect.x() + xm;
if (checked && !ignoreCheckMark) {
const qreal boxMargin = 3.5;
const qreal boxWidth = checkcol - 2 * boxMargin;
const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
#ifdef Q_OS_MAC
QRectF checkRectF(0, option->rect.y(), xpos, option->rect.height());
QRect checkRect = checkRectF.toRect();
checkRect.setWidth(checkRect.height());
checkRect.adjust(windowsItemFrame + (xpos - windowsItemFrame - checkRect.width()) / 2, 0, 0, 0);
#else
QRectF checkRectF(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth / 2 + 1, boxWidth, boxWidth);
QRect checkRect = checkRectF.toRect();
checkRect.setWidth(checkRect.height()); // avoid .toRect() round error results in non-perfect square
#endif
checkRect = visualRect(o->direction, o->rect, checkRect);
QStyleOptionButton box;
box.QStyleOption::operator=(*option);
box.rect = checkRect;
if (checked) {
box.state |= State_On;
}
drawPrimitive(PE_IndicatorCheckBox, &box, p, widget);
}
if (!ignoreCheckMark) {
if (!o->icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
if (act && !dis) {
mode = QIcon::Active;
}
QPixmap pixmap;
if (checked) {
pixmap = o->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
} else {
pixmap = o->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode);
}
double dpr = pixmap.devicePixelRatio();
if (dpr > 0) {
const int pixw = int(pixmap.width() / dpr);
const int pixh = int(pixmap.height() / dpr);
#ifdef Q_OS_MAC
QRect pmr(xpos, vCheckRect.y() + (vCheckRect.height() - pixh) / 2, pixw, pixh);
p->setPen(o->palette.text().color());
p->drawPixmap(pmr.topLeft(), pixmap);
xpos += pmr.width() + 4;
#else
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(vCheckRect.center());
p->setPen(o->palette.text().color());
p->drawPixmap(pmr.topLeft(), pixmap);
#endif
}
}
} else {
if (o->icon.isNull()) {
checkcol = 0;
} else {
checkcol = o->maxIconWidth;
}
}
p->setPen(o->palette.buttonText().color());
const QColor textColor = o->palette.text().color();
if (dis) {
p->setPen(textColor);
}
QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(option->direction, o->rect, textRect);
QString s = o->text;
if (!s.isEmpty()) { // draw text
p->save();
int t = s.indexOf(QLatin1Char('\t'));
int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
if (!styleHint(SH_UnderlineShortcut, o, widget)) {
text_flags |= Qt::TextHideMnemonic;
}
text_flags |= Qt::AlignLeft;
if (t >= 0) {
QRect vShortcutRect = visualRect(option->direction, o->rect, QRect(textRect.topRight(), QPoint(o->rect.right(), textRect.bottom())));
p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
s = s.left(t);
}
QFont font = o->font;
if (o->menuItemType == QStyleOptionMenuItem::DefaultItem) {
font.setBold(true);
}
p->setFont(font);
p->setPen(textColor);
p->drawText(vTextRect, text_flags, s.left(t));
p->restore();
}
if (o->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
int dim = (h - 2 * windowsItemFrame) / 2;
PrimitiveElement arrow;
arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
QRect vSubMenuRect = visualRect(option->direction, o->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
QStyleOptionMenuItem newMI = *o;
newMI.rect = vSubMenuRect;
newMI.state = dis ? State_None : State_Enabled;
drawPrimitive(arrow, &newMI, p, widget);
}
}
return;
}
if (ce == CE_TabBarTabShape) {
#ifdef Q_OS_MAC
if (auto const *o = qstyleoption_cast<QStyleOptionTab const *>(option)) {
drawButton(p, option, false);
bool selected = o->state & State_Selected;
if (selected) {
drawSelectedItemFrame(p, o->rect.adjusted(0, 0, -2, -2), widget);
}
return;
}
#else
if (auto const *o = qstyleoption_cast<QStyleOptionTab const *>(option)) {
bool rtlHorTabs = (o->direction == Qt::RightToLeft && (o->shape == QTabBar::RoundedNorth || o->shape == QTabBar::RoundedSouth));
bool selected = o->state & State_Selected;
bool lastTab = ((!rtlHorTabs && o->position == QStyleOptionTab::End) || (rtlHorTabs && o->position == QStyleOptionTab::Beginning));
bool firstTab = ((!rtlHorTabs && o->position == QStyleOptionTab::Beginning) || (rtlHorTabs && o->position == QStyleOptionTab::End));
bool onlyOne = o->position == QStyleOptionTab::OnlyOneTab;
bool previousSelected = ((!rtlHorTabs && o->selectedPosition == QStyleOptionTab::PreviousIsSelected) || (rtlHorTabs && o->selectedPosition == QStyleOptionTab::NextIsSelected));
bool nextSelected = ((!rtlHorTabs && o->selectedPosition == QStyleOptionTab::NextIsSelected) || (rtlHorTabs && o->selectedPosition == QStyleOptionTab::PreviousIsSelected));
int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, o, widget);
bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft) || (rtlHorTabs && tabBarAlignment == Qt::AlignRight);
bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight) || (rtlHorTabs && tabBarAlignment == Qt::AlignLeft);
QColor light = o->palette.light().color();
// QColor dark = o->palette.dark().color();
QColor shadow = o->palette.shadow().color();
int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, o, widget);
if (selected) {
borderThinkness /= 2;
}
QRect r2(option->rect);
int x1 = r2.left();
int x2 = r2.right();
int y1 = r2.top();
int y2 = r2.bottom();
switch (o->shape) {
default:
QProxyStyle::drawControl(ce, o, p, widget);
break;
case QTabBar::RoundedNorth:
{
#ifdef Q_OS_WIN
if (selected) {
y2 += 2;
} else {
y2 += 1;
y1 += 2;
x1 += onlyOne || firstTab ? borderThinkness : 0;
x2 -= onlyOne || lastTab ? borderThinkness : 0;
}
#elif 1
if (selected) {
y2 += 2;
} else {
y2 += 1;
y1 += 2;
x1 += onlyOne || firstTab ? borderThinkness : 0;
x2 -= onlyOne || lastTab ? borderThinkness : 0;
}
#else
if (!selected) {
y1 += 2;
x1 += onlyOne || firstTab ? borderThinkness : 0;
x2 -= onlyOne || lastTab ? borderThinkness : 0;
}
#endif
p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), o->palette.background());
// Left
if (firstTab || selected || onlyOne || !previousSelected) {
p->setPen(light);
p->drawLine(x1, y1 + 2, x1, y2 - 1 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
p->drawPoint(x1 + 1, y1 + 1);
}
// Top
{
int beg = x1 + (previousSelected ? 0 : 2);
int end = x2 - (nextSelected ? 0 : 2);
p->setPen(light);
p->drawLine(beg, y1, end, y1);
}
// Right
if (lastTab || selected || onlyOne || !nextSelected) {
p->setPen(shadow);
p->drawLine(x2, y1 + 2, x2, y2 - 1 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
p->drawPoint(x2 - 1, y1 + 1);
}
break;
}
case QTabBar::RoundedSouth:
{
#ifdef Q_OS_WIN
if (selected) {
y1 -= 2;
} else {
x1 -= 1;
y1 -= 1;
y2 -= 2;
x1 += firstTab ? borderThinkness : 0;
x2 -= lastTab ? borderThinkness : 0;
}
#elif 1
if (selected) {
y1 -= 2;
} else {
y1 -= 1;
y2 -= 2;
x1 += firstTab ? borderThinkness : 0;
x2 -= lastTab ? borderThinkness : 0;
}
#else
if (!selected) {
y2 -= 2;
x1 += firstTab ? borderThinkness : 0;
x2 -= lastTab ? borderThinkness : 0;
}
#endif
p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), o->palette.background());
// Left
if (firstTab || selected || onlyOne || !previousSelected) {
p->setPen(light);
p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
p->drawPoint(x1 + 1, y2 - 1);
}
// Bottom
{
int beg = x1 + (previousSelected ? 0 : 2);
int end = x2 - (nextSelected ? 0 : 2);
p->setPen(shadow);
p->drawLine(beg, y2, end, y2);
}
// Right
if (lastTab || selected || onlyOne || !nextSelected) {
p->setPen(shadow);
p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
p->drawPoint(x2 - 1, y2 - 1);
}
break; }
case QTabBar::RoundedWest:
{
#ifdef Q_OS_WIN
if (selected) {
x2 += 1;
} else {
x1 += 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
#elif 1
if (selected) {
x2 += 1;
} else {
x1 += 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
#else
if (!selected) {
x1 += 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
#endif
p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), o->palette.background());
// Top
if (firstTab || selected || onlyOne || !previousSelected) {
p->setPen(light);
p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
p->drawPoint(x1 + 1, y1 + 1);
}
// Left
{
int beg = y1 + (previousSelected ? 0 : 2);
int end = y2 - (nextSelected ? 0 : 2);
p->setPen(light);
p->drawLine(x1, beg, x1, end);
}
// Bottom
if (lastTab || selected || onlyOne || !nextSelected) {
p->setPen(shadow);
p->drawLine(x1 + 2, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
p->drawPoint(x1 + 1, y2 - 1);
}
break;
}
case QTabBar::RoundedEast:
{
#ifdef Q_OS_WIN
if (selected) {
x1 -= 2;
} else {
y1 -= 2;
x1 -= 1;
x2 -= 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
#elif 1
if (selected) {
x1 -= 2;
} else {
x1 -= 1;
x2 -= 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
#else
if (!selected) {
x2 -= 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
#endif
p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), o->palette.background());
// Top
if (firstTab || selected || onlyOne || !previousSelected) {
p->setPen(light);
p->drawLine(x2 - 2, y1, x1 - 1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
p->drawPoint(x2 - 1, y1 + 1);
}
// Right
{
int beg = y1 + (previousSelected ? 0 : 2);
int end = y2 - (nextSelected ? 0 : 2);
p->setPen(shadow);
p->drawLine(x2, beg, x2, end);
}
// Bottom
if (lastTab || selected || onlyOne || !nextSelected) {
p->setPen(shadow);
p->drawLine(x2 - 2, y2, x1 - 1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
p->drawPoint(x2 - 1, y2 - 1);
}
break;
}
}
}
#endif
return;
}
if (ce == CE_ProgressBarGroove || ce == CE_ProgressBarContents) {
if (auto const *o = qstyleoption_cast<QStyleOptionProgressBar const *>(option)) {
QColor color(0, 128, 255);
bool horz = (o->orientation == Qt::Horizontal);
QString key;
QImage const *image;
if (horz) {
key = "horz";
image = &m->progress_horz;
} else {
key = "vert";
image = &m->progress_vert;
}
p->save();
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width();
int h = option->rect.height();
if (ce == CE_ProgressBarContents) {
int len = o->progress - o->minimum;
int div = o->maximum - o->minimum;
bool inv = o->invertedAppearance;
if (horz) {
int v = div > 0 ? (w * len / div) : 0;
if (inv) {
x = x + w - v;
}
w = v;
} else {
int v = div > 0 ? (h * len / div) : 0;
if (!inv) {
y = y + h - v;
}
h = v;
}
QRect r(x, y, w, h);
p->setClipRect(r);
p->fillRect(option->rect, color);
}
QPixmap pm;
QSize size(w, h);
key = pixmapkey("progress_bar", key, size, m->base_color);
if (!QPixmapCache::find(key, &pm)) {
QImage im = image->scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
pm = QPixmap::fromImage(im);
QPixmapCache::insert(key, pm);
}
p->setOpacity(0.5);
p->drawPixmap(option->rect, pm, pm.rect());
p->restore();
}
return;
}
if (ce == CE_HeaderSection || ce == CE_HeaderEmptyArea) {
bool horz = true;
if (auto const *o = qstyleoption_cast<QStyleOptionHeader const *>(option)) {
horz = (o->orientation == Qt::Horizontal);
}
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width();
int h = option->rect.height();
QLinearGradient gradient;
gradient.setStart(x, y);
gradient.setFinalStop(x, y + h / 4.0);
gradient.setColorAt(0, option->palette.color(QPalette::Light));
gradient.setColorAt(1, option->palette.color(QPalette::Window));
p->fillRect(x, y, w, h, gradient);
p->fillRect(x, y + h - 1, w, 1, option->palette.color(QPalette::Dark));
if (horz) {
p->fillRect(x + w - 1, y, 1, h, option->palette.color(QPalette::Dark));
}
if (ce == CE_HeaderSection) {
if (horz) {
p->fillRect(x, y, 1, h, option->palette.color(QPalette::Light));
}
if (option->state & QStyle::State_MouseOver) {
p->save();
p->fillRect(x, y, w, h, QColor(255, 255, 255, 32));
p->restore();
}
}
if (option->state & QStyle::State_Sunken) {
drawFocusFrame(p, option->rect.adjusted(0, 0, -1, -1), 0);
}
return;
}
if (ce == CE_HeaderLabel) {
if (auto const *o = qstyleoption_cast<QStyleOptionHeader const *>(option)) {
QRect rect = o->rect;
if (!o->icon.isNull()) {
int iconExtent = pixelMetric(PM_SmallIconSize, option, widget);
QPixmap pixmap = o->icon.pixmap(QSize(iconExtent, iconExtent), (o->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
int pixw = int(pixmap.width() / pixmap.devicePixelRatio());
QRect aligned = alignedRect(o->direction, QFlag(o->iconAlignment), pixmap.size() / pixmap.devicePixelRatio(), rect);
QRect inter = aligned.intersected(rect);
p->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), int(aligned.width() * pixmap.devicePixelRatio()), int(pixmap.height() * pixmap.devicePixelRatio()));
const int margin = pixelMetric(QStyle::PM_HeaderMargin, option, widget);
if (o->direction == Qt::LeftToRight) {
rect.setLeft(rect.left() + pixw + margin);
} else {
rect.setRight(rect.right() - pixw - margin);
}
}
if (o->state & QStyle::State_On) {
QFont fnt = p->font();
fnt.setBold(true);
p->setFont(fnt);
}
int leftmargin = 0;
auto align = o->textAlignment;
if (align & Qt::AlignLeft) {
leftmargin += 4;
}
drawItemText(p, rect.adjusted(leftmargin, 0, 0, 0), align, o->palette, (o->state & State_Enabled), o->text, QPalette::ButtonText);
}
return;
}
#ifdef Q_OS_MAC
if (ce == CE_DockWidgetTitle) {
if (auto const *o = qstyleoption_cast<QStyleOptionDockWidget const *>(option)) {
auto const *dockWidget = qobject_cast<QDockWidget const *>(widget);
QRect rect = option->rect;
if (dockWidget && dockWidget->isFloating()) {
QProxyStyle::drawControl(ce, option, p, widget);
return;
}
auto const *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(o);
bool verticalTitleBar = v2 && v2->verticalTitleBar;
if (verticalTitleBar) {
rect.setSize(rect.size().transposed());
p->translate(rect.left() - 1, rect.top() + rect.width());
p->rotate(-90);
p->translate(-rect.left() + 1, -rect.top());
}
p->setBrush(option->palette.background().color().darker(110));
p->setPen(option->palette.background().color().darker(130));
p->drawRect(rect.adjusted(0, 1, -1, -3));
int buttonMargin = 4;
int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, o, widget);
int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, o, widget);
auto const *dw = qobject_cast<const QDockWidget *>(widget);
bool isFloating = dw && dw->isFloating();
QRect r = option->rect.adjusted(0, 2, -1, -3);
QRect titleRect = r;
if (o->closable) {
QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, o, widget).actualSize(QSize(10, 10));
titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
}
if (o->floatable) {
QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, o, widget).actualSize(QSize(10, 10));
titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
}
if (isFloating) {
titleRect.adjust(0, -fw, 0, 0);
if (widget && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) {
titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
}
} else {
titleRect.adjust(mw, 0, 0, 0);
if (!o->floatable && !o->closable) {
titleRect.adjust(0, 0, -mw, 0);
}
}
if (!verticalTitleBar) {
titleRect = visualRect(o->direction, r, titleRect);
}
if (!o->title.isEmpty()) {
QString titleText = p->fontMetrics().elidedText(o->title, Qt::ElideRight, verticalTitleBar ? titleRect.height() : titleRect.width());
const int indent = 4;
int align = Qt::AlignRight | Qt::AlignVCenter;
drawItemText(p, rect.adjusted(indent + 1, 1, -indent - 1, -1), align, o->palette, o->state & State_Enabled, titleText, QPalette::WindowText);
}
}
return;
}
#endif // Q_OS_MAC
#ifdef Q_OS_LINUX
if (ce == CE_Splitter) {
p->fillRect(option->rect, option->palette.color(QPalette::Window));
return;
}
#endif
if (ce == CE_ItemViewItem) {
#if 0
if (auto const *o = qstyleoption_cast<QStyleOptionViewItem const *>(option)) {
p->save();
p->setFont(o->font);
drawPrimitive(PE_PanelItemViewItem, option, p, widget);
drawItemText(p, o->rect.adjusted(2, 0, 0, 0), o->displayAlignment, option->palette, true, o->text);
p->restore();
return;
}
#else
if (auto const *o = qstyleoption_cast<QStyleOptionViewItem const *>(option)) {
p->save();
p->setClipRect(o->rect);
QRect checkRect = subElementRect(SE_ItemViewItemCheckIndicator, o, widget);
QRect iconRect = subElementRect(SE_ItemViewItemDecoration, o, widget);
QRect textRect = subElementRect(SE_ItemViewItemText, o, widget);
textRect.adjust(2, 0, 0, 0);
// draw the background
drawPrimitive(PE_PanelItemViewItem, o, p, widget);
// draw the check mark
if (o->features & QStyleOptionViewItem::HasCheckIndicator) {
QStyleOptionViewItem o2(*o);
o2.rect = checkRect;
o2.state = o2.state & ~QStyle::State_HasFocus;
switch (o->checkState) {
case Qt::Unchecked:
o2.state |= QStyle::State_Off;
break;
case Qt::PartiallyChecked:
o2.state |= QStyle::State_NoChange;
break;
case Qt::Checked:
o2.state |= QStyle::State_On;
break;
}
drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &o2, p, widget);
}
// draw the icon
QIcon::Mode mode = QIcon::Normal;
if (!(o->state & QStyle::State_Enabled)) {
mode = QIcon::Disabled;
} else if (o->state & QStyle::State_Selected) {
mode = QIcon::Selected;
}
QIcon::State state = o->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
o->icon.paint(p, iconRect, o->decorationAlignment, mode, state);
// draw the text
if (!o->text.isEmpty()) {
QPalette::ColorGroup cg = o->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
if (cg == QPalette::Normal && !(o->state & QStyle::State_Active)) {
cg = QPalette::Inactive;
}
if (o->state & QStyle::State_Selected) {
p->setPen(o->palette.color(cg, QPalette::HighlightedText));
} else {
p->setPen(o->palette.color(cg, QPalette::Text));
}
if (o->state & QStyle::State_Editing) {
p->setPen(o->palette.color(cg, QPalette::Text));
p->drawRect(textRect.adjusted(0, 0, -1, -1));
}
drawItemViewText(p, o, textRect, true);
}
#if 0
// draw the focus rect
if (o->state & QStyle::State_HasFocus) {
QStyleOptionFocusRect o3;
o3.QStyleOption::operator=(*o);
o3.rect = subElementRect(SE_ItemViewItemFocusRect, o, widget);
o3.state |= QStyle::State_KeyboardFocusChange;
o3.state |= QStyle::State_Item;
QPalette::ColorGroup cg = (o->state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
o3.backgroundColor = o->palette.color(cg, (o->state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Window);
drawPrimitive(PE_FrameFocusRect, &o3, p, widget);
}
#endif
p->restore();
}
return;
#endif
}
if (ce == CE_Header) {
drawControl(CE_HeaderSection, option, p, widget);
drawControl(CE_HeaderLabel, option, p, widget);
return;
}
if (ce == CE_TabBarTab) {
drawControl(CE_TabBarTabShape, option, p, widget);
drawControl(CE_TabBarTabLabel, option, p, widget);
return;
}
if (ce == CE_PushButton) {
drawControl(CE_PushButtonBevel, option, p, widget);
drawControl(CE_PushButtonLabel, option, p, widget);
return;
}
if (ce == CE_ProgressBar) {
drawControl(CE_ProgressBarGroove, option, p, widget);
drawControl(CE_ProgressBarContents, option, p, widget);
return;
}
// qDebug() << ce;
QProxyStyle::drawControl(ce, option, p, widget);
}
void DarkStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p, const QWidget *widget) const
{
// qDebug() << cc;
if (cc == QStyle::CC_ComboBox) {
if (auto const *o = qstyleoption_cast<QStyleOptionComboBox const *>(option)) {
SubControls sub = option->subControls;
if (o->editable) {
#define EP_EDITBORDER_NOSCROLL 6
#define EP_EDITBORDER_HVSCROLL 9
if (sub & SC_ComboBoxEditField) {
p->fillRect(option->rect, option->palette.color(QPalette::Dark));
drawFrame(p, option->rect, option->palette.color(QPalette::Shadow), option->palette.color(QPalette::Light));
}
if (sub & SC_ComboBoxArrow) {
QRect subRect = subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
QStyleOptionComplex opt = *option;
opt.rect = subRect;
drawToolButton(p, &opt);
opt.rect = QRect(subRect.right() - 4, subRect.y() + subRect.height() / 2 - 1, 2, 2);
drawPrimitive(PE_IndicatorArrowDown, &opt, p, widget);
}
} else {
if (sub & SC_ComboBoxFrame) {
QStyleOptionButton btn;
btn.QStyleOption::operator=(*option);
btn.rect = option->rect.adjusted(-1, -1, 1, 1);
if (sub & SC_ComboBoxArrow) {
btn.features = QStyleOptionButton::HasMenu;
}
drawControl(QStyle::CE_PushButton, &btn, p, widget);
}
}
}
return;
}
if (cc == QStyle::CC_ToolButton) {
QStyle::State flags = option->state;
if (auto const *o = qstyleoption_cast<QStyleOptionToolButton const *>(option)) {
QRect button, menuarea;
button = subControlRect(cc, o, SC_ToolButton, widget);
menuarea = subControlRect(cc, o, SC_ToolButtonMenu, widget);
State bflags = o->state & ~State_Sunken;
State mflags = bflags;
bool autoRaise = flags & State_AutoRaise;
if (autoRaise) {
if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
bflags &= ~State_Raised;
}
}
if (o->state & State_Sunken) {
if (o->activeSubControls & SC_ToolButton) {
bflags |= State_Sunken;
mflags |= State_MouseOver | State_Sunken;
} else if (o->activeSubControls & SC_ToolButtonMenu) {
mflags |= State_Sunken;
bflags |= State_MouseOver;
}
}
QStyleOption tool(0);
tool.palette = o->palette;
if (o->subControls & SC_ToolButton) {
if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
tool.rect = option->rect;
tool.state = bflags;
drawToolButton(p, &tool);
}
}
if (o->state & State_HasFocus) {
QStyleOptionFocusRect fr;
fr.QStyleOption::operator=(*o);
fr.rect.adjust(3, 3, -3, -3);
if (o->features & QStyleOptionToolButton::MenuButtonPopup) {
fr.rect.adjust(0, 0, -pixelMetric(QStyle::PM_MenuButtonIndicator, o, widget), 0);
}
drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
}
QStyleOptionToolButton label = *o;
label.state = bflags;
int fw = 2;
if (!autoRaise)
label.state &= ~State_Sunken;
label.rect = button.adjusted(fw, fw, -fw, -fw);
drawControl(CE_ToolButtonLabel, &label, p, widget);
if (o->subControls & SC_ToolButtonMenu) {
tool.rect = menuarea;
tool.state = mflags;
if (autoRaise) {
drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
} else {
tool.state = mflags;
menuarea.adjust(-2, 0, 0, 0);
// Draw menu button
if ((bflags & State_Sunken) != (mflags & State_Sunken)){
p->save();
p->setClipRect(menuarea);
tool.rect = option->rect;
drawToolButton(p, &tool);
p->restore();
}
// Draw arrow
p->save();
p->setPen(option->palette.dark().color());
p->drawLine(menuarea.left(), menuarea.top() + 3, menuarea.left(), menuarea.bottom() - 3);
p->setPen(option->palette.light().color());
p->drawLine(menuarea.left() - 1, menuarea.top() + 3, menuarea.left() - 1, menuarea.bottom() - 3);
tool.rect = menuarea.adjusted(2, 3, -2, -1);
drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
p->restore();
}
} else if (o->features & QStyleOptionToolButton::HasMenu) {
int mbi = pixelMetric(PM_MenuButtonIndicator, o, widget);
QRect ir = o->rect;
QStyleOptionToolButton newBtn = *o;
newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
}
}
return;
}
if (cc == QStyle::CC_ScrollBar) {
bool ishorz = (option->state & State_Horizontal);
auto *tx = const_cast<ScrollBarTextures *>(ishorz ? &m->hsb : &m->vsb);
int extent = (ishorz ? tx->slider.im_normal.height() : tx->slider.im_normal.width()) - 2;
auto DrawNinePatchImage2 = [&](QImage const &image, QRect const &r){
int w, h;
if (ishorz) {
h = extent;
int d = r.height();
w = (d == 0) ? 0 : (h * r.width() / d);
} else {
w = extent;
int d = r.width();
h = (d == 0) ? 0 : (w * r.height() / d);
}
drawNinePatchImage(p, image, r, w, h);
};
p->fillRect(option->rect, color(64));
p->setRenderHint(QPainter::Antialiasing);
{
#ifdef Q_OS_MAC
QRect r = option->rect;
#else
QRect r1 = subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
QRect r2 = subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
QRect r = r1.united(r2);
#endif
DrawNinePatchImage2(tx->page_bg, r);
}
#ifndef Q_OS_MAC // macOSのスクロールバーには、ラインステップボタンが無い
{
QRect r = subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
DrawNinePatchImage2(tx->page_bg, r);
}
{
QRect r = subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
DrawNinePatchImage2(tx->page_bg, r);
}
auto DrawAddSubButton = [&](ButtonImages const &ims, SubControl subctl){
QRect r = subControlRect(CC_ScrollBar, option, subctl, widget);
QPixmap pm;;
if (!(option->activeSubControls & subctl)) {
pm = pixmapFromImage(ims.im_normal, r.size());
p->drawPixmap(r.topLeft(), pm);
} else {
pm = pixmapFromImage(ims.im_hover, r.size());
p->drawPixmap(r.topLeft(), pm);
}
};
DrawAddSubButton(tx->sub_line, SC_ScrollBarSubLine);
DrawAddSubButton(tx->add_line, SC_ScrollBarAddLine);
#endif
{
QRect r = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
int w, h;
if (ishorz) {
h = extent;
int d = r.height();
w = (d == 0) ? 0 : (h * r.width() / d);
} else {
w = extent;
int d = r.width();
h = (d == 0) ? 0 : (w * r.height() / d);
}
#ifdef Q_OS_MAC // macだとズレて見えるので調整する
if (ishorz) {
r = r.translated(1, 0);
} else {
r = r.translated(0, 1);
}
#endif
if (!(option->activeSubControls & SC_ScrollBarSlider)) {
DrawNinePatchImage2(tx->slider.im_normal, r);
} else {
DrawNinePatchImage2(tx->slider.im_hover, r);
}
}
return;
}
if (cc == CC_GroupBox) {
if (auto const *o = qstyleoption_cast<QStyleOptionGroupBox const *>(option)) {
QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
if (o->subControls & QStyle::SC_GroupBoxFrame) {
QStyleOptionFrame frame;
frame.QStyleOption::operator=(*o);
frame.features = o->features;
frame.lineWidth = o->lineWidth;
frame.midLineWidth = o->midLineWidth;
frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
p->save();
QRegion region(o->rect);
if (!o->text.isEmpty()) {
bool ltr = o->direction == Qt::LeftToRight;
QRect finalRect;
if (o->subControls & QStyle::SC_GroupBoxCheckBox) {
finalRect = checkBoxRect.united(textRect);
finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
} else {
finalRect = textRect;
}
region -= finalRect;
}
p->setClipRegion(region);
drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
p->restore();
}
// Draw title
if ((o->subControls & QStyle::SC_GroupBoxLabel) && !o->text.isEmpty()) {
QColor textColor = o->textColor;
if (textColor.isValid()) {
p->setPen(textColor);
}
int alignment = int(o->textAlignment);
if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) {
alignment |= Qt::TextHideMnemonic;
}
alignment |= Qt::TextShowMnemonic;
alignment |= Qt::AlignHCenter;
drawItemText(p, textRect, alignment, o->palette, o->state & State_Enabled, o->text, QPalette::WindowText);
if (o->state & State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*o);
fropt.rect = textRect;
drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
}
// Draw checkbox
if (o->subControls & SC_GroupBoxCheckBox) {
QStyleOptionButton box;
box.QStyleOption::operator=(*o);
box.rect = checkBoxRect;
drawPrimitive(PE_IndicatorCheckBox, &box, p, widget);
}
}
return;
}
if (cc == CC_Slider) {
if (auto const *o = qstyleoption_cast<QStyleOptionSlider const *>(option)) {
QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
bool horizontal = o->orientation == Qt::Horizontal;
bool ticksAbove = o->tickPosition & QSlider::TicksAbove;
bool ticksBelow = o->tickPosition & QSlider::TicksBelow;
QPixmap cache;
QBrush oldBrush = p->brush();
QPen oldPen = p->pen();
QColor shadowAlpha(Qt::black);
shadowAlpha.setAlpha(10);
if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
QRect rect(0, 0, groove.width(), groove.height());
QString key = pixmapkey("slider_groove", horizontal ? "horz" : "vert", rect.size(), m->base_color);
QRectF grooveRect;
double r = std::min(groove.width(), groove.height()) / 2.0;
{
double n = r * 3 / 4;
grooveRect = QRectF(rect).adjusted(n, n, -n, -n);
r -= n;
}
// draw background groove
QPixmap cache;
if (!QPixmapCache::find(key, cache)) {
cache = QPixmap(rect.size());
cache.fill(Qt::transparent);
QPainter groovePainter(&cache);
groovePainter.setRenderHint(QPainter::Antialiasing, true);
groovePainter.translate(0.5, 0.5);
QLinearGradient gradient;
if (horizontal) {
gradient.setStart(grooveRect.center().x(), grooveRect.top());
gradient.setFinalStop(grooveRect.center().x(), grooveRect.bottom());
} else {
gradient.setStart(grooveRect.left(), grooveRect.center().y());
gradient.setFinalStop(grooveRect.right(), grooveRect.center().y());
}
groovePainter.setPen(Qt::NoPen);
gradient.setColorAt(0, color(32));
gradient.setColorAt(1, color(128));
groovePainter.setBrush(gradient);
groovePainter.drawRoundedRect(grooveRect, r, r);
groovePainter.end();
QPixmapCache::insert(key, cache);
}
p->drawPixmap(groove.topLeft(), cache);
}
if (option->subControls & SC_SliderTickmarks) {
int tickSize = pixelMetric(PM_SliderTickmarkOffset, option, widget);
int available = pixelMetric(PM_SliderSpaceAvailable, o, widget);
int interval = o->tickInterval;
if (interval <= 0) {
interval = o->singleStep;
if (QStyle::sliderPositionFromValue(o->minimum, o->maximum, interval, available) - QStyle::sliderPositionFromValue(o->minimum, o->maximum, 0, available) < 3) {
interval = o->pageStep;
}
}
if (interval <= 0) {
interval = 1;
}
int v = o->minimum;
int len = pixelMetric(PM_SliderLength, o, widget);
while (v <= o->maximum + 1) {
if (v == o->maximum + 1 && interval == 1) break;
const int v2 = qMin(v, o->maximum);
int pos = sliderPositionFromValue(o->minimum, o->maximum,
v2, (horizontal
? o->rect.width()
: o->rect.height()) - len,
o->upsideDown) + len / 2;
int extra = 2 - ((v2 == o->minimum || v2 == o->maximum) ? 1 : 0);
if (horizontal) {
if (ticksAbove) {
p->setPen(color(128));
p->drawLine(pos, o->rect.top() + extra, pos, o->rect.top() + tickSize);
}
if (ticksBelow) {
p->setPen(color(0));
p->drawLine(pos, o->rect.bottom() - extra, pos, o->rect.bottom() - tickSize);
}
} else {
if (ticksAbove) {
p->setPen(color(128));
p->drawLine(o->rect.left() + extra, pos, o->rect.left() + tickSize, pos);
}
if (ticksBelow) {
p->setPen(color(0));
p->drawLine(o->rect.right() - extra, pos, o->rect.right() - tickSize, pos);
}
}
// in the case where maximum is max int
int nextInterval = v + interval;
if (nextInterval < v) break;
v = nextInterval;
}
}
// draw handle
if ((option->subControls & SC_SliderHandle) ) {
QRect pixmapRect(0, 0, handle.width(), handle.height());
QRect r = pixmapRect.adjusted(0, 0, -1, -1);
QPainterPath path;
path.addEllipse(r);
QString handlePixmapName = pixmapkey(QLatin1String("slider_handle"), "", handle.size(), m->base_color);
if (!QPixmapCache::find(handlePixmapName, cache)) {
cache = QPixmap(handle.size());
cache.fill(Qt::transparent);
QPainter handlePainter(&cache);
handlePainter.setRenderHint(QPainter::Antialiasing, true);
handlePainter.translate(0.5, 0.5);
QLinearGradient gradient;
gradient.setStart(pixmapRect.topLeft());
gradient.setFinalStop(pixmapRect.bottomRight());
gradient.setColorAt(0, color(192));
gradient.setColorAt(1, QColor(0, 0, 0));
handlePainter.save();
handlePainter.setClipPath(path);
handlePainter.fillRect(r, gradient);
QColor highlight_color = colorize(color(160).rgb(), 192, 255);
handlePainter.setPen(QPen(highlight_color, 2));
handlePainter.setBrush(Qt::NoBrush);
handlePainter.drawEllipse(r.adjusted(0, 0, 2, 2));
handlePainter.setPen(QPen(QColor(0, 0, 0), 2));
handlePainter.setBrush(Qt::NoBrush);
handlePainter.drawEllipse(r.adjusted(-2, -2, 0, 0));
handlePainter.restore();
handlePainter.end();
QPixmapCache::insert(handlePixmapName, cache);
}
QPoint topleft = handle.topLeft();
p->drawPixmap(topleft, cache);
if ((option->state & State_HasFocus) && (option->state & State_KeyboardFocusChange)) {
p->save();
p->setClipPath(path.translated(topleft));
p->fillRect(handle, QColor(255, 255, 255, 32));
p->restore();
}
}
p->setBrush(oldBrush);
p->setPen(oldPen);
}
return;
}
// qDebug() << cc;
QProxyStyle::drawComplexControl(cc, option, p, widget);
}
diff --git a/version.rb b/version.rb
index 3fa3e06..3585ed4 100644
--- a/version.rb
+++ b/version.rb
@@ -1,51 +1,51 @@
#!/dev/null
$product_name = "Guitar"
$copyright_year = 2019
$version_a = 1
$version_b = 1
-$version_c = 0
+$version_c = 999
$version_d = 0
# v1.1.0 2019-08-29
# - 中国語対応
# - 日本語翻訳ファイルのtypo修正
# - Windows版インストーラー対応
# - ファイルリストのバッジを描画
# - コミットグラフで異なるブランチの線が重なって描画されることがあった問題を修正
# - コミットグラフで先祖のブランチを強調表示する機能
# - ダークテーマの描画を改良
# - Ctrl+HでHEADにジャンプする
# - fetch tags -f コマンド
# - 新マージダイアログ
# - チェリーピックダイアログ
#
# v1.0.0 2019-06-01
# - ロシア語対応
# - 細かい修正
#
# v0.9.3 2019-01-19
# - stashコマンドを実装
# - GitHubウェブページからのドラッグアンドドロップ動作を改良
# - メニューバー項目を整理
#
# v0.9.2 2018-11-06
# - 定期的リモート監視機能
# - ソースコードリファクタリング
# - 安定性向上
# - cmake対応
#
# v0.9.1 2018-11-06
# - support ssh key with passphrase
#
# v0.9.0 2018-10-24
# -
#
# v0.2.0 2017-12-18
# -
#
# v0.1.0 2017-05-03
# -
#
# v0.0.0 2016-12-25
# - alpha release
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 17, 9:11 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
72591
Default Alt Text
(90 KB)
Attached To
Mode
R77 Guitar
Attached
Detach File
Event Timeline