Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
121 KB
Referenced Files
None
Subscribers
None
diff --git a/Guitar.pro b/Guitar.pro
index 537aa23..6eb8e4b 100644
--- a/Guitar.pro
+++ b/Guitar.pro
@@ -1,393 +1,394 @@
QT += core gui widgets svg network
win32:QT += winextras
CONFIG(debug,debug|release):TARGET = Guitard
CONFIG(release,debug|release):TARGET = Guitar
TEMPLATE = app
CONFIG += c++11
DESTDIR = $$PWD/_bin
TRANSLATIONS = Guitar_ja.ts
DEFINES += APP_GUITAR
DEFINES += USE_DARK_THEME
DEFINES += HAVE_POSIX_OPENPT
macx:DEFINES += HAVE_SYS_TIME_H
macx:DEFINES += HAVE_UTMPX
gcc:QMAKE_CXXFLAGS += -Wall -Wextra -Werror=return-type -Werror=trigraphs -Wno-switch -Wno-reorder
linux:QMAKE_RPATHDIR += $ORIGIN
macx:QMAKE_RPATHDIR += @executable_path/../Frameworks
linux:QTPLUGIN += ibusplatforminputcontextplugin
#linux:QTPLUGIN += fcitxplatforminputcontextplugin
INCLUDEPATH += $$PWD/src
INCLUDEPATH += $$PWD/src/texteditor
-win32:INCLUDEPATH += $$PWD/winpty
-win32:LIBS += $$PWD/winpty/winpty.lib
+win32:INCLUDEPATH += $$PWD/misc/winpty
+win32:LIBS += $$PWD/misc/winpty/winpty.lib
# OpenSSL
linux:LIBS += -lssl -lcrypto
haiku:LIBS += -lssl -lcrypto -lnetwork
macx:INCLUDEPATH += /usr/local/include
macx:LIBS += /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a
win32:msvc {
INCLUDEPATH += C:\openssl\include
+ INCLUDEPATH += $$PWD/../zlib
LIBS += -LC:\openssl\lib
}
win32:gcc {
INCLUDEPATH += C:\Qt\Tools\mingw530_32\opt\include
LIBS += -LC:\Qt\Tools\mingw530_32\opt\lib
LIBS += -lcrypto -lssl
}
# execute 'ruby prepare.rb' automatically
prepare.target = prepare
prepare.commands = cd $$PWD && ruby -W0 prepare.rb
QMAKE_EXTRA_TARGETS += prepare
PRE_TARGETDEPS += prepare
# zlib
win32:msvc {
CONFIG(debug, debug|release):LIBS += $$PWD/_bin/libz.lib
CONFIG(release, debug|release):LIBS += $$PWD/_bin/libz.lib
}
win32:gcc {
CONFIG(debug, debug|release):LIBS += $$PWD/_bin/liblibz.a
CONFIG(release, debug|release):LIBS += $$PWD/_bin/liblibz.a
}
!haiku {
unix:CONFIG(debug, debug|release):LIBS += $$PWD/_bin/libzd.a
unix:CONFIG(release, debug|release):LIBS += $$PWD/_bin/libz.a
#unix:LIBS += -lz
}
haiku:LIBS += -lz
win32 {
LIBS += -ladvapi32 -lshell32 -luser32 -lws2_32
RC_FILE = win.rc
QMAKE_SUBSYSTEM_SUFFIX=,5.01
}
macx {
QMAKE_INFO_PLIST = Info.plist
ICON += Guitar.icns
t.path=Contents/Resources
QMAKE_BUNDLE_DATA += t
}
SOURCES += \
src/main.cpp\
src/MainWindow.cpp \
src/Git.cpp \
src/common/joinpath.cpp \
src/common/misc.cpp \
src/ConfigCredentialHelperDialog.cpp \
src/MySettings.cpp \
src/FileDiffWidget.cpp \
src/TextEditDialog.cpp \
src/LogTableWidget.cpp \
src/FileDiffSliderWidget.cpp \
src/FileUtil.cpp \
src/SettingsDialog.cpp \
src/MergeBranchDialog.cpp \
src/CloneDialog.cpp \
src/AboutDialog.cpp \
src/RepositoryInfoFrame.cpp \
src/RepositoryPropertyDialog.cpp \
src/RepositoryData.cpp \
src/MyToolButton.cpp \
src/GitDiff.cpp \
src/CommitPropertyDialog.cpp \
src/Terminal.cpp \
src/DeleteTagsDialog.cpp \
src/RepositoriesTreeWidget.cpp \
src/SelectCommandDialog.cpp \
src/ImageViewWidget.cpp \
src/FileHistoryWindow.cpp \
src/GitPackIdxV2.cpp \
src/GitPack.cpp \
src/GitObjectManager.cpp \
src/FilePropertyDialog.cpp \
src/BigDiffWindow.cpp \
src/MaximizeButton.cpp \
src/CommitExploreWindow.cpp \
src/ReadOnlyLineEdit.cpp \
src/ReadOnlyPlainTextEdit.cpp \
src/MyTableWidgetDelegate.cpp \
src/SetRemoteUrlDialog.cpp \
src/ClearButton.cpp \
src/SetUserDialog.cpp \
src/SearchFromGitHubDialog.cpp \
src/webclient.cpp \
src/charvec.cpp \
src/urlencode.cpp \
src/HyperLinkLabel.cpp \
src/JumpDialog.cpp \
src/CheckoutDialog.cpp \
src/DeleteBranchDialog.cpp \
src/BasicRepositoryDialog.cpp \
src/RemoteRepositoriesTableWidget.cpp \
src/LocalSocketReader.cpp \
src/PushDialog.cpp \
src/StatusLabel.cpp \
src/RepositoryLineEdit.cpp \
src/DirectoryLineEdit.cpp \
src/AbstractSettingForm.cpp \
src/SettingExampleForm.cpp \
src/CreateRepositoryDialog.cpp \
src/GitHubAPI.cpp \
src/MemoryReader.cpp \
src/ExperimentDialog.cpp \
src/gunzip.cpp \
src/AvatarLoader.cpp \
src/SettingNetworkForm.cpp \
src/Photoshop.cpp \
src/SettingBehaviorForm.cpp \
src/MyProcess.cpp \
src/FileViewWidget.cpp \
src/MyTextEditorWidget.cpp \
src/AbstractProcess.cpp \
src/texteditor/AbstractCharacterBasedApplication.cpp \
src/texteditor/InputMethodPopup.cpp \
src/texteditor/TextEditorTheme.cpp \
src/texteditor/TextEditorWidget.cpp \
src/texteditor/unicode.cpp \
src/texteditor/UnicodeWidth.cpp \
src/MyImageViewWidget.cpp \
src/SetGlobalUserDialog.cpp \
src/ReflogWindow.cpp \
src/Theme.cpp \
src/ApplicationGlobal.cpp \
src/BlameWindow.cpp \
src/MenuButton.cpp \
src/SettingGeneralForm.cpp \
src/WelcomeWizardDialog.cpp \
src/DialogHeaderFrame.cpp \
src/CommitViewWindow.cpp \
src/EditRemoteDialog.cpp \
src/gpg.cpp \
src/SelectGpgKeyDialog.cpp \
src/SetGpgSigningDialog.cpp \
src/CommitDialog.cpp \
src/ConfigSigningDialog.cpp \
src/AreYouSureYouWantToContinueConnectingDialog.cpp \
src/LineEditDialog.cpp \
src/SettingProgramsForm.cpp \
src/InputNewTagDialog.cpp \
src/EditTagsDialog.cpp \
src/darktheme/DarkStyle.cpp \
src/darktheme/NinePatch.cpp \
src/darktheme/StandardStyle.cpp \
src/darktheme/TraditionalWindowsStyleTreeControl.cpp \
src/EditGitIgnoreDialog.cpp \
src/SelectItemDialog.cpp \
src/RebaseOntoDialog.cpp \
src/DoYouWantToInitDialog.cpp \
src/RemoteWatcher.cpp
HEADERS += \
src/MainWindow.h \
src/Git.h \
src/common/joinpath.h \
src/common/misc.h \
src/ConfigCredentialHelperDialog.h \
src/MySettings.h \
src/main.h \
src/FileDiffWidget.h \
src/TextEditDialog.h \
src/LogTableWidget.h \
src/FileDiffSliderWidget.h \
src/FileUtil.h \
src/SettingsDialog.h \
src/MergeBranchDialog.h \
src/CloneDialog.h \
src/AboutDialog.h \
src/RepositoryInfoFrame.h \
src/RepositoryPropertyDialog.h \
src/RepositoryData.h \
src/MyToolButton.h \
src/GitDiff.h \
src/CommitPropertyDialog.h \
src/Terminal.h \
src/DeleteTagsDialog.h \
src/RepositoriesTreeWidget.h \
src/SelectCommandDialog.h \
src/ImageViewWidget.h \
src/FileHistoryWindow.h \
src/Debug.h \
src/GitPackIdxV2.h \
src/GitPack.h \
src/GitObjectManager.h \
src/FilePropertyDialog.h \
src/BigDiffWindow.h \
src/MaximizeButton.h \
src/CommitExploreWindow.h \
src/ReadOnlyLineEdit.h \
src/ReadOnlyPlainTextEdit.h \
src/MyTableWidgetDelegate.h \
src/SetRemoteUrlDialog.h \
src/ClearButton.h \
src/SetUserDialog.h \
src/SearchFromGitHubDialog.h \
src/webclient.h \
src/charvec.h \
src/urlencode.h \
src/HyperLinkLabel.h \
src/JumpDialog.h \
src/CheckoutDialog.h \
src/DeleteBranchDialog.h \
src/BasicRepositoryDialog.h \
src/RemoteRepositoriesTableWidget.h \
src/LocalSocketReader.h \
src/PushDialog.h \
src/StatusLabel.h \
src/RepositoryLineEdit.h \
src/DirectoryLineEdit.h \
src/AbstractSettingForm.h \
src/SettingExampleForm.h \
src/CreateRepositoryDialog.h \
src/GitHubAPI.h \
src/MemoryReader.h \
src/ExperimentDialog.h \
src/gunzip.h \
src/AvatarLoader.h \
src/SettingNetworkForm.h \
src/Photoshop.h \
src/SettingBehaviorForm.h \
src/MyProcess.h \
src/MyTextEditorWidget.h \
src/AbstractProcess.h \
src/texteditor/AbstractCharacterBasedApplication.h \
src/texteditor/InputMethodPopup.h \
src/texteditor/TextEditorTheme.h \
src/texteditor/TextEditorWidget.h \
src/texteditor/unicode.h \
src/texteditor/UnicodeWidth.h \
src/MyImageViewWidget.h \
src/SetGlobalUserDialog.h \
src/ReflogWindow.h \
src/Theme.h \
src/ApplicationGlobal.h \
src/BlameWindow.h \
src/MenuButton.h \
src/SettingGeneralForm.h \
src/WelcomeWizardDialog.h \
src/DialogHeaderFrame.h \
src/CommitViewWindow.h \
src/EditRemoteDialog.h \
src/gpg.h \
src/SelectGpgKeyDialog.h \
src/SetGpgSigningDialog.h \
src/CommitDialog.h \
src/ConfigSigningDialog.h \
src/AreYouSureYouWantToContinueConnectingDialog.h \
src/LineEditDialog.h \
src/SettingProgramsForm.h \
src/InputNewTagDialog.h \
src/EditTagsDialog.h \
src/darktheme/DarkStyle.h \
src/darktheme/NinePatch.h \
src/darktheme/StandardStyle.h \
src/darktheme/TraditionalWindowsStyleTreeControl.h \
src/EditGitIgnoreDialog.h \
src/SelectItemDialog.h \
src/RebaseOntoDialog.h \
src/DoYouWantToInitDialog.h \
src/RemoteWatcher.h
FORMS += \
src/MainWindow.ui \
src/ConfigCredentialHelperDialog.ui \
src/TextEditDialog.ui \
src/SettingsDialog.ui \
src/MergeBranchDialog.ui \
src/CloneDialog.ui \
src/AboutDialog.ui \
src/RepositoryPropertyDialog.ui \
src/CommitPropertyDialog.ui \
src/DeleteTagsDialog.ui \
src/SelectCommandDialog.ui \
src/FileDiffWidget.ui \
src/FileHistoryWindow.ui \
src/FilePropertyDialog.ui \
src/BigDiffWindow.ui \
src/CommitExploreWindow.ui \
src/SetRemoteUrlDialog.ui \
src/SetUserDialog.ui \
src/SearchFromGitHubDialog.ui \
src/JumpDialog.ui \
src/CheckoutDialog.ui \
src/DeleteBranchDialog.ui \
src/PushDialog.ui \
src/SettingExampleForm.ui \
src/CreateRepositoryDialog.ui \
src/ExperimentDialog.ui \
src/SettingNetworkForm.ui \
src/SettingBehaviorForm.ui \
src/SetGlobalUserDialog.ui \
src/ReflogWindow.ui \
src/BlameWindow.ui \
src/SettingGeneralForm.ui \
src/WelcomeWizardDialog.ui \
src/CommitViewWindow.ui \
src/EditRemoteDialog.ui \
src/SelectGpgKeyDialog.ui \
src/SetGpgSigningDialog.ui \
src/CommitDialog.ui \
src/ConfigSigningDialog.ui \
src/AreYouSureYouWantToContinueConnectingDialog.ui \
src/LineEditDialog.ui \
src/SettingProgramsForm.ui \
src/InputNewTagDialog.ui \
src/EditTagsDialog.ui \
src/EditGitIgnoreDialog.ui \
src/SelectItemDialog.ui \
src/RebaseOntoDialog.ui \
src/DoYouWantToInitDialog.ui
RESOURCES += \
src/resources/resources.qrc
unix {
SOURCES += \
src/unix/UnixProcess.cpp \
src/unix/UnixPtyProcess.cpp
HEADERS += \
src/unix/UnixProcess.h \
src/unix/UnixPtyProcess.h
}
win32 {
SOURCES += \
src/win32/thread.cpp \
src/win32/event.cpp \
src/win32/win32.cpp \
src/win32/Win32Process.cpp \
src/win32/Win32PtyProcess.cpp
HEADERS += \
src/win32/thread.h \
src/win32/event.h \
src/win32/mutex.h \
src/win32/win32.h \
src/win32/Win32Process.h \
src/win32/Win32PtyProcess.h
}
diff --git a/misc/winpty/winpty.h b/misc/winpty/winpty.h
new file mode 100644
index 0000000..fdfe4bc
--- /dev/null
+++ b/misc/winpty/winpty.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2011-2016 Ryan Prichard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef WINPTY_H
+#define WINPTY_H
+
+#include <windows.h>
+
+#include "winpty_constants.h"
+
+/* On 32-bit Windows, winpty functions have the default __cdecl (not __stdcall)
+ * calling convention. (64-bit Windows has only a single calling convention.)
+ * When compiled with __declspec(dllexport), with either MinGW or MSVC, the
+ * winpty functions are unadorned--no underscore prefix or '@nn' suffix--so
+ * GetProcAddress can be used easily. */
+#ifdef COMPILING_WINPTY_DLL
+#define WINPTY_API __declspec(dllexport)
+#else
+#define WINPTY_API __declspec(dllimport)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The winpty API uses wide characters, instead of UTF-8, to avoid conversion
+ * complications related to surrogates. Windows generally tolerates unpaired
+ * surrogates in text, which makes conversion to and from UTF-8 ambiguous and
+ * complicated. (There are different UTF-8 variants that deal with UTF-16
+ * surrogates differently.) */
+
+
+
+/*****************************************************************************
+ * Error handling. */
+
+/* All the APIs have an optional winpty_error_t output parameter. If a
+ * non-NULL argument is specified, then either the API writes NULL to the
+ * value (on success) or writes a newly allocated winpty_error_t object. The
+ * object must be freed using winpty_error_free. */
+
+/* An error object. */
+typedef struct winpty_error_s winpty_error_t;
+typedef winpty_error_t *winpty_error_ptr_t;
+
+/* An error code -- one of WINPTY_ERROR_xxx. */
+typedef DWORD winpty_result_t;
+
+/* Gets the error code from the error object. */
+WINPTY_API winpty_result_t winpty_error_code(winpty_error_ptr_t err);
+
+/* Returns a textual representation of the error. The string is freed when
+ * the error is freed. */
+WINPTY_API LPCWSTR winpty_error_msg(winpty_error_ptr_t err);
+
+/* Free the error object. Every error returned from the winpty API must be
+ * freed. */
+WINPTY_API void winpty_error_free(winpty_error_ptr_t err);
+
+
+
+/*****************************************************************************
+ * Configuration of a new agent. */
+
+/* The winpty_config_t object is not thread-safe. */
+typedef struct winpty_config_s winpty_config_t;
+
+/* Allocate a winpty_config_t value. Returns NULL on error. There are no
+ * required settings -- the object may immediately be used. agentFlags is a
+ * set of zero or more WINPTY_FLAG_xxx values. An unrecognized flag results
+ * in an assertion failure. */
+WINPTY_API winpty_config_t *
+winpty_config_new(UINT64 agentFlags, winpty_error_ptr_t *err /*OPTIONAL*/);
+
+/* Free the cfg object after passing it to winpty_open. */
+WINPTY_API void winpty_config_free(winpty_config_t *cfg);
+
+WINPTY_API void
+winpty_config_set_initial_size(winpty_config_t *cfg, int cols, int rows);
+
+/* Set the mouse mode to one of the WINPTY_MOUSE_MODE_xxx constants. */
+WINPTY_API void
+winpty_config_set_mouse_mode(winpty_config_t *cfg, int mouseMode);
+
+/* Amount of time to wait for the agent to startup and to wait for any given
+ * agent RPC request. Must be greater than 0. Can be INFINITE. */
+WINPTY_API void
+winpty_config_set_agent_timeout(winpty_config_t *cfg, DWORD timeoutMs);
+
+
+
+/*****************************************************************************
+ * Start the agent. */
+
+/* The winpty_t object is thread-safe. */
+typedef struct winpty_s winpty_t;
+
+/* Starts the agent. Returns NULL on error. This process will connect to the
+ * agent over a control pipe, and the agent will open data pipes (e.g. CONIN
+ * and CONOUT). */
+WINPTY_API winpty_t *
+winpty_open(const winpty_config_t *cfg,
+ winpty_error_ptr_t *err /*OPTIONAL*/);
+
+/* A handle to the agent process. This value is valid for the lifetime of the
+ * winpty_t object. Do not close it. */
+WINPTY_API HANDLE winpty_agent_process(winpty_t *wp);
+
+
+
+/*****************************************************************************
+ * I/O pipes. */
+
+/* Returns the names of named pipes used for terminal I/O. Each input or
+ * output direction uses a different half-duplex pipe. The agent creates
+ * these pipes, and the client can connect to them using ordinary I/O methods.
+ * The strings are freed when the winpty_t object is freed.
+ *
+ * winpty_conerr_name returns NULL unless WINPTY_FLAG_CONERR is specified.
+ *
+ * N.B.: CreateFile does not block when connecting to a local server pipe. If
+ * the server pipe does not exist or is already connected, then it fails
+ * instantly. */
+WINPTY_API LPCWSTR winpty_conin_name(winpty_t *wp);
+WINPTY_API LPCWSTR winpty_conout_name(winpty_t *wp);
+WINPTY_API LPCWSTR winpty_conerr_name(winpty_t *wp);
+
+
+
+/*****************************************************************************
+ * winpty agent RPC call: process creation. */
+
+/* The winpty_spawn_config_t object is not thread-safe. */
+typedef struct winpty_spawn_config_s winpty_spawn_config_t;
+
+/* winpty_spawn_config strings do not need to live as long as the config
+ * object. They are copied. Returns NULL on error. spawnFlags is a set of
+ * zero or more WINPTY_SPAWN_FLAG_xxx values. An unrecognized flag results in
+ * an assertion failure.
+ *
+ * env is a a pointer to an environment block like that passed to
+ * CreateProcess--a contiguous array of NUL-terminated "VAR=VAL" strings
+ * followed by a final NUL terminator.
+ *
+ * N.B.: If you want to gather all of the child's output, you may want the
+ * WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN flag.
+ */
+WINPTY_API winpty_spawn_config_t *
+winpty_spawn_config_new(UINT64 spawnFlags,
+ LPCWSTR appname /*OPTIONAL*/,
+ LPCWSTR cmdline /*OPTIONAL*/,
+ LPCWSTR cwd /*OPTIONAL*/,
+ LPCWSTR env /*OPTIONAL*/,
+ winpty_error_ptr_t *err /*OPTIONAL*/);
+
+/* Free the cfg object after passing it to winpty_spawn. */
+WINPTY_API void winpty_spawn_config_free(winpty_spawn_config_t *cfg);
+
+/*
+ * Spawns the new process.
+ *
+ * The function initializes all output parameters to zero or NULL.
+ *
+ * On success, the function returns TRUE. For each of process_handle and
+ * thread_handle that is non-NULL, the HANDLE returned from CreateProcess is
+ * duplicated from the agent and returned to the winpty client. The client is
+ * responsible for closing these HANDLES.
+ *
+ * On failure, the function returns FALSE, and if err is non-NULL, then *err
+ * is set to an error object.
+ *
+ * If the agent's CreateProcess call failed, then *create_process_error is set
+ * to GetLastError(), and the WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED error
+ * is returned.
+ *
+ * winpty_spawn can only be called once per winpty_t object. If it is called
+ * before the output data pipe(s) is/are connected, then collected output is
+ * buffered until the pipes are connected, rather than being discarded.
+ *
+ * N.B.: GetProcessId works even if the process has exited. The PID is not
+ * recycled until the NT process object is freed.
+ * (https://blogs.msdn.microsoft.com/oldnewthing/20110107-00/?p=11803)
+ */
+WINPTY_API BOOL
+winpty_spawn(winpty_t *wp,
+ const winpty_spawn_config_t *cfg,
+ HANDLE *process_handle /*OPTIONAL*/,
+ HANDLE *thread_handle /*OPTIONAL*/,
+ DWORD *create_process_error /*OPTIONAL*/,
+ winpty_error_ptr_t *err /*OPTIONAL*/);
+
+
+
+/*****************************************************************************
+ * winpty agent RPC calls: everything else */
+
+/* Change the size of the Windows console window. */
+WINPTY_API BOOL
+winpty_set_size(winpty_t *wp, int cols, int rows,
+ winpty_error_ptr_t *err /*OPTIONAL*/);
+
+/* Gets a list of processes attached to the console. */
+WINPTY_API int
+winpty_get_console_process_list(winpty_t *wp, int *processList, const int processCount,
+ winpty_error_ptr_t *err /*OPTIONAL*/);
+
+/* Frees the winpty_t object and the OS resources contained in it. This
+ * call breaks the connection with the agent, which should then close its
+ * console, terminating the processes attached to it.
+ *
+ * This function must not be called if any other threads are using the
+ * winpty_t object. Undefined behavior results. */
+WINPTY_API void winpty_free(winpty_t *wp);
+
+
+
+/****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WINPTY_H */
diff --git a/misc/winpty/winpty.lib b/misc/winpty/winpty.lib
new file mode 100644
index 0000000..a35c429
Binary files /dev/null and b/misc/winpty/winpty.lib differ
diff --git a/misc/winpty/winpty_constants.h b/misc/winpty/winpty_constants.h
new file mode 100644
index 0000000..11e34cf
--- /dev/null
+++ b/misc/winpty/winpty_constants.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016 Ryan Prichard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef WINPTY_CONSTANTS_H
+#define WINPTY_CONSTANTS_H
+
+/*
+ * You may want to include winpty.h instead, which includes this header.
+ *
+ * This file is split out from winpty.h so that the agent can access the
+ * winpty flags without also declaring the libwinpty APIs.
+ */
+
+/*****************************************************************************
+ * Error codes. */
+
+#define WINPTY_ERROR_SUCCESS 0
+#define WINPTY_ERROR_OUT_OF_MEMORY 1
+#define WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED 2
+#define WINPTY_ERROR_LOST_CONNECTION 3
+#define WINPTY_ERROR_AGENT_EXE_MISSING 4
+#define WINPTY_ERROR_UNSPECIFIED 5
+#define WINPTY_ERROR_AGENT_DIED 6
+#define WINPTY_ERROR_AGENT_TIMEOUT 7
+#define WINPTY_ERROR_AGENT_CREATION_FAILED 8
+
+
+
+/*****************************************************************************
+ * Configuration of a new agent. */
+
+/* Create a new screen buffer (connected to the "conerr" terminal pipe) and
+ * pass it to child processes as the STDERR handle. This flag also prevents
+ * the agent from reopening CONOUT$ when it polls -- regardless of whether the
+ * active screen buffer changes, winpty continues to monitor the original
+ * primary screen buffer. */
+#define WINPTY_FLAG_CONERR 0x1ull
+
+/* Don't output escape sequences. */
+#define WINPTY_FLAG_PLAIN_OUTPUT 0x2ull
+
+/* Do output color escape sequences. These escapes are output by default, but
+ * are suppressed with WINPTY_FLAG_PLAIN_OUTPUT. Use this flag to reenable
+ * them. */
+#define WINPTY_FLAG_COLOR_ESCAPES 0x4ull
+
+/* On XP and Vista, winpty needs to put the hidden console on a desktop in a
+ * service window station so that its polling does not interfere with other
+ * (visible) console windows. To create this desktop, it must change the
+ * process' window station (i.e. SetProcessWindowStation) for the duration of
+ * the winpty_open call. In theory, this change could interfere with the
+ * winpty client (e.g. other threads, spawning children), so winpty by default
+ * spawns a special agent process to create the hidden desktop. Spawning
+ * processes on Windows is slow, though, so if
+ * WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION is set, winpty changes this
+ * process' window station instead.
+ * See https://github.com/rprichard/winpty/issues/58. */
+#define WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION 0x8ull
+
+#define WINPTY_FLAG_MASK (0ull \
+ | WINPTY_FLAG_CONERR \
+ | WINPTY_FLAG_PLAIN_OUTPUT \
+ | WINPTY_FLAG_COLOR_ESCAPES \
+ | WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION \
+)
+
+/* QuickEdit mode is initially disabled, and the agent does not send mouse
+ * mode sequences to the terminal. If it receives mouse input, though, it
+ * still writes MOUSE_EVENT_RECORD values into CONIN. */
+#define WINPTY_MOUSE_MODE_NONE 0
+
+/* QuickEdit mode is initially enabled. As CONIN enters or leaves mouse
+ * input mode (i.e. where ENABLE_MOUSE_INPUT is on and ENABLE_QUICK_EDIT_MODE
+ * is off), the agent enables or disables mouse input on the terminal.
+ *
+ * This is the default mode. */
+#define WINPTY_MOUSE_MODE_AUTO 1
+
+/* QuickEdit mode is initially disabled, and the agent enables the terminal's
+ * mouse input mode. It does not disable terminal mouse mode (until exit). */
+#define WINPTY_MOUSE_MODE_FORCE 2
+
+
+
+/*****************************************************************************
+ * winpty agent RPC call: process creation. */
+
+/* If the spawn is marked "auto-shutdown", then the agent shuts down console
+ * output once the process exits. The agent stops polling for new console
+ * output, and once all pending data has been written to the output pipe, the
+ * agent closes the pipe. (At that point, the pipe may still have data in it,
+ * which the client may read. Once all the data has been read, further reads
+ * return EOF.) */
+#define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ull
+
+/* After the agent shuts down output, and after all output has been written
+ * into the pipe(s), exit the agent by closing the console. If there any
+ * surviving processes still attached to the console, they are killed.
+ *
+ * Note: With this flag, an RPC call (e.g. winpty_set_size) issued after the
+ * agent exits will fail with an I/O or dead-agent error. */
+#define WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN 2ull
+
+/* All the spawn flags. */
+#define WINPTY_SPAWN_FLAG_MASK (0ull \
+ | WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN \
+ | WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN \
+)
+
+
+
+#endif /* WINPTY_CONSTANTS_H */
diff --git a/prepare.rb b/prepare.rb
index 0f87dcb..15f2b8c 100755
--- a/prepare.rb
+++ b/prepare.rb
@@ -1,89 +1,89 @@
#!/usr/bin/ruby
# create the following files
# * version.c
# * win.rc
# * Info.plist
load 'version.rb'
def get_revision()
rev = ""
if Dir.exist?(".git")
hash = `git rev-parse HEAD`
if hash =~ /^[0-9A-Za-z]+/
rev = hash[0, 7]
end
end
return rev
end
File.open("src/version.h", "w") {|f|
f.puts <<_____
int copyright_year = #{$copyright_year};
char const product_version[] = "#{$version_a}.#{$version_b}.#{$version_c}";
char const source_revision[] = "#{get_revision()}";
_____
}
File.open("win.rc", "w") {|f|
f.puts <<_____
#include <windows.h>
-100 ICON DISCARDABLE "#{$product_name}.ico"
+100 ICON DISCARDABLE "src/resources/#{$product_name}.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION #{$version_a},#{$version_b},#{$version_c},#{$version_d}
PRODUCTVERSION #{$version_a},#{$version_b},#{$version_c},#{$version_d}
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "041103a4"
BEGIN
VALUE "CompanyName", "S.Fuchita"
VALUE "FileDescription", "The Git GUI Client"
VALUE "FileVersion", "#{$version_a}, #{$version_b}, #{$version_c}, #{$version_d}"
VALUE "InternalName", "#{$product_name}.exe"
VALUE "LegalCopyright", "Copyright (C) #{$copyright_year} S.Fuchita (@soramimi_jp)"
VALUE "OriginalFilename","#{$product_name}.exe"
VALUE "ProductName", "#{$product_name}"
VALUE "ProductVersion", "#{$version_a}, #{$version_b}, #{$version_c}, #{$version_d}"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0411, 932
END
END
_____
}
File.open("Info.plist", "w") {|f|
f.puts <<_____
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleIconFile</key>
<string>#{$product_name}.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>#{$version_a}.#{$version_b}.#{$version_c}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>#{$product_name}</string>
<key>CFBundleIdentifier</key>
<string>jp.soramimi.#{$product_name}</string>
</dict>
</plist>
_____
}
diff --git a/src/darktheme/DarkStyle.cpp b/src/darktheme/DarkStyle.cpp
index 6dad4db..e21ef6e 100644
--- a/src/darktheme/DarkStyle.cpp
+++ b/src/darktheme/DarkStyle.cpp
@@ -1,2368 +1,2256 @@
#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 <QToolTip>
-#include <math.h>
-#include <stdint.h>
+#include <cmath>
+#include <cstdint>
#define MBI_NORMAL 1
#define MBI_HOT 2
#define MBI_PUSHED 3
#define MBI_DISABLED 4
namespace {
-static const int windowsItemFrame = 2; // menu item frame width
-static const int windowsItemHMargin = 3; // menu item hor text margin
-static const int windowsItemVMargin = 4; // menu item ver text margin
-static const int windowsArrowHMargin = 6; // arrow horizontal margin
-static const int windowsRightBorder = 15; // right border on windows
+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 color_topleft, QColor 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;
-// int alpha = qAlpha(source);
if (alpha != 0) {
-// int light = qGray(source);
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 base_color)
+DarkStyle::DarkStyle(QColor const &base_color)
: m(new Private)
{
setBaseColor(base_color);
-// setBaseColor(QColor(128, 255, 240));
-// setBaseColor(QColor(128, 240, 255));
}
DarkStyle::~DarkStyle()
{
delete m;
}
QColor DarkStyle::getBaseColor()
{
return m->base_color;
}
-void DarkStyle::setBaseColor(QColor 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();
- //image = image.convertToFormat(QImage::Format_ARGB32);
Q_ASSERT(image.format() == QImage::Format_ARGB32);
for (int y = 0; y < h; y++) {
- QRgb *p = (QRgb *)image.scanLine(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, const QString &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(const QString &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 = (QRgb *)source.scanLine(y + 1);
- QRgb *src2 = (QRgb *)source.scanLine(y + 2);
- QRgb *src3 = (QRgb *)source.scanLine(y + 3);
- QRgb *dst0 = (QRgb *)buttons.im_normal.scanLine(y + 2) + 2;
- QRgb *dst1 = (QRgb *)buttons.im_hover.scanLine(y + 2) + 2;
+ 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] = qRgba(v, v, v, alpha);
dst0[x] = colorize(rgb, v, alpha);
v = lighten[v];
-// dst1[x] = qRgba(v, v, v, alpha);
dst1[x] = colorize(rgb, v, alpha);
}
}
-// buttons.im_normal = colorizeImage(buttons.im_normal);
-// buttons.im_hover = colorizeImage(buttons.im_hover);
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 = (QRgb *)newimage.scanLine(y + 1) + 1;
+ 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] = qRgba(v, v, v, qAlpha(ptr[x]));
ptr[x] = colorize(rgb, v, qAlpha(ptr[x]));
}
}
-// newimage = colorizeImage(newimage);
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::colorForSelectedFrame(const QStyleOption *opt) const
{
(void)opt;
return QColor(128, 192, 255);
-
}
QColor DarkStyle::colorForItemView(QStyleOption const *opt) const
{
return opt->palette.color(QPalette::Dark);
// return opt->palette.color(QPalette::Base); // これじゃない
}
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));
#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::drawSelectedMenuFrame(const QStyleOption *option, QPainter *p, QRect rect, const QWidget *widget, bool deep) const
{
(void)widget;
QColor color = colorForSelectedFrame(option);
int x, y, w, h;
x = rect.x();
y = rect.y();
w = rect.width();
h = rect.height();
auto SetAlpha = [&](QColor *color, int alpha){
if (deep) {
alpha = alpha * 3 / 2;
}
color->setAlpha(alpha);
};
- QString key;
- {
- char tmp[100];
- sprintf(tmp, "selection_frame:%02x%02x%02x:%dx%d", color.red(), color.green(), color.blue(), w, h);
- key = tmp;
- }
+ QString key = QString().sprintf("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;
SetAlpha(&pencolor, 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;
SetAlpha(&color0, 96 * a / 255);
SetAlpha(&color1, 32 * 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::drawButton(QPainter *p, const QStyleOption *option) const
{
QRect rect = option->rect;
int w = rect.width();
int h = rect.height();
#ifdef Q_OS_MAC
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();
}
}
#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
p->setPen(QColor(80, 160, 255));
p->setBrush(Qt::NoBrush);
double m = 3.5;
p->drawRoundedRect(((QRectF)rect).adjusted(m, m, -m, -m), 4, 4);
#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);
+ 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 (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ if (const auto *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
QRect rect;
int extent = std::min(widget->width(), widget->height());
int span = pixelMetric(PM_SliderLength, slider, widget);
bool horizontal = slider->orientation == Qt::Horizontal;
int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum,
slider->sliderPosition,
(horizontal ? slider->rect.width()
: slider->rect.height()) - span,
slider->upsideDown);
if (horizontal) {
rect.setRect(slider->rect.x() + sliderPos, slider->rect.y(), span, extent);
} else {
rect.setRect(slider->rect.x(), slider->rect.y() + sliderPos, extent, span);
}
return rect;
}
}
if (cc == CC_GroupBox) {
-// return QProxyStyle::subControlRect(cc, option, sc, widget);
QRect ret;
- if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ if (const auto *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
switch (sc) {
case SC_GroupBoxFrame:
case SC_GroupBoxContents:
{
int topMargin = 0;
int topHeight = 0;
int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
#ifdef Q_OS_MACX
verticalAlignment |= Qt::AlignVCenter;
#endif
if (groupBox->text.size() || (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)) {
topHeight = groupBox->fontMetrics.height();
if (verticalAlignment & Qt::AlignVCenter) {
topMargin = topHeight / 2;
} else if (verticalAlignment & Qt::AlignTop) {
topMargin = topHeight;
}
}
QRect frameRect = groupBox->rect;
frameRect.setTop(topMargin);
if (sc == SC_GroupBoxFrame) {
ret = frameRect;
break;
}
int frameWidth = 0;
if ((groupBox->features & QStyleOptionFrame::Flat) == 0) {
frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, groupBox, widget);
}
ret = frameRect.adjusted(frameWidth, frameWidth + topHeight - topMargin, -frameWidth, -frameWidth);
}
break;
case SC_GroupBoxCheckBox:
case SC_GroupBoxLabel:
{
QFontMetrics fontMetrics = groupBox->fontMetrics;
int h = fontMetrics.height();
int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
int marg = (groupBox->features & QStyleOptionFrame::Flat) ? 0 : 8;
ret = groupBox->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 = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
// Adjusted rect for label + indicatorWidth + indicatorSpace
QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment, QSize(tw + checkBoxSize, h), ret);
// Adjust totalRect if checkbox is set
if (hasCheckBox) {
bool ltr = groupBox->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);
}
void DarkStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, const QWidget *widget) const
{
// qDebug() << pe;
#ifdef Q_OS_LINUX
if (pe == PE_FrameFocusRect) {
QColor color(64, 128, 255);
drawFrame(p, option->rect, color, color);
return;
}
#endif
if (pe == PE_IndicatorArrowDown) {
- // p->fillRect(option->rect, Qt::red);
switch (pe) {
case PE_IndicatorArrowUp:
case PE_IndicatorArrowDown:
case PE_IndicatorArrowRight:
case PE_IndicatorArrowLeft:
{
- if (option->rect.width() <= 1 || option->rect.height() <= 1)
+ 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;
-// QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-")
-// % QLatin1String(metaObject()->className()), option, QSize(size, size))
-// % HexString<uint>(pe);
- if (1) {//if (!QPixmapCache::find(pixmapName, pixmap)) {
- int border = size/5;
- int sqsize = 2*(size/2);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
-// QPixmapCache::insert(pixmapName, pixmap);
}
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) {
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) {
drawRaisedFrame(p, option->rect, option->palette);
return;
}
if (pe == PE_PanelLineEdit) {
- if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
-// p->fillRect(option->rect, option->palette.color(QPalette::Dark));
+ if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(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));
}
-
-// option->
-// if (qobject_cast<QComboBox const *>(widget->parent())) {
-// // nop
-// } else {
-// }
}
return;
}
if (pe == PE_FrameGroupBox) {
-#if 0
-// p->save();
-// p->setRenderHint(QPainter::Antialiasing);
- QRectF r = option->rect;
- qDebug() << r;
-// r = r.adjusted(19.5, 19.5, -18.5, -18.5);
- p->setPen(option->palette.color(QPalette::Light));
- p->fillRect(r, Qt::red);
-// r = r.adjusted(-1, -1, -1, -1);
-// p->setPen(option->palette.color(QPalette::Dark));
-// p->drawRoundedRect(r, 5, 5);
-// p->restore();
-#else
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();
-#endif
return;
}
if (pe == PE_PanelItemViewRow) {
#ifdef Q_OS_WIN
// thru
#else
return;
#endif
}
if (pe == PE_PanelItemViewItem) {
// p->fillRect(option->rect, colorForItemView(option)); // 選択枠を透過描画させるので背景は描かない
- if (QTableView const *tableview = qobject_cast<QTableView const *>(widget)) {
+ if (auto const *tableview = qobject_cast<QTableView const *>(widget)) {
Qt::PenStyle grid_pen_style = Qt::NoPen;
if (tableview->showGrid()) {
grid_pen_style = tableview->gridStyle();
}
QAbstractItemView::SelectionBehavior selection_behavior = tableview->selectionBehavior();
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));
}
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());
}
- drawSelectedMenuFrame(option, p, r, widget, false);
+ drawSelectedMenuFrame(option, p, r, widget);
p->restore();
}
} else {
int n = 0;
if (option->state & State_Selected) {
n++;
}
-// if (option->state & State_MouseOver) {
-// n++;
-// }
if (n > 0) {
drawSelectedMenuFrame(option, p, option->rect, widget, n > 1);
}
}
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 = 0;
+ 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;
}
-// if (ce == CE_ToolButtonLabel) {
-// 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 (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
QRect ir = button->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, button, widget)) {
tf |= Qt::TextShowMnemonic;
} else {
tf |= Qt::TextHideMnemonic;
}
if (!button->icon.isNull()) {
//Center both icon and text
QPoint point;
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
if (mode == QIcon::Normal && button->state & State_HasFocus) {
mode = QIcon::Active;
}
QIcon::State state = QIcon::Off;
if (button->state & State_On) {
state = QIcon::On;
}
QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
int w = pixmap.width();
int h = pixmap.height();
if (!button->text.isEmpty()) {
w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 4;
}
point = QPoint(ir.x() + ir.width() / 2 - w / 2, ir.y() + ir.height() / 2 - h / 2);
if (button->direction == Qt::RightToLeft) {
point.rx() += pixmap.width();
}
p->drawPixmap(visualPos(button->direction, button->rect, point + buttonShift), pixmap);
if (button->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 (!button->text.isEmpty()) {
tf |= Qt::AlignLeft;
}
} else {
tf |= Qt::AlignHCenter;
}
ir.translate(buttonShift);
if (button->features & QStyleOptionButton::HasMenu) {
ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
}
drawItemText(p, ir, tf, option->palette, (button->state & State_Enabled), button->text, QPalette::ButtonText);
return;
}
}
if (ce == CE_RadioButton || ce == CE_CheckBox) {
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
bool isRadio = (ce == CE_RadioButton);
QStyleOptionButton subopt = *btn;
subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, btn, widget);
proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, &subopt, p, widget);
subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents : SE_CheckBoxContents, btn, widget);
drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
if (btn->state & State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*btn);
fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect, btn, widget);
drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
return;
}
}
if (ce == CE_RadioButtonLabel || ce == CE_CheckBoxLabel) {
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
if (!styleHint(SH_UnderlineShortcut, btn, widget)) {
alignment |= Qt::TextHideMnemonic;
}
QPixmap pix;
QRect textRect = btn->rect;
if (!btn->icon.isNull()) {
pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
drawItemPixmap(p, btn->rect, alignment, pix);
if (btn->direction == Qt::RightToLeft) {
textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
} else {
textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
}
}
if (!btn->text.isEmpty()){
drawItemText(p, textRect, alignment | Qt::TextShowMnemonic, btn->palette, btn->state & State_Enabled, btn->text, QPalette::ButtonText);
}
return;
}
}
if (ce == CE_ComboBoxLabel) {
if (const QStyleOptionComboBox *opt = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
QRect editRect = subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, widget);
uint alignment = Qt::AlignLeft | Qt::AlignVCenter;
if (!styleHint(SH_UnderlineShortcut, opt, widget)) {
alignment |= Qt::TextHideMnemonic;
}
QPixmap pix;
QRect iconRect(editRect);
QIcon icon = opt->currentIcon;
QString text = opt->currentText;
if (!icon.isNull()) {
pix = icon.pixmap(opt->iconSize, opt->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
drawItemPixmap(p, iconRect, alignment, pix);
if (opt->direction == Qt::RightToLeft) {
editRect.setRight(editRect.right() - opt->iconSize.width() - 4);
} else {
editRect.setLeft(editRect.left() + opt->iconSize.width() + 4);
}
}
if (!text.isEmpty()){
drawItemText(p, editRect, alignment, opt->palette, opt->state & State_Enabled, text, QPalette::ButtonText);
}
return;
}
}
#endif
if (ce == CE_ShapedFrame) {
- if (QStyleOptionFrameV3 const *o = qstyleoption_cast<QStyleOptionFrameV3 const *>(option)) {
+ 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) {
- enum PartID {
- BP_PUSHBUTTON,
- BP_COMMANDLINK,
- };
-
- enum StateID {
- PBS_DISABLED,
- PBS_PRESSED,
- PBS_HOT,
- PBS_DEFAULTED,
- PBS_NORMAL,
- };
-
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- int state = option->state;
- State flags = option->state;
- int partId = BP_PUSHBUTTON;
- int stateId = 0;
- if (btn->features & QStyleOptionButton::CommandLinkButton) {
- partId = BP_COMMANDLINK;
- }
- if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat)) {
- stateId = PBS_DISABLED;
- } else if (flags & (State_Sunken | State_On)) {
- stateId = PBS_PRESSED;
- } else if (flags & State_MouseOver) {
- stateId = PBS_HOT;
- } else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active)) {
- stateId = PBS_DEFAULTED;
+ if (const auto *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ if (btn->features & QStyleOptionButton::Flat) {
+ // nop
} else {
- stateId = PBS_NORMAL;
+ drawButton(p, option);
}
- drawButton(p, option);
-
if (btn->features & QStyleOptionButton::HasMenu) {
int mbiw = 0, mbih = 0;
- QRect r = subElementRect(SE_PushButtonContents, option, 0);
+ QRect r = subElementRect(SE_PushButtonContents, option, nullptr);
QStyleOptionButton newBtn = *btn;
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);
}
}
return;
}
if (ce == CE_MenuBarEmptyArea) {
drawMenuBarBG(p, option, widget);
return;
}
if (ce == CE_MenuBarItem) {
drawMenuBarBG(p, option, widget);
if (option->state & State_Selected) {
- drawSelectedMenuFrame(option, p, option->rect, widget, false);
+ drawSelectedMenuFrame(option, p, option->rect, widget);
}
- if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ if (const auto *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
QPixmap pix = mbi->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
if (!styleHint(SH_UnderlineShortcut, mbi, widget)) {
alignment |= Qt::TextHideMnemonic;
}
if (!pix.isNull()) {
drawItemPixmap(p, mbi->rect, alignment, pix);
} else {
drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
}
}
return;
}
if (ce == CE_MenuEmptyArea) {
return;
}
if (ce == CE_MenuItem) {
- if (const QStyleOptionMenuItem *opt = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- int stateId = 0;
+ if (const auto *opt = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
// windows always has a check column, regardless whether we have an icon or not
int checkcol = 25;// / QWindowsXPStylePrivate::devicePixelRatio(widget);
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));
}
ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
}
//draw vertical menu line
if (option->direction == Qt::LeftToRight) {
checkcol += rect.x();
}
int x, y, w, h;
opt->rect.getRect(&x, &y, &w, &h);
int tab = opt->tabWidth;
bool dis = !(opt->state & State_Enabled);
- bool checked = opt->checkType != QStyleOptionMenuItem::NotCheckable ? opt->checked : false;
+ bool checked = (opt->checkType != QStyleOptionMenuItem::NotCheckable) && opt->checked;
bool act = opt->state & State_Selected;
if (opt->menuItemType == QStyleOptionMenuItem::Separator) {
QRect r = option->rect.adjusted(2, 0, -2, 0);
drawGutter(p, r);
return;
}
QRect vCheckRect = visualRect(option->direction, opt->rect, QRect(opt->rect.x(), opt->rect.y(), checkcol - (gutterWidth + opt->rect.x()), opt->rect.height()));
if (act) {
- stateId = dis ? MBI_DISABLED : MBI_HOT;
- drawSelectedMenuFrame(option, p, option->rect, widget, false);
+ drawSelectedMenuFrame(option, p, option->rect, widget);
}
if (checked && !ignoreCheckMark) {
const qreal boxMargin = 3.5;
const qreal boxWidth = checkcol - 2 * boxMargin;
const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
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
checkRect = visualRect(opt->direction, opt->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 (!opt->icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
if (act && !dis) {
mode = QIcon::Active;
}
QPixmap pixmap;
if (checked) {
pixmap = opt->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
} else {
pixmap = opt->icon.pixmap(pixelMetric(PM_SmallIconSize, option, widget), mode);
}
- const int pixw = pixmap.width() / pixmap.devicePixelRatio();
- const int pixh = pixmap.height() / pixmap.devicePixelRatio();
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vCheckRect.center());
- p->setPen(opt->palette.text().color());
- p->drawPixmap(pmr.topLeft(), pixmap);
+ double dpr = pixmap.devicePixelRatio();
+ if (dpr > 0) {
+ const int pixw = int(pixmap.width() / dpr);
+ const int pixh = int(pixmap.height() / dpr);
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ p->setPen(opt->palette.text().color());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ }
}
} else {
if (opt->icon.isNull()) {
checkcol = 0;
} else {
checkcol = opt->maxIconWidth;
}
}
p->setPen(opt->palette.buttonText().color());
const QColor textColor = opt->palette.text().color();
if (dis) {
p->setPen(textColor);
}
int xm = windowsItemFrame + checkcol + windowsItemHMargin + (gutterWidth - opt->rect.x()) - 1;
int xpos = opt->rect.x() + xm;
QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(option->direction, opt->rect, textRect);
QString s = opt->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, opt, widget)) {
text_flags |= Qt::TextHideMnemonic;
}
text_flags |= Qt::AlignLeft;
if (t >= 0) {
QRect vShortcutRect = visualRect(option->direction, opt->rect, QRect(textRect.topRight(), QPoint(opt->rect.right(), textRect.bottom())));
p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
s = s.left(t);
}
QFont font = opt->font;
if (opt->menuItemType == QStyleOptionMenuItem::DefaultItem) {
font.setBold(true);
}
p->setFont(font);
p->setPen(textColor);
p->drawText(vTextRect, text_flags, s.left(t));
p->restore();
}
if (opt->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, opt->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
QStyleOptionMenuItem newMI = *opt;
newMI.rect = vSubMenuRect;
newMI.state = dis ? State_None : State_Enabled;
drawPrimitive(arrow, &newMI, p, widget);
}
}
return;
}
if (ce == CE_TabBarTabShape) {
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ if (const auto *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
bool rtlHorTabs = (tab->direction == Qt::RightToLeft && (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedSouth));
bool selected = tab->state & State_Selected;
bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End) || (rtlHorTabs && tab->position == QStyleOptionTab::Beginning));
bool firstTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::Beginning) || (rtlHorTabs && tab->position == QStyleOptionTab::End));
bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
bool previousSelected = ((!rtlHorTabs && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected) || (rtlHorTabs && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
bool nextSelected = ((!rtlHorTabs && tab->selectedPosition == QStyleOptionTab::NextIsSelected) || (rtlHorTabs && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected));
int tabBarAlignment = styleHint(SH_TabBar_Alignment, tab, widget);
bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft) || (rtlHorTabs && tabBarAlignment == Qt::AlignRight);
bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight) || (rtlHorTabs && tabBarAlignment == Qt::AlignLeft);
QColor light = tab->palette.light().color();
QColor dark = tab->palette.dark().color();
QColor shadow = tab->palette.shadow().color();
int borderThinkness = pixelMetric(PM_TabBarBaseOverlap, tab, 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 (tab->shape) {
default:
{
p->save();
QRect rect(tab->rect);
int tabOverlap = onlyOne ? 0 : pixelMetric(PM_TabBarTabOverlap, option, widget);
if (!selected) {
switch (tab->shape) {
case QTabBar::TriangularNorth:
rect.adjust(0, 0, 0, -tabOverlap);
if(!selected) rect.adjust(1, 1, -1, 0);
break;
case QTabBar::TriangularSouth:
rect.adjust(0, tabOverlap, 0, 0);
if(!selected) rect.adjust(1, 0, -1, -1);
break;
case QTabBar::TriangularEast:
rect.adjust(tabOverlap, 0, 0, 0);
if(!selected) rect.adjust(0, 1, -1, -1);
break;
case QTabBar::TriangularWest:
rect.adjust(0, 0, -tabOverlap, 0);
if(!selected) rect.adjust(1, 1, 0, -1);
break;
default:
break;
}
}
p->setPen(QPen(tab->palette.foreground(), 0));
if (selected) {
p->setBrush(tab->palette.background());
} else {
if (widget && widget->parentWidget()) {
p->setBrush(widget->parentWidget()->palette().shadow());
} else {
p->setBrush(tab->palette.shadow());
}
}
int y;
int x;
QPolygon a(10);
switch (tab->shape) {
case QTabBar::TriangularNorth:
case QTabBar::TriangularSouth:
{
a.setPoint(0, 0, -1);
a.setPoint(1, 0, 0);
y = rect.height() - 2;
x = y / 3;
a.setPoint(2, x++, y - 1);
++x;
a.setPoint(3, x++, y++);
a.setPoint(4, x, y);
int i;
int right = rect.width() - 1;
for (i = 0; i < 5; ++i) {
a.setPoint(9 - i, right - a.point(i).x(), a.point(i).y());
}
if (tab->shape == QTabBar::TriangularNorth) {
for (i = 0; i < 10; ++i) {
a.setPoint(i, a.point(i).x(), rect.height() - 1 - a.point(i).y());
}
}
a.translate(rect.left(), rect.top());
p->setRenderHint(QPainter::Antialiasing);
p->translate(0, 0.5);
QPainterPath path;
path.addPolygon(a);
p->drawPath(path);
break;
}
case QTabBar::TriangularEast:
case QTabBar::TriangularWest:
{
a.setPoint(0, -1, 0);
a.setPoint(1, 0, 0);
x = rect.width() - 2;
y = x / 3;
a.setPoint(2, x - 1, y++);
++y;
a.setPoint(3, x++, y++);
a.setPoint(4, x, y);
int i;
int bottom = rect.height() - 1;
for (i = 0; i < 5; ++i) {
a.setPoint(9 - i, a.point(i).x(), bottom - a.point(i).y());
}
if (tab->shape == QTabBar::TriangularWest) {
for (i = 0; i < 10; ++i) {
a.setPoint(i, rect.width() - 1 - a.point(i).x(), a.point(i).y());
}
}
a.translate(rect.left(), rect.top());
p->setRenderHint(QPainter::Antialiasing);
p->translate(0.5, 0);
QPainterPath path;
path.addPolygon(a);
p->drawPath(path);
break;
}
default:
break;
}
p->restore();
}
break;
case QTabBar::RoundedNorth:
{
if (!selected) {
y1 += 2;
x1 += onlyOne || firstTab ? borderThinkness : 0;
x2 -= onlyOne || lastTab ? borderThinkness : 0;
}
p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background());
// Delete border
if (selected) {
p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.background());
p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.background());
}
// Left
if (firstTab || selected || onlyOne || !previousSelected) {
p->setPen(light);
p->drawLine(x1, y1 + 2, x1, y2 - ((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 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
p->drawPoint(x2 - 1, y1 + 1);
p->setPen(dark);
p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
}
break;
}
case QTabBar::RoundedSouth:
{
if (!selected) {
y2 -= 2;
x1 += firstTab ? borderThinkness : 0;
x2 -= lastTab ? borderThinkness : 0;
}
p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
// Delete border
if (selected) {
p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.background());
p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->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);
p->setPen(dark);
p->drawLine(beg, y2 - 1, end, y2 - 1);
}
// 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);
p->setPen(dark);
p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
}
break;
}
case QTabBar::RoundedWest:
{
if (!selected) {
x1 += 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background());
// Delete border
if (selected) {
p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.background());
p->fillRect(QRect(x2, y1, 1, y2-y1), tab->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 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
p->drawPoint(x1 + 2, y2 - 1);
p->setPen(dark);
p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
p->drawPoint(x1 + 1, y2 - 1);
p->drawPoint(x1 + 2, y2);
}
break;
}
case QTabBar::RoundedEast:
{
if (!selected) {
x2 -= 2;
y1 += firstTab ? borderThinkness : 0;
y2 -= lastTab ? borderThinkness : 0;
}
p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
// Delete border
if (selected) {
p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.background());
p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.background());
}
// Top
if (firstTab || selected || onlyOne || !previousSelected) {
p->setPen(light);
p->drawLine(x2 - 2, y1, x1 + ((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);
p->setPen(dark);
p->drawLine(x2 - 1, beg, x2 - 1, end);
}
// Bottom
if (lastTab || selected || onlyOne || !nextSelected) {
p->setPen(shadow);
p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
p->drawPoint(x2 - 1, y2 - 1);
p->setPen(dark);
p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
}
break;
}
}
}
return;
}
if (ce == CE_ProgressBarGroove || ce == CE_ProgressBarContents) {
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ if (const auto *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
QColor color(0, 128, 255);
- QImage const *image = &m->progress_horz;
+ bool horz = (bar->orientation == Qt::Horizontal);
- QString key = "horz";
+ QString key;
+ QImage const *image;
- bool horz = true;
- if (bar->orientation == Qt::Vertical) {
- image = &m->progress_vert;
+ if (horz) {
+ key = "horz";
+ image = &m->progress_horz;
+ } else {
key = "vert";
- horz = false;
+ 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 = bar->progress - bar->minimum;
int div = bar->maximum - bar->minimum;
bool inv = bar->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) {
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);
+ 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 (ce == CE_HeaderSection) {
if (option->state & QStyle::State_MouseOver) {
p->save();
p->fillRect(x, y, w, h, QColor(255, 255, 255, 32));
p->restore();
}
}
return;
}
#ifdef Q_OS_MAC
if (ce == CE_DockWidgetTitle) {
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
- const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget);
+ if (const auto *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ const auto *dockWidget = qobject_cast<const QDockWidget *>(widget);
QRect rect = option->rect;
if (dockWidget && dockWidget->isFloating()) {
QProxyStyle::drawControl(ce, option, p, widget);
return;
}
- const QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+ const auto *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ 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, dwOpt, widget);
int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
- const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
- bool isFloating = dw != 0 && dw->isFloating();
+ const auto *dw = qobject_cast<const QDockWidget *>(widget);
+ bool isFloating = dw && dw->isFloating();
QRect r = option->rect.adjusted(0, 2, -1, -3);
QRect titleRect = r;
if (dwOpt->closable) {
QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
}
if (dwOpt->floatable) {
QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
}
if (isFloating) {
titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ if (widget && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) {
titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+ }
} else {
titleRect.adjust(mw, 0, 0, 0);
- if (!dwOpt->floatable && !dwOpt->closable)
+ if (!dwOpt->floatable && !dwOpt->closable) {
titleRect.adjust(0, 0, -mw, 0);
+ }
}
- if (!verticalTitleBar)
+ if (!verticalTitleBar) {
titleRect = visualRect(dwOpt->direction, r, titleRect);
+ }
if (!dwOpt->title.isEmpty()) {
QString titleText = p->fontMetrics().elidedText(dwOpt->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, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText,
- QPalette::WindowText);
+ drawItemText(p, rect.adjusted(indent + 1, 1, -indent - 1, -1), align, dwOpt->palette, dwOpt->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
// 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 (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ if (const auto *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
SubControls sub = option->subControls;
if (cmb->editable) {
- int partId = 0;
-// int stateId = 0;
#define EP_EDITBORDER_NOSCROLL 6
#define EP_EDITBORDER_HVSCROLL 9
- State flags = option->state;
if (sub & SC_ComboBoxEditField) {
- partId = EP_EDITBORDER_NOSCROLL;
-// if (!(flags & State_Enabled))
-// stateId = ETS_DISABLED;
-// else if (flags & State_MouseOver)
-// stateId = ETS_HOT;
-// else if (flags & State_HasFocus)
-// stateId = ETS_FOCUSED;
-// else
-// stateId = ETS_NORMAL;
-
-// XPThemeData theme(widget, painter,
-// QWindowsXPStylePrivate::EditTheme,
-// partId, stateId, r);
-
-// d->drawBackground(theme);
p->fillRect(option->rect, option->palette.color(QPalette::Dark));
drawFrame(p, option->rect, option->palette.color(QPalette::Shadow), option->palette.color(QPalette::Light));
-// drawFrame(p, option->rect, option->palette.color(QPalette::Dark), option->palette.color(QPalette::Light));
}
if (sub & SC_ComboBoxArrow) {
QRect subRect = subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
-// XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
-// theme.rect = subRect;
-// partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
-
-// if (!(cmb->state & State_Enabled))
-// stateId = CBXS_DISABLED;
-// else if (cmb->state & State_Sunken || cmb->state & State_On)
-// stateId = CBXS_PRESSED;
-// else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
-// stateId = CBXS_HOT;
-// else
-// stateId = CBXS_NORMAL;
-
-// theme.partId = partId;
-// theme.stateId = stateId;
-// d->drawBackground(theme);
QStyleOptionComplex opt = *option;
-// p->fillRect(subRect, Qt::blue);
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 (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ if (const auto *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
QRect button, menuarea;
button = subControlRect(cc, toolbutton, SC_ToolButton, widget);
menuarea = subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
State bflags = toolbutton->state & ~State_Sunken;
State mflags = bflags;
bool autoRaise = flags & State_AutoRaise;
if (autoRaise) {
if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
bflags &= ~State_Raised;
}
}
if (toolbutton->state & State_Sunken) {
if (toolbutton->activeSubControls & SC_ToolButton) {
bflags |= State_Sunken;
mflags |= State_MouseOver | State_Sunken;
} else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
mflags |= State_Sunken;
bflags |= State_MouseOver;
}
}
QStyleOption tool(0);
tool.palette = toolbutton->palette;
if (toolbutton->subControls & SC_ToolButton) {
if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
tool.rect = option->rect;
tool.state = bflags;
drawToolButton(p, &tool);
}
}
if (toolbutton->state & State_HasFocus) {
QStyleOptionFocusRect fr;
fr.QStyleOption::operator=(*toolbutton);
fr.rect.adjust(3, 3, -3, -3);
if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) {
fr.rect.adjust(0, 0, -pixelMetric(QStyle::PM_MenuButtonIndicator, toolbutton, widget), 0);
}
drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
}
QStyleOptionToolButton label = *toolbutton;
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 (toolbutton->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 (toolbutton->features & QStyleOptionToolButton::HasMenu) {
int mbi = pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
QRect ir = toolbutton->rect;
QStyleOptionToolButton newBtn = *toolbutton;
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);
- ScrollBarTextures *tx = const_cast<ScrollBarTextures *>(ishorz ? &m->hsb : &m->vsb);
+ 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 (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ if (const auto *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
QStyleOptionFrame frame;
frame.QStyleOption::operator=(*groupBox);
frame.features = groupBox->features;
frame.lineWidth = groupBox->lineWidth;
frame.midLineWidth = groupBox->midLineWidth;
frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
p->save();
QRegion region(groupBox->rect);
if (!groupBox->text.isEmpty()) {
bool ltr = groupBox->direction == Qt::LeftToRight;
QRect finalRect;
if (groupBox->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 ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
QColor textColor = groupBox->textColor;
if (textColor.isValid()) {
p->setPen(textColor);
}
int alignment = int(groupBox->textAlignment);
if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) {
alignment |= Qt::TextHideMnemonic;
}
drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, groupBox->palette, groupBox->state & State_Enabled, groupBox->text, QPalette::WindowText);
if (groupBox->state & State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*groupBox);
fropt.rect = textRect;
drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
}
// Draw checkbox
if (groupBox->subControls & SC_GroupBoxCheckBox) {
QStyleOptionButton box;
box.QStyleOption::operator=(*groupBox);
box.rect = checkBoxRect;
drawPrimitive(PE_IndicatorCheckBox, &box, p, widget);
}
}
return;
}
if (cc == CC_Slider) {
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ if (const auto *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
bool horizontal = slider->orientation == Qt::Horizontal;
bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
bool ticksBelow = slider->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;
+ double r = std::min(groove.width(), groove.height()) / 2.0;
{
double n = r * 3 / 4;
- grooveRect = rect.adjusted(n, n, -n, -n);
+ 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, slider, widget);
int interval = slider->tickInterval;
if (interval <= 0) {
interval = slider->singleStep;
if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, available) - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, 0, available) < 3) {
interval = slider->pageStep;
}
}
if (interval <= 0) {
interval = 1;
}
int v = slider->minimum;
int len = pixelMetric(PM_SliderLength, slider, widget);
while (v <= slider->maximum + 1) {
if (v == slider->maximum + 1 && interval == 1) break;
const int v2 = qMin(v, slider->maximum);
int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
v2, (horizontal
? slider->rect.width()
: slider->rect.height()) - len,
slider->upsideDown) + len / 2;
int extra = 2 - ((v2 == slider->minimum || v2 == slider->maximum) ? 1 : 0);
if (horizontal) {
if (ticksAbove) {
p->setPen(color(128));
p->drawLine(pos, slider->rect.top() + extra, pos, slider->rect.top() + tickSize);
}
if (ticksBelow) {
p->setPen(color(0));
p->drawLine(pos, slider->rect.bottom() - extra, pos, slider->rect.bottom() - tickSize);
}
} else {
if (ticksAbove) {
p->setPen(color(128));
p->drawLine(slider->rect.left() + extra, pos, slider->rect.left() + tickSize, pos);
}
if (ticksBelow) {
p->setPen(color(0));
p->drawLine(slider->rect.right() - extra, pos, slider->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/src/darktheme/DarkStyle.h b/src/darktheme/DarkStyle.h
index 6ab5f2b..faa0b77 100644
--- a/src/darktheme/DarkStyle.h
+++ b/src/darktheme/DarkStyle.h
@@ -1,59 +1,59 @@
#ifndef DARKSTYLE_H
#define DARKSTYLE_H
#include <QPainter>
#include <QProxyStyle>
class DarkStyle : public QProxyStyle {
public:
private:
struct Private;
Private *m;
class ButtonImages {
public:
QImage im_normal;
QImage im_hover;
};
struct ScrollBarTextures {
QImage page_bg;
ButtonImages sub_line;
ButtonImages add_line;
ButtonImages slider;
};
QImage colorizeImage(QImage image);
QImage loadColorizedImage(const QString &path, const QString &role = QString());
ButtonImages generateButtonImages(const QString &path);
QImage generateHoverImage(const QImage &source);
QPixmap pixmapFromImage(QImage const &image, QSize size) const;
void loadImages();
QColor colorForSelectedFrame(QStyleOption const *opt) const;
QColor colorForItemView(QStyleOption const *opt) const;
void drawNinePatchImage(QPainter *p, QImage const &image, QRect const &r, int w, int h) const;
void drawGutter(QPainter *p, QRect const &r) const;
- void drawSelectedMenuFrame(const QStyleOption *option, QPainter *p, QRect rect, QWidget const *widget, bool deep) const;
+ void drawSelectedMenuFrame(const QStyleOption *option, QPainter *p, QRect rect, QWidget const *widget, bool deep = false) const;
void drawButton(QPainter *p, QStyleOption const *option) const;
void drawToolButton(QPainter *p, QStyleOption const *option) const;
void drawMenuBarBG(QPainter *p, const QStyleOption *option, const QWidget *widget) const;
QColor color(int level, int alpha = 255) const;
public:
- DarkStyle(QColor base_color = QColor());
- ~DarkStyle();
+ DarkStyle(const QColor &base_color = QColor());
+ ~DarkStyle() override;
QColor getBaseColor();
- void setBaseColor(QColor color);
+ void setBaseColor(const QColor &color);
void setScrollBarExtent(int n);
- void polish(QPalette &palette);
- int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const;
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, const QWidget *widget) const;
- void drawControl(ControlElement ce, const QStyleOption *option, QPainter *p, const QWidget *widget) const;
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p, const QWidget *widget) const;
+ void polish(QPalette &palette) override;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const override;
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, const QWidget *widget) const override;
+ void drawControl(ControlElement ce, const QStyleOption *option, QPainter *p, const QWidget *widget) const override;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p, const QWidget *widget) const override;
};
#endif // DARKSTYLE_H
diff --git a/src/darktheme/NinePatch.cpp b/src/darktheme/NinePatch.cpp
index 84a029e..9ac30f0 100644
--- a/src/darktheme/NinePatch.cpp
+++ b/src/darktheme/NinePatch.cpp
@@ -1,139 +1,133 @@
#include "NinePatch.h"
#include <QPainter>
#include <vector>
-#include <math.h>
+#include <cmath>
struct Part {
- bool stretchable;
- int pos;
- int len;
- Part()
- : stretchable(false)
- , pos(0)
- , len(0)
- {
- }
+ bool stretchable = false;
+ int pos = 0;
+ int len = 0;
+ Part() = default;
Part(int pos, int len, bool stretchable)
: stretchable(stretchable)
, pos(pos)
, len(len)
{
}
};
static inline bool isStretchableMarker(QRgb pixel)
{
return (qAlpha(pixel) >> 7) & 1;
}
static QImage resize9patch(QImage const &image, int dw, int dh)
{
int sw = image.width();
int sh = image.height();
if (sw > 2 && sh > 2 && dw > 0 && dh > 0) {
QImage newimage(dw, dh, image.format());
newimage.fill(Qt::transparent);
QPainter pr(&newimage);
pr.setRenderHint(QPainter::SmoothPixmapTransform);
std::vector<Part> horz;
std::vector<Part> vert;
int horz_stretch = 0;
int vert_stretch = 0;
{
int pos;
QRgb last;
QRgb next;
pos = 0;
last = image.pixel(1, 0);
for (int x = 1; x < sw - 1; x++) {
next = image.pixel(x + 1, 0);
if (isStretchableMarker(last) != isStretchableMarker(next) || x == sw - 2) {
bool stretchable = isStretchableMarker(last);
int len = x - pos;
- horz.push_back(Part(pos, len, stretchable));
+ horz.emplace_back(pos, len, stretchable);
if (stretchable) horz_stretch += len;
last = next;
pos = x;
}
}
pos = 0;
last = image.pixel(0, 1);
for (int y = 1; y < sh - 1; y++) {
next = image.pixel(0, y + 1);
if (isStretchableMarker(last) != isStretchableMarker(next) || y == sh - 2) {
bool stretchable = isStretchableMarker(last);
int len = y - pos;
- vert.push_back(Part(pos, len, stretchable));
+ vert.emplace_back(pos, len, stretchable);
if (stretchable) vert_stretch += len;
last = next;
pos = y;
}
}
}
double horz_mul = 0;
double vert_mul = 0;
if (horz_stretch > 0) horz_mul = (double)(dw - (sw - 2 - horz_stretch)) / horz_stretch;
if (vert_stretch > 0) vert_mul = (double)(dh - (sh - 2 - vert_stretch)) / vert_stretch;
int dy0 = 0;
int dy1 = 0;
double vstretch = 0;
for (int i = 0; i < (int)vert.size(); i++) {
int sy0 = vert[i].pos;
int sy1 = vert[i].pos + vert[i].len;
if (i + 1 == (int)vert.size()) {
dy1 = dh;
} else if (vert[i].stretchable) {
vstretch += (double)vert[i].len * vert_mul;
double s = floor(vstretch);
vstretch -= s;
dy1 += (int)s;
} else {
dy1 += vert[i].len;
}
int dx0 = 0;
int dx1 = 0;
double hstretch = 0;
for (int j = 0; j < (int)horz.size(); j++) {
int sx0 = horz[j].pos;
int sx1 = horz[j].pos + horz[j].len;
if (j + 1 == (int)horz.size()) {
dx1 = dw;
} else if (horz[j].stretchable) {
hstretch += (double)horz[j].len * horz_mul;
double s = floor(hstretch);
hstretch -= s;
dx1 += (int)s;
} else {
dx1 += horz[j].len;
}
pr.drawImage(QRect(dx0, dy0, dx1 - dx0, dy1 - dy0), image, QRect(sx0 + 1, sy0 + 1, sx1 - sx0, sy1 - sy0));
dx0 = dx1;
}
dy0 = dy1;
}
return newimage;
}
return QImage();
}
QImage createImageFromNinePatchImage(QImage const &image, int dw, int dh)
{
int w = dw;
int h = dh;
if (w < image.width() || h < image.height()) { // shrink
if (w < image.width()) w = image.width();
if (h < image.height()) h = image.height();
QImage pm1 = resize9patch(image, w, h);
if (pm1.isNull()) return QImage();
QImage pm2(dw, dh, image.format());
pm2.fill(Qt::transparent);
QPainter pr(&pm2);
pr.setRenderHint(QPainter::SmoothPixmapTransform);
pr.drawImage(QRect(0, 0, dw, dh), pm1, QRect(0, 0, w, h));
return pm2;
- } else {
- return resize9patch(image, w, h);
}
+ return resize9patch(image, w, h);
}
diff --git a/src/darktheme/NinePatch.h b/src/darktheme/NinePatch.h
index f9f32e0..666d269 100644
--- a/src/darktheme/NinePatch.h
+++ b/src/darktheme/NinePatch.h
@@ -1,9 +1,8 @@
#ifndef NINEPATCH_H
#define NINEPATCH_H
#include <QImage>
-#include <QPixmap>
QImage createImageFromNinePatchImage(QImage const &image, int dw, int dh);
#endif // NINEPATCH_H
diff --git a/src/darktheme/TraditionalWindowsStyleTreeControl.cpp b/src/darktheme/TraditionalWindowsStyleTreeControl.cpp
index c389036..86b8d13 100644
--- a/src/darktheme/TraditionalWindowsStyleTreeControl.cpp
+++ b/src/darktheme/TraditionalWindowsStyleTreeControl.cpp
@@ -1,87 +1,87 @@
#include "TraditionalWindowsStyleTreeControl.h"
#include <QStyleOption>
#include <QPainter>
#include <QDebug>
static unsigned char plus_image[9][9] = {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
};
static unsigned char minus_image[9][9] = {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
};
TraditionalWindowsStyleTreeControl::TraditionalWindowsStyleTreeControl()
{
// create brush
{
QImage img(2, 2, QImage::Format_RGB32);
QRgb *p;
QRgb t = qRgb(0xff, 0xff, 0xff);
QRgb u = qRgb(0x80, 0x80, 0x80);
- p = (QRgb *)img.scanLine(0);
+ p = reinterpret_cast<QRgb *>(img.scanLine(0));
p[0] = u;
p[1] = t;
- p = (QRgb *)img.scanLine(1);
+ p = reinterpret_cast<QRgb *>(img.scanLine(1));
p[0] = t;
p[1] = u;
br_branch = QBrush(img);
}
// create open/close buttons
QImage img_plus(9, 9, QImage::Format_RGB32);
QImage img_minus(9, 9, QImage::Format_RGB32);
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
unsigned char v;
v = plus_image[y][x];
- ((QRgb *)img_plus.scanLine(y))[x] = qRgb(v, v, v);
+ reinterpret_cast<QRgb *>(img_plus.scanLine(y))[x] = qRgb(v, v, v);
v = minus_image[y][x];
- ((QRgb *)img_minus.scanLine(y))[x] = qRgb(v, v, v);
+ reinterpret_cast<QRgb *>(img_minus.scanLine(y))[x] = qRgb(v, v, v);
}
}
pm_plus = QPixmap::fromImage(img_plus);
pm_minus = QPixmap::fromImage(img_minus);
}
bool TraditionalWindowsStyleTreeControl::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *) const
{
if (element == QStyle::PE_IndicatorBranch) {
int ox = option->rect.x() + option->rect.width() / 2;
int oy = option->rect.y() + option->rect.height() / 2;
if (option->state & QStyle::State_Item) {
painter->fillRect(ox, oy, option->rect.right() - ox + 1, 1, br_branch);
}
if (option->state & QStyle::State_Sibling) {
painter->fillRect(ox, oy, 1, option->rect.bottom() - oy + 1, br_branch);
}
if (option->state & (QStyle::State_Open | QStyle::State_Children | QStyle::State_Item | QStyle::State_Sibling)) {
painter->fillRect(ox, option->rect.y(), 1, oy - option->rect.y(), br_branch);
}
if (option->state & QStyle::State_Children) {
if (option->state & QStyle::State_Open) {
painter->drawPixmap(ox - 4, oy - 4, pm_minus);
} else {
painter->drawPixmap(ox - 4, oy - 4, pm_plus);
}
}
return true;
}
return false;
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 16, 12:23 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71419
Default Alt Text
(121 KB)

Event Timeline