diff --git a/.gitmodules b/.gitmodules index f20fc3b..d324edc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "dependencies/vmprofiler"] path = dependencies/vmprofiler url = https://githacks.org/vmp2/vmprofiler.git -[submodule "dependencies/DarkStyle"] - path = dependencies/DarkStyle - url = https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle.git [submodule "dependencies/ia32-doc"] path = dependencies/ia32-doc url = https://github.com/wbenny/ia32-doc.git diff --git a/dependencies/DarkStyle b/dependencies/DarkStyle deleted file mode 160000 index 79425f5..0000000 --- a/dependencies/DarkStyle +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 79425f53ef154ea33faf4e2964f5762645b54d91 diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index e95ef25..c8ff24a 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit e95ef2537184639e89a4dbbd38355a11ffc46bac +Subproject commit c8ff24a8b44466dd2a9e2e342c83774b61004eb5 diff --git a/src/darkstyle/.gitignore b/src/darkstyle/.gitignore new file mode 100644 index 0000000..8e83ba7 --- /dev/null +++ b/src/darkstyle/.gitignore @@ -0,0 +1,40 @@ +# C++ objects and libs + +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.dll +*.dylib + +# Qt-es + +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +Makefile* +*build-* + +# QtCreator + +*.autosave + +# QtCtreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCtreator CMake +CMakeLists.txt.user* + +.directory diff --git a/src/darkstyle/DarkStyle.cpp b/src/darkstyle/DarkStyle.cpp new file mode 100644 index 0000000..8b31bf7 --- /dev/null +++ b/src/darkstyle/DarkStyle.cpp @@ -0,0 +1,73 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#include "DarkStyle.h" + +DarkStyle::DarkStyle() : DarkStyle(styleBase()) {} + +DarkStyle::DarkStyle(QStyle *style) : QProxyStyle(style) {} + +QStyle *DarkStyle::styleBase(QStyle *style) const { + static QStyle *base = + !style ? QStyleFactory::create(QStringLiteral("Fusion")) : style; + return base; +} + +QStyle *DarkStyle::baseStyle() const { return styleBase(); } + +void DarkStyle::polish(QPalette &palette) { + // modify palette to dark + palette.setColor(QPalette::Window, QColor(53, 53, 53)); + palette.setColor(QPalette::WindowText, Qt::white); + palette.setColor(QPalette::Disabled, QPalette::WindowText, + QColor(127, 127, 127)); + palette.setColor(QPalette::Base, QColor(42, 42, 42)); + palette.setColor(QPalette::AlternateBase, QColor(66, 66, 66)); + palette.setColor(QPalette::ToolTipBase, Qt::white); + palette.setColor(QPalette::ToolTipText, QColor(53, 53, 53)); + palette.setColor(QPalette::Text, Qt::white); + palette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127)); + palette.setColor(QPalette::Dark, QColor(35, 35, 35)); + palette.setColor(QPalette::Shadow, QColor(20, 20, 20)); + palette.setColor(QPalette::Button, QColor(53, 53, 53)); + palette.setColor(QPalette::ButtonText, Qt::white); + palette.setColor(QPalette::Disabled, QPalette::ButtonText, + QColor(127, 127, 127)); + palette.setColor(QPalette::BrightText, Qt::red); + palette.setColor(QPalette::Link, QColor(42, 130, 218)); + palette.setColor(QPalette::Highlight, QColor(42, 130, 218)); + palette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80)); + palette.setColor(QPalette::HighlightedText, Qt::white); + palette.setColor(QPalette::Disabled, QPalette::HighlightedText, + QColor(127, 127, 127)); +} + +void DarkStyle::polish(QApplication *app) { + if (!app) return; + + // increase font size for better reading, + // setPointSize was reduced from +2 because when applied this way in Qt5, the + // font is larger than intended for some reason + QFont defaultFont = QApplication::font(); + defaultFont.setPointSize(defaultFont.pointSize() + 1); + app->setFont(defaultFont); + + // loadstylesheet + QFile qfDarkstyle(QStringLiteral(":/darkstyle/darkstyle.qss")); + if (qfDarkstyle.open(QIODevice::ReadOnly | QIODevice::Text)) { + // set stylesheet + QString qsStylesheet = QString::fromLatin1(qfDarkstyle.readAll()); + app->setStyleSheet(qsStylesheet); + qfDarkstyle.close(); + } +} diff --git a/src/darkstyle/DarkStyle.h b/src/darkstyle/DarkStyle.h new file mode 100644 index 0000000..16187d0 --- /dev/null +++ b/src/darkstyle/DarkStyle.h @@ -0,0 +1,39 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#ifndef DARKSTYLE_HPP +#define DARKSTYLE_HPP + +#include +#include +#include +#include +#include + +class DarkStyle : public QProxyStyle { + Q_OBJECT + + public: + DarkStyle(); + explicit DarkStyle(QStyle *style); + + QStyle *baseStyle() const; + + void polish(QPalette &palette) override; + void polish(QApplication *app) override; + + private: + QStyle *styleBase(QStyle *style = Q_NULLPTR) const; +}; + +#endif // DARKSTYLE_HPP diff --git a/src/darkstyle/README.md b/src/darkstyle/README.md new file mode 100644 index 0000000..6813e85 --- /dev/null +++ b/src/darkstyle/README.md @@ -0,0 +1,104 @@ +# Qt Frameless Window with DarkStyle +simple MainWindow class implementation with frameless window and custom dark style. + +It adds also support for titlebar and buttons (minimize, maximize, close) + +Look is based on the VS2013 application window (flat and frameless window) + + + + + + + + +
Screenshots
mac enabledmac disabled
+ + +## Qt and OS +* tested with Qt5.5.0, Qt5.9.0 and Qt5.10.0 +* tested on Windows 7, Windows 10,MacOSX 10.12.5 and MacOS 10.13.2 + +## PyQt5 +Here is an [unofficial Python port](https://github.com/gmarull/qtmodern) of my implementation. + +## How to use +* add additional include plath to **framelesswindow** +* add resources **framelesswindow.qrc** and **darkstyle.qrc** +* add ``#include "framelesswindow.h"`` into **main.cpp**, create window ``FramelessWindow framelessWindow;`` and assign your mainwindow object as content ``framelessWindow.setContent(mainWindow);`` and show it ``framelessWindow.show();`` +* add ``#include "DarkStyle.h"`` into **main.cpp** and call ``a.setStyle(new DarkStyle);`` + + +```qt +#include +#include "DarkStyle.h" +#include "framelesswindow.h" +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + // style our application with custom dark style + QApplication::setStyle(new DarkStyle); + //QApplication::setPalette(QApplication::style()->standardPalette()); + + // create frameless window (and set windowState or title) + FramelessWindow framelessWindow; + //framelessWindow.setWindowState(Qt::WindowMaximized); + //framelessWindow.setWindowTitle("test title"); + //framelessWindow.setWindowIcon(a.style()->standardIcon(QStyle::SP_DesktopIcon)); + + // create our mainwindow instance + MainWindow *mainWindow = new MainWindow; + + // add the mainwindow to our custom frameless window + framelessWindow.setContent(mainWindow); + framelessWindow.show(); + + return a.exec(); +} +``` + + +## features +* frameless window +* custom dark style (based on **Fusion style** with dark palette and custom stylesheets) +* title bar +* buttons (minimize | restore | maximize | close) +* move window by drag the title bar +* dobule click title bar to toggle between window styte (maximize and normal) +* use of native events, like minimizing or system menu + + +## todo +* [ ] [resize window on each corner [#1]](https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle/issues/1) (some work done by [notecola](https://github.com/notecola) :+1:) +* [ ] [snap on screen edges [#3]](https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle/issues/3) + + +## thanks +Many thanks goes to the [Qt Forum](https://forum.qt.io/topic/80654/how-to-create-vs2013-like-frameless-window-with-dark-style) and especially to [Chris Kawa](https://forum.qt.io/user/chris-kawa) for pointing me to some usual issues and hints of great must have features. + + +## Licence +> The MIT License +> +> Copyright (c) 2018, Juergen Skrotzky (https://github.com/Jorgen-VikingGod, JorgenVikingGod@gmail.com) +> +> 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. diff --git a/src/darkstyle/darkstyle.qrc b/src/darkstyle/darkstyle.qrc new file mode 100644 index 0000000..1bcbdf7 --- /dev/null +++ b/src/darkstyle/darkstyle.qrc @@ -0,0 +1,28 @@ + + + darkstyle/darkstyle.qss + darkstyle/icon_close.png + darkstyle/icon_restore.png + darkstyle/icon_undock.png + darkstyle/icon_branch_closed.png + darkstyle/icon_branch_end.png + darkstyle/icon_branch_more.png + darkstyle/icon_branch_open.png + darkstyle/icon_vline.png + darkstyle/icon_checkbox_checked.png + darkstyle/icon_checkbox_indeterminate.png + darkstyle/icon_checkbox_unchecked.png + darkstyle/icon_checkbox_checked_pressed.png + darkstyle/icon_checkbox_indeterminate_pressed.png + darkstyle/icon_checkbox_unchecked_pressed.png + darkstyle/icon_checkbox_checked_disabled.png + darkstyle/icon_checkbox_indeterminate_disabled.png + darkstyle/icon_checkbox_unchecked_disabled.png + darkstyle/icon_radiobutton_checked.png + darkstyle/icon_radiobutton_unchecked.png + darkstyle/icon_radiobutton_checked_pressed.png + darkstyle/icon_radiobutton_unchecked_pressed.png + darkstyle/icon_radiobutton_checked_disabled.png + darkstyle/icon_radiobutton_unchecked_disabled.png + + diff --git a/src/darkstyle/darkstyle/darkstyle.qss b/src/darkstyle/darkstyle/darkstyle.qss new file mode 100644 index 0000000..44e5c68 --- /dev/null +++ b/src/darkstyle/darkstyle/darkstyle.qss @@ -0,0 +1,343 @@ +QToolTip{ + color:#ffffff; + background-color:palette(base); + border:1px solid palette(highlight); + border-radius:4px; +} +QStatusBar{ + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + color:palette(mid); +} +QMenuBar{ + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-bottom:2px solid rgba(25,25,25,75); +} +QMenuBar::item{ + spacing:2px; + padding:3px 4px; + background:transparent; +} +QMenuBar::item:selected{ + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(106,106,106,255),stop:1 rgba(106,106,106,75)); + border-left:1px solid rgba(106,106,106,127); + border-right:1px solid rgba(106,106,106,127); +} +QMenuBar::item:pressed{ + background-color:palette(highlight); + border-left:1px solid rgba(25,25,25,127); + border-right:1px solid rgba(25,25,25,127); +} +QMenu{ + background-color:palette(window); + border:1px solid palette(shadow); +} +QMenu::item{ + padding:3px 25px 3px 25px; + border:1px solid transparent; +} +QMenu::item:disabled{ + background-color:rgba(35,35,35,127); + color:palette(disabled); +} +QMenu::item:selected{ + border-color:rgba(147,191,236,127); + background:palette(highlight); +} +QMenu::icon:checked{ + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border:1px solid palette(highlight); + border-radius:2px; +} +QMenu::separator{ + height:1px; + background:palette(alternate-base); + margin-left:5px; + margin-right:5px; +} +QMenu::indicator{ + width:18px; + height:18px; +} +QMenu::indicator:non-exclusive:checked{ + image:url(:/darkstyle/icon_checkbox_checked.png); + padding-left:2px; +} +QMenu::indicator:non-exclusive:unchecked{ + image:url(:/darkstyle/icon_checkbox_unchecked.png); + padding-left:2px; +} +QMenu::indicator:exclusive:checked{ + image:url(:/darkstyle/icon_radiobutton_checked.png); + padding-left:2px; +} +QMenu::indicator:exclusive:unchecked{ + image:url(:/darkstyle/icon_radiobutton_unchecked.png); + padding-left:2px; +} +QToolBar::top{ + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-bottom:3px solid qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); +} +QToolBar::bottom{ + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-top:3px solid qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); +} +QToolBar::left{ + background-color:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-right:3px solid qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); +} +QToolBar::right{ + background-color:qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-left:3px solid qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); +} +QMainWindow::separator{ + width:6px; + height:5px; + padding:2px; +} +QSplitter::handle:horizontal{ + width:10px; +} +QSplitter::handle:vertical{ + height:10px; +} +QMainWindow::separator:hover,QSplitter::handle:hover{ + background:palette(highlight); +} +QDockWidget::title{ + padding:4px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border:1px solid rgba(25,25,25,75); + border-bottom:2px solid rgba(25,25,25,75); +} +QDockWidget{ + titlebar-close-icon:url(:/darkstyle/icon_close.png); + titlebar-normal-icon:url(:/darkstyle/icon_restore.png); +} +QDockWidget::close-button,QDockWidget::float-button{ + subcontrol-position:top right; + subcontrol-origin:margin; + position:absolute; + top:3px; + bottom:0px; + width:20px; + height:20px; +} +QDockWidget::close-button{ + right:3px; +} +QDockWidget::float-button{ + right:25px; +} +QGroupBox{ + background-color:rgba(66,66,66,50%); + margin-top:27px; + border:1px solid rgba(25,25,25,127); + border-radius:4px; +} +QGroupBox::title{ + subcontrol-origin:margin; + subcontrol-position:left top; + padding:4px 6px; + margin-left:3px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border:1px solid rgba(25,25,25,75); + border-bottom:2px solid rgb(127,127,127); + border-top-left-radius:4px; + border-top-right-radius:4px; +} +QTabWidget::pane{ + background-color:rgba(66,66,66,50%); + border-top:1px solid rgba(25,25,25,50%); +} +QTabWidget::tab-bar{ + left:3px; + top:1px; +} +QTabBar{ + background-color:transparent; + qproperty-drawBase:0; + border-bottom:1px solid rgba(25,25,25,50%); +} +QTabBar::tab{ + padding:4px 6px; + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border:1px solid rgba(25,25,25,75); + border-top-left-radius:4px; + border-top-right-radius:4px; +} +QTabBar::tab:selected,QTabBar::tab:hover{ + background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(53,53,53,127),stop:1 rgba(66,66,66,50%)); + border-bottom-color:rgba(66,66,66,75%); +} +QTabBar::tab:selected{ + border-bottom:2px solid palette(highlight); +} +QTabBar::tab::selected:disabled{ + border-bottom:2px solid rgb(127,127,127); +} +QTabBar::tab:!selected{ + margin-top:2px; +} +QCheckBox::indicator{ + width:18px; + height:18px; +} +QCheckBox::indicator:checked,QTreeView::indicator:checked,QTableView::indicator:checked,QGroupBox::indicator:checked{ + image:url(:/darkstyle/icon_checkbox_checked.png); +} +QCheckBox::indicator:checked:pressed,QTreeView::indicator:checked:pressed,QTableView::indicator:checked:pressed,QGroupBox::indicator:checked:pressed{ + image:url(:/darkstyle/icon_checkbox_checked_pressed.png); +} +QCheckBox::indicator:checked:disabled,QTreeView::indicator:checked:disabled,QTableView::indicator:checked:disabled,QGroupBox::indicator:checked:disabled{ + image:url(:/darkstyle/icon_checkbox_checked_disabled.png); +} +QCheckBox::indicator:unchecked,QTreeView::indicator:unchecked,QTableView::indicator:unchecked,QGroupBox::indicator:unchecked{ + image:url(:/darkstyle/icon_checkbox_unchecked.png); +} +QCheckBox::indicator:unchecked:pressed,QTreeView::indicator:unchecked:pressed,QTableView::indicator:unchecked:pressed,QGroupBox::indicator:unchecked:pressed{ + image:url(:/darkstyle/icon_checkbox_unchecked_pressed.png); +} +QCheckBox::indicator:unchecked:disabled,QTreeView::indicator:unchecked:disabled,QTableView::indicator:unchecked:disabled,QGroupBox::indicator:unchecked:disabled{ + image:url(:/darkstyle/icon_checkbox_unchecked_disabled.png); +} +QCheckBox::indicator:indeterminate,QTreeView::indicator:indeterminate,QTableView::indicator:indeterminate,QGroupBox::indicator:indeterminate{ + image:url(:/darkstyle/icon_checkbox_indeterminate.png); +} +QCheckBox::indicator:indeterminate:pressed,QTreeView::indicator:indeterminate:pressed,QTableView::indicator:indeterminate:pressed,QGroupBox::indicator:indeterminate:pressed{ + image:url(:/darkstyle/icon_checkbox_indeterminate_pressed.png); +} +QCheckBox::indicator:indeterminate:disabled,QTreeView::indicator:indeterminate:disabled,QTableView::indicator:indeterminate:disabled,QGroupBox::indicator:indeterminate:disabled{ + image:url(:/darkstyle/icon_checkbox_indeterminate_disabled.png); +} +QRadioButton::indicator{ + width:18px; + height:18px; +} +QRadioButton::indicator:checked{ + image:url(:/darkstyle/icon_radiobutton_checked.png); +} +QRadioButton::indicator:checked:pressed{ + image:url(:/darkstyle/icon_radiobutton_checked_pressed.png); +} +QRadioButton::indicator:checked:disabled{ + image:url(:/darkstyle/icon_radiobutton_checked_disabled.png); +} +QRadioButton::indicator:unchecked{ + image:url(:/darkstyle/icon_radiobutton_unchecked.png); +} +QRadioButton::indicator:unchecked:pressed{ + image:url(:/darkstyle/icon_radiobutton_unchecked_pressed.png); +} +QRadioButton::indicator:unchecked:disabled{ + image:url(:/darkstyle/icon_radiobutton_unchecked_disabled.png); +} +QTreeView, QTableView{ + alternate-background-color:palette(window); + background:palette(base); +} +QTreeView QHeaderView::section, QTableView QHeaderView::section{ + background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); + border-style:none; + border-bottom:1px solid palette(dark); + padding-left:5px; + padding-right:5px; +} +QTreeView::item:selected:disabled, QTableView::item:selected:disabled{ + background:rgb(80,80,80); +} +QTreeView::branch{ + background-color:palette(base); +} +QTreeView::branch:has-siblings:!adjoins-item{ + border-image:url(:/darkstyle/icon_vline.png) 0; +} +QTreeView::branch:has-siblings:adjoins-item{ + border-image:url(:/darkstyle/icon_branch_more.png) 0; +} +QTreeView::branch:!has-children:!has-siblings:adjoins-item{ + border-image:url(:/darkstyle/icon_branch_end.png) 0; +} +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings{ + border-image:none; + image:url(:/darkstyle/icon_branch_closed.png); +} +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings{ + border-image:none; + image:url(:/darkstyle/icon_branch_open.png); +} +QScrollBar:vertical{ + background:palette(base); + border-top-right-radius:2px; + border-bottom-right-radius:2px; + width:16px; + margin:0px; +} +QScrollBar::handle:vertical{ + background-color:palette(alternate-base); + border-radius:2px; + min-height:20px; + margin:2px 4px 2px 4px; +} +QScrollBar::handle:vertical:hover{ + background-color:palette(highlight); +} +QScrollBar::add-line:vertical{ + background:none; + height:0px; + subcontrol-position:right; + subcontrol-origin:margin; +} +QScrollBar::sub-line:vertical{ + background:none; + height:0px; + subcontrol-position:left; + subcontrol-origin:margin; +} +QScrollBar:horizontal{ + background:palette(base); + height:16px; + margin:0px; +} +QScrollBar::handle:horizontal{ + background-color:palette(alternate-base); + border-radius:2px; + min-width:20px; + margin:4px 2px 4px 2px; +} +QScrollBar::handle:horizontal:hover{ + background-color:palette(highlight); +} +QScrollBar::add-line:horizontal{ + background:none; + width:0px; + subcontrol-position:bottom; + subcontrol-origin:margin; +} +QScrollBar::sub-line:horizontal{ + background:none; + width:0px; + subcontrol-position:top; + subcontrol-origin:margin; +} +QSlider::handle:horizontal{ + border-radius:4px; + border:1px solid rgba(25,25,25,255); + background-color:palette(alternate-base); + min-height:20px; + margin:0 -4px; +} +QSlider::handle:horizontal:hover{ + background:palette(highlight); +} +QSlider::add-page:horizontal{ + background:palette(base); +} +QSlider::sub-page:horizontal{ + background:palette(highlight); +} +QSlider::sub-page:horizontal:disabled{ + background:rgb(80,80,80); +} diff --git a/src/darkstyle/darkstyle/icon_branch_closed.png b/src/darkstyle/darkstyle/icon_branch_closed.png new file mode 100644 index 0000000..fa785cc Binary files /dev/null and b/src/darkstyle/darkstyle/icon_branch_closed.png differ diff --git a/src/darkstyle/darkstyle/icon_branch_end.png b/src/darkstyle/darkstyle/icon_branch_end.png new file mode 100644 index 0000000..d90a04c Binary files /dev/null and b/src/darkstyle/darkstyle/icon_branch_end.png differ diff --git a/src/darkstyle/darkstyle/icon_branch_more.png b/src/darkstyle/darkstyle/icon_branch_more.png new file mode 100644 index 0000000..bdbe4ed Binary files /dev/null and b/src/darkstyle/darkstyle/icon_branch_more.png differ diff --git a/src/darkstyle/darkstyle/icon_branch_open.png b/src/darkstyle/darkstyle/icon_branch_open.png new file mode 100644 index 0000000..9dd05d6 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_branch_open.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_checked.png b/src/darkstyle/darkstyle/icon_checkbox_checked.png new file mode 100644 index 0000000..fa22907 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_checked.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_checked_disabled.png b/src/darkstyle/darkstyle/icon_checkbox_checked_disabled.png new file mode 100644 index 0000000..441d0d9 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_checked_disabled.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_checked_pressed.png b/src/darkstyle/darkstyle/icon_checkbox_checked_pressed.png new file mode 100644 index 0000000..7b508c8 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_checked_pressed.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_indeterminate.png b/src/darkstyle/darkstyle/icon_checkbox_indeterminate.png new file mode 100644 index 0000000..87ebf23 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_indeterminate.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_indeterminate_disabled.png b/src/darkstyle/darkstyle/icon_checkbox_indeterminate_disabled.png new file mode 100644 index 0000000..ee7d112 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_indeterminate_disabled.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_indeterminate_pressed.png b/src/darkstyle/darkstyle/icon_checkbox_indeterminate_pressed.png new file mode 100644 index 0000000..562c482 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_indeterminate_pressed.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_unchecked.png b/src/darkstyle/darkstyle/icon_checkbox_unchecked.png new file mode 100644 index 0000000..c3c14dd Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_unchecked.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_unchecked_disabled.png b/src/darkstyle/darkstyle/icon_checkbox_unchecked_disabled.png new file mode 100644 index 0000000..3ac26d8 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_unchecked_disabled.png differ diff --git a/src/darkstyle/darkstyle/icon_checkbox_unchecked_pressed.png b/src/darkstyle/darkstyle/icon_checkbox_unchecked_pressed.png new file mode 100644 index 0000000..c24130c Binary files /dev/null and b/src/darkstyle/darkstyle/icon_checkbox_unchecked_pressed.png differ diff --git a/src/darkstyle/darkstyle/icon_close.png b/src/darkstyle/darkstyle/icon_close.png new file mode 100644 index 0000000..ece7c28 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_close.png differ diff --git a/src/darkstyle/darkstyle/icon_radiobutton_checked.png b/src/darkstyle/darkstyle/icon_radiobutton_checked.png new file mode 100644 index 0000000..f747f49 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_radiobutton_checked.png differ diff --git a/src/darkstyle/darkstyle/icon_radiobutton_checked_disabled.png b/src/darkstyle/darkstyle/icon_radiobutton_checked_disabled.png new file mode 100644 index 0000000..fa554cb Binary files /dev/null and b/src/darkstyle/darkstyle/icon_radiobutton_checked_disabled.png differ diff --git a/src/darkstyle/darkstyle/icon_radiobutton_checked_pressed.png b/src/darkstyle/darkstyle/icon_radiobutton_checked_pressed.png new file mode 100644 index 0000000..7b4bb11 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_radiobutton_checked_pressed.png differ diff --git a/src/darkstyle/darkstyle/icon_radiobutton_unchecked.png b/src/darkstyle/darkstyle/icon_radiobutton_unchecked.png new file mode 100644 index 0000000..e74f040 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_radiobutton_unchecked.png differ diff --git a/src/darkstyle/darkstyle/icon_radiobutton_unchecked_disabled.png b/src/darkstyle/darkstyle/icon_radiobutton_unchecked_disabled.png new file mode 100644 index 0000000..87d1846 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_radiobutton_unchecked_disabled.png differ diff --git a/src/darkstyle/darkstyle/icon_radiobutton_unchecked_pressed.png b/src/darkstyle/darkstyle/icon_radiobutton_unchecked_pressed.png new file mode 100644 index 0000000..8f4d548 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_radiobutton_unchecked_pressed.png differ diff --git a/src/darkstyle/darkstyle/icon_restore.png b/src/darkstyle/darkstyle/icon_restore.png new file mode 100644 index 0000000..be29650 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_restore.png differ diff --git a/src/darkstyle/darkstyle/icon_undock.png b/src/darkstyle/darkstyle/icon_undock.png new file mode 100644 index 0000000..25e317e Binary files /dev/null and b/src/darkstyle/darkstyle/icon_undock.png differ diff --git a/src/darkstyle/darkstyle/icon_vline.png b/src/darkstyle/darkstyle/icon_vline.png new file mode 100644 index 0000000..14228c8 Binary files /dev/null and b/src/darkstyle/darkstyle/icon_vline.png differ diff --git a/src/darkstyle/frameless_window_dark.pro b/src/darkstyle/frameless_window_dark.pro new file mode 100644 index 0000000..ec30a1c --- /dev/null +++ b/src/darkstyle/frameless_window_dark.pro @@ -0,0 +1,38 @@ +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +INCLUDEPATH +="framelesswindow" + +TARGET = QtFramelessWindowDarkStyle +TEMPLATE = app + +SOURCES += main.cpp\ + mainwindow.cpp \ + framelesswindow/framelesswindow.cpp \ + framelesswindow/windowdragger.cpp \ + DarkStyle.cpp + + +HEADERS += mainwindow.h \ + framelesswindow/framelesswindow.h \ + framelesswindow/windowdragger.h \ + DarkStyle.h + + +FORMS += mainwindow.ui \ + framelesswindow/framelesswindow.ui + +RESOURCES += darkstyle.qrc \ + framelesswindow.qrc diff --git a/src/darkstyle/framelesswindow.qrc b/src/darkstyle/framelesswindow.qrc new file mode 100644 index 0000000..2ece118 --- /dev/null +++ b/src/darkstyle/framelesswindow.qrc @@ -0,0 +1,8 @@ + + + images/icon_window_minimize.png + images/icon_window_restore.png + images/icon_window_maximize.png + images/icon_window_close.png + + diff --git a/src/darkstyle/framelesswindow/framelesswindow.cpp b/src/darkstyle/framelesswindow/framelesswindow.cpp new file mode 100644 index 0000000..5f267e6 --- /dev/null +++ b/src/darkstyle/framelesswindow/framelesswindow.cpp @@ -0,0 +1,458 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#include "framelesswindow.h" +#include +#include +#include +#include + +#include "ui_framelesswindow.h" + +FramelessWindow::FramelessWindow(QWidget *parent) + : QWidget(parent), + ui(new Ui::FramelessWindow), + m_bMousePressed(false), + m_bDragTop(false), + m_bDragLeft(false), + m_bDragRight(false), + m_bDragBottom(false) { + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint); + // append minimize button flag in case of windows, + // for correct windows native handling of minimize function +#if defined(Q_OS_WIN) + setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint); +#endif + setAttribute(Qt::WA_NoSystemBackground, true); + setAttribute(Qt::WA_TranslucentBackground); + + ui->setupUi(this); + ui->restoreButton->setVisible(false); + + // shadow under window title text + QGraphicsDropShadowEffect *textShadow = new QGraphicsDropShadowEffect; + textShadow->setBlurRadius(4.0); + textShadow->setColor(QColor(0, 0, 0)); + textShadow->setOffset(0.0); + ui->titleText->setGraphicsEffect(textShadow); + + // window shadow + QGraphicsDropShadowEffect *windowShadow = new QGraphicsDropShadowEffect; + windowShadow->setBlurRadius(9.0); + windowShadow->setColor(palette().color(QPalette::Highlight)); + windowShadow->setOffset(0.0); + ui->windowFrame->setGraphicsEffect(windowShadow); + + QObject::connect(qApp, &QGuiApplication::applicationStateChanged, this, + &FramelessWindow::on_applicationStateChanged); + setMouseTracking(true); + + // important to watch mouse move from all child widgets + QApplication::instance()->installEventFilter(this); +} + +FramelessWindow::~FramelessWindow() { delete ui; } + +void FramelessWindow::on_restoreButton_clicked() { + ui->restoreButton->setVisible(false); + + ui->maximizeButton->setVisible(true); + setWindowState(Qt::WindowNoState); + // on MacOS this hack makes sure the + // background window is repaint correctly + hide(); + show(); +} + +void FramelessWindow::on_maximizeButton_clicked() { + ui->restoreButton->setVisible(true); + ui->maximizeButton->setVisible(false); + this->setWindowState(Qt::WindowMaximized); + this->showMaximized(); + styleWindow(true, false); +} + +void FramelessWindow::changeEvent(QEvent *event) { + if (event->type() == QEvent::WindowStateChange) { + if (windowState().testFlag(Qt::WindowNoState)) { + ui->restoreButton->setVisible(false); + ui->maximizeButton->setVisible(true); + styleWindow(true, true); + event->ignore(); + } else if (windowState().testFlag(Qt::WindowMaximized)) { + ui->restoreButton->setVisible(true); + ui->maximizeButton->setVisible(false); + styleWindow(true, false); + event->ignore(); + } + } + event->accept(); +} + +void FramelessWindow::setContent(QWidget *w) { + ui->windowContent->layout()->addWidget(w); +} + +void FramelessWindow::setWindowTitle(const QString &text) { + ui->titleText->setText(text); +} + +void FramelessWindow::setWindowIcon(const QIcon &ico) { + ui->icon->setPixmap(ico.pixmap(16, 16)); +} + +void FramelessWindow::styleWindow(bool bActive, bool bNoState) { + if (bActive) { + if (bNoState) { + layout()->setMargin(15); + ui->windowTitlebar->setStyleSheet(QStringLiteral( + "#windowTitlebar{border: 0px none palette(shadow); " + "border-top-left-radius:5px; border-top-right-radius:5px; " + "background-color:palette(shadow); height:20px;}")); + ui->windowFrame->setStyleSheet(QStringLiteral( + "#windowFrame{border:1px solid palette(highlight); border-radius:5px " + "5px 5px 5px; background-color:palette(Window);}")); + QGraphicsEffect *oldShadow = ui->windowFrame->graphicsEffect(); + if (oldShadow) delete oldShadow; + QGraphicsDropShadowEffect *windowShadow = new QGraphicsDropShadowEffect; + windowShadow->setBlurRadius(9.0); + windowShadow->setColor(palette().color(QPalette::Highlight)); + windowShadow->setOffset(0.0); + ui->windowFrame->setGraphicsEffect(windowShadow); + } else { + layout()->setMargin(0); + ui->windowTitlebar->setStyleSheet(QStringLiteral( + "#windowTitlebar{border: 0px none palette(shadow); " + "border-top-left-radius:0px; border-top-right-radius:0px; " + "background-color:palette(shadow); height:20px;}")); + ui->windowFrame->setStyleSheet(QStringLiteral( + "#windowFrame{border:1px solid palette(dark); border-radius:0px 0px " + "0px 0px; background-color:palette(Window);}")); + QGraphicsEffect *oldShadow = ui->windowFrame->graphicsEffect(); + if (oldShadow) delete oldShadow; + ui->windowFrame->setGraphicsEffect(nullptr); + } // if (bNoState) else maximize + } else { + if (bNoState) { + layout()->setMargin(15); + ui->windowTitlebar->setStyleSheet(QStringLiteral( + "#windowTitlebar{border: 0px none palette(shadow); " + "border-top-left-radius:5px; border-top-right-radius:5px; " + "background-color:palette(dark); height:20px;}")); + ui->windowFrame->setStyleSheet(QStringLiteral( + "#windowFrame{border:1px solid #000000; border-radius:5px 5px 5px " + "5px; background-color:palette(Window);}")); + QGraphicsEffect *oldShadow = ui->windowFrame->graphicsEffect(); + if (oldShadow) delete oldShadow; + QGraphicsDropShadowEffect *windowShadow = new QGraphicsDropShadowEffect; + windowShadow->setBlurRadius(9.0); + windowShadow->setColor(palette().color(QPalette::Shadow)); + windowShadow->setOffset(0.0); + ui->windowFrame->setGraphicsEffect(windowShadow); + } else { + layout()->setMargin(0); + ui->windowTitlebar->setStyleSheet(QStringLiteral( + "#titlebarWidget{border: 0px none palette(shadow); " + "border-top-left-radius:0px; border-top-right-radius:0px; " + "background-color:palette(dark); height:20px;}")); + ui->windowFrame->setStyleSheet(QStringLiteral( + "#windowFrame{border:1px solid palette(shadow); border-radius:0px " + "0px 0px 0px; background-color:palette(Window);}")); + QGraphicsEffect *oldShadow = ui->windowFrame->graphicsEffect(); + if (oldShadow) delete oldShadow; + ui->windowFrame->setGraphicsEffect(nullptr); + } // if (bNoState) { else maximize + } // if (bActive) { else no focus +} + +void FramelessWindow::on_applicationStateChanged(Qt::ApplicationState state) { + if (windowState().testFlag(Qt::WindowNoState)) { + if (state == Qt::ApplicationActive) { + styleWindow(true, true); + } else { + styleWindow(false, true); + } + } else if (windowState().testFlag(Qt::WindowFullScreen)) { + if (state == Qt::ApplicationActive) { + styleWindow(true, false); + } else { + styleWindow(false, false); + } + } +} + +void FramelessWindow::on_minimizeButton_clicked() { + setWindowState(Qt::WindowMinimized); +} + +void FramelessWindow::on_closeButton_clicked() { close(); } + +void FramelessWindow::on_windowTitlebar_doubleClicked() { + if (windowState().testFlag(Qt::WindowNoState)) { + on_maximizeButton_clicked(); + } else if (windowState().testFlag(Qt::WindowFullScreen)) { + on_restoreButton_clicked(); + } +} + +void FramelessWindow::mouseDoubleClickEvent(QMouseEvent *event) { + Q_UNUSED(event); +} + +void FramelessWindow::checkBorderDragging(QMouseEvent *event) { + if (isMaximized()) { + return; + } + + QPoint globalMousePos = event->globalPos(); + if (m_bMousePressed) { + QScreen *screen = QGuiApplication::primaryScreen(); + // available geometry excludes taskbar + QRect availGeometry = screen->availableGeometry(); + int h = availGeometry.height(); + int w = availGeometry.width(); + QList screenlist = screen->virtualSiblings(); + if (screenlist.contains(screen)) { + QSize sz = QApplication::desktop()->size(); + h = sz.height(); + w = sz.width(); + } + + // top right corner + if (m_bDragTop && m_bDragRight) { + int diff = + globalMousePos.x() - (m_StartGeometry.x() + m_StartGeometry.width()); + int neww = m_StartGeometry.width() + diff; + diff = globalMousePos.y() - m_StartGeometry.y(); + int newy = m_StartGeometry.y() + diff; + if (neww > 0 && newy > 0 && newy < h - 50) { + QRect newg = m_StartGeometry; + newg.setWidth(neww); + newg.setX(m_StartGeometry.x()); + newg.setY(newy); + setGeometry(newg); + } + } + // top left corner + else if (m_bDragTop && m_bDragLeft) { + int diff = globalMousePos.y() - m_StartGeometry.y(); + int newy = m_StartGeometry.y() + diff; + diff = globalMousePos.x() - m_StartGeometry.x(); + int newx = m_StartGeometry.x() + diff; + if (newy > 0 && newx > 0) { + QRect newg = m_StartGeometry; + newg.setY(newy); + newg.setX(newx); + setGeometry(newg); + } + } + // bottom right corner + else if (m_bDragBottom && m_bDragLeft) { + int diff = + globalMousePos.y() - (m_StartGeometry.y() + m_StartGeometry.height()); + int newh = m_StartGeometry.height() + diff; + diff = globalMousePos.x() - m_StartGeometry.x(); + int newx = m_StartGeometry.x() + diff; + if (newh > 0 && newx > 0) { + QRect newg = m_StartGeometry; + newg.setX(newx); + newg.setHeight(newh); + setGeometry(newg); + } + } else if (m_bDragTop) { + int diff = globalMousePos.y() - m_StartGeometry.y(); + int newy = m_StartGeometry.y() + diff; + if (newy > 0 && newy < h - 50) { + QRect newg = m_StartGeometry; + newg.setY(newy); + setGeometry(newg); + } + } else if (m_bDragLeft) { + int diff = globalMousePos.x() - m_StartGeometry.x(); + int newx = m_StartGeometry.x() + diff; + if (newx > 0 && newx < w - 50) { + QRect newg = m_StartGeometry; + newg.setX(newx); + setGeometry(newg); + } + } else if (m_bDragRight) { + int diff = + globalMousePos.x() - (m_StartGeometry.x() + m_StartGeometry.width()); + int neww = m_StartGeometry.width() + diff; + if (neww > 0) { + QRect newg = m_StartGeometry; + newg.setWidth(neww); + newg.setX(m_StartGeometry.x()); + setGeometry(newg); + } + } else if (m_bDragBottom) { + int diff = + globalMousePos.y() - (m_StartGeometry.y() + m_StartGeometry.height()); + int newh = m_StartGeometry.height() + diff; + if (newh > 0) { + QRect newg = m_StartGeometry; + newg.setHeight(newh); + newg.setY(m_StartGeometry.y()); + setGeometry(newg); + } + } + } else { + // no mouse pressed + if (leftBorderHit(globalMousePos) && topBorderHit(globalMousePos)) { + setCursor(Qt::SizeFDiagCursor); + } else if (rightBorderHit(globalMousePos) && topBorderHit(globalMousePos)) { + setCursor(Qt::SizeBDiagCursor); + } else if (leftBorderHit(globalMousePos) && + bottomBorderHit(globalMousePos)) { + setCursor(Qt::SizeBDiagCursor); + } else { + if (topBorderHit(globalMousePos)) { + setCursor(Qt::SizeVerCursor); + } else if (leftBorderHit(globalMousePos)) { + setCursor(Qt::SizeHorCursor); + } else if (rightBorderHit(globalMousePos)) { + setCursor(Qt::SizeHorCursor); + } else if (bottomBorderHit(globalMousePos)) { + setCursor(Qt::SizeVerCursor); + } else { + m_bDragTop = false; + m_bDragLeft = false; + m_bDragRight = false; + m_bDragBottom = false; + setCursor(Qt::ArrowCursor); + } + } + } +} + +// pos in global virtual desktop coordinates +bool FramelessWindow::leftBorderHit(const QPoint &pos) { + const QRect &rect = this->geometry(); + if (pos.x() >= rect.x() && pos.x() <= rect.x() + CONST_DRAG_BORDER_SIZE) { + return true; + } + return false; +} + +bool FramelessWindow::rightBorderHit(const QPoint &pos) { + const QRect &rect = this->geometry(); + int tmp = rect.x() + rect.width(); + if (pos.x() <= tmp && pos.x() >= (tmp - CONST_DRAG_BORDER_SIZE)) { + return true; + } + return false; +} + +bool FramelessWindow::topBorderHit(const QPoint &pos) { + const QRect &rect = this->geometry(); + if (pos.y() >= rect.y() && pos.y() <= rect.y() + CONST_DRAG_BORDER_SIZE) { + return true; + } + return false; +} + +bool FramelessWindow::bottomBorderHit(const QPoint &pos) { + const QRect &rect = this->geometry(); + int tmp = rect.y() + rect.height(); + if (pos.y() <= tmp && pos.y() >= (tmp - CONST_DRAG_BORDER_SIZE)) { + return true; + } + return false; +} + +void FramelessWindow::mousePressEvent(QMouseEvent *event) { + if (isMaximized()) { + return; + } + + m_bMousePressed = true; + m_StartGeometry = this->geometry(); + + QPoint globalMousePos = mapToGlobal(QPoint(event->x(), event->y())); + + if (leftBorderHit(globalMousePos) && topBorderHit(globalMousePos)) { + m_bDragTop = true; + m_bDragLeft = true; + setCursor(Qt::SizeFDiagCursor); + } else if (rightBorderHit(globalMousePos) && topBorderHit(globalMousePos)) { + m_bDragRight = true; + m_bDragTop = true; + setCursor(Qt::SizeBDiagCursor); + } else if (leftBorderHit(globalMousePos) && bottomBorderHit(globalMousePos)) { + m_bDragLeft = true; + m_bDragBottom = true; + setCursor(Qt::SizeBDiagCursor); + } else { + if (topBorderHit(globalMousePos)) { + m_bDragTop = true; + setCursor(Qt::SizeVerCursor); + } else if (leftBorderHit(globalMousePos)) { + m_bDragLeft = true; + setCursor(Qt::SizeHorCursor); + } else if (rightBorderHit(globalMousePos)) { + m_bDragRight = true; + setCursor(Qt::SizeHorCursor); + } else if (bottomBorderHit(globalMousePos)) { + m_bDragBottom = true; + setCursor(Qt::SizeVerCursor); + } + } +} + +void FramelessWindow::mouseReleaseEvent(QMouseEvent *event) { + Q_UNUSED(event); + if (isMaximized()) { + return; + } + + m_bMousePressed = false; + bool bSwitchBackCursorNeeded = + m_bDragTop || m_bDragLeft || m_bDragRight || m_bDragBottom; + m_bDragTop = false; + m_bDragLeft = false; + m_bDragRight = false; + m_bDragBottom = false; + if (bSwitchBackCursorNeeded) { + setCursor(Qt::ArrowCursor); + } +} + +bool FramelessWindow::eventFilter(QObject *obj, QEvent *event) { + if (isMaximized()) { + return QWidget::eventFilter(obj, event); + } + + // check mouse move event when mouse is moved on any object + if (event->type() == QEvent::MouseMove) { + QMouseEvent *pMouse = dynamic_cast(event); + if (pMouse) { + checkBorderDragging(pMouse); + } + } + // press is triggered only on frame window + else if (event->type() == QEvent::MouseButtonPress && obj == this) { + QMouseEvent *pMouse = dynamic_cast(event); + if (pMouse) { + mousePressEvent(pMouse); + } + } else if (event->type() == QEvent::MouseButtonRelease) { + if (m_bMousePressed) { + QMouseEvent *pMouse = dynamic_cast(event); + if (pMouse) { + mouseReleaseEvent(pMouse); + } + } + } + + return QWidget::eventFilter(obj, event); +} diff --git a/src/darkstyle/framelesswindow/framelesswindow.h b/src/darkstyle/framelesswindow/framelesswindow.h new file mode 100644 index 0000000..62bd08e --- /dev/null +++ b/src/darkstyle/framelesswindow/framelesswindow.h @@ -0,0 +1,69 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#ifndef FRAMELESSWINDOW_H +#define FRAMELESSWINDOW_H + +#include + +namespace Ui { +class FramelessWindow; +} + +class FramelessWindow : public QWidget { + Q_OBJECT + + public: + explicit FramelessWindow(QWidget *parent = Q_NULLPTR); + virtual ~FramelessWindow(); + void setContent(QWidget *w); + + private: + bool leftBorderHit(const QPoint &pos); + bool rightBorderHit(const QPoint &pos); + bool topBorderHit(const QPoint &pos); + bool bottomBorderHit(const QPoint &pos); + void styleWindow(bool bActive, bool bNoState); + + public slots: + void setWindowTitle(const QString &text); + void setWindowIcon(const QIcon &ico); + + private slots: + void on_applicationStateChanged(Qt::ApplicationState state); + void on_minimizeButton_clicked(); + void on_restoreButton_clicked(); + void on_maximizeButton_clicked(); + void on_closeButton_clicked(); + void on_windowTitlebar_doubleClicked(); + + protected: + virtual void changeEvent(QEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void checkBorderDragging(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual bool eventFilter(QObject *obj, QEvent *event); + + private: + Ui::FramelessWindow *ui; + QRect m_StartGeometry; + const quint8 CONST_DRAG_BORDER_SIZE = 15; + bool m_bMousePressed; + bool m_bDragTop; + bool m_bDragLeft; + bool m_bDragRight; + bool m_bDragBottom; +}; + +#endif // FRAMELESSWINDOW_H diff --git a/src/darkstyle/framelesswindow/framelesswindow.ui b/src/darkstyle/framelesswindow/framelesswindow.ui new file mode 100644 index 0000000..7bb5ecd --- /dev/null +++ b/src/darkstyle/framelesswindow/framelesswindow.ui @@ -0,0 +1,304 @@ + + + FramelessWindow + + + + 0 + 0 + 1737 + 1157 + + + + + + + false + + + + 0 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + false + + + #windowFrame{border:1px solid palette(highlight); border-radius:5px 5px 5px 5px; background-color:palette(Window);} + + + + 0 + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + false + + + #windowTitlebar{border: 0px none palette(base); border-top-left-radius:5px; border-top-right-radius:5px; background-color:palette(shadow); height:20px;} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 4 + 0 + + + + + 4 + 16777215 + + + + + + + + + 16 + 16 + + + + + 16 + 16 + + + + Qt::NoContextMenu + + + #icon {background-color:palette(shadow);} + + + + + + + + 75 + true + + + + padding-left:5px; + color:rgb(153,153,153); + + + VMProtect 2 - Virtual Instruction Inspector (v1.6 BETA) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 75 + true + + + + #minimizeButton{ + background-color:none; + border:none; + width:16px; + height:16px; + padding:4px; + image:url(:/images/icon_window_minimize.png); +} +#minimizeButton:hover{ + background-color:palette(alternate-base); +} +#minimizeButton:pressed{ + background-color:palette(highlight); +} + + + + + + + + + + #restoreButton{ + background-color:none; + border:none; + width:16px; + height:16px; + padding:4px; + image:url(:/images/icon_window_restore.png); +} +#restoreButton:hover{ + background-color:palette(alternate-base); +} +#restoreButton:pressed{ + background-color:palette(highlight); +} + + + + + + + + + + #maximizeButton{ + background-color:none; + border:none; + width:16px; + height:16px; + padding:4px; + image:url(:/images/icon_window_maximize.png); +} +#maximizeButton:hover{ + background-color:palette(alternate-base); +} +##maximizeButton:pressed{ + background-color:palette(highlight); +} + + + + + + + + + + + 75 + true + + + + #closeButton{ + background-color:none; + border:none; + width:16px; + height:16px; + padding:4px; + image:url(:/images/icon_window_close.png); + border-top-right-radius: 5px; +} +#closeButton:hover{ + background-color:palette(alternate-base); +} +##closeButton:pressed{ + background-color:palette(highlight); +} + + + + + + + + + + false + + + #windowContent{ + border: 0px none palette(base); + border-radius:0px 0px 5px 5px; +} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + WindowDragger + QWidget +
windowdragger.h
+ 1 +
+
+ + +
diff --git a/src/darkstyle/framelesswindow/windowdragger.cpp b/src/darkstyle/framelesswindow/windowdragger.cpp new file mode 100644 index 0000000..1d8627f --- /dev/null +++ b/src/darkstyle/framelesswindow/windowdragger.cpp @@ -0,0 +1,56 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#include "windowdragger.h" +#include +#include + +WindowDragger::WindowDragger(QWidget *parent) : QWidget(parent) { + mousePressed = false; +} + +void WindowDragger::mousePressEvent(QMouseEvent *event) { + mousePressed = true; + mousePos = event->globalPos(); + + QWidget *parent = parentWidget(); + if (parent) parent = parent->parentWidget(); + + if (parent) wndPos = parent->pos(); +} + +void WindowDragger::mouseMoveEvent(QMouseEvent *event) { + QWidget *parent = parentWidget(); + if (parent) parent = parent->parentWidget(); + + if (parent && mousePressed) + parent->move(wndPos + (event->globalPos() - mousePos)); +} + +void WindowDragger::mouseReleaseEvent(QMouseEvent *event) { + Q_UNUSED(event); + mousePressed = false; +} + +void WindowDragger::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + QStyleOption styleOption; + styleOption.init(this); + QPainter painter(this); + style()->drawPrimitive(QStyle::PE_Widget, &styleOption, &painter, this); +} + +void WindowDragger::mouseDoubleClickEvent(QMouseEvent *event) { + Q_UNUSED(event); + emit doubleClicked(); +} diff --git a/src/darkstyle/framelesswindow/windowdragger.h b/src/darkstyle/framelesswindow/windowdragger.h new file mode 100644 index 0000000..be5b539 --- /dev/null +++ b/src/darkstyle/framelesswindow/windowdragger.h @@ -0,0 +1,43 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#ifndef WINDOWDRAGGER_H +#define WINDOWDRAGGER_H + +#include +#include + +class WindowDragger : public QWidget { + Q_OBJECT + + public: + explicit WindowDragger(QWidget *parent = Q_NULLPTR); + virtual ~WindowDragger() {} + + signals: + void doubleClicked(); + + protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + + protected: + QPoint mousePos; + QPoint wndPos; + bool mousePressed; +}; + +#endif // WINDOWDRAGGER_H diff --git a/src/darkstyle/images/icon_window_close.png b/src/darkstyle/images/icon_window_close.png new file mode 100644 index 0000000..ece7c28 Binary files /dev/null and b/src/darkstyle/images/icon_window_close.png differ diff --git a/src/darkstyle/images/icon_window_maximize.png b/src/darkstyle/images/icon_window_maximize.png new file mode 100644 index 0000000..53ae289 Binary files /dev/null and b/src/darkstyle/images/icon_window_maximize.png differ diff --git a/src/darkstyle/images/icon_window_minimize.png b/src/darkstyle/images/icon_window_minimize.png new file mode 100644 index 0000000..29bceed Binary files /dev/null and b/src/darkstyle/images/icon_window_minimize.png differ diff --git a/src/darkstyle/images/icon_window_restore.png b/src/darkstyle/images/icon_window_restore.png new file mode 100644 index 0000000..be29650 Binary files /dev/null and b/src/darkstyle/images/icon_window_restore.png differ diff --git a/src/darkstyle/main.cpp b/src/darkstyle/main.cpp new file mode 100644 index 0000000..322e5bc --- /dev/null +++ b/src/darkstyle/main.cpp @@ -0,0 +1,40 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#include +#include "DarkStyle.h" +#include "framelesswindow.h" +#include "mainwindow.h" + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + + // style our application with custom dark style + QApplication::setStyle(new DarkStyle); + QApplication::setPalette(QApplication::style()->standardPalette()); + + // create frameless window (and set windowState or title) + FramelessWindow framelessWindow; + //framelessWindow.setWindowState(Qt::WindowFullScreen); + //framelessWindow.setWindowTitle("test title"); + framelessWindow.setWindowIcon(a.style()->standardIcon(QStyle::SP_DesktopIcon)); + + // create our mainwindow instance + MainWindow *mainWindow = new MainWindow; + + // add the mainwindow to our custom frameless window + framelessWindow.setContent(mainWindow); + framelessWindow.show(); + + return a.exec(); +} diff --git a/src/darkstyle/mainwindow.cpp b/src/darkstyle/mainwindow.cpp new file mode 100644 index 0000000..b4bdcc7 --- /dev/null +++ b/src/darkstyle/mainwindow.cpp @@ -0,0 +1,23 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent /*, Qt::FramelessWindowHint*/), + ui(new Ui::MainWindow) { + ui->setupUi(this); +} + +MainWindow::~MainWindow() { delete ui; } diff --git a/src/darkstyle/mainwindow.h b/src/darkstyle/mainwindow.h new file mode 100644 index 0000000..8ed9b90 --- /dev/null +++ b/src/darkstyle/mainwindow.h @@ -0,0 +1,34 @@ +/* +############################################################################### +# # +# The MIT License # +# # +# Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # +# >> https://github.com/Jorgen-VikingGod # +# # +# Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # +# # +############################################################################### +*/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + explicit MainWindow(QWidget *parent = Q_NULLPTR); + ~MainWindow(); + + private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/src/darkstyle/mainwindow.ui b/src/darkstyle/mainwindow.ui new file mode 100644 index 0000000..c51e31b --- /dev/null +++ b/src/darkstyle/mainwindow.ui @@ -0,0 +1,645 @@ + + + MainWindow + + + + 0 + 0 + 670 + 559 + + + + MainWindow + + + + + + + + + Label + + + + + + + + New Item + + + + + New Item 2 + + + + + New Item 3 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Disable Widgets + + + false + + + + + + + + + GroupBox + + + + + + -10 + + + RadioButton + + + true + + + + + + + RadioButton + + + + + + + RadioButton + + + + + + + CheckBox + + + true + + + false + + + false + + + true + + + + + + + + + + GroupBox + + + + + + PushButton + + + + + + + PushButton + + + true + + + + + + + PushButton + + + true + + + + + + + PushButton + + + true + + + + + + + + + + 1 + + + + TextEdit + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'.SF NS Text'; font-size:13pt;">test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br />test<br /></span></p></body></html> + + + + + + + + Tab Table + + + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + Cell 1/1 + + + + + Cell 2/1 + + + + + Cell 1/2 + + + + + + + + + + + + GroupBox + + + true + + + + + + 30 + + + + + + + + + + 60 + + + Qt::Horizontal + + + + + + + + + + 25 + + + Qt::Horizontal + + + + + + + test + + + QLineEdit::Password + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 24 + + + + + + + + + 0 + 0 + 670 + 20 + + + + + Test + + + + + + + + + Test2 + + + + Test2 + + + + + + + + + + + + TopToolBarArea + + + false + + + + + + + + + Test + + + + + true + + + true + + + Test + + + + + true + + + Test + + + + + Test3 + + + + + Test3 + + + + + + + + checkBox_4 + toggled(bool) + groupBox_2 + setDisabled(bool) + + + 543 + 70 + + + 376 + 97 + + + + + checkBox_4 + toggled(bool) + groupBox + setDisabled(bool) + + + 617 + 70 + + + 47 + 104 + + + + + checkBox_4 + toggled(bool) + tabWidget + setDisabled(bool) + + + 623 + 74 + + + 234 + 264 + + + + + checkBox_4 + toggled(bool) + groupBox_3 + setDisabled(bool) + + + 503 + 80 + + + 503 + 262 + + + + + checkBox_4 + toggled(bool) + progressBar + setDisabled(bool) + + + 631 + 73 + + + 607 + 517 + + + + + checkBox_4 + toggled(bool) + mainToolBar + setDisabled(bool) + + + 648 + 71 + + + 105 + 33 + + + + + checkBox_4 + toggled(bool) + menuBar + setDisabled(bool) + + + 634 + 73 + + + 64 + 7 + + + + + checkBox_4 + toggled(bool) + statusBar + setDisabled(bool) + + + 650 + 70 + + + 533 + 549 + + + + + checkBox_4 + toggled(bool) + comboBox + setDisabled(bool) + + + 626 + 70 + + + 297 + 65 + + + + + checkBox_4 + toggled(bool) + label + setDisabled(bool) + + + 639 + 78 + + + 28 + 66 + + + + + diff --git a/src/darkstyle/screenshot_mac_frameless_window_qt_dark_style_disabled.png b/src/darkstyle/screenshot_mac_frameless_window_qt_dark_style_disabled.png new file mode 100644 index 0000000..df1a7e7 Binary files /dev/null and b/src/darkstyle/screenshot_mac_frameless_window_qt_dark_style_disabled.png differ diff --git a/src/darkstyle/screenshot_mac_frameless_window_qt_dark_style_enabled.png b/src/darkstyle/screenshot_mac_frameless_window_qt_dark_style_enabled.png new file mode 100644 index 0000000..0a2092f Binary files /dev/null and b/src/darkstyle/screenshot_mac_frameless_window_qt_dark_style_enabled.png differ diff --git a/src/darkstyle/screenshot_win7_frameless_window_qt_dark_style_enabled.png b/src/darkstyle/screenshot_win7_frameless_window_qt_dark_style_enabled.png new file mode 100644 index 0000000..29be04b Binary files /dev/null and b/src/darkstyle/screenshot_win7_frameless_window_qt_dark_style_enabled.png differ diff --git a/vmprofiler-qt.vcxproj b/vmprofiler-qt.vcxproj index c0fe076..262c7f9 100644 --- a/vmprofiler-qt.vcxproj +++ b/vmprofiler-qt.vcxproj @@ -19,9 +19,9 @@ - - - + + + @@ -33,22 +33,13 @@ - - - - - + + - - - - - - - + @@ -61,6 +52,9 @@ + + + {A0485AE3-1965-4BE3-A2C4-A8257337C271} @@ -107,10 +101,10 @@ - G:\Qt\5.15.1\msvc2019_64\include;$(ProjectDir);$(ProjectDir)dependencies\DarkStyle\framelesswindow\;$(ProjectDir)dependencies\DarkStyle;$(IncludePath);$(ProjectDir)dependencies\vmprofiler\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\dependencies\zycore\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\msvc;$(ProjectDir)dependencies\ia32-doc\out\ + G:\Qt\5.15.1\msvc2019_64\include;$(ProjectDir);$(ProjectDir)src\DarkStyle\framelesswindow\;$(ProjectDir)src\DarkStyle;$(IncludePath);$(ProjectDir)dependencies\vmprofiler\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\dependencies\zycore\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\msvc;$(ProjectDir)dependencies\ia32-doc\out\ - G:\Qt\5.15.1\msvc2019_64\include;$(ProjectDir);$(ProjectDir)dependencies\DarkStyle\framelesswindow\;$(ProjectDir)dependencies\DarkStyle;$(IncludePath);$(ProjectDir)dependencies\vmprofiler\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\dependencies\zycore\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\msvc;$(ProjectDir)dependencies\ia32-doc\out\ + G:\Qt\5.15.1\msvc2019_64\include;$(ProjectDir);$(ProjectDir)src\DarkStyle\framelesswindow\;$(ProjectDir)src\DarkStyle;$(IncludePath);$(ProjectDir)dependencies\vmprofiler\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\dependencies\zycore\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\msvc;$(ProjectDir)dependencies\ia32-doc\out\ diff --git a/vmprofiler-qt.vcxproj.filters b/vmprofiler-qt.vcxproj.filters index fdb8756..b9cfd35 100644 --- a/vmprofiler-qt.vcxproj.filters +++ b/vmprofiler-qt.vcxproj.filters @@ -11,16 +11,16 @@ {8c45819e-3375-4fa3-81c3-ef06ca9b22f8} - {3be16123-7e90-4e97-86f4-92801c3f4ede} + {12ad7b7f-216d-4e4f-a08a-c42ed0fc9450} - {5a2542d9-b470-4c74-9c19-80a1e210d6ab} + {105cb913-ac75-4192-b597-963e012ddf2e} - {fdddc2b4-b9cf-403b-96b3-604807a6d797} + {d58a423a-4c09-4775-a839-0ab9e403f57e} - {12186088-c49f-41bf-b3c9-b41a8d847495} + {48472175-af91-4abd-bcc9-9801caeb83c9} @@ -33,13 +33,13 @@ Source Files - + Source Files\darkstyle\framelesswindow - + Source Files\darkstyle\framelesswindow - + Source Files\darkstyle @@ -50,32 +50,32 @@ Header Files - + Header Files\darkstyle - + Header Files\darkstyle\framelesswindow - + Header Files\darkstyle\framelesswindow - + Resource Files - + Resource Files - + Resource Files - + Resource Files - + Resource Files