From 94d24ad14c26f3701a3e97b8241a1789016c9cb9 Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:31:03 +0200 Subject: [PATCH 1/7] Introduced the Phosphor icon design system --- editor/CMakeLists.txt | 2 + editor/assets/PHOSPHOR_LICENSE.txt | 21 +++ editor/assets/Phosphor.ttf | Bin 0 -> 488636 bytes editor/main.cpp | 13 +- editor/styling/icons.cpp | 207 +++++++++++++++++++++++++++++ include/editor/styling/icons.h | 88 ++++++++++++ 6 files changed, 328 insertions(+), 3 deletions(-) create mode 100644 editor/assets/PHOSPHOR_LICENSE.txt create mode 100644 editor/assets/Phosphor.ttf create mode 100644 editor/styling/icons.cpp create mode 100644 include/editor/styling/icons.h diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 30f07967..47608e5e 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -92,6 +92,8 @@ qt_add_resources(AtlasEditor "atlas_editor_assets" "${CMAKE_SOURCE_DIR}/editor/assets/Icon-iOS-Default-1024x1024@1x.png" "${CMAKE_SOURCE_DIR}/editor/assets/iconFile-iOS-Dark-1024x1024@1x.png" "${CMAKE_SOURCE_DIR}/editor/assets/Manrope-VariableFont_wght.ttf" + "${CMAKE_SOURCE_DIR}/editor/assets/Phosphor.ttf" + "${CMAKE_SOURCE_DIR}/editor/assets/PHOSPHOR_LICENSE.txt" ) target_include_directories(AtlasEditor diff --git a/editor/assets/PHOSPHOR_LICENSE.txt b/editor/assets/PHOSPHOR_LICENSE.txt new file mode 100644 index 00000000..c04a19d1 --- /dev/null +++ b/editor/assets/PHOSPHOR_LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2021 Phosphor Icons + +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/editor/assets/Phosphor.ttf b/editor/assets/Phosphor.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7c1b8a7ad06519d3e61ddb1ef128dfce7df3b9d9 GIT binary patch literal 488636 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%0A_oI)(GY<;d`rcgnPsT8c&D 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%0A~`sc!AR78tRZ(qAcIIgw#dAaQ&0dru5 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

%GjXSUmSe1N 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 literal 0 HcmV?d00001 diff --git a/editor/main.cpp b/editor/main.cpp index a5c9814f..ea659bd0 100644 --- a/editor/main.cpp +++ b/editor/main.cpp @@ -23,6 +23,7 @@ #include "DockWidget.h" #include "../include/editor/application/styling.h" #include "editor/debug.h" +#include "editor/styling/icons.h" #include "editor/views/editorWindow.h" #include "editor/views/projectBrowser.h" #include "editor/views/splashScreen.h" @@ -41,9 +42,15 @@ int main(int argc, char **argv) { qWarning() << "Failed to load Manrope"; } - const QFont systemFont = - QFontDatabase::systemFont(QFontDatabase::GeneralFont); - app.setFont(systemFont); + const QStringList manropeFamilies = + QFontDatabase::applicationFontFamilies(manropeFont); + QFont applicationFont = manropeFamilies.isEmpty() + ? QFontDatabase::systemFont( + QFontDatabase::GeneralFont) + : QFont(manropeFamilies.first()); + applicationFont.setPointSizeF(11.0); + app.setFont(applicationFont); + styling::loadIconFont(); #ifdef ATLAS_DEBUG_BUILD app.setWindowIcon( diff --git a/editor/styling/icons.cpp b/editor/styling/icons.cpp new file mode 100644 index 00000000..baabeeea --- /dev/null +++ b/editor/styling/icons.cpp @@ -0,0 +1,207 @@ +#include "editor/styling/icons.h" + +#include +#include +#include +#include +#include + +namespace { + +QString iconFamily; +bool iconFontAttempted = false; + +ushort codepoint(styling::Icon icon) { + switch (icon) { + case styling::Icon::Aperture: + return 0xE00A; + case styling::Icon::ArrowClockwise: + return 0xE036; + case styling::Icon::ArrowCounterClockwise: + return 0xE038; + case styling::Icon::ArrowLeft: + return 0xE058; + case styling::Icon::ArrowRight: + case styling::Icon::Assign: + return 0xE06C; + case styling::Icon::ArrowUp: + return 0xE08E; + case styling::Icon::ArrowsOutCardinal: + return 0xE0A4; + case styling::Icon::BoundingBox: + return 0xE6CE; + case styling::Icon::Camera: + return 0xE10E; + case styling::Icon::CaretDown: + return 0xE136; + case styling::Icon::CaretLeft: + return 0xE138; + case styling::Icon::CaretRight: + return 0xE13A; + case styling::Icon::CaretUp: + return 0xE13C; + case styling::Icon::Check: + return 0xE182; + case styling::Icon::Close: + return 0xE4F6; + case styling::Icon::Cloud: + return 0xE1AA; + case styling::Icon::Code: + return 0xE1BC; + case styling::Icon::Crosshair: + return 0xE1D6; + case styling::Icon::Cube: + return 0xE1DA; + case styling::Icon::CubeFocus: + return 0xED0A; + case styling::Icon::CursorClick: + return 0xE7C8; + case styling::Icon::Database: + return 0xE1DE; + case styling::Icon::DotsVertical: + return 0xE208; + case styling::Icon::Export: + return 0xEAF0; + case styling::Icon::Eye: + return 0xE220; + case styling::Icon::EyeSlash: + return 0xE224; + case styling::Icon::File: + return 0xE230; + case styling::Icon::FileCode: + return 0xE914; + case styling::Icon::FilmStrip: + return 0xE792; + case styling::Icon::FloppyDisk: + return 0xE248; + case styling::Icon::Folder: + return 0xE24A; + case styling::Icon::FolderOpen: + return 0xE256; + case styling::Icon::GameController: + return 0xE26E; + case styling::Icon::Gear: + return 0xE270; + case styling::Icon::Globe: + return 0xE288; + case styling::Icon::Hand: + return 0xE298; + case styling::Icon::HardDrives: + return 0xE2A0; + case styling::Icon::Image: + return 0xE2CA; + case styling::Icon::Layout: + return 0xE6D6; + case styling::Icon::Lightbulb: + return 0xE2DC; + case styling::Icon::MagnifyingGlass: + return 0xE30C; + case styling::Icon::Material: + return 0xE6F0; + case styling::Icon::Monitor: + return 0xE32E; + case styling::Icon::MonitorPlay: + return 0xE58C; + case styling::Icon::Mountains: + return 0xE7AE; + case styling::Icon::MusicNote: + return 0xE33C; + case styling::Icon::Package: + return 0xE390; + case styling::Icon::PaintBrush: + return 0xE6F0; + case styling::Icon::Palette: + return 0xE6C8; + case styling::Icon::Pause: + return 0xE39E; + case styling::Icon::Play: + return 0xE3D0; + case styling::Icon::Plus: + return 0xE3D4; + case styling::Icon::RocketLaunch: + return 0xE3FE; + case styling::Icon::Rows: + return 0xE5A2; + case styling::Icon::Sidebar: + return 0xEAB6; + case styling::Icon::SkipForward: + return 0xE5A6; + case styling::Icon::SlidersHorizontal: + return 0xE434; + case styling::Icon::Sparkle: + return 0xE6A2; + case styling::Icon::SpeakerHigh: + return 0xE44A; + case styling::Icon::Sphere: + return 0xEE66; + case styling::Icon::SquaresFour: + return 0xE464; + case styling::Icon::Stack: + return 0xE466; + case styling::Icon::Stop: + return 0xE46C; + case styling::Icon::Sun: + return 0xE472; + case styling::Icon::TerminalWindow: + return 0xEAE8; + case styling::Icon::Trash: + return 0xE4A6; + case styling::Icon::TreeStructure: + return 0xE67C; + case styling::Icon::Warning: + return 0xE4E0; + case styling::Icon::Waveform: + return 0xE802; + case styling::Icon::Wrench: + return 0xE5D4; + } + return 0xE230; +} + +QPixmap renderIcon(styling::Icon icon, const QColor &color, int size) { + QPixmap pixmap(size, size); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::TextAntialiasing); + painter.setPen(color); + QFont font(iconFamily); + font.setPixelSize(qRound(size * 0.82)); + font.setStyleStrategy(QFont::PreferAntialias); + painter.setFont(font); + painter.drawText(pixmap.rect(), Qt::AlignCenter, + QString(QChar(codepoint(icon)))); + return pixmap; +} + +} + +bool styling::loadIconFont() { + if (iconFontAttempted) + return !iconFamily.isEmpty(); + iconFontAttempted = true; + const int id = QFontDatabase::addApplicationFont( + ":/editor/assets/Phosphor.ttf"); + const QStringList families = QFontDatabase::applicationFontFamilies(id); + if (!families.isEmpty()) + iconFamily = families.first(); + return !iconFamily.isEmpty(); +} + +QIcon styling::icon(Icon icon, const QColor &color) { + loadIconFont(); + if (iconFamily.isEmpty()) + return {}; + QIcon result; + const QColor disabled("#566174"); + const QColor active = color.lighter(118); + for (const int size : {16, 20, 24, 32, 48}) { + result.addPixmap(renderIcon(icon, color, size), QIcon::Normal, + QIcon::Off); + result.addPixmap(renderIcon(icon, active, size), QIcon::Active, + QIcon::Off); + result.addPixmap(renderIcon(icon, disabled, size), QIcon::Disabled, + QIcon::Off); + } + return result; +} diff --git a/include/editor/styling/icons.h b/include/editor/styling/icons.h new file mode 100644 index 00000000..459ccb1c --- /dev/null +++ b/include/editor/styling/icons.h @@ -0,0 +1,88 @@ +#ifndef ATLAS_EDITOR_ICONS_H +#define ATLAS_EDITOR_ICONS_H + +#include +#include + +namespace styling { + +enum class Icon { + Aperture, + ArrowClockwise, + ArrowCounterClockwise, + ArrowLeft, + ArrowRight, + ArrowUp, + ArrowsOutCardinal, + Assign, + BoundingBox, + Camera, + CaretDown, + CaretLeft, + CaretRight, + CaretUp, + Check, + Close, + Cloud, + Code, + Crosshair, + Cube, + CubeFocus, + CursorClick, + Database, + DotsVertical, + Export, + Eye, + EyeSlash, + File, + FileCode, + FilmStrip, + FloppyDisk, + Folder, + FolderOpen, + GameController, + Gear, + Globe, + Hand, + HardDrives, + Image, + Layout, + Lightbulb, + MagnifyingGlass, + Material, + Monitor, + MonitorPlay, + Mountains, + MusicNote, + Package, + PaintBrush, + Palette, + Pause, + Play, + Plus, + RocketLaunch, + Rows, + Sidebar, + SkipForward, + SlidersHorizontal, + Sparkle, + SpeakerHigh, + Sphere, + SquaresFour, + Stack, + Stop, + Sun, + TerminalWindow, + Trash, + TreeStructure, + Warning, + Waveform, + Wrench +}; + +bool loadIconFont(); +QIcon icon(Icon icon, const QColor &color = QColor("#AAB4C4")); + +} + +#endif From a33491a041105d7fba46d7b7e44cb1b344db5d96 Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:38:54 +0200 Subject: [PATCH 2/7] Remodeled the editor shell and visual language --- editor/main.cpp | 1 - editor/styling/dark.qss | 1918 +++++++++-------------- editor/styling/icons.cpp | 2 + editor/styling/theme.cpp | 36 +- editor/views/editor/editor.cpp | 187 ++- editor/views/editor/hierarchy.cpp | 61 +- editor/views/editor/inspector.cpp | 84 +- editor/views/editor/materialEditor.cpp | 7 +- editor/views/editor/postProcessing.cpp | 10 +- editor/views/editor/viewportTools.cpp | 28 +- editor/views/general/contentBrowser.cpp | 56 +- editor/views/general/projectBrowser.cpp | 45 +- editor/views/general/splashScreen.cpp | 60 +- include/editor/styling/icons.h | 1 + include/editor/views/editorWindow.h | 1 + 15 files changed, 1142 insertions(+), 1355 deletions(-) diff --git a/editor/main.cpp b/editor/main.cpp index ea659bd0..ed83a49b 100644 --- a/editor/main.cpp +++ b/editor/main.cpp @@ -29,7 +29,6 @@ #include "editor/views/splashScreen.h" int main(int argc, char **argv) { - QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); QApplication app(argc, argv); app.setApplicationName("Atlas Engine"); app.setApplicationDisplayName("Atlas Engine"); diff --git a/editor/styling/dark.qss b/editor/styling/dark.qss index 461a2d73..e150192f 100644 --- a/editor/styling/dark.qss +++ b/editor/styling/dark.qss @@ -1,104 +1,93 @@ * { - font-family: "Helvetica Neue", "Segoe UI", Arial, sans-serif; + font-family: "Manrope"; font-size: 12px; - color: #DCE2E5; - selection-background-color: #3D8BFF; + color: #E7ECF3; + selection-background-color: #6F55E8; selection-color: #FFFFFF; + outline: none; } QWidget { - background-color: #222526; - color: #DCE2E5; + background-color: #0D1117; + color: #E7ECF3; } QMainWindow, QDialog, QFrame { - background-color: #222526; -} - -QToolTip { - background-color: #151819; - color: #F4F7F8; - border: 1px solid #3C4245; - border-radius: 3px; - padding: 4px 6px; + background-color: #0D1117; } QLabel { - background-color: transparent; - color: #DCE2E5; + background: transparent; } QLabel:disabled { - color: #727B80; + color: #566174; +} + +QToolTip { + background-color: #202838; + color: #F7F9FC; + border: 1px solid #3A465A; + border-radius: 5px; + padding: 6px 8px; } QGroupBox { - background-color: #222526; - border: 1px solid #3A4144; - border-radius: 3px; - margin-top: 15px; - padding: 8px; - color: #E7ECEF; - font-weight: 600; + background-color: #141A23; + border: 1px solid #252E3C; + border-radius: 7px; + margin-top: 18px; + padding: 12px 10px 10px 10px; + color: #F1F4F8; + font-weight: 650; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; - left: 7px; - padding: 0 4px; - color: #AEB8BE; - background-color: #222526; -} - -QGroupBox > QWidget { - background-color: #222526; + left: 9px; + padding: 0 6px; + color: #AEB8C8; + background-color: #141A23; } QScrollArea, QAbstractScrollArea { - background-color: #222526; - border: 1px solid #343A3D; - border-radius: 3px; + background-color: #10151C; + border: none; } QAbstractScrollArea::corner { - background-color: #222526; + background-color: #10151C; } QScrollBar:vertical { - background-color: #1E2122; - width: 10px; - margin: 0; + background-color: transparent; + width: 9px; + margin: 2px; border: none; } QScrollBar:horizontal { - background-color: #1E2122; - height: 10px; - margin: 0; + background-color: transparent; + height: 9px; + margin: 2px; border: none; } QScrollBar::handle:vertical, QScrollBar::handle:horizontal { - background-color: #444C50; - border: 2px solid #1E2122; - border-radius: 4px; - min-height: 28px; - min-width: 28px; + background-color: #364154; + border-radius: 3px; + min-height: 30px; + min-width: 30px; } QScrollBar::handle:vertical:hover, QScrollBar::handle:horizontal:hover { - background-color: #5A6469; -} - -QScrollBar::handle:vertical:pressed, -QScrollBar::handle:horizontal:pressed { - background-color: #6A757B; + background-color: #536078; } QScrollBar::add-line, @@ -113,194 +102,59 @@ QScrollBar::sub-page { QPushButton, QToolButton { - background-color: #303538; - border: 1px solid #444B4F; - border-radius: 3px; - padding: 3px 7px; - color: #EEF3F5; - min-height: 18px; + background-color: #1A2230; + border: 1px solid #2D3849; + border-radius: 5px; + padding: 5px 9px; + color: #E9EDF4; + min-height: 20px; + font-weight: 550; } QPushButton:hover, QToolButton:hover { - background-color: #394045; - border-color: #59656C; + background-color: #222C3C; + border-color: #46536A; } QPushButton:pressed, QToolButton:pressed { - background-color: #24282A; - border-color: #3D8BFF; + background-color: #121923; + border-color: #7C5CFC; } QPushButton:checked, QToolButton:checked { - background-color: #22496D; - border-color: #5FB3FF; + background-color: #2B2455; + border-color: #7C5CFC; color: #FFFFFF; } -QPushButton:default { - background-color: #346FA8; - border-color: #68BFFF; +QPushButton:default, +#primaryAction { + background-color: #6F55E8; + border-color: #8F76FF; color: #FFFFFF; + font-weight: 650; +} + +QPushButton:default:hover, +#primaryAction:hover { + background-color: #7C5CFC; + border-color: #A18DFF; } QPushButton:disabled, QToolButton:disabled { - background-color: #292D2F; - border-color: #33393C; - color: #6F787D; + background-color: #121820; + border-color: #1D2531; + color: #566174; } QToolButton::menu-indicator { image: none; } -#viewportToolbar { - background-color: #1B1E20; - border-bottom: 1px solid #353B3E; -} - -#viewportPlaybackButton, -#viewportModeButton, -#viewportOptionButton { - min-width: 22px; - min-height: 20px; - padding: 2px 4px; -} - -#viewportPlaybackButton { - border-radius: 3px; -} - -#viewportShadingMode { - min-width: 92px; - padding-top: 2px; - padding-bottom: 2px; -} - -#viewportFpsLabel { - color: #9DA8AE; -} - -#viewportShortcutHint { - background-color: #181B1D; - border-top: 1px solid #303639; - color: #8F9AA0; - font-size: 10px; - padding: 4px 8px; -} - -#sceneTabs { - background-color: #171A1C; - border-bottom: 1px solid #343A3E; -} - -#sceneTabs::tab { - background-color: #202427; - border-right: 1px solid #343A3E; - color: #98A3A9; - min-width: 120px; - padding: 5px 10px; -} - -#sceneTabs::tab:selected { - background-color: #2B3134; - color: #EDF2F4; - border-bottom: 2px solid #4EA4E8; -} - -#sceneTabs::close-button { - subcontrol-position: right; -} - -#materialEditorHeader { - background-color: #1B1E20; - border-bottom: 1px solid #363C3F; -} - -#materialEditorTitle { - color: #F3F6F7; - font-size: 14px; - font-weight: 650; -} - -#materialEditorStatus { - color: #89959B; -} - -#materialEditorScroll, -#materialEditorBody { - border: none; - background-color: #202324; -} - -#materialPreview { - background-color: #191C1D; - border: 1px solid #3A4144; - border-radius: 3px; -} - -#materialEditorEmpty { - color: #879299; - padding: 40px; -} - -#postProcessingToolbar { - background-color: #1B1E20; - border-bottom: 1px solid #363C3F; -} - -#postProcessingTitle, -#postProcessingSectionTitle, -#inspectorCameraTitle { - color: #F3F6F7; - font-size: 14px; - font-weight: 650; -} - -#postProcessingStatus { - color: #89959B; -} - -#postProcessingScroll, -#postProcessingBody { - border: none; - background-color: #202324; -} - -#postProcessingEmpty { - color: #879299; - padding: 40px; -} - -#materialTextureSlot { - background-color: #1B1E20; - border: 1px solid #343B3E; - border-radius: 3px; -} - -#materialTexturePreview { - background-color: #25292B; - border: 1px solid #41494D; - border-radius: 3px; - color: #EF8C7B; - font-weight: 700; - qproperty-alignment: AlignCenter; -} - -#materialTextureLabel { - color: #CDD4D8; - font-weight: 600; -} - -#materialTexturePath { - color: #8F9AA0; - padding-top: 3px; - padding-bottom: 3px; -} - QLineEdit, QTextEdit, QPlainTextEdit, @@ -310,16 +164,11 @@ QDoubleSpinBox, QDateEdit, QTimeEdit, QDateTimeEdit { - background-color: #1A1D1E; - border: 1px solid #363D41; - border-radius: 3px; - padding: 3px 6px; - color: #EDF2F4; -} - -QTextEdit, -QPlainTextEdit { - selection-background-color: #315D90; + background-color: #0F141B; + border: 1px solid #273141; + border-radius: 5px; + padding: 5px 8px; + color: #EEF2F7; } QLineEdit:hover, @@ -327,11 +176,8 @@ QTextEdit:hover, QPlainTextEdit:hover, QComboBox:hover, QSpinBox:hover, -QDoubleSpinBox:hover, -QDateEdit:hover, -QTimeEdit:hover, -QDateTimeEdit:hover { - border-color: #4A555B; +QDoubleSpinBox:hover { + border-color: #3D4A60; } QLineEdit:focus, @@ -339,1391 +185,1089 @@ QTextEdit:focus, QPlainTextEdit:focus, QComboBox:focus, QSpinBox:focus, -QDoubleSpinBox:focus, -QDateEdit:focus, -QTimeEdit:focus, -QDateTimeEdit:focus { - border-color: #5FB3FF; - background-color: #171A1B; +QDoubleSpinBox:focus { + background-color: #111824; + border-color: #7C5CFC; } QLineEdit:disabled, QTextEdit:disabled, -QPlainTextEdit:disabled, QComboBox:disabled, QSpinBox:disabled, -QDoubleSpinBox:disabled, -QDateEdit:disabled, -QTimeEdit:disabled, -QDateTimeEdit:disabled { - background-color: #25292B; - border-color: #303638; - color: #727B80; +QDoubleSpinBox:disabled { + background-color: #11161D; + border-color: #1D2530; + color: #566174; } QComboBox { - padding-right: 23px; + padding-right: 24px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 22px; - border-left: 1px solid #343B3F; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - background-color: #252A2C; -} - -QComboBox::down-arrow { - image: none; - width: 0; - height: 0; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 5px solid #AEB8BE; + border-left: 1px solid #273141; } QComboBox QAbstractItemView { - background-color: #1C2021; - border: 1px solid #444D52; - border-radius: 3px; - padding: 3px; - color: #E8EEF1; - selection-background-color: #315D90; + background-color: #171E29; + border: 1px solid #344156; + border-radius: 6px; + padding: 4px; + selection-background-color: #2B2455; } QAbstractSpinBox::up-button, QAbstractSpinBox::down-button { - background-color: #252A2C; - border-left: 1px solid #343B3F; + background-color: #171F2B; + border: none; width: 16px; } QAbstractSpinBox::up-button:hover, QAbstractSpinBox::down-button:hover { - background-color: #333A3E; -} - -QAbstractSpinBox::up-arrow { - image: none; - width: 0; - height: 0; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-bottom: 5px solid #AEB8BE; -} - -QAbstractSpinBox::down-arrow { - image: none; - width: 0; - height: 0; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 5px solid #AEB8BE; + background-color: #263144; } QCheckBox, QRadioButton { - spacing: 6px; - background-color: transparent; - color: #DCE2E5; + spacing: 7px; + color: #C9D1DE; } QCheckBox::indicator, QRadioButton::indicator { - width: 13px; - height: 13px; - background-color: #171A1B; - border: 1px solid #515B61; -} - -QCheckBox::indicator { - border-radius: 2px; -} - -QRadioButton::indicator { - border-radius: 7px; -} - -QCheckBox::indicator:hover, -QRadioButton::indicator:hover { - border-color: #6FBFFF; - background-color: #1D252B; -} - -QCheckBox::indicator:checked { - background-color: #3D8BFF; - border-color: #72C7FF; - border-radius: 2px; -} - -QRadioButton::indicator:checked { - background-color: #3D8BFF; - border: 4px solid #171A1B; -} - -QCheckBox::indicator:disabled, -QRadioButton::indicator:disabled { - background-color: #2A2F31; - border-color: #3A4145; + width: 15px; + height: 15px; } QSlider::groove:horizontal { + background-color: #202A38; height: 4px; - background-color: #171A1B; - border-radius: 2px; -} - -QSlider::groove:vertical { - width: 4px; - background-color: #171A1B; - border-radius: 2px; -} - -QSlider::sub-page:horizontal, -QSlider::add-page:vertical { - background-color: #3D8BFF; border-radius: 2px; } QSlider::handle:horizontal { - width: 16px; - height: 16px; - margin: -6px 0; - background-color: #DCE2E5; - border: 1px solid #FFFFFF; - border-radius: 8px; -} - -QSlider::handle:vertical { - width: 16px; - height: 16px; - margin: 0 -6px; - background-color: #DCE2E5; - border: 1px solid #FFFFFF; - border-radius: 8px; -} - -QSlider::handle:horizontal:hover, -QSlider::handle:vertical:hover { - background-color: #FFFFFF; - border-color: #72C7FF; + background-color: #8A70FF; + border: 2px solid #C8BCFF; + width: 12px; + margin: -5px 0; + border-radius: 7px; } QProgressBar { - background-color: #171A1B; - border: 1px solid #343B3F; + background-color: #151C26; + border: 1px solid #293446; border-radius: 5px; + height: 8px; text-align: center; - color: #DCE2E5; - min-height: 8px; } QProgressBar::chunk { - background-color: #3D8BFF; + background-color: #7C5CFC; border-radius: 4px; } +QTreeView, QListView, QListWidget, -QTreeView, -QTreeWidget, QTableView, QTableWidget { - background-color: #1C2021; - alternate-background-color: #202526; - border: 1px solid #343B3F; - border-radius: 3px; - padding: 2px; - color: #DCE2E5; - gridline-color: #303638; + background-color: #10151C; + alternate-background-color: #121923; + border: none; + color: #DCE3EC; + show-decoration-selected: 1; } +QTreeView::item, QListView::item, QListWidget::item, -QTreeView::item, -QTreeWidget::item, QTableView::item, QTableWidget::item { - min-height: 20px; - padding: 2px 6px; - border-radius: 3px; + border: 1px solid transparent; + border-radius: 4px; + padding: 4px 6px; } +QTreeView::item:hover, QListView::item:hover, QListWidget::item:hover, -QTreeView::item:hover, -QTreeWidget::item:hover, QTableView::item:hover, QTableWidget::item:hover { - background-color: #2D363B; + background-color: #1A2230; + border-color: #293548; } +QTreeView::item:selected, QListView::item:selected, QListWidget::item:selected, -QTreeView::item:selected, -QTreeWidget::item:selected, QTableView::item:selected, QTableWidget::item:selected { - background-color: #315D90; + background-color: #2A2452; + border-color: #6F55E8; color: #FFFFFF; } -#panelToolbar { - background-color: #222526; - border: none; +QHeaderView { + background-color: #111720; } -#panelAddButton { - background-color: #2C3235; - border-color: #414A4F; - padding: 2px 7px; - min-height: 19px; +QHeaderView::section { + background-color: #171E29; + border: none; + border-right: 1px solid #283243; + border-bottom: 1px solid #283243; + padding: 7px 9px; + color: #98A4B7; font-weight: 600; } -#panelMoreButton, -#browserRevealButton, -#browserNavigationButton { - background-color: transparent; - border-color: transparent; - padding: 2px; - min-width: 20px; - min-height: 19px; +QTabWidget::pane { + background-color: #10151C; + border: 1px solid #273141; + border-radius: 0 0 5px 5px; } -#panelMoreButton:hover, -#browserRevealButton:hover, -#browserNavigationButton:hover { - background-color: #30373A; - border-color: #424B50; +QTabBar::tab { + background-color: #111720; + border: none; + border-right: 1px solid #232C3A; + border-bottom: 1px solid #273141; + color: #7F8B9D; + min-width: 88px; + padding: 7px 12px; } -#contentPathField { - background-color: #191D1F; - border-color: #30373B; - color: #AEB8BE; - padding: 2px 6px; - min-height: 19px; +QTabBar::tab:hover { + background-color: #18202B; + color: #C8D1DF; } -#contentSearchField { - padding: 2px 6px; - min-height: 19px; +QTabBar::tab:selected { + background-color: #151C26; + color: #F2F5F9; + border-bottom: 2px solid #7C5CFC; } -QTreeView#hierarchyTree { - background-color: #1B1F20; - border: none; - border-radius: 4px; - padding: 3px; - show-decoration-selected: 1; +QMenuBar#atlasMenuBar { + background-color: #090D12; + border-bottom: 1px solid #202836; + padding: 2px 6px; } -QTreeView#hierarchyTree::item { - min-height: 20px; - padding: 2px 5px; +QMenuBar#atlasMenuBar::item { + background: transparent; + color: #B8C2D0; + padding: 5px 9px; + border-radius: 4px; } -QListView#contentGrid { - background-color: #1B1F20; - border: none; - border-radius: 4px; - padding: 8px; +QMenuBar#atlasMenuBar::item:selected, +QMenuBar#atlasMenuBar::item:pressed { + background-color: #202838; + color: #FFFFFF; } -QListView#contentGrid::item { - min-height: 88px; - padding: 6px; - margin: 2px; - border: 1px solid transparent; +QMenu { + background-color: #171E29; + border: 1px solid #344156; border-radius: 7px; + padding: 5px; } -QListView#contentGrid::item:hover { - background-color: #272E31; - border-color: #353F44; +QMenu::item { + background: transparent; + border-radius: 4px; + padding: 7px 34px 7px 10px; + color: #DCE3EC; } -QListView#contentGrid::item:selected { - background-color: #284E73; - border-color: #579FE3; +QMenu::item:selected { + background-color: #2A2452; color: #FFFFFF; } -QScrollArea#inspectorScroll { - background-color: #1B1F20; - border: none; - border-radius: 0; +QMenu::item:disabled { + color: #596477; } -#inspectorContent { - background-color: #1B1F20; +QMenu::separator { + background-color: #2A3444; + height: 1px; + margin: 5px 8px; } -#inspectorHeader { - background-color: #24292B; - border: 1px solid #353D41; - border-radius: 3px; +QSplitter::handle { + background-color: #080C11; } -#inspectorObjectIcon { - background-color: #1C2022; - border: 1px solid #3B4449; - border-radius: 3px; - padding: 2px; +QSplitter::handle:horizontal { + width: 4px; } -#inspectorNameField { - background-color: transparent; - border: 1px solid transparent; - border-radius: 4px; - color: #F4F7F8; - font-size: 14px; - font-weight: 650; - padding: 2px 4px; - min-height: 20px; -} - -#inspectorNameField:hover { - background-color: #1D2123; - border-color: #3C464B; -} - -#inspectorNameField:focus { - background-color: #171A1B; - border-color: #5FB3FF; -} - -#inspectorTypeLabel { - color: #879299; - padding-left: 5px; - font-size: 11px; +QSplitter::handle:vertical { + height: 4px; } -#inspectorComponent { - background-color: #23282A; - border: 1px solid #363E42; - border-radius: 3px; +QSplitter::handle:hover { + background-color: #7C5CFC; } -#inspectorComponentHeaderRow { - background-color: #2A3033; - border: none; - border-bottom: 1px solid #343D41; - border-radius: 3px; +QStatusBar { + background-color: #090D12; + border-top: 1px solid #202836; + color: #8490A4; } -#inspectorComponentHeader { - background-color: transparent; +#workspaceBar { + background-color: #10151C; border: none; - border-radius: 3px; - padding: 4px 7px; - color: #EEF2F4; - font-weight: 650; - text-align: left; -} - -#inspectorComponentHeader:hover { - background-color: #30373A; -} - -#inspectorComponentRemoveButton { - background-color: transparent; - border-color: transparent; - min-width: 20px; - min-height: 20px; - padding: 1px; + border-bottom: 1px solid #273141; + spacing: 3px; + padding: 4px 7px 4px 0; } -#inspectorComponentRemoveButton:hover { - background-color: #543136; - border-color: #78444C; -} - -#inspectorComponentBody { - background-color: transparent; +#workspaceIdentity { + background: transparent; + border-right: 1px solid #2A3444; } -#inspectorPropertyRow { - background-color: transparent; - border: none; +#workspaceMark { + background: transparent; } -#inspectorPropertyLabel { - color: #ABB5BA; +#workspaceBrand { + color: #F5F7FA; font-size: 12px; + font-weight: 800; + letter-spacing: 1px; } -#inspectorVectorField, -#inspectorColorField, -#inspectorNumericField { - background-color: #191C1D; - border: 1px solid #363D41; - border-radius: 3px; -} - -#inspectorAxisLabel { - color: #748088; - font-size: 10px; - font-weight: 700; - min-width: 10px; -} - -#inspectorVectorField QDoubleSpinBox { - background-color: transparent; - border: none; - border-radius: 0; - padding: 2px; -} - -#inspectorNumericField QDoubleSpinBox { - background-color: transparent; - border: none; -} - -#inspectorSyncButton { - background-color: transparent; - border: none; - min-width: 20px; - min-height: 20px; - padding: 1px; -} - -#inspectorSyncButton:hover { - background-color: #30373A; -} - -#inspectorSyncButton[matched="true"] { - background-color: #242A2D; - border: 1px solid #465158; - color: #D5DDE1; - padding: 2px 6px; - text-align: left; -} - -#inspectorSyncButton[matched="true"]:hover { - background-color: #30383C; - border-color: #5B6A72; -} - -#inspectorColorSwatch { - border: 1px solid #566167; - border-radius: 4px; - padding: 0; - min-height: 18px; -} - -#inspectorColorText { - background-color: transparent; - border: none; - padding: 3px; -} - -#inspectorNestedGroup { - background-color: #202426; - border-top: 1px solid #30373A; - border-bottom: 1px solid #30373A; -} - -#inspectorNestedTitle { - color: #D1D8DC; - font-weight: 650; - padding: 2px 1px 4px 1px; -} - -#inspectorArrayTitle { - color: #7FB9EC; +#workspaceProject { + color: #7F8B9D; font-size: 11px; - font-weight: 650; - padding: 5px 2px 1px 2px; } -#inspectorArrayButton { +#workspaceModeButton { background-color: transparent; border: 1px solid transparent; - border-radius: 4px; - color: #AEB8BE; - min-width: 20px; - min-height: 18px; - padding: 1px 4px; -} - -#inspectorArrayButton:hover { - background-color: #30373A; - border-color: #465157; - color: #FFFFFF; -} - -#inspectorEmptyTitle { - color: #DDE3E6; - font-size: 15px; - font-weight: 650; -} - -#inspectorEmptyHint { - color: #77838A; - font-size: 12px; -} - -#inspectorOpenAssetButton { - min-height: 24px; -} - -#inspectorAddComponentButton { - background-color: #2B3235; - border: 1px solid #465158; - border-radius: 3px; - color: #E9EEF0; - font-weight: 600; - min-height: 20px; - padding: 3px 8px; -} - -#inspectorAddComponentButton:hover { - background-color: #343C40; - border-color: #5B6970; -} - -#inspectorAudioControls { - background-color: #202426; - border: 1px solid #343D41; - border-top: none; - border-bottom-left-radius: 7px; - border-bottom-right-radius: 7px; -} - -QHeaderView { - background-color: #252A2C; - border: none; -} - -QHeaderView::section { - background-color: #252A2C; - color: #AEB8BE; - border: none; - border-right: 1px solid #343B3F; - border-bottom: 1px solid #343B3F; - padding: 4px 6px; - font-weight: 600; -} - -QHeaderView::section:hover { - background-color: #2E3538; - color: #EAF0F2; -} - -QTabWidget::pane { - background-color: #222526; - border: 1px solid #343B3F; - border-radius: 3px; - top: -1px; -} - -QTabBar::tab { - background-color: #252A2C; - color: #9EA9AF; - border: 1px solid #343B3F; - border-bottom-color: #343B3F; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - padding: 4px 9px; - min-width: 46px; -} - -QTabBar::tab:first { - border-top-left-radius: 5px; -} - -QTabBar::tab:last { - border-top-right-radius: 5px; -} - -QTabBar::tab:hover { - background-color: #30383B; - color: #E3EAED; -} - -QTabBar::tab:selected { - background-color: #303638; - color: #FFFFFF; - border-top: 1px solid #343B3F; - border-bottom-color: #303638; + border-radius: 5px; + color: #94A0B2; + padding: 5px 9px; + margin: 0 1px; } -QMenuBar { - background-color: #222526; - color: #CCD4D8; - border-bottom: none; +#workspaceModeButton:hover { + background-color: #1B2431; + color: #DDE4ED; } -QMenuBar::item { - background-color: transparent; - padding: 4px 8px; -} - -QMenuBar::item:selected { - background-color: #30383B; +#workspaceModeButton:checked { + background-color: #25203F; + border-color: #4E3C8D; color: #FFFFFF; } -QMenu { - background-color: #1B1F20; - color: #E5ECEF; - border: 1px solid #3D454A; - border-radius: 3px; - padding: 3px; -} - -QMenu::item { - padding: 4px 24px 4px 8px; - border-radius: 3px; +#workspaceUtilityButton { + background: transparent; + border-color: transparent; + min-width: 26px; } -QMenu::item:selected { - background-color: #315D90; - color: #FFFFFF; +#workspaceBuildButton { + background-color: #2C2618; + border-color: #5D4B23; + color: #F5D184; } -QMenu::separator { - height: 1px; - background-color: #343B3F; - margin: 3px 5px; +#workspaceLaunchButton { + background-color: #183020; + border-color: #285A38; + color: #92E6A9; + margin-left: 3px; } -QSplitter::handle { - background-color: #222526; +#workspaceBuildButton:hover { + background-color: #3A311D; + border-color: #80682D; } -QSplitter::handle:horizontal { - width: 6px; +#workspaceLaunchButton:hover { + background-color: #20412A; + border-color: #3A7A4B; } -QSplitter::handle:vertical { - height: 6px; +#sceneTabs { + background-color: #0C1117; + border-bottom: 1px solid #273141; } -QSplitter::handle:hover { - background-color: #4FAAFF; +#sceneTabs::tab { + background-color: #111720; + border-right: 1px solid #252E3B; + color: #7F8B9D; + min-width: 128px; + padding: 6px 12px; } -QStatusBar { - background-color: #1B1E1F; - color: #AEB8BE; - border-top: 1px solid #303638; +#sceneTabs::tab:selected { + background-color: #171E29; + color: #F3F6FA; + border-bottom: 2px solid #55C2FF; } -QStatusBar::item { - border: none; +#viewportTools { + background-color: #090D12; } -ads--CDockContainerWidget { - background-color: #222526; +#viewportToolbar { + background-color: #111720; + border-bottom: 1px solid #273141; } -ads--CDockContainerWidget > QSplitter { - padding: 1px; +#viewportPlaybackButton, +#viewportModeButton, +#viewportOptionButton { + background-color: #171E29; + border-color: #283345; + min-width: 25px; + min-height: 22px; + padding: 3px 5px; } -ads--CDockSplitter::handle, -ads--CDockContainerWidget ads--CDockSplitter::handle { - background-color: #222526; +#viewportPlaybackButton:hover, +#viewportModeButton:hover, +#viewportOptionButton:hover { + background-color: #222C3C; + border-color: #46536A; } -ads--CDockSplitter::handle:hover, -ads--CDockContainerWidget ads--CDockSplitter::handle:hover { - background-color: #4FAAFF; +#viewportModeButton:checked { + background-color: #2A2452; + border-color: #7C5CFC; } -ads--CDockAreaWidget { - background-color: #222526; - border: none; - border-radius: 0; +#viewportShadingMode { + min-width: 104px; + background-color: #111720; } -ads--CDockAreaWidget[focused="true"] { - border: none; +#viewportFpsLabel { + color: #6EDB8C; + font-size: 10px; + font-weight: 650; } -ads--CDockAreaTitleBar { - background-color: #222526; - border-bottom: none; - border-radius: 0; - padding: 0; +#viewportShortcutHint { + background-color: #090D12; + border-top: 1px solid #202836; + color: #68758A; + font-size: 10px; + padding: 5px 9px; } -ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { - background-color: #222526; - border-bottom: none; +#panelToolbar, +#materialEditorHeader, +#postProcessingToolbar, +#workspaceToolbar { + background-color: #131922; + border-bottom: 1px solid #283243; + padding: 4px; } -ads--CDockAreaTabBar, -#tabsContainerWidget { - background-color: #222526; - border: none; - border-radius: 0; +#panelAddButton, +#materialSaveButton, +#workspaceApplyButton { + background-color: #2A2452; + border-color: #5946AD; + color: #E8E2FF; } -ads--CTitleBarButton { +#panelMoreButton, +#browserNavigationButton, +#browserRevealButton { background-color: transparent; - border: none; - border-radius: 4px; - padding: 2px; - margin: 2px; - min-width: 18px; - min-height: 18px; + border-color: transparent; + min-width: 24px; } -ads--CTitleBarButton:hover { - background-color: #394045; +#panelMoreButton:hover, +#browserNavigationButton:hover, +#browserRevealButton:hover { + background-color: #202A38; + border-color: #334056; } -ads--CTitleBarButton:pressed { - background-color: #1A1D1E; +#contentPathField { + background-color: #0E131A; + color: #8490A4; + font-size: 11px; } -#tabsMenuButton::menu-indicator { - image: none; +#contentSearchField { + min-width: 130px; } -#tabsMenuButton { - qproperty-icon: url(:/ads/images/tabs-menu-button_dark.svg); - qproperty-iconSize: 16px; +QTreeView#hierarchyTree { + background-color: #10151C; + border-top: 1px solid #202836; + padding: 5px 3px; } -#dockAreaCloseButton { - qproperty-icon: url(:/ads/images/close-button_dark.svg), url(:/ads/images/close-button-disabled_dark.svg) disabled; - qproperty-iconSize: 16px; +QTreeView#hierarchyTree::item { + min-height: 24px; + padding: 3px 5px; } -#detachGroupButton { - qproperty-icon: url(:/ads/images/detach-button_dark.svg), url(:/ads/images/detach-button-disabled_dark.svg) disabled; - qproperty-iconSize: 16px; +QTreeView#hierarchyTree::item:selected { + background-color: #2A2452; + border-left: 2px solid #A78BFA; } -#dockAreaAutoHideButton { - qproperty-icon: url(:/ads/images/vs-pin-button_dark.svg), url(:/ads/images/vs-pin-button-disabled_dark.svg) disabled; - qproperty-iconSize: 16px; +QListView#contentGrid { + background-color: #0D1218; + border-top: 1px solid #202836; + padding: 8px; } -#dockAreaMinimizeButton { - qproperty-icon: url(:/ads/images/minimize-button-focused_dark.svg); - qproperty-iconSize: 16px; +QListView#contentGrid::item { + background-color: #121923; + border: 1px solid #202A38; + border-radius: 7px; + padding: 10px; + color: #BCC6D4; } -ads--CDockWidgetTab { - background-color: #252A2C; - border: none; - border-right: 1px solid #303638; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - margin: 2px 1px 0 0; - padding: 0 7px; - qproperty-iconSize: 14px 14px; +QListView#contentGrid::item:hover { + background-color: #182130; + border-color: #3A465A; } -ads--CDockWidgetTab:hover { - background-color: #30383B; +QListView#contentGrid::item:selected { + background-color: #29234B; + border-color: #7C5CFC; + color: #FFFFFF; } -ads--CDockWidgetTab[activeTab="true"] { - background-color: #303638; - border-top: none; - border-right: 1px solid #343B3F; +QScrollArea#inspectorScroll, +#inspectorContent, +#materialEditorBody, +#postProcessingBody { + background-color: #10151C; + border: none; } -ads--CDockWidgetTab[focused="true"] { - background-color: #303638; - border-top: none; +#inspectorHeader { + background-color: #141B25; + border: 1px solid #273243; + border-radius: 7px; + padding: 8px; } -ads--CDockWidgetTab QLabel, -ads--CDockWidgetTab #dockWidgetTabLabel { - color: #9EA9AF; - background-color: transparent; +#inspectorObjectIcon { + background-color: #20283A; + border: 1px solid #38455B; + border-radius: 7px; + padding: 6px; } -ads--CDockWidgetTab:hover QLabel, -ads--CDockWidgetTab:hover #dockWidgetTabLabel { - color: #E3EAED; +#inspectorNameField { + background: transparent; + border: 1px solid transparent; + color: #F3F6FA; + font-size: 14px; + font-weight: 700; } -ads--CDockWidgetTab[activeTab="true"] QLabel, -ads--CDockWidgetTab[activeTab="true"] #dockWidgetTabLabel, -ads--CDockWidgetTab[focused="true"] QLabel, -ads--CDockWidgetTab[focused="true"] #dockWidgetTabLabel { - color: #FFFFFF; +#inspectorNameField:hover, +#inspectorNameField:focus { + background-color: #10151C; + border-color: #46536A; } -#tabCloseButton { - background-color: transparent; - border: none; - border-radius: 4px; - padding: 1px; - margin: 2px 0 2px 4px; - qproperty-icon: url(:/ads/images/close-button_dark.svg), url(:/ads/images/close-button-disabled_dark.svg) disabled; - qproperty-iconSize: 16px; +#inspectorTypeLabel { + color: #7E8A9E; + font-size: 10px; + font-weight: 600; } -#tabCloseButton:hover { - background-color: #3D454A; +#inspectorComponent { + background-color: #141A23; + border: 1px solid #252F3E; + border-radius: 7px; + margin-top: 5px; } -#tabCloseButton:pressed { - background-color: #16191A; +#inspectorComponentHeaderRow { + background-color: #171E29; + border-bottom: 1px solid #252F3E; + border-radius: 7px 7px 0 0; } -ads--CDockWidgetTab[focused="true"] > #tabCloseButton { - qproperty-icon: url(:/ads/images/close-button-focused_dark.svg); +#inspectorComponentHeader { + background: transparent; + border: none; + color: #E8ECF2; + font-weight: 650; + text-align: left; + padding: 7px 8px; } -ads--CDockWidget { - background-color: #222526; - border-top: 1px solid #303638; +#inspectorComponentHeader:hover { + background-color: #1D2634; } -QScrollArea#dockWidgetScrollArea { - background-color: #222526; +#inspectorComponentRemoveButton { + background: transparent; border: none; - border-radius: 0; - padding: 0; -} - -QWidget[dockWidgetContent="true"] { - background-color: #222526; + min-width: 22px; } -QWidget#collapsibleSection { - background-color: #222526; - border: none; - border-radius: 0; +#inspectorComponentRemoveButton:hover { + background-color: #43212A; + border: 1px solid #713141; } -QToolButton#collapsibleHeader { - background-color: transparent; - border: none; - border-radius: 0; - padding: 4px 0; - color: #E7ECEF; - font-weight: 600; - text-align: left; +#inspectorComponentBody { + background-color: #141A23; + padding: 5px; } -QToolButton#collapsibleHeader:hover { - background-color: transparent; - color: #FFFFFF; +#inspectorPropertyRow { + background: transparent; + min-height: 27px; } -QToolButton#collapsibleHeader:checked { - background-color: transparent; +#inspectorPropertyLabel { + color: #929EB0; + font-size: 11px; } -QToolButton#collapsibleHeader::menu-indicator { - image: none; +#inspectorVectorField, +#inspectorColorField, +#inspectorNumericField { + background-color: #0F141B; + border: 1px solid #263142; + border-radius: 5px; } -QWidget#collapsibleBody { - background-color: #222526; +#inspectorVectorField QDoubleSpinBox, +#inspectorNumericField QDoubleSpinBox { + background: transparent; border: none; - border-radius: 0; } -#autoHideTitleLabel { - color: #EAF0F2; - background-color: transparent; - padding-left: 6px; - font-weight: 600; +#inspectorAxisLabel { + background-color: #202A38; + border-radius: 3px; + color: #AAB5C5; + font-size: 9px; + font-weight: 750; + padding: 2px 4px; } -ads--CAutoHideSideBar { - background-color: #1B1E1F; - border: none; - qproperty-spacing: 8; +#inspectorSyncButton, +#inspectorArrayButton { + background: transparent; + border-color: transparent; + min-width: 22px; } -#sideTabsContainerWidget { - background-color: transparent; +#inspectorSyncButton[matched="true"] { + background-color: #1C3827; + border-color: #2F6841; + color: #8FE1A6; } -ads--CAutoHideSideBar[sideBarLocation="0"] { - border-bottom: 1px solid #303638; +#inspectorColorSwatch { + border: 1px solid #4A566A; + border-radius: 4px; } -ads--CAutoHideSideBar[sideBarLocation="1"] { - border-right: 1px solid #303638; +#inspectorColorText { + color: #9CA8BA; + font-family: "Menlo"; + font-size: 10px; } -ads--CAutoHideSideBar[sideBarLocation="2"] { - border-left: 1px solid #303638; +#inspectorNestedGroup { + background-color: #111720; + border: 1px solid #222C3A; + border-radius: 6px; + margin: 3px 0; + padding: 6px; } -ads--CAutoHideSideBar[sideBarLocation="3"] { - border-top: 1px solid #303638; +#inspectorNestedTitle, +#inspectorArrayTitle { + color: #AEB8C8; + font-weight: 650; } -ads--CAutoHideTab { - background-color: transparent; - border: none; - color: #AEB8BE; - padding: 4px 6px; - min-height: 24px; - qproperty-iconSize: 16px 16px; +#inspectorEmptyTitle, +#materialEditorEmpty, +#postProcessingEmpty { + color: #C4CDDA; + font-size: 14px; + font-weight: 650; } -ads--CAutoHideTab:hover { - background-color: #30383B; - color: #FFFFFF; +#inspectorEmptyHint { + color: #728096; + line-height: 1.4; } -ads--CAutoHideTab[activeTab="true"] { - background-color: #303638; - color: #FFFFFF; +#inspectorOpenAssetButton, +#inspectorAddComponentButton { + background-color: #1B2431; + border: 1px dashed #46536A; + color: #C7D0DD; + padding: 8px; } -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="0"], -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="2"], -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="0"] { - border-top: 3px solid #465157; +#inspectorAddComponentButton:hover { + background-color: #29234B; + border-color: #7C5CFC; + color: #FFFFFF; } -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="1"], -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="3"], -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="3"] { - border-bottom: 3px solid #465157; +#inspectorAudioControls { + background-color: #111720; + border-radius: 5px; } -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="1"] { - border-left: 3px solid #465157; +#materialEditorTitle, +#postProcessingTitle, +#postProcessingSectionTitle, +#inspectorCameraTitle, +#workspaceTitle { + color: #F3F6FA; + font-size: 13px; + font-weight: 700; } -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="2"] { - border-right: 3px solid #465157; +#materialEditorStatus, +#postProcessingStatus, +#workspaceStatus, +#workspaceAutoApply { + color: #7E8A9E; + font-size: 10px; } -ads--CAutoHideTab:hover[iconOnly="false"][sideBarLocation="0"], -ads--CAutoHideTab:hover[iconOnly="false"][sideBarLocation="2"], -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="0"][activeTab="true"], -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="2"][activeTab="true"], -ads--CAutoHideTab:hover[iconOnly="true"][sideBarLocation="0"], -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="0"][activeTab="true"] { - border-top: 3px solid #AEB8BE; +#materialPreview { + background-color: #090D12; + border: 1px solid #2B3648; + border-radius: 8px; } -ads--CAutoHideTab:hover[iconOnly="false"][sideBarLocation="1"], -ads--CAutoHideTab:hover[iconOnly="false"][sideBarLocation="3"], -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="1"][activeTab="true"], -ads--CAutoHideTab[iconOnly="false"][sideBarLocation="3"][activeTab="true"], -ads--CAutoHideTab:hover[iconOnly="true"][sideBarLocation="3"], -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="3"][activeTab="true"] { - border-bottom: 3px solid #AEB8BE; +#materialTextureSlot { + background-color: #121923; + border: 1px solid #263142; + border-radius: 7px; + padding: 5px; } -ads--CAutoHideTab:hover[iconOnly="true"][sideBarLocation="1"], -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="1"][activeTab="true"] { - border-left: 3px solid #AEB8BE; +#materialTexturePreview { + background-color: #0D1218; + border: 1px solid #344156; + border-radius: 6px; + color: #F472B6; + font-weight: 750; } -ads--CAutoHideTab:hover[iconOnly="true"][sideBarLocation="2"], -ads--CAutoHideTab[iconOnly="true"][sideBarLocation="2"][activeTab="true"] { - border-right: 3px solid #AEB8BE; +#materialTextureLabel { + color: #D6DDE7; + font-weight: 650; } -ads--CAutoHideDockContainer { - background-color: #222526; - border: 1px solid #6A7479; +#materialTexturePath { + color: #7D899C; } -ads--CAutoHideDockContainer ads--CDockAreaTitleBar, -ads--CAutoHideDockContainer ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { - background-color: #2B3032; +#environmentPages, +#environmentWorkspace, +#environmentPage { + background-color: #10151C; border: none; - padding: 0; } -ads--CAutoHideDockContainer #autoHideTitleLabel { - color: #FFFFFF; +QListWidget#environmentCategories { + background-color: #0E131A; + border-right: 1px solid #273141; + padding: 7px; } -ads--CAutoHideDockContainer #dockAreaAutoHideButton { - qproperty-icon: url(:/ads/images/vs-pin-button-pinned-focused_dark.svg); - qproperty-iconSize: 16px; +QListWidget#environmentCategories::item { + padding: 8px 10px; + margin: 2px 0; } -ads--CAutoHideDockContainer #dockAreaCloseButton { - qproperty-icon: url(:/ads/images/close-button-focused_dark.svg); +QListWidget#environmentCategories::item:selected { + background-color: #2A2452; + border-left: 2px solid #A78BFA; } -ads--CAutoHideDockContainer ads--CTitleBarButton:hover { - background-color: #34536A; +#environmentPageTitle { + color: #F3F6FA; + font-size: 17px; + font-weight: 750; } -ads--CAutoHideDockContainer ads--CTitleBarButton:pressed { - background-color: #17222A; +#environmentPageSubtitle { + color: #778499; } -ads--CResizeHandle { - background-color: #1B1E1F; +QGroupBox#environmentSection { + background-color: #141A23; + border-color: #273141; } -ads--CAutoHideDockContainer[sideBarLocation="0"] ads--CResizeHandle, -ads--CAutoHideDockContainer[sideBarLocation="3"] ads--CResizeHandle { - border-top: 1px solid #6A7479; +ads--CDockContainerWidget { + background-color: #080C11; } -ads--CAutoHideDockContainer[sideBarLocation="1"] ads--CResizeHandle { - border-left: 1px solid #6A7479; +ads--CDockContainerWidget > QSplitter { + background-color: #080C11; } -ads--CAutoHideDockContainer[sideBarLocation="2"] ads--CResizeHandle { - border-right: 1px solid #6A7479; +ads--CDockContainerWidget ads--CDockSplitter::handle { + background-color: #080C11; } -#DockWidgetAreaLabel { - background-color: rgba(61, 139, 255, 64); - border: 1px solid rgba(114, 199, 255, 190); - border-radius: 6px; +ads--CDockContainerWidget ads--CDockSplitter::handle:hover { + background-color: #7C5CFC; } -#workspaceToolbar { - background-color: #191C1D; - border-bottom: 1px solid #32383B; +ads--CDockAreaWidget { + background-color: #10151C; + border: 1px solid #202A38; } -#workspaceTitle { - color: #F2F5F6; - font-size: 14px; - font-weight: 650; +ads--CDockAreaWidget[focused="true"] { + border-color: #39465B; } -#workspaceStatus, -#workspaceAutoApply { - color: #89949A; - font-size: 11px; +ads--CDockAreaTitleBar { + background-color: #111720; + border-bottom: 1px solid #273141; + min-height: 30px; } -#workspaceApplyButton { - background-color: #293238; - border-color: #3C4C55; - min-height: 19px; - padding: 2px 7px; +ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { + background-color: #151C27; } -#environmentWorkspace, -#environmentPages { - background-color: #202324; - border: none; +#tabsContainerWidget { + background-color: transparent; } -QListWidget#environmentCategories { - background-color: #191C1D; +ads--CTitleBarButton { + background: transparent; border: none; - border-right: 1px solid #32383B; - border-radius: 0; - padding: 5px 3px; - outline: none; + border-radius: 4px; + min-width: 22px; + min-height: 22px; + padding: 2px; } -QListWidget#environmentCategories::item { - min-height: 26px; - padding: 3px 6px; - border: 1px solid transparent; - border-radius: 3px; +ads--CTitleBarButton:hover { + background-color: #263144; } -QListWidget#environmentCategories::item:hover { - background-color: #282E31; +ads--CDockWidgetTab { + background-color: #111720; + border: none; + border-right: 1px solid #252E3B; + border-bottom: 1px solid #273141; + padding: 2px 7px; } -QListWidget#environmentCategories::item:selected { - background-color: #303A40; - border-color: #46545C; - color: #FFFFFF; +ads--CDockWidgetTab:hover { + background-color: #18212D; } -QScrollArea#environmentScroll, -#environmentPage { - background-color: #202324; - border: none; - border-radius: 0; +ads--CDockWidgetTab[activeTab="true"] { + background-color: #171E29; + border-bottom: 2px solid #7C5CFC; } -#environmentPageTitle { - color: #F0F3F4; - font-size: 17px; - font-weight: 650; +ads--CDockWidgetTab[focused="true"] { + background-color: #1A2230; } -#environmentPageSubtitle { - color: #838E94; +ads--CDockWidgetTab #dockWidgetTabLabel { + color: #7F8B9D; font-size: 11px; + padding: 4px 2px; } -QGroupBox#environmentSection { - background-color: #242829; - border: 1px solid #363D40; - border-radius: 3px; - margin-top: 15px; - padding: 7px; +ads--CDockWidgetTab[activeTab="true"] #dockWidgetTabLabel, +ads--CDockWidgetTab[focused="true"] #dockWidgetTabLabel { + color: #F1F4F8; } -QGroupBox#environmentSection::title { - background-color: #242829; - color: #BDC6CA; - left: 7px; - padding: 0 4px; +#tabCloseButton, +#dockAreaCloseButton, +#detachGroupButton, +#dockAreaAutoHideButton, +#dockAreaMinimizeButton, +#tabsMenuButton { + background: transparent; + border: none; + min-width: 20px; + min-height: 20px; } -#compactVectorField { - background-color: #191C1D; - border: 1px solid #363D41; - border-radius: 3px; +#tabCloseButton:hover, +#dockAreaCloseButton:hover, +#detachGroupButton:hover, +#dockAreaAutoHideButton:hover, +#dockAreaMinimizeButton:hover, +#tabsMenuButton:hover { + background-color: #2A3444; } -#compactAxisLabel { - color: #718087; - font-size: 10px; - font-weight: 700; - min-width: 9px; +ads--CDockWidget { + background-color: #10151C; } -#compactVectorField QDoubleSpinBox { - background-color: transparent; - border: none; - border-radius: 0; - padding: 2px 1px; +ads--CAutoHideSideBar, +#sideTabsContainerWidget { + background-color: #090D12; +} + +ads--CAutoHideTab { + background-color: #111720; + border: 1px solid #263142; + color: #7F8B9D; + padding: 5px; } -#compactColorButton { - border: 1px solid #566167; +ads--CAutoHideTab:hover, +ads--CAutoHideTab[activeTab="true"] { + background-color: #2A2452; + border-color: #6F55E8; color: #FFFFFF; - font-weight: 650; - text-align: left; } #projectBrowserRoot, -#projectBrowserContent, -#createProjectDialog { - background-color: #181B1D; - font-family: "Manrope", "Helvetica Neue", sans-serif; +#projectBrowserContent { + background-color: #0D1117; } #projectSidebar { - background-color: #111315; - border-right: 1px solid #2A2E31; + background-color: #0A0E13; + border-right: 1px solid #202836; } #projectBrand { - background: transparent; - color: #F4F7F8; - font-size: 22px; - font-weight: 700; + color: #F5F7FA; + font-size: 16px; + font-weight: 750; +} + +#projectSidebarVersion { + color: #68758A; + font-size: 10px; + font-weight: 600; } #projectNavSelected { - background-color: #252A2D; - border: 1px solid #32383C; - border-radius: 8px; - color: #F4F7F8; - padding: 9px 12px; + background-color: #24203F; + border: 1px solid #493A86; + border-left: 3px solid #8F76FF; + color: #EEE9FF; + padding: 8px 11px; text-align: left; } #projectNavSelected:disabled { - background-color: #252A2D; - border-color: #32383C; - color: #F4F7F8; -} - -#projectSidebarVersion { - background: transparent; - color: #697277; - font-size: 11px; + color: #EEE9FF; } #projectBrowserTitle, #dialogTitle { - background: transparent; - color: #F7F9FA; - font-size: 28px; - font-weight: 700; + color: #F4F6FA; + font-size: 24px; + font-weight: 750; } #projectBrowserSubtitle, #dialogSubtitle, -#emptyStateSubtitle { - background: transparent; - color: #889197; - font-size: 13px; -} - -#primaryAction { - background-color: #2F85F5; - border: 1px solid #55A0FF; - border-radius: 7px; - color: #FFFFFF; - font-weight: 600; - padding: 8px 14px; -} - -#primaryAction:hover { - background-color: #3B91FF; - border-color: #72B1FF; -} - -#primaryAction:pressed { - background-color: #2876DA; -} - -#primaryAction:disabled { - background-color: #2A3034; - border-color: #363D41; - color: #697277; -} - -QPushButton[secondary="true"] { - background-color: #252A2D; - border: 1px solid #3A4145; - border-radius: 7px; - color: #DDE3E6; - padding: 8px 14px; -} - -QPushButton[secondary="true"]:hover { - background-color: #2D3337; - border-color: #4A5358; +#emptyStateSubtitle, +#templateDescription { + color: #7F8B9D; } #projectSearch { - background-color: #222629; - border: 1px solid #343A3E; - border-radius: 8px; - color: #EEF2F4; + background-color: #111720; + border: 1px solid #2A3547; + border-radius: 7px; padding: 9px 12px; + font-size: 13px; } #projectSearch:focus { - border-color: #4B9EFF; + border-color: #7C5CFC; } #projectList { - background: transparent; + background-color: transparent; border: none; - outline: none; } #projectList::item { background: transparent; border: none; + padding: 0; } #projectRow { - background-color: #222629; - border: 1px solid #30363A; - border-radius: 10px; + background-color: #141A23; + border: 1px solid #252F3E; + border-radius: 8px; } #projectRow:hover { - background-color: #282D31; - border-color: #465057; + background-color: #18212D; + border-color: #40506A; } #projectRow[available="false"] { - background-color: #1D2022; - border-color: #532F34; + background-color: #11161D; + border-color: #1D2530; +} + +#projectIcon, +#templateIcon { + background-color: #1D2532; + border: 1px solid #334056; + border-radius: 7px; } #projectName { - background: transparent; - color: #F0F4F5; + color: #EEF2F7; font-size: 14px; - font-weight: 650; + font-weight: 700; } #projectPath, #projectDate { - background: transparent; - color: #788187; - font-size: 11px; + color: #768398; + font-size: 10px; } #rendererBadge { - background-color: #243B51; - border: 1px solid #31536E; - border-radius: 9px; - color: #9ED1FF; - font-size: 10px; - font-weight: 600; - padding: 3px 8px; + background-color: #1C3527; + border: 1px solid #2C6340; + border-radius: 5px; + color: #8DE2A5; + padding: 3px 7px; + font-size: 9px; + font-weight: 700; } #projectMoreButton { background: transparent; - border: none; - color: #98A2A8; - font-size: 14px; - padding: 6px; + border-color: transparent; } #projectMoreButton:hover { - background-color: #363D41; - border-radius: 6px; - color: #FFFFFF; + background-color: #253044; + border-color: #3B4860; } #projectEmptyState { - background-color: #1D2022; - border: 1px dashed #343A3E; - border-radius: 12px; + background-color: #10151C; + border: 1px dashed #2F3A4D; + border-radius: 9px; } #emptyStateTitle { - background: transparent; - color: #E9EEF0; - font-size: 17px; - font-weight: 650; + color: #CDD5E1; + font-size: 16px; + font-weight: 700; +} + +#createProjectDialog { + background-color: #10151C; } QFrame[templateCard="true"] { - background-color: #222629; - border: 1px solid #343A3E; - border-radius: 10px; + background-color: #141A23; + border: 1px solid #293445; + border-radius: 8px; } QFrame[templateCard="true"]:hover { - background-color: #282E32; - border-color: #4B5961; + background-color: #1A2230; + border-color: #46536A; } QFrame[templateCard="true"][selected="true"] { - background-color: #20354A; - border: 2px solid #4B9EFF; + background-color: #29234B; + border-color: #7C5CFC; } #templateOption { - background: transparent; - color: #F3F6F7; - font-size: 14px; + color: #E7ECF3; font-weight: 650; } -#templateDescription { - background: transparent; - color: #879096; +#fieldLabel { + color: #AAB5C5; font-size: 11px; + font-weight: 650; } -#fieldLabel { - background: transparent; - color: #B3BCC1; +#dialogError { + color: #FF7D8A; font-size: 11px; - font-weight: 600; } -#dialogError { - background-color: #41262A; - border: 1px solid #704048; +QPushButton[secondary="true"] { + background-color: #171E29; + border-color: #344156; +} + +QPushButton[secondary="true"]:hover { + background-color: #222C3C; + border-color: #4A5870; +} + +#commandPaletteDialog, +#globalSearchDialog { + background-color: #111720; + border: 1px solid #46536A; + border-radius: 10px; +} + +#commandPaletteSearch, +#globalSearchField { + background-color: #0D1218; + border: 1px solid #3A465A; border-radius: 7px; - color: #FFB4BE; - padding: 8px 10px; + padding: 10px 12px; + font-size: 14px; +} + +#commandPaletteSearch:focus, +#globalSearchField:focus { + border-color: #8F76FF; +} + +#commandPaletteList, +#globalSearchResults { + background-color: #111720; + border: none; + padding: 5px; +} + +#commandPaletteList::item, +#globalSearchResults::item { + min-height: 30px; + padding: 6px 8px; } diff --git a/editor/styling/icons.cpp b/editor/styling/icons.cpp index baabeeea..773f6df1 100644 --- a/editor/styling/icons.cpp +++ b/editor/styling/icons.cpp @@ -90,6 +90,8 @@ ushort codepoint(styling::Icon icon) { return 0xE2A0; case styling::Icon::Image: return 0xE2CA; + case styling::Icon::Info: + return 0xE2CE; case styling::Icon::Layout: return 0xE6D6; case styling::Icon::Lightbulb: diff --git a/editor/styling/theme.cpp b/editor/styling/theme.cpp index b4d824d5..7aa7588c 100644 --- a/editor/styling/theme.cpp +++ b/editor/styling/theme.cpp @@ -16,12 +16,12 @@ void styling::applyColorPalette(QApplication& app) { QPalette p; - const QColor bg = QColor("#222526"); - const QColor panel = QColor("#282C2E"); - const QColor panel2 = QColor("#1A1D1E"); - const QColor text = QColor("#DCE2E5"); - const QColor mutedText = QColor("#8F9AA0"); - const QColor accent = QColor("#3D8BFF"); + const QColor bg = QColor("#0D1117"); + const QColor panel = QColor("#151B24"); + const QColor panel2 = QColor("#10151C"); + const QColor text = QColor("#E7ECF3"); + const QColor mutedText = QColor("#8490A4"); + const QColor accent = QColor("#7C5CFC"); p.setColor(QPalette::Window, bg); p.setColor(QPalette::WindowText, text); @@ -30,24 +30,24 @@ void styling::applyColorPalette(QApplication& app) { p.setColor(QPalette::ToolTipBase, panel2); p.setColor(QPalette::ToolTipText, text); p.setColor(QPalette::Text, text); - p.setColor(QPalette::Button, QColor("#303538")); + p.setColor(QPalette::Button, QColor("#1A2230")); p.setColor(QPalette::ButtonText, text); p.setColor(QPalette::BrightText, QColor("#FFFFFF")); - p.setColor(QPalette::Light, QColor("#4A555B")); - p.setColor(QPalette::Midlight, QColor("#3A4246")); - p.setColor(QPalette::Mid, QColor("#303638")); - p.setColor(QPalette::Dark, QColor("#151819")); - p.setColor(QPalette::Shadow, QColor("#0D0F10")); + p.setColor(QPalette::Light, QColor("#364154")); + p.setColor(QPalette::Midlight, QColor("#2A3444")); + p.setColor(QPalette::Mid, QColor("#222B39")); + p.setColor(QPalette::Dark, QColor("#090C11")); + p.setColor(QPalette::Shadow, QColor("#05070A")); p.setColor(QPalette::Highlight, accent); p.setColor(QPalette::HighlightedText, QColor("#FFFFFF")); p.setColor(QPalette::PlaceholderText, mutedText); - p.setColor(QPalette::Disabled, QPalette::WindowText, QColor("#727B80")); - p.setColor(QPalette::Disabled, QPalette::Text, QColor("#727B80")); - p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#727B80")); - p.setColor(QPalette::Disabled, QPalette::Button, QColor("#292D2F")); - p.setColor(QPalette::Disabled, QPalette::Base, QColor("#25292B")); - p.setColor(QPalette::Disabled, QPalette::Highlight, QColor("#34404A")); + p.setColor(QPalette::Disabled, QPalette::WindowText, QColor("#566174")); + p.setColor(QPalette::Disabled, QPalette::Text, QColor("#566174")); + p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#566174")); + p.setColor(QPalette::Disabled, QPalette::Button, QColor("#131922")); + p.setColor(QPalette::Disabled, QPalette::Base, QColor("#11161D")); + p.setColor(QPalette::Disabled, QPalette::Highlight, QColor("#332A5E")); app.setPalette(p); } diff --git a/editor/views/editor/editor.cpp b/editor/views/editor/editor.cpp index d80694e3..d98a4e98 100644 --- a/editor/views/editor/editor.cpp +++ b/editor/views/editor/editor.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -52,10 +53,14 @@ #include #include #include +#include +#include #include #include #include +#include #include +#include #include #include @@ -64,6 +69,7 @@ #include "DockManager.h" #include "editor/debug.h" +#include "editor/styling/icons.h" #include "editor/views/fileExplorer.h" #include "editor/views/hierarchyPanel.h" #include "editor/views/inspectorView.h" @@ -76,6 +82,50 @@ namespace { constexpr int DockStateVersion = 8; constexpr auto DockStateKey = "docking/state/v8"; +QIcon commandIcon(const QString &name) { + const QString command = name.toLower(); + if (command.contains("save")) + return styling::icon(styling::Icon::FloppyDisk, "#F5B942"); + if (command.contains("open")) + return styling::icon(styling::Icon::FolderOpen, "#55C2FF"); + if (command.contains("new") || command.contains("create") || + command.contains("add")) + return styling::icon(styling::Icon::Plus, "#A78BFA"); + if (command.contains("export")) + return styling::icon(styling::Icon::Export, "#55C2FF"); + if (command.contains("build")) + return styling::icon(styling::Icon::Package, "#F5B942"); + if (command.contains("run") || command.contains("play")) + return styling::icon(styling::Icon::RocketLaunch, "#52D273"); + if (command.contains("stop")) + return styling::icon(styling::Icon::Stop, "#FF6B7A"); + if (command.contains("reload") || command.contains("refresh") || + command.contains("undo")) + return styling::icon(styling::Icon::ArrowCounterClockwise, "#55C2FF"); + if (command.contains("redo")) + return styling::icon(styling::Icon::ArrowClockwise, "#55C2FF"); + if (command.contains("settings")) + return styling::icon(styling::Icon::Gear, "#A78BFA"); + if (command.contains("find") || command.contains("search") || + command.contains("palette")) + return styling::icon(styling::Icon::MagnifyingGlass, "#55C2FF"); + if (command.contains("screenshot")) + return styling::icon(styling::Icon::Camera, "#F472B6"); + if (command.contains("delete") || command.contains("remove")) + return styling::icon(styling::Icon::Trash, "#FF6B7A"); + if (command.contains("layout") || command.contains("window")) + return styling::icon(styling::Icon::Layout, "#A78BFA"); + if (command.contains("close") || command.contains("quit")) + return styling::icon(styling::Icon::Close, "#FF6B7A"); + if (command.contains("camera")) + return styling::icon(styling::Icon::Camera, "#F472B6"); + if (command.contains("light")) + return styling::icon(styling::Icon::Lightbulb, "#F5B942"); + if (command.contains("object")) + return styling::icon(styling::Icon::Cube, "#A78BFA"); + return {}; +} + bool copyExportPath(const QString &sourcePath, const QString &destinationPath, QString *error) { const QFileInfo source(sourcePath); @@ -176,6 +226,7 @@ EditorWindow::EditorWindow(const QString &projectFile, QWidget *parent) setupWindow(); setupMenus(); setupDocks(); + setupWorkspaceBar(); restoreLayout(); qApp->installEventFilter(this); @@ -187,7 +238,8 @@ void EditorWindow::setupWindow() { projectName = project.has_value() ? project->name : QStringLiteral("Project"); updateWindowTitle(false); resize(1280, 720); - menuBar()->setNativeMenuBar(true); + menuBar()->setNativeMenuBar(false); + menuBar()->setObjectName("atlasMenuBar"); ads::CDockManager::setConfigFlag(ads::CDockManager::OpaqueSplitterResize, true); @@ -229,6 +281,7 @@ void EditorWindow::setupMenus() { const QString &shortcut, const std::function &handler) { QAction *action = menu->addAction(name, this, handler); + action->setIcon(commandIcon(name)); if (!shortcut.isEmpty()) { const bool plainShift = shortcut.startsWith("Shift+") && !shortcut.contains("Meta+") && @@ -248,6 +301,8 @@ void EditorWindow::setupMenus() { addCommand(fileMenu, "New Scene", "Meta+N", [this] { createScene(); }); addCommand(fileMenu, "Open Scene…", "Meta+O", [this] { openScene(); }); auto *saveAction = fileMenu->addAction("Save Scene"); + saveAction->setIcon( + styling::icon(styling::Icon::FloppyDisk, "#F5B942")); saveAction->setShortcut(QKeySequence::Save); saveAction->setShortcutContext(Qt::ApplicationShortcut); connect(saveAction, &QAction::triggered, this, [this] { @@ -279,6 +334,8 @@ void EditorWindow::setupMenus() { auto *editMenu = menuBar()->addMenu("Edit"); auto *undoAction = editMenu->addAction("Undo"); + undoAction->setIcon( + styling::icon(styling::Icon::ArrowCounterClockwise, "#55C2FF")); undoAction->setShortcut(QKeySequence::Undo); undoAction->setShortcutContext(Qt::ApplicationShortcut); connect(undoAction, &QAction::triggered, this, [this] { @@ -293,6 +350,8 @@ void EditorWindow::setupMenus() { } }); auto *redoAction = editMenu->addAction("Redo"); + redoAction->setIcon( + styling::icon(styling::Icon::ArrowClockwise, "#55C2FF")); redoAction->setShortcut(QKeySequence::Redo); redoAction->setShortcutContext(Qt::ApplicationShortcut); connect(redoAction, &QAction::triggered, this, [this] { @@ -416,6 +475,8 @@ void EditorWindow::setupMenus() { viewMenu = menuBar()->addMenu("View"); auto *resetLayoutAction = viewMenu->addAction("Reset Layout"); + resetLayoutAction->setIcon( + styling::icon(styling::Icon::Layout, "#A78BFA")); connect(resetLayoutAction, &QAction::triggered, this, [this] { if (coreManager != nullptr && !defaultDockState.isEmpty()) { restoringLayout = true; @@ -498,6 +559,7 @@ void EditorWindow::setupMenus() { QStringLiteral("Atlas Engine %1\nby Neutral Software") .arg(QStringLiteral(ATLAS_VERSION))); }); + aboutAction->setIcon(styling::icon(styling::Icon::Info, "#55C2FF")); aboutAction->setMenuRole(QAction::AboutRole); } @@ -520,15 +582,15 @@ void EditorWindow::setupDocks() { .title = "Viewport", .widget = viewportTools, .area = EditorDockArea::Center, - .icon = style()->standardIcon(QStyle::SP_DirOpenIcon)}); + .icon = styling::icon(styling::Icon::CubeFocus, "#55C2FF")}); hierarchyPanel = new HierarchyPanel(viewportPanel); auto *hierarchyDock = dockManager->addPanel( {.id = "hierarchy", - .title = "Hierarchy Panel", + .title = "Scene", .widget = hierarchyPanel, .area = EditorDockArea::Left, - .icon = style()->standardIcon(QStyle::SP_DirOpenIcon)}); + .icon = styling::icon(styling::Icon::TreeStructure, "#A78BFA")}); inspectorPanel = new InspectorPanel(viewportPanel, projectFile); auto *inspectorDock = dockManager->addPanel( @@ -536,7 +598,7 @@ void EditorWindow::setupDocks() { .title = "Inspector", .widget = inspectorPanel, .area = EditorDockArea::Right, - .icon = style()->standardIcon(QStyle::SP_DirOpenIcon)}); + .icon = styling::icon(styling::Icon::SlidersHorizontal, "#F5B942")}); contentBrowser = new ContentBrowserPanel(projectFile); auto *contentDock = dockManager->addPanel( @@ -544,7 +606,7 @@ void EditorWindow::setupDocks() { .title = "Content Browser", .widget = contentBrowser, .area = EditorDockArea::Bottom, - .icon = style()->standardIcon(QStyle::SP_DirOpenIcon)}); + .icon = styling::icon(styling::Icon::FolderOpen, "#55C2FF")}); materialEditorPanel = new MaterialEditorPanel(viewportPanel); auto *materialDock = dockManager->addPanel( @@ -552,7 +614,7 @@ void EditorWindow::setupDocks() { .title = "Material Editor", .widget = materialEditorPanel, .area = EditorDockArea::Right, - .icon = style()->standardIcon(QStyle::SP_FileDialogContentsView)}); + .icon = styling::icon(styling::Icon::Material, "#F472B6")}); coreManager->addDockWidgetTabToArea(materialDock, viewportDock->dockAreaWidget()); @@ -562,7 +624,7 @@ void EditorWindow::setupDocks() { .title = "Post Processing", .widget = postProcessingPanel, .area = EditorDockArea::Right, - .icon = style()->standardIcon(QStyle::SP_ComputerIcon)}); + .icon = styling::icon(styling::Icon::Sparkle, "#52D273")}); coreManager->addDockWidgetTabToArea(postProcessingDock, viewportDock->dockAreaWidget()); @@ -588,7 +650,7 @@ void EditorWindow::setupDocks() { if (windowMenu != nullptr) { windowMenu->addSeparator(); for (ads::CDockWidget *dock : managedDocks) { - dock->toggleViewAction()->setIcon({}); + dock->toggleViewAction()->setIcon(dock->icon()); windowMenu->addAction(dock->toggleViewAction()); } windowMenu->addSeparator(); @@ -607,6 +669,7 @@ void EditorWindow::setupDocks() { dock->setAsCurrentTab(); dock->raise(); }); + action->setIcon(dock->icon()); action->setShortcut(QKeySequence( QStringLiteral("Ctrl+%1").arg(index + 1))); action->setShortcutContext(Qt::ApplicationShortcut); @@ -650,6 +713,101 @@ void EditorWindow::setupDocks() { }); } +void EditorWindow::setupWorkspaceBar() { + auto *bar = new QToolBar("Workspace", this); + bar->setObjectName("workspaceBar"); + bar->setMovable(false); + bar->setFloatable(false); + bar->setIconSize(QSize(17, 17)); + bar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + addToolBar(Qt::TopToolBarArea, bar); + + auto *identity = new QWidget(bar); + identity->setObjectName("workspaceIdentity"); + auto *identityLayout = new QHBoxLayout(identity); + identityLayout->setContentsMargins(10, 0, 14, 0); + identityLayout->setSpacing(8); + auto *mark = new QLabel(identity); + mark->setObjectName("workspaceMark"); + mark->setPixmap(windowIcon().pixmap(22, 22)); + auto *brand = new QLabel("ATLAS", identity); + brand->setObjectName("workspaceBrand"); + auto *project = new QLabel(projectName, identity); + project->setObjectName("workspaceProject"); + identityLayout->addWidget(mark); + identityLayout->addWidget(brand); + identityLayout->addWidget(project); + bar->addWidget(identity); + + auto *modes = new QButtonGroup(bar); + modes->setExclusive(true); + auto addMode = [this, bar, modes](const QString &text, + styling::Icon icon, + const QColor &color, + const QString &dockId, + bool selected = false) { + auto *button = new QToolButton(bar); + button->setObjectName("workspaceModeButton"); + button->setText(text); + button->setIcon(styling::icon(icon, color)); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setCheckable(true); + button->setChecked(selected); + modes->addButton(button); + bar->addWidget(button); + connect(button, &QToolButton::clicked, this, + [this, dockId] { + if (auto *dock = dockManager->panel(dockId)) { + dock->toggleView(true); + dock->setAsCurrentTab(); + dock->raise(); + } + }); + }; + addMode("Layout", styling::Icon::Layout, "#A78BFA", "viewport", true); + addMode("Materials", styling::Icon::Material, "#F472B6", + "materialEditor"); + addMode("Look Dev", styling::Icon::Sparkle, "#52D273", + "postProcessing"); + addMode("Assets", styling::Icon::FolderOpen, "#55C2FF", "fileExplorer"); + + auto *spacer = new QWidget(bar); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + bar->addWidget(spacer); + + auto *save = new QToolButton(bar); + save->setObjectName("workspaceUtilityButton"); + save->setIcon(styling::icon(styling::Icon::FloppyDisk, "#F5B942")); + save->setToolTip("Save Scene"); + bar->addWidget(save); + connect(save, &QToolButton::clicked, this, [this] { + if (materialEditorPanel != nullptr && materialEditorPanel->isVisible()) + materialEditorPanel->saveMaterial(); + if (viewportPanel != nullptr) + viewportPanel->saveRuntimeScene(); + }); + + auto *build = new QToolButton(bar); + build->setObjectName("workspaceBuildButton"); + build->setText("Build"); + build->setIcon(styling::icon(styling::Icon::Package, "#F5B942")); + build->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + build->setToolTip("Build Project"); + bar->addWidget(build); + connect(build, &QToolButton::clicked, this, + [this] { runProjectCommand(true); }); + + auto *launch = new QToolButton(bar); + launch->setObjectName("workspaceLaunchButton"); + launch->setText("Launch"); + launch->setIcon(styling::icon(styling::Icon::RocketLaunch, "#52D273")); + launch->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + launch->setToolTip("Run Project"); + bar->addWidget(launch); + connect(launch, &QToolButton::clicked, this, + [this] { runProjectCommand(false); }); +} + void EditorWindow::createScene() { const QString root = QFileInfo(projectFile).absolutePath(); QString path = QFileDialog::getSaveFileName( @@ -1063,13 +1221,16 @@ void EditorWindow::showExportDialog() { void EditorWindow::showCommandPalette() { QDialog dialog(this); + dialog.setObjectName("commandPaletteDialog"); dialog.setWindowTitle("Command Palette"); dialog.setWindowFlags(dialog.windowFlags() | Qt::FramelessWindowHint); dialog.resize(620, 430); auto *layout = new QVBoxLayout(&dialog); auto *search = new QLineEdit(&dialog); + search->setObjectName("commandPaletteSearch"); search->setPlaceholderText("Type a command…"); auto *commands = new QListWidget(&dialog); + commands->setObjectName("commandPaletteList"); layout->addWidget(search); layout->addWidget(commands, 1); const QList actions = findChildren(); @@ -1080,6 +1241,7 @@ void EditorWindow::showCommandPalette() { } auto *item = new QListWidgetItem(commands); item->setText(action->text().remove('&')); + item->setIcon(action->icon()); item->setData(Qt::UserRole, QVariant::fromValue( reinterpret_cast(action))); @@ -1160,13 +1322,16 @@ void EditorWindow::showCommandPalette() { void EditorWindow::showGlobalSearch() { QDialog dialog(this); + dialog.setObjectName("globalSearchDialog"); dialog.setWindowTitle("Search Atlas Project"); dialog.setWindowFlags(dialog.windowFlags() | Qt::FramelessWindowHint); dialog.resize(680, 460); auto *layout = new QVBoxLayout(&dialog); auto *search = new QLineEdit(&dialog); + search->setObjectName("globalSearchField"); search->setPlaceholderText("Search scenes, assets, and commands…"); auto *results = new QListWidget(&dialog); + results->setObjectName("globalSearchResults"); layout->addWidget(search); layout->addWidget(results, 1); constexpr int SearchKindRole = Qt::UserRole + 1; @@ -1182,6 +1347,7 @@ void EditorWindow::showGlobalSearch() { continue; auto *item = new QListWidgetItem( QStringLiteral("Asset %1").arg(relative), results); + item->setIcon(styling::icon(styling::Icon::File, "#55C2FF")); item->setToolTip(path); item->setData(SearchKindRole, 0); item->setData(SearchValueRole, path); @@ -1200,6 +1366,8 @@ void EditorWindow::showGlobalSearch() { if (!name.isEmpty() && id >= 0) { auto *item = new QListWidgetItem( QStringLiteral("Object %1").arg(name), results); + item->setIcon( + styling::icon(styling::Icon::Cube, "#A78BFA")); item->setToolTip(object.value("type").toString()); item->setData(SearchKindRole, 1); item->setData(SearchValueRole, id); @@ -1216,6 +1384,7 @@ void EditorWindow::showGlobalSearch() { auto *item = new QListWidgetItem( QStringLiteral("Command %1").arg(action->text().remove('&')), results); + item->setIcon(action->icon()); item->setData(SearchKindRole, 2); item->setData( SearchValueRole, diff --git a/editor/views/editor/hierarchy.cpp b/editor/views/editor/hierarchy.cpp index c1857df3..243ff0da 100644 --- a/editor/views/editor/hierarchy.cpp +++ b/editor/views/editor/hierarchy.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include @@ -40,43 +41,27 @@ namespace { constexpr int ObjectIdRole = Qt::UserRole + 1; constexpr int ObjectTypeRole = Qt::UserRole + 2; -QIcon hierarchyIcon(QWidget *widget, const QString &type) { +QIcon hierarchyIcon(QWidget *, const QString &type) { const QString normalized = type.toLower(); - QStyle::StandardPixmap fallback = QStyle::SP_FileIcon; - QString themeName = "application-x-executable"; - - if (normalized == "scene") { - fallback = QStyle::SP_DesktopIcon; - themeName = "view-grid"; - } else if (normalized == "compound" || normalized == "group") { - fallback = QStyle::SP_DirClosedIcon; - themeName = "folder"; - } else if (normalized == "camera") { - fallback = QStyle::SP_ComputerIcon; - themeName = "camera-photo"; - } else if (normalized == "environment") { - fallback = QStyle::SP_DesktopIcon; - themeName = "weather-clear"; - } else if (normalized.contains("light") || normalized == "sun") { - fallback = QStyle::SP_MessageBoxInformation; - themeName = "weather-clear"; - } else if (normalized == "terrain" || normalized == "landscape") { - fallback = QStyle::SP_DriveHDIcon; - themeName = "applications-graphics"; - } else if (normalized == "particleemitter" || normalized == "particles") { - fallback = QStyle::SP_BrowserReload; - themeName = "weather-showers-scattered"; - } else if (normalized == "model") { - fallback = QStyle::SP_FileDialogContentsView; - themeName = "model"; - } else if (normalized == "cube" || normalized == "sphere" || - normalized == "plane" || normalized == "pyramid" || - normalized == "capsule" || normalized == "solid") { - fallback = QStyle::SP_DirIcon; - themeName = "applications-games"; - } - - return QIcon::fromTheme(themeName, widget->style()->standardIcon(fallback)); + if (normalized == "scene") + return styling::icon(styling::Icon::CubeFocus, "#55C2FF"); + if (normalized == "compound" || normalized == "group") + return styling::icon(styling::Icon::Folder, "#8490A4"); + if (normalized == "camera") + return styling::icon(styling::Icon::Camera, "#F472B6"); + if (normalized == "environment") + return styling::icon(styling::Icon::Globe, "#55C2FF"); + if (normalized.contains("light") || normalized == "sun") + return styling::icon(styling::Icon::Lightbulb, "#F5B942"); + if (normalized == "terrain" || normalized == "landscape") + return styling::icon(styling::Icon::Mountains, "#52D273"); + if (normalized == "particleemitter" || normalized == "particles") + return styling::icon(styling::Icon::Sparkle, "#A78BFA"); + if (normalized == "model") + return styling::icon(styling::Icon::Cube, "#55C2FF"); + if (normalized == "sphere") + return styling::icon(styling::Icon::Sphere, "#A78BFA"); + return styling::icon(styling::Icon::Cube, "#A78BFA"); } QString objectSignature(const QJsonArray &objects) { @@ -109,7 +94,7 @@ HierarchyPanel::HierarchyPanel(ViewportPanel *viewport, QWidget *parent) addButton = new QToolButton(toolbar); addButton->setObjectName("panelAddButton"); - addButton->setIcon(style()->standardIcon(QStyle::SP_FileDialogNewFolder)); + addButton->setIcon(styling::icon(styling::Icon::Plus, "#A78BFA")); addButton->setText("Add"); addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addButton->setPopupMode(QToolButton::InstantPopup); @@ -118,7 +103,7 @@ HierarchyPanel::HierarchyPanel(ViewportPanel *viewport, QWidget *parent) moreButton = new QToolButton(toolbar); moreButton->setObjectName("panelMoreButton"); moreButton->setIcon( - style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton)); + styling::icon(styling::Icon::DotsVertical, "#8490A4")); moreButton->setPopupMode(QToolButton::InstantPopup); moreButton->setToolTip("Hierarchy actions"); diff --git a/editor/views/editor/inspector.cpp b/editor/views/editor/inspector.cpp index 8b371482..0b80c259 100644 --- a/editor/views/editor/inspector.cpp +++ b/editor/views/editor/inspector.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include @@ -170,44 +171,35 @@ bool isColorProperty(const QString &name, const QJsonArray &array) { (array.size() == 3 || array.size() == 4) && isNumericArray(array); } -QIcon inspectorIcon(QWidget *widget, const QString &type) { +QIcon inspectorIcon(QWidget *, const QString &type) { const QString normalized = type.toLower(); - QStyle::StandardPixmap fallback = QStyle::SP_FileIcon; - QString themeName = "application-x-executable"; - if (normalized == "folder") { - fallback = QStyle::SP_DirIcon; - themeName = "folder"; - } else if (normalized.contains("camera")) { - fallback = QStyle::SP_ComputerIcon; - themeName = "camera-photo"; - } else if (normalized.contains("environment") || - normalized.contains("atmosphere")) { - fallback = QStyle::SP_DesktopIcon; - themeName = "weather-clear"; - } else if (normalized.contains("light") || normalized == "sun") { - fallback = QStyle::SP_MessageBoxInformation; - themeName = "weather-clear"; - } else if (normalized.contains("terrain")) { - fallback = QStyle::SP_DriveHDIcon; - themeName = "applications-graphics"; - } else if (normalized.contains("particle")) { - fallback = QStyle::SP_BrowserReload; - themeName = "weather-showers-scattered"; - } else if (normalized.contains("audio") || normalized == "wav" || - normalized == "mp3" || normalized == "ogg" || - normalized == "flac") { - fallback = QStyle::SP_MediaVolume; - themeName = "audio-x-generic"; - } else if (normalized == "model") { - fallback = QStyle::SP_FileDialogContentsView; - themeName = "model"; - } else if (normalized == "solid" || normalized == "cube" || - normalized == "sphere" || normalized == "plane" || - normalized == "pyramid" || normalized == "capsule") { - fallback = QStyle::SP_DirIcon; - themeName = "applications-games"; - } - return QIcon::fromTheme(themeName, widget->style()->standardIcon(fallback)); + if (normalized == "folder") + return styling::icon(styling::Icon::Folder, "#55C2FF"); + if (normalized.contains("camera")) + return styling::icon(styling::Icon::Camera, "#F472B6"); + if (normalized.contains("environment") || + normalized.contains("atmosphere")) + return styling::icon(styling::Icon::Globe, "#55C2FF"); + if (normalized.contains("light") || normalized == "sun") + return styling::icon(styling::Icon::Lightbulb, "#F5B942"); + if (normalized.contains("terrain")) + return styling::icon(styling::Icon::Mountains, "#52D273"); + if (normalized.contains("particle")) + return styling::icon(styling::Icon::Sparkle, "#A78BFA"); + if (normalized.contains("audio") || normalized == "wav" || + normalized == "mp3" || normalized == "ogg" || + normalized == "flac") + return styling::icon(styling::Icon::MusicNote, "#52D273"); + if (normalized.contains("material")) + return styling::icon(styling::Icon::Material, "#F472B6"); + if (normalized.contains("script") || normalized == "ts" || + normalized == "js") + return styling::icon(styling::Icon::FileCode, "#55C2FF"); + if (normalized.contains("rigidbody") || normalized.contains("joint")) + return styling::icon(styling::Icon::Wrench, "#F5B942"); + if (normalized == "sphere") + return styling::icon(styling::Icon::Sphere, "#A78BFA"); + return styling::icon(styling::Icon::Cube, "#A78BFA"); } QString componentTitle(const QString &type) { @@ -619,7 +611,7 @@ void addSyncPicker(QHBoxLayout *layout, const QString &path, auto *button = new QToolButton(parent); button->setObjectName("inspectorSyncButton"); button->setIcon( - parent->style()->standardIcon(QStyle::SP_BrowserReload)); + styling::icon(styling::Icon::ArrowCounterClockwise, "#52D273")); button->setToolTip("Match this value with another property"); button->setPopupMode(QToolButton::InstantPopup); auto showMatch = [button, valueEditor](const QString &name) { @@ -1173,7 +1165,7 @@ QFrame *componentCard(const QString &title, const QJsonObject &properties, auto *removeButton = new QToolButton(headerRow); removeButton->setObjectName("inspectorComponentRemoveButton"); removeButton->setIcon( - card->style()->standardIcon(QStyle::SP_DialogDiscardButton)); + styling::icon(styling::Icon::Trash, "#FF6B7A")); removeButton->setToolTip(QStringLiteral("Remove %1").arg(title)); headerLayout->addWidget(removeButton); QObject::connect(removeButton, &QToolButton::clicked, card, remove); @@ -1512,15 +1504,17 @@ void InspectorPanel::showObject(const QJsonObject &object) { controlsLayout->setContentsMargins(8, 4, 8, 6); controlsLayout->setSpacing(5); const QStringList audioActions{"Play", "Pause", "Stop"}; - const QList audioIcons{ - QStyle::SP_MediaPlay, QStyle::SP_MediaPause, - QStyle::SP_MediaStop}; + const QList audioIcons{ + styling::Icon::Play, styling::Icon::Pause, + styling::Icon::Stop}; + const QList audioColors{ + QColor("#52D273"), QColor("#F5B942"), QColor("#FF6B7A")}; for (int actionIndex = 0; actionIndex < audioActions.size(); ++actionIndex) { const QString &action = audioActions.at(actionIndex); auto *button = new QToolButton(controls); - button->setIcon( - style()->standardIcon(audioIcons.at(actionIndex))); + button->setIcon(styling::icon( + audioIcons.at(actionIndex), audioColors.at(actionIndex))); button->setToolTip(action); controlsLayout->addWidget(button); connect(button, &QToolButton::clicked, this, @@ -1538,7 +1532,7 @@ void InspectorPanel::showObject(const QJsonObject &object) { auto *addComponent = new QToolButton(content); addComponent->setObjectName("inspectorAddComponentButton"); addComponent->setIcon( - style()->standardIcon(QStyle::SP_FileDialogNewFolder)); + styling::icon(styling::Icon::Plus, "#A78BFA")); addComponent->setText("Add Component"); addComponent->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addComponent->setPopupMode(QToolButton::InstantPopup); diff --git a/editor/views/editor/materialEditor.cpp b/editor/views/editor/materialEditor.cpp index c2d9f1aa..f7d4ed43 100644 --- a/editor/views/editor/materialEditor.cpp +++ b/editor/views/editor/materialEditor.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -363,10 +364,12 @@ MaterialEditorPanel::MaterialEditorPanel(ViewportPanel *viewport, statusLabel->setObjectName("materialEditorStatus"); auto *saveButton = new QPushButton("Save", header); saveButton->setObjectName("materialSaveButton"); - saveButton->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton)); + saveButton->setIcon( + styling::icon(styling::Icon::FloppyDisk, "#F5B942")); auto *assignButton = new QPushButton("Assign to Selected", header); assignButton->setObjectName("materialAssignButton"); - assignButton->setIcon(style()->standardIcon(QStyle::SP_ArrowRight)); + assignButton->setIcon( + styling::icon(styling::Icon::Assign, "#F472B6")); headerLayout->addWidget(titleLabel, 1); headerLayout->addWidget(statusLabel); headerLayout->addWidget(assignButton); diff --git a/editor/views/editor/postProcessing.cpp b/editor/views/editor/postProcessing.cpp index af87f406..5e13842f 100644 --- a/editor/views/editor/postProcessing.cpp +++ b/editor/views/editor/postProcessing.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -104,15 +105,16 @@ PostProcessingPanel::PostProcessingPanel(ViewportPanel *viewport, targetSelector->setMinimumWidth(180); auto *addTargetButton = new QToolButton(toolbar); addTargetButton->setIcon( - style()->standardIcon(QStyle::SP_FileDialogNewFolder)); + styling::icon(styling::Icon::Plus, "#A78BFA")); addTargetButton->setText("Target"); addTargetButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); removeTargetButton = new QToolButton(toolbar); removeTargetButton->setText("Remove"); removeTargetButton->setIcon( - style()->standardIcon(QStyle::SP_DialogDiscardButton)); + styling::icon(styling::Icon::Trash, "#FF6B7A")); auto *applyButton = new QPushButton("Apply to Preview", toolbar); - applyButton->setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); + applyButton->setIcon( + styling::icon(styling::Icon::Sparkle, "#52D273")); statusLabel = new QLabel(toolbar); statusLabel->setObjectName("postProcessingStatus"); toolbarLayout->addWidget(title); @@ -243,7 +245,7 @@ void PostProcessingPanel::rebuildEditor() { effectsTitle->setObjectName("postProcessingSectionTitle"); auto *addEffectButton = new QToolButton(effectsHeading); addEffectButton->setIcon( - style()->standardIcon(QStyle::SP_FileDialogNewFolder)); + styling::icon(styling::Icon::Plus, "#A78BFA")); addEffectButton->setText("Add Effect"); addEffectButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addEffectButton->setPopupMode(QToolButton::InstantPopup); diff --git a/editor/views/editor/viewportTools.cpp b/editor/views/editor/viewportTools.cpp index babd20c5..1813541a 100644 --- a/editor/views/editor/viewportTools.cpp +++ b/editor/views/editor/viewportTools.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -41,23 +42,25 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, playButton = new QToolButton(toolbar); playButton->setObjectName("viewportPlaybackButton"); - playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + playButton->setIcon(styling::icon(styling::Icon::Play, "#52D273")); playButton->setToolTip("Play"); pauseButton = new QToolButton(toolbar); pauseButton->setObjectName("viewportPlaybackButton"); - pauseButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); + pauseButton->setIcon(styling::icon(styling::Icon::Pause, "#F5B942")); pauseButton->setToolTip("Pause"); stepButton = new QToolButton(toolbar); stepButton->setObjectName("viewportPlaybackButton"); - stepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward)); + stepButton->setIcon( + styling::icon(styling::Icon::SkipForward, "#55C2FF")); stepButton->setToolTip("Step one frame"); stopButton = new QToolButton(toolbar); stopButton->setObjectName("viewportPlaybackButton"); - stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop)); + stopButton->setIcon(styling::icon(styling::Icon::Stop, "#FF6B7A")); stopButton->setToolTip("Stop and restore the scene"); reloadButton = new QToolButton(toolbar); reloadButton->setObjectName("viewportPlaybackButton"); - reloadButton->setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); + reloadButton->setIcon( + styling::icon(styling::Icon::ArrowCounterClockwise, "#A78BFA")); reloadButton->setToolTip("Reload runtime"); playButton->setShortcut(QKeySequence("Ctrl+P")); pauseButton->setShortcut(QKeySequence("Ctrl+Shift+P")); @@ -74,13 +77,17 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, auto *transformGroup = new QActionGroup(toolbar); transformGroup->setExclusive(true); const QStringList transformNames{"Select", "Move", "Rotate", "Scale"}; - const QList transformIcons{ - QStyle::SP_ArrowUp, QStyle::SP_ArrowRight, QStyle::SP_BrowserReload, - QStyle::SP_TitleBarMaxButton}; + const QList transformIcons{ + styling::Icon::CursorClick, styling::Icon::ArrowsOutCardinal, + styling::Icon::ArrowClockwise, styling::Icon::BoundingBox}; + const QList transformColors{ + QColor("#55C2FF"), QColor("#52D273"), QColor("#F5B942"), + QColor("#F472B6")}; for (int index = 0; index < transformNames.size(); ++index) { auto *button = new QToolButton(toolbar); button->setObjectName("viewportModeButton"); - button->setIcon(style()->standardIcon(transformIcons.at(index))); + button->setIcon( + styling::icon(transformIcons.at(index), transformColors.at(index))); button->setToolTip(transformNames.at(index) + " tool"); button->setCheckable(true); auto *action = new QAction(transformNames.at(index), button); @@ -111,7 +118,8 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, auto *fpsButton = new QToolButton(toolbar); fpsButton->setObjectName("viewportOptionButton"); - fpsButton->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon)); + fpsButton->setIcon( + styling::icon(styling::Icon::Monitor, "#52D273")); fpsButton->setText("FPS"); fpsButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); fpsButton->setCheckable(true); diff --git a/editor/views/general/contentBrowser.cpp b/editor/views/general/contentBrowser.cpp index 1890f70b..ed6be939 100644 --- a/editor/views/general/contentBrowser.cpp +++ b/editor/views/general/contentBrowser.cpp @@ -8,6 +8,7 @@ */ #include "editor/views/fileExplorer.h" +#include "editor/styling/icons.h" #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +94,35 @@ bool copyEntry(const QString &source, const QString &destination) { } return QFile::copy(source, destination); } + +class AtlasFileIconProvider : public QFileIconProvider { +public: + QIcon icon(const QFileInfo &info) const override { + if (info.isDir()) + return styling::icon(styling::Icon::Folder, "#55C2FF"); + const QString suffix = info.suffix().toLower(); + if (suffix == "ascene") + return styling::icon(styling::Icon::CubeFocus, "#A78BFA"); + if (suffix == "amat" || suffix == "material") + return styling::icon(styling::Icon::Material, "#F472B6"); + if (suffix == "ts" || suffix == "js" || suffix == "cpp" || + suffix == "h" || suffix == "json") + return styling::icon(styling::Icon::FileCode, "#55C2FF"); + if (suffix == "png" || suffix == "jpg" || suffix == "jpeg" || + suffix == "hdr") + return styling::icon(styling::Icon::Image, "#F5B942"); + if (suffix == "wav" || suffix == "mp3" || suffix == "ogg" || + suffix == "flac") + return styling::icon(styling::Icon::MusicNote, "#52D273"); + return styling::icon(styling::Icon::File, "#8490A4"); + } + + QIcon icon(IconType type) const override { + if (type == Folder || type == Drive) + return styling::icon(styling::Icon::Folder, "#55C2FF"); + return styling::icon(styling::Icon::File, "#8490A4"); + } +}; } // namespace ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, @@ -116,15 +147,17 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, backButton = new QToolButton(toolbar); backButton->setObjectName("browserNavigationButton"); - backButton->setIcon(style()->standardIcon(QStyle::SP_ArrowBack)); + backButton->setIcon( + styling::icon(styling::Icon::ArrowLeft, "#AAB4C4")); backButton->setToolTip("Back"); forwardButton = new QToolButton(toolbar); forwardButton->setObjectName("browserNavigationButton"); - forwardButton->setIcon(style()->standardIcon(QStyle::SP_ArrowForward)); + forwardButton->setIcon( + styling::icon(styling::Icon::ArrowRight, "#AAB4C4")); forwardButton->setToolTip("Forward"); upButton = new QToolButton(toolbar); upButton->setObjectName("browserNavigationButton"); - upButton->setIcon(style()->standardIcon(QStyle::SP_ArrowUp)); + upButton->setIcon(styling::icon(styling::Icon::ArrowUp, "#AAB4C4")); upButton->setToolTip("Parent Folder"); pathField = new QLineEdit(toolbar); @@ -139,21 +172,21 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, createButton = new QToolButton(toolbar); createButton->setObjectName("panelAddButton"); - createButton->setIcon( - style()->standardIcon(QStyle::SP_FileDialogNewFolder)); + createButton->setIcon(styling::icon(styling::Icon::Plus, "#A78BFA")); createButton->setText("Create"); createButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); createButton->setPopupMode(QToolButton::InstantPopup); revealButton = new QToolButton(toolbar); revealButton->setObjectName("browserRevealButton"); - revealButton->setIcon(style()->standardIcon(QStyle::SP_DirOpenIcon)); + revealButton->setIcon( + styling::icon(styling::Icon::FolderOpen, "#55C2FF")); revealButton->setToolTip("Reveal in Finder"); moreButton = new QToolButton(toolbar); moreButton->setObjectName("panelMoreButton"); moreButton->setIcon( - style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton)); + styling::icon(styling::Icon::DotsVertical, "#8490A4")); moreButton->setPopupMode(QToolButton::InstantPopup); moreButton->setToolTip("Content actions"); @@ -168,6 +201,7 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, layout->addWidget(toolbar); model = new QFileSystemModel(this); + model->setIconProvider(new AtlasFileIconProvider()); model->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); model->setReadOnly(false); model->setRootPath(projectRoot); @@ -195,15 +229,15 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, layout->addWidget(gridView, 1); auto *createMenu = new QMenu(createButton); - createMenu->addAction(style()->standardIcon(QStyle::SP_DirIcon), "Folder", + createMenu->addAction(styling::icon(styling::Icon::Folder, "#55C2FF"), "Folder", this, &ContentBrowserPanel::createFolder); createMenu->addSeparator(); - createMenu->addAction(style()->standardIcon(QStyle::SP_FileIcon), "Scene", + createMenu->addAction(styling::icon(styling::Icon::CubeFocus, "#A78BFA"), "Scene", this, &ContentBrowserPanel::createScene); - createMenu->addAction(style()->standardIcon(QStyle::SP_FileIcon), + createMenu->addAction(styling::icon(styling::Icon::Material, "#F472B6"), "Material", this, &ContentBrowserPanel::createMaterial); - createMenu->addAction(style()->standardIcon(QStyle::SP_FileIcon), + createMenu->addAction(styling::icon(styling::Icon::FileCode, "#55C2FF"), "TypeScript Script", this, &ContentBrowserPanel::createScript); createButton->setMenu(createMenu); diff --git a/editor/views/general/projectBrowser.cpp b/editor/views/general/projectBrowser.cpp index ef30ae45..88055a49 100644 --- a/editor/views/general/projectBrowser.cpp +++ b/editor/views/general/projectBrowser.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -42,6 +43,7 @@ constexpr int ProjectAvailableRole = Qt::UserRole + 1; class TemplateCard : public QFrame { public: TemplateCard(const QString& title, const QString& description, + styling::Icon icon, const QColor& color, QWidget* parent = nullptr) : QFrame(parent) { setProperty("templateCard", true); @@ -53,10 +55,19 @@ class TemplateCard : public QFrame { auto* layout = new QVBoxLayout(this); layout->setContentsMargins(16, 14, 16, 14); layout->setSpacing(8); + auto* heading = new QHBoxLayout(); + heading->setSpacing(8); + auto* iconLabel = new QLabel(this); + iconLabel->setObjectName("templateIcon"); + iconLabel->setPixmap(styling::icon(icon, color).pixmap(24, 24)); + iconLabel->setFixedSize(28, 28); + iconLabel->setAlignment(Qt::AlignCenter); option = new QRadioButton(title, this); option->setObjectName("templateOption"); option->setCursor(Qt::PointingHandCursor); - layout->addWidget(option); + heading->addWidget(iconLabel); + heading->addWidget(option, 1); + layout->addLayout(heading); auto* descriptionLabel = new QLabel(description, this); descriptionLabel->setObjectName("templateDescription"); descriptionLabel->setWordWrap(true); @@ -115,13 +126,15 @@ class CreateProjectDialog : public QDialog { templateGroup->setExclusive(true); auto* pbr = new TemplateCard( "PBR", "Deferred physically based rendering for most 3D projects.", - this); + styling::Icon::Cube, "#A78BFA", this); auto* ddgi = new TemplateCard( "PBR + DDGI", - "PBR with dynamic diffuse global illumination enabled.", this); + "PBR with dynamic diffuse global illumination enabled.", + styling::Icon::Sun, "#F5B942", this); auto* pathTracing = new TemplateCard( "Path Tracing", - "Progressive ray-traced lighting for high-fidelity scenes.", this); + "Progressive ray-traced lighting for high-fidelity scenes.", + styling::Icon::Aperture, "#F472B6", this); templateGroup->addButton(pbr->button(), static_cast(AtlasProjectTemplate::Pbr)); templateGroup->addButton( @@ -159,6 +172,8 @@ class CreateProjectDialog : public QDialog { locationLayout->addWidget(locationField, 1); auto* browse = new QPushButton("Browse…", this); browse->setProperty("secondary", true); + browse->setIcon( + styling::icon(styling::Icon::FolderOpen, "#55C2FF")); locationLayout->addWidget(browse); fields->addLayout(locationLayout); root->addLayout(fields); @@ -176,6 +191,8 @@ class CreateProjectDialog : public QDialog { actions->addWidget(cancel); createButton = new QPushButton("Create project", this); createButton->setObjectName("primaryAction"); + createButton->setIcon( + styling::icon(styling::Icon::RocketLaunch, "#FFFFFF")); createButton->setDefault(true); createButton->setEnabled(false); actions->addWidget(createButton); @@ -239,6 +256,15 @@ class ProjectRow : public QFrame { layout->setContentsMargins(16, 12, 12, 12); layout->setSpacing(14); + auto* projectIcon = new QLabel(this); + projectIcon->setObjectName("projectIcon"); + projectIcon->setPixmap( + styling::icon(styling::Icon::GameController, "#A78BFA") + .pixmap(30, 30)); + projectIcon->setFixedSize(36, 36); + projectIcon->setAlignment(Qt::AlignCenter); + layout->addWidget(projectIcon); + auto* copy = new QVBoxLayout(); copy->setSpacing(3); auto* title = new QLabel(project.name, this); @@ -266,7 +292,7 @@ class ProjectRow : public QFrame { moreButton = new QToolButton(this); moreButton->setObjectName("projectMoreButton"); moreButton->setIcon( - style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton)); + styling::icon(styling::Icon::DotsVertical, "#8490A4")); moreButton->setToolTip("Project options"); layout->addWidget(moreButton); } @@ -327,7 +353,8 @@ void ProjectBrowser::setupUi() { auto* projectsNav = new QPushButton("Projects", sidebar); projectsNav->setObjectName("projectNavSelected"); - projectsNav->setIcon(style()->standardIcon(QStyle::SP_DirHomeIcon)); + projectsNav->setIcon( + styling::icon(styling::Icon::SquaresFour, "#A78BFA")); projectsNav->setEnabled(false); sidebarLayout->addWidget(projectsNav); sidebarLayout->addStretch(); @@ -354,11 +381,13 @@ void ProjectBrowser::setupUi() { auto* openButton = new QPushButton("Open existing", content); openButton->setProperty("secondary", true); - openButton->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton)); + openButton->setIcon( + styling::icon(styling::Icon::FolderOpen, "#55C2FF")); headingLayout->addWidget(openButton); auto* createButton = new QPushButton("New project", content); createButton->setObjectName("primaryAction"); - createButton->setIcon(style()->standardIcon(QStyle::SP_FileDialogNewFolder)); + createButton->setIcon( + styling::icon(styling::Icon::Plus, "#FFFFFF")); headingLayout->addWidget(createButton); contentLayout->addLayout(headingLayout); diff --git a/editor/views/general/splashScreen.cpp b/editor/views/general/splashScreen.cpp index c8ae66b1..36bc8cbf 100644 --- a/editor/views/general/splashScreen.cpp +++ b/editor/views/general/splashScreen.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifndef ATLAS_VERSION @@ -22,11 +23,11 @@ SplashScreen::SplashScreen(QWidget *parent) setAttribute(Qt::WA_TranslucentBackground); setModal(true); setObjectName("atlasSplash"); - setFixedSize(708, 218); + setFixedSize(708, 252); auto *card = new QFrame(this); card->setObjectName("splashCard"); - card->setGeometry(0, 0, 708, 218); + card->setGeometry(0, 0, 708, 252); auto *shadow = new QGraphicsDropShadowEffect(card); shadow->setBlurRadius(20.0); shadow->setOffset(0.0, 5.0); @@ -35,7 +36,7 @@ SplashScreen::SplashScreen(QWidget *parent) auto *icon = new QLabel(card); icon->setObjectName("splashIcon"); - icon->setGeometry(28, 32, 110, 110); + icon->setGeometry(30, 38, 108, 108); #ifdef ATLAS_DEBUG_BUILD icon->setPixmap(QPixmap(":/editor/assets/Icon-iOS-Default-1024x1024@1x.png") .scaled(icon->size(), Qt::KeepAspectRatio, @@ -49,7 +50,7 @@ SplashScreen::SplashScreen(QWidget *parent) auto *title = new QLabel(card); title->setObjectName("splashTitle"); - title->setGeometry(162, 42, 530, 44); + title->setGeometry(164, 42, 514, 44); QFont titleFont = title->font(); titleFont.setLetterSpacing(QFont::AbsoluteSpacing, -0.3); @@ -65,7 +66,7 @@ SplashScreen::SplashScreen(QWidget *parent) auto *version = new QLabel(card); version->setObjectName("splashVersion"); - version->setGeometry(162, 85, 500, 32); + version->setGeometry(164, 86, 500, 28); #ifdef ATLAS_DEBUG_BUILD version->setText(QStringLiteral("%1 (build %2)") .arg(QStringLiteral(ATLAS_VERSION), @@ -77,13 +78,19 @@ SplashScreen::SplashScreen(QWidget *parent) auto *company = new QLabel("by neutral software", card); company->setObjectName("splashCompany"); - company->setGeometry(162, 116, 400, 23); + company->setGeometry(164, 114, 400, 22); company->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); statusLabel = new QLabel("Loading the engine…", card); statusLabel->setObjectName("splashStatus"); - statusLabel->setGeometry(0, 136, 708, 22); - statusLabel->setAlignment(Qt::AlignCenter); + statusLabel->setGeometry(164, 151, 500, 22); + statusLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + + auto *progress = new QProgressBar(card); + progress->setObjectName("splashProgress"); + progress->setGeometry(164, 181, 500, 5); + progress->setRange(0, 0); + progress->setTextVisible(false); #ifdef ATLAS_DEBUG_BUILD auto *warning = new QLabel( @@ -95,7 +102,7 @@ SplashScreen::SplashScreen(QWidget *parent) "appropriate runtime in your system that works with this version.", card); warning->setObjectName("splashWarning"); - warning->setGeometry(40, 161, 628, 48); + warning->setGeometry(40, 199, 628, 44); warning->setWordWrap(true); warning->setAlignment(Qt::AlignLeft | Qt::AlignTop); #endif @@ -105,38 +112,47 @@ SplashScreen::SplashScreen(QWidget *parent) background: transparent; } #splashCard { - background: #1F2427; - border: 1px solid rgba(20, 24, 28, 18); - border-radius: 40px; + background: #111720; + border: 1px solid #344156; + border-radius: 18px; } #splashTitle { background: transparent; - color: #FFFFFF; - font-size: 40px; - font-weight: 700; + color: #F5F7FA; + font-size: 34px; + font-weight: 750; } #splashVersion { background: transparent; - color: #A1A5A8; - font-size: 18px; + color: #A78BFA; + font-size: 14px; font-weight: 700; } #splashCompany { background: transparent; - color: #A1A5A8; + color: #7F8B9D; font-family: "Manrope"; font-size: 12px; font-weight: 650; } #splashStatus { background: transparent; - color: #9A9EA1; - font-size: 9px; - font-weight: 450; + color: #B7C1CF; + font-size: 10px; + font-weight: 550; +} +#splashProgress { + background: #202A38; + border: none; + border-radius: 2px; +} +#splashProgress::chunk { + background: #7C5CFC; + border-radius: 2px; } #splashWarning { background: transparent; - color: #A4A8AB; + color: #68758A; font-size: 9px; font-weight: 450; } diff --git a/include/editor/styling/icons.h b/include/editor/styling/icons.h index 459ccb1c..e2d23562 100644 --- a/include/editor/styling/icons.h +++ b/include/editor/styling/icons.h @@ -46,6 +46,7 @@ enum class Icon { Hand, HardDrives, Image, + Info, Layout, Lightbulb, MagnifyingGlass, diff --git a/include/editor/views/editorWindow.h b/include/editor/views/editorWindow.h index 69ea91ca..c9dffdbe 100644 --- a/include/editor/views/editorWindow.h +++ b/include/editor/views/editorWindow.h @@ -49,6 +49,7 @@ class EditorWindow : public QMainWindow { void setupWindow(); void setupMenus(); void setupDocks(); + void setupWorkspaceBar(); void saveLayout(); void restoreLayout(); From a56b5058246f5400d0bbdc9127efedda650f0c4e Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:38:54 +0200 Subject: [PATCH 3/7] Polished the complete editor workspace experience --- editor/styling/dark.qss | 73 +++++++++++++++- editor/views/editor/editor.cpp | 106 +++++++++++++++++++++--- editor/views/editor/hierarchy.cpp | 12 ++- editor/views/editor/inspector.cpp | 14 +++- editor/views/editor/materialEditor.cpp | 5 +- editor/views/editor/postProcessing.cpp | 13 ++- editor/views/editor/viewportTools.cpp | 12 ++- editor/views/general/contentBrowser.cpp | 25 ++++-- editor/views/general/projectBrowser.cpp | 12 ++- 9 files changed, 236 insertions(+), 36 deletions(-) diff --git a/editor/styling/dark.qss b/editor/styling/dark.qss index e150192f..b521e0b9 100644 --- a/editor/styling/dark.qss +++ b/editor/styling/dark.qss @@ -4,7 +4,6 @@ color: #E7ECF3; selection-background-color: #6F55E8; selection-color: #FFFFFF; - outline: none; } QWidget { @@ -422,6 +421,31 @@ QStatusBar { color: #8490A4; } +#atlasStatusBar { + min-height: 21px; + padding: 0 6px; +} + +#statusRuntimeIcon { + padding: 0 4px; +} + +#statusRenderer { + background-color: #192B22; + border: 1px solid #2C573B; + border-radius: 4px; + color: #8DE2A5; + font-size: 9px; + font-weight: 700; + padding: 2px 6px; +} + +#statusVersion { + color: #68758A; + font-size: 9px; + padding: 0 6px; +} + #workspaceBar { background-color: #10151C; border: none; @@ -443,7 +467,6 @@ QStatusBar { color: #F5F7FA; font-size: 12px; font-weight: 800; - letter-spacing: 1px; } #workspaceProject { @@ -817,7 +840,6 @@ QScrollArea#inspectorScroll, #inspectorEmptyHint { color: #728096; - line-height: 1.4; } #inspectorOpenAssetButton, @@ -1238,6 +1260,51 @@ QPushButton[secondary="true"]:hover { border-color: #4A5870; } +#projectSettingsDialog, +#exportDialog { + background-color: #0D1117; +} + +#dialogHero { + background-color: #141A23; + border: 1px solid #293445; + border-radius: 8px; + padding: 7px; +} + +#dialogHeroIcon { + background-color: #211C3B; + border: 1px solid #493A86; + border-radius: 7px; + padding: 8px; +} + +#dialogHeroTitle { + color: #F3F6FA; + font-size: 17px; + font-weight: 750; +} + +#dialogHeroSubtitle, +#exportSummary { + color: #7F8B9D; +} + +#exportSummary { + background-color: #121923; + border: 1px solid #273141; + border-radius: 6px; + padding: 8px; +} + +#exportLog { + background-color: #090D12; + border-color: #263142; + color: #9CE2AF; + font-family: "Menlo"; + font-size: 10px; +} + #commandPaletteDialog, #globalSearchDialog { background-color: #111720; diff --git a/editor/views/editor/editor.cpp b/editor/views/editor/editor.cpp index d98a4e98..9982a933 100644 --- a/editor/views/editor/editor.cpp +++ b/editor/views/editor/editor.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -237,7 +239,8 @@ void EditorWindow::setupWindow() { const auto project = ProjectStore::projectInfo(projectFile); projectName = project.has_value() ? project->name : QStringLiteral("Project"); updateWindowTitle(false); - resize(1280, 720); + setMinimumSize(1100, 700); + resize(1440, 900); menuBar()->setNativeMenuBar(false); menuBar()->setObjectName("atlasMenuBar"); @@ -806,6 +809,33 @@ void EditorWindow::setupWorkspaceBar() { bar->addWidget(launch); connect(launch, &QToolButton::clicked, this, [this] { runProjectCommand(false); }); + + statusBar()->setObjectName("atlasStatusBar"); + statusBar()->showMessage("Ready"); + auto *runtimeIcon = new QLabel(statusBar()); + runtimeIcon->setObjectName("statusRuntimeIcon"); + runtimeIcon->setPixmap( + styling::icon(styling::Icon::Check, "#52D273").pixmap(14, 14)); + auto *renderer = new QLabel(statusBar()); + renderer->setObjectName("statusRenderer"); + const auto projectInfo = ProjectStore::projectInfo(projectFile); + renderer->setText(projectInfo.has_value() ? projectInfo->renderer + : QStringLiteral("ATLAS")); + auto *version = new QLabel(QStringLiteral(ATLAS_VERSION), statusBar()); + version->setObjectName("statusVersion"); + statusBar()->addPermanentWidget(runtimeIcon); + statusBar()->addPermanentWidget(renderer); + statusBar()->addPermanentWidget(version); + connect(viewportPanel, &ViewportPanel::runtimeAvailabilityChanged, this, + [this, runtimeIcon](bool available) { + runtimeIcon->setPixmap(styling::icon( + available ? styling::Icon::Check : styling::Icon::Warning, + available ? QColor("#52D273") : QColor("#F5B942")) + .pixmap(14, 14)); + statusBar()->showMessage(available ? "Runtime ready" + : "Runtime unavailable", + 3000); + }); } void EditorWindow::createScene() { @@ -874,23 +904,44 @@ void EditorWindow::saveSceneAs() { void EditorWindow::showProjectSettings() { QDialog dialog(this); + dialog.setObjectName("projectSettingsDialog"); dialog.setWindowTitle("Project Settings"); dialog.resize(720, 520); auto *layout = new QVBoxLayout(&dialog); + auto *header = new QFrame(&dialog); + header->setObjectName("dialogHero"); + auto *headerLayout = new QHBoxLayout(header); + auto *headerIcon = new QLabel(header); + headerIcon->setObjectName("dialogHeroIcon"); + headerIcon->setPixmap( + styling::icon(styling::Icon::Gear, "#A78BFA").pixmap(28, 28)); + auto *headerCopy = new QVBoxLayout(); + auto *headerTitle = new QLabel("Project Settings", header); + headerTitle->setObjectName("dialogHeroTitle"); + auto *headerSubtitle = new QLabel( + "Configure runtime, rendering, controls, and packaging for this project.", + header); + headerSubtitle->setObjectName("dialogHeroSubtitle"); + headerCopy->addWidget(headerTitle); + headerCopy->addWidget(headerSubtitle); + headerLayout->addWidget(headerIcon); + headerLayout->addLayout(headerCopy, 1); + layout->addWidget(header); auto *tabs = new QTabWidget(&dialog); const QString settingsDirectory = QDir(QFileInfo(projectFile).absolutePath()).filePath(".atlas"); QDir().mkpath(settingsDirectory); QSettings settings(QDir(settingsDirectory).filePath("project-settings.ini"), QSettings::IniFormat); - auto addPage = [tabs](const QString &name) { + auto addPage = [tabs](const QString &name, styling::Icon icon, + const QColor &color) { auto *page = new QWidget(tabs); auto *form = new QFormLayout(page); form->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); - tabs->addTab(page, name); + tabs->addTab(page, styling::icon(icon, color), name); return form; }; - auto *general = addPage("General"); + auto *general = addPage("General", styling::Icon::Gear, "#A78BFA"); auto *defaultScene = new QComboBox(&dialog); QDirIterator sceneIterator(QFileInfo(projectFile).absolutePath(), {"*.ascene"}, QDir::Files, @@ -927,7 +978,8 @@ void EditorWindow::showProjectSettings() { general->addRow("Window width", windowWidth); general->addRow("Window height", windowHeight); general->addRow(QString(), fullscreen); - auto *rendering = addPage("Rendering"); + auto *rendering = + addPage("Rendering", styling::Icon::Aperture, "#F472B6"); auto *renderer = new QComboBox(&dialog); renderer->addItems({"PBR", "PBR + DDGI", "Path Tracing"}); renderer->setCurrentText(settings.value("project/renderer", "PBR").toString()); @@ -936,31 +988,33 @@ void EditorWindow::showProjectSettings() { frameLimit->setValue(settings.value("project/frameLimit", 0).toInt()); rendering->addRow("Renderer", renderer); rendering->addRow("Frame limit (0 = unlimited)", frameLimit); - auto *physics = addPage("Physics"); + auto *physics = addPage("Physics", styling::Icon::Wrench, "#F5B942"); auto *gravity = new QLineEdit(settings.value("project/gravity", "0, -9.81, 0").toString(), &dialog); auto *fixedStep = new QLineEdit(settings.value("project/fixedStep", "0.0166667").toString(), &dialog); physics->addRow("Gravity", gravity); physics->addRow("Fixed timestep", fixedStep); - auto *input = addPage("Input"); + auto *input = + addPage("Input", styling::Icon::GameController, "#52D273"); auto *inputMap = new QLineEdit(settings.value("project/inputMap", "input.json").toString(), &dialog); auto *controller = new QComboBox(&dialog); controller->addItems({"Automatic", "Keyboard + Mouse", "Gamepad"}); controller->setCurrentText(settings.value("project/controller", "Automatic").toString()); input->addRow("Input map", inputMap); input->addRow("Primary controller", controller); - auto *build = addPage("Build & Run"); + auto *build = addPage("Build & Run", styling::Icon::Package, "#F5B942"); auto *buildCommand = new QLineEdit(settings.value("project/buildCommand", "atlas pack --backend METAL").toString(), &dialog); auto *runCommand = new QLineEdit(settings.value("project/runCommand", "atlas run project.atlas").toString(), &dialog); build->addRow("Build command", buildCommand); build->addRow("Run command", runCommand); - auto *editor = addPage("Editor"); + auto *editor = addPage("Editor", styling::Icon::Layout, "#55C2FF"); auto *autosave = new QSpinBox(&dialog); autosave->setRange(0, 120); autosave->setValue(settings.value("project/autosaveMinutes", 5).toInt()); auto *snap = new QLineEdit(settings.value("project/snapIncrement", "0.5").toString(), &dialog); editor->addRow("Autosave interval (minutes)", autosave); editor->addRow("Transform snapping", snap); - auto *packaging = addPage("Packaging"); + auto *packaging = + addPage("Packaging", styling::Icon::Export, "#A78BFA"); auto *identifier = new QLineEdit( settings.value("project/bundleIdentifier", "org.atlasengine." + projectName.toLower().replace(' ', '-')) @@ -978,6 +1032,8 @@ void EditorWindow::showProjectSettings() { layout->addWidget(tabs); auto *buttons = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Save, &dialog); + buttons->button(QDialogButtonBox::Save) + ->setIcon(styling::icon(styling::Icon::FloppyDisk, "#F5B942")); layout->addWidget(buttons); connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); @@ -1046,9 +1102,29 @@ void EditorWindow::showProjectSettings() { void EditorWindow::showExportDialog() { QDialog dialog(this); + dialog.setObjectName("exportDialog"); dialog.setWindowTitle("Export Atlas Project"); dialog.resize(660, 460); auto *layout = new QVBoxLayout(&dialog); + auto *header = new QFrame(&dialog); + header->setObjectName("dialogHero"); + auto *headerLayout = new QHBoxLayout(header); + auto *headerIcon = new QLabel(header); + headerIcon->setObjectName("dialogHeroIcon"); + headerIcon->setPixmap( + styling::icon(styling::Icon::Export, "#52D273").pixmap(28, 28)); + auto *headerCopy = new QVBoxLayout(); + auto *headerTitle = new QLabel("Export Project", header); + headerTitle->setObjectName("dialogHeroTitle"); + auto *headerSubtitle = new QLabel( + "Package the current project into a distributable application.", + header); + headerSubtitle->setObjectName("dialogHeroSubtitle"); + headerCopy->addWidget(headerTitle); + headerCopy->addWidget(headerSubtitle); + headerLayout->addWidget(headerIcon); + headerLayout->addLayout(headerCopy, 1); + layout->addWidget(header); auto *form = new QFormLayout; auto *platform = new QComboBox(&dialog); #ifdef Q_OS_MACOS @@ -1079,6 +1155,8 @@ void EditorWindow::showExportDialog() { .toString(), &dialog); auto *browse = new QPushButton("Choose…", &dialog); + browse->setIcon( + styling::icon(styling::Icon::FolderOpen, "#55C2FF")); auto *outputRow = new QWidget(&dialog); auto *outputLayout = new QHBoxLayout(outputRow); outputLayout->setContentsMargins(0, 0, 0, 0); @@ -1092,6 +1170,7 @@ void EditorWindow::showExportDialog() { auto *summary = new QLabel( "Atlas will save the current scene and package the configured runtime with the project resources.", &dialog); + summary->setObjectName("exportSummary"); summary->setWordWrap(true); layout->addWidget(summary); auto *progress = new QProgressBar(&dialog); @@ -1099,12 +1178,17 @@ void EditorWindow::showExportDialog() { progress->setVisible(false); layout->addWidget(progress); auto *log = new QPlainTextEdit(&dialog); + log->setObjectName("exportLog"); log->setReadOnly(true); log->setPlaceholderText("Packaging output will appear here."); layout->addWidget(log, 1); auto *buttons = new QDialogButtonBox(QDialogButtonBox::Cancel, &dialog); auto *exportButton = buttons->addButton("Export", QDialogButtonBox::AcceptRole); + exportButton->setIcon( + styling::icon(styling::Icon::RocketLaunch, "#52D273")); auto *revealButton = buttons->addButton("Reveal Export", QDialogButtonBox::ActionRole); + revealButton->setIcon( + styling::icon(styling::Icon::FolderOpen, "#55C2FF")); revealButton->setEnabled(false); layout->addWidget(buttons); connect(browse, &QPushButton::clicked, &dialog, [&dialog, output] { @@ -1611,7 +1695,7 @@ void EditorWindow::configureDockSplitters() { if (coreManager == nullptr) return; for (QSplitter *splitter : coreManager->findChildren()) { - splitter->setHandleWidth(6); + splitter->setHandleWidth(4); splitter->setOpaqueResize(true); splitter->setChildrenCollapsible(false); if (!splitter->property("atlasLayoutTracking").toBool()) { diff --git a/editor/views/editor/hierarchy.cpp b/editor/views/editor/hierarchy.cpp index 243ff0da..53abb4be 100644 --- a/editor/views/editor/hierarchy.cpp +++ b/editor/views/editor/hierarchy.cpp @@ -432,12 +432,16 @@ void HierarchyPanel::showContextMenu(const QPoint &position) { } if (index.isValid() && selectedObjectId() >= 0) { menu.addSeparator(); - menu.addAction("Focus", this, &HierarchyPanel::focusSelectedObject); - menu.addAction("Rename", this, &HierarchyPanel::renameSelectedObject); - menu.addAction("Move to Scene Root", this, + menu.addAction(styling::icon(styling::Icon::Crosshair, "#55C2FF"), + "Focus", this, &HierarchyPanel::focusSelectedObject); + menu.addAction(styling::icon(styling::Icon::File, "#A78BFA"), + "Rename", this, &HierarchyPanel::renameSelectedObject); + menu.addAction(styling::icon(styling::Icon::TreeStructure, "#52D273"), + "Move to Scene Root", this, &HierarchyPanel::moveSelectedObjectToRoot); menu.addSeparator(); - menu.addAction("Delete", this, &HierarchyPanel::deleteSelectedObject); + menu.addAction(styling::icon(styling::Icon::Trash, "#FF6B7A"), + "Delete", this, &HierarchyPanel::deleteSelectedObject); } menu.exec(treeView->viewport()->mapToGlobal(position)); } diff --git a/editor/views/editor/inspector.cpp b/editor/views/editor/inspector.cpp index 0b80c259..6cdefc81 100644 --- a/editor/views/editor/inspector.cpp +++ b/editor/views/editor/inspector.cpp @@ -974,7 +974,9 @@ void addPropertyRows(QVBoxLayout *layout, const QJsonObject &properties, title->setObjectName("inspectorNestedTitle"); auto *add = new QToolButton(heading); add->setObjectName("inspectorArrayButton"); - add->setText("+"); + add->setIcon( + styling::icon(styling::Icon::Plus, "#A78BFA")); + add->setToolTip("Add item"); add->setToolTip(QStringLiteral("Add %1").arg(humanize(key))); headingLayout->addWidget(title, 1); headingLayout->addWidget(add); @@ -1004,7 +1006,9 @@ void addPropertyRows(QVBoxLayout *layout, const QJsonObject &properties, itemTitle->setObjectName("inspectorArrayTitle"); auto *remove = new QToolButton(itemHeading); remove->setObjectName("inspectorArrayButton"); - remove->setText("−"); + remove->setIcon( + styling::icon(styling::Icon::Trash, "#FF6B7A")); + remove->setToolTip("Remove item"); remove->setToolTip("Remove"); itemHeadingLayout->addWidget(itemTitle, 1); itemHeadingLayout->addWidget(remove); @@ -1158,7 +1162,7 @@ QFrame *componentCard(const QString &title, const QJsonObject &properties, header->setText(title); header->setCheckable(true); header->setChecked(true); - header->setArrowType(Qt::DownArrow); + header->setIcon(styling::icon(styling::Icon::CaretDown, "#8490A4")); header->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); headerLayout->addWidget(header, 1); if (remove) { @@ -1181,7 +1185,9 @@ QFrame *componentCard(const QString &title, const QJsonObject &properties, QObject::connect( header, &QToolButton::toggled, card, [header, body](bool expanded) { body->setVisible(expanded); - header->setArrowType(expanded ? Qt::DownArrow : Qt::RightArrow); + header->setIcon(styling::icon( + expanded ? styling::Icon::CaretDown : styling::Icon::CaretRight, + "#8490A4")); }); return card; } diff --git a/editor/views/editor/materialEditor.cpp b/editor/views/editor/materialEditor.cpp index f7d4ed43..a65e77ce 100644 --- a/editor/views/editor/materialEditor.cpp +++ b/editor/views/editor/materialEditor.cpp @@ -607,8 +607,11 @@ void MaterialEditorPanel::showMaterial() { field->setPlaceholderText("No image"); auto *choose = new QToolButton(row); choose->setText("Choose…"); + choose->setIcon( + styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + choose->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); auto *clear = new QToolButton(row); - clear->setText("×"); + clear->setIcon(styling::icon(styling::Icon::Close, "#FF6B7A")); clear->setToolTip("Remove texture"); auto *identity = new QWidget(row); auto *identityLayout = new QVBoxLayout(identity); diff --git a/editor/views/editor/postProcessing.cpp b/editor/views/editor/postProcessing.cpp index 5e13842f..d4411577 100644 --- a/editor/views/editor/postProcessing.cpp +++ b/editor/views/editor/postProcessing.cpp @@ -257,7 +257,9 @@ void PostProcessingPanel::rebuildEditor() { "posterization", "pixelation", "dilation", "film_grain"}; for (const QString &effect : effects) { - effectMenu->addAction(effectTitle(effect), this, + effectMenu->addAction( + styling::icon(styling::Icon::Sparkle, "#52D273"), + effectTitle(effect), this, [this, effect] { addEffect(effect); }); } addEffectButton->setMenu(effectMenu); @@ -327,12 +329,21 @@ void PostProcessingPanel::rebuildEditor() { actionsLayout->setSpacing(4); auto *moveUp = new QToolButton(actions); moveUp->setText("Move Up"); + moveUp->setIcon( + styling::icon(styling::Icon::CaretUp, "#55C2FF")); + moveUp->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); moveUp->setEnabled(effectIndex > 0); auto *moveDown = new QToolButton(actions); moveDown->setText("Move Down"); + moveDown->setIcon( + styling::icon(styling::Icon::CaretDown, "#55C2FF")); + moveDown->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); moveDown->setEnabled(effectIndex + 1 < effectStack.size()); auto *remove = new QToolButton(actions); remove->setText("Remove Effect"); + remove->setIcon( + styling::icon(styling::Icon::Trash, "#FF6B7A")); + remove->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); actionsLayout->addStretch(); actionsLayout->addWidget(moveUp); actionsLayout->addWidget(moveDown); diff --git a/editor/views/editor/viewportTools.cpp b/editor/views/editor/viewportTools.cpp index 1813541a..e8d168b9 100644 --- a/editor/views/editor/viewportTools.cpp +++ b/editor/views/editor/viewportTools.cpp @@ -105,7 +105,8 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, spaceButton = new QToolButton(toolbar); spaceButton->setObjectName("viewportOptionButton"); spaceButton->setText("World"); - spaceButton->setToolButtonStyle(Qt::ToolButtonTextOnly); + spaceButton->setIcon(styling::icon(styling::Icon::Globe, "#55C2FF")); + spaceButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); spaceButton->setToolTip("Transform space (Shift+T)"); tools->addWidget(spaceButton); @@ -114,6 +115,12 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, shading->setObjectName("viewportShadingMode"); shading->addItems({"Lit", "Wireframe", "Points"}); shading->setToolTip("Viewport shading"); + auto *shadingIcon = new QLabel(toolbar); + shadingIcon->setObjectName("viewportShadingIcon"); + shadingIcon->setPixmap( + styling::icon(styling::Icon::Sphere, "#F472B6").pixmap(17, 17)); + shadingIcon->setToolTip("Viewport shading"); + tools->addWidget(shadingIcon); tools->addWidget(shading); auto *fpsButton = new QToolButton(toolbar); @@ -162,6 +169,9 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, connect(viewport, &ViewportPanel::transformSpaceChanged, this, [this](bool local) { spaceButton->setText(local ? "Local" : "World"); + spaceButton->setIcon(styling::icon( + local ? styling::Icon::Cube : styling::Icon::Globe, + local ? QColor("#A78BFA") : QColor("#55C2FF"))); }); connect(fpsButton, &QToolButton::toggled, fpsLabel, &QWidget::setVisible); connect(viewport, &ViewportPanel::frameRateChanged, this, diff --git a/editor/views/general/contentBrowser.cpp b/editor/views/general/contentBrowser.cpp index ed6be939..ec3ad44c 100644 --- a/editor/views/general/contentBrowser.cpp +++ b/editor/views/general/contentBrowser.cpp @@ -123,6 +123,8 @@ class AtlasFileIconProvider : public QFileIconProvider { return styling::icon(styling::Icon::File, "#8490A4"); } }; + +AtlasFileIconProvider atlasFileIconProvider; } // namespace ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, @@ -201,7 +203,7 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, layout->addWidget(toolbar); model = new QFileSystemModel(this); - model->setIconProvider(new AtlasFileIconProvider()); + model->setIconProvider(&atlasFileIconProvider); model->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); model->setReadOnly(false); model->setRootPath(projectRoot); @@ -215,8 +217,8 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, gridView->setWrapping(true); gridView->setResizeMode(QListView::Adjust); gridView->setMovement(QListView::Static); - gridView->setGridSize(QSize(176, 142)); - gridView->setIconSize(QSize(64, 64)); + gridView->setGridSize(QSize(154, 118)); + gridView->setIconSize(QSize(50, 50)); gridView->setWordWrap(true); gridView->setTextElideMode(Qt::ElideNone); gridView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -243,17 +245,24 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, createButton->setMenu(createMenu); auto *moreMenu = new QMenu(moreButton); - moreMenu->addAction("Open", this, [this] { + moreMenu->addAction( + styling::icon(styling::Icon::FolderOpen, "#55C2FF"), "Open", this, [this] { if (gridView->currentIndex().isValid()) { openIndex(gridView->currentIndex()); } }); - moreMenu->addAction("Rename", this, &ContentBrowserPanel::renameSelection); - moreMenu->addAction("Delete", this, &ContentBrowserPanel::deleteSelection); + moreMenu->addAction(styling::icon(styling::Icon::File, "#A78BFA"), + "Rename", this, + &ContentBrowserPanel::renameSelection); + moreMenu->addAction(styling::icon(styling::Icon::Trash, "#FF6B7A"), + "Delete", this, + &ContentBrowserPanel::deleteSelection); moreMenu->addSeparator(); - moreMenu->addAction("Reveal in Finder", this, + moreMenu->addAction(styling::icon(styling::Icon::FolderOpen, "#55C2FF"), + "Reveal in Finder", this, &ContentBrowserPanel::revealSelection); - moreMenu->addAction("Copy Path", this, + moreMenu->addAction(styling::icon(styling::Icon::FileCode, "#8490A4"), + "Copy Path", this, &ContentBrowserPanel::copySelectionPath); moreButton->setMenu(moreMenu); diff --git a/editor/views/general/projectBrowser.cpp b/editor/views/general/projectBrowser.cpp index 88055a49..32b68d31 100644 --- a/editor/views/general/projectBrowser.cpp +++ b/editor/views/general/projectBrowser.cpp @@ -539,12 +539,18 @@ void ProjectBrowser::showProjectMenu(const QPoint& position) { const bool available = ProjectStore::isProjectFile(projectFile); QMenu menu(this); - QAction* open = menu.addAction("Open project"); + QAction* open = menu.addAction( + styling::icon(styling::Icon::GameController, "#A78BFA"), + "Open project"); open->setEnabled(available); - QAction* reveal = menu.addAction("Show in Finder"); + QAction* reveal = menu.addAction( + styling::icon(styling::Icon::FolderOpen, "#55C2FF"), + "Show in Finder"); reveal->setEnabled(QFileInfo::exists(QFileInfo(projectFile).absolutePath())); menu.addSeparator(); - QAction* remove = menu.addAction("Remove from list"); + QAction* remove = menu.addAction( + styling::icon(styling::Icon::Trash, "#FF6B7A"), + "Remove from list"); QAction* selected = menu.exec(projectList->viewport()->mapToGlobal(position)); if (selected == open) { openSelectedProject(); From acb7724b583ad35d51f31c25f81116f37c1846a5 Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:38:54 +0200 Subject: [PATCH 4/7] Refined workspaces and viewport controls --- editor/styling/dark.qss | 271 ++-- editor/styling/icons.cpp | 4 + editor/styling/theme.cpp | 4 +- editor/views/editor/editor.cpp | 227 +-- editor/views/editor/hierarchy.cpp | 28 +- editor/views/editor/inspector.cpp | 36 +- editor/views/editor/materialEditor.cpp | 8 +- editor/views/editor/postProcessing.cpp | 16 +- editor/views/editor/viewport.cpp | 27 +- editor/views/editor/viewportTools.cpp | 100 +- editor/views/general/contentBrowser.cpp | 34 +- editor/views/general/projectBrowser.cpp | 20 +- editor/views/general/splashScreen.cpp | 4 +- include/editor/core/themes.h | 1974 +++++++++-------------- include/editor/styling/icons.h | 2 + include/editor/views/editorWindow.h | 5 + include/editor/views/viewport.h | 1 + 17 files changed, 1210 insertions(+), 1551 deletions(-) diff --git a/editor/styling/dark.qss b/editor/styling/dark.qss index b521e0b9..8f6f34e3 100644 --- a/editor/styling/dark.qss +++ b/editor/styling/dark.qss @@ -2,7 +2,7 @@ font-family: "Manrope"; font-size: 12px; color: #E7ECF3; - selection-background-color: #6F55E8; + selection-background-color: #3F78D8; selection-color: #FFFFFF; } @@ -29,16 +29,16 @@ QToolTip { background-color: #202838; color: #F7F9FC; border: 1px solid #3A465A; - border-radius: 5px; - padding: 6px 8px; + border-radius: 3px; + padding: 4px 6px; } QGroupBox { background-color: #141A23; border: 1px solid #252E3C; - border-radius: 7px; - margin-top: 18px; - padding: 12px 10px 10px 10px; + border-radius: 4px; + margin-top: 14px; + padding: 8px; color: #F1F4F8; font-weight: 650; } @@ -103,10 +103,10 @@ QPushButton, QToolButton { background-color: #1A2230; border: 1px solid #2D3849; - border-radius: 5px; - padding: 5px 9px; + border-radius: 3px; + padding: 3px 7px; color: #E9EDF4; - min-height: 20px; + min-height: 18px; font-weight: 550; } @@ -119,28 +119,28 @@ QToolButton:hover { QPushButton:pressed, QToolButton:pressed { background-color: #121923; - border-color: #7C5CFC; + border-color: #4C8DFF; } QPushButton:checked, QToolButton:checked { - background-color: #2B2455; - border-color: #7C5CFC; + background-color: #182C4A; + border-color: #4C8DFF; color: #FFFFFF; } QPushButton:default, #primaryAction { - background-color: #6F55E8; - border-color: #8F76FF; + background-color: #3F78D8; + border-color: #6BA3FF; color: #FFFFFF; font-weight: 650; } QPushButton:default:hover, #primaryAction:hover { - background-color: #7C5CFC; - border-color: #A18DFF; + background-color: #4C8DFF; + border-color: #78A9F2; } QPushButton:disabled, @@ -165,8 +165,8 @@ QTimeEdit, QDateTimeEdit { background-color: #0F141B; border: 1px solid #273141; - border-radius: 5px; - padding: 5px 8px; + border-radius: 3px; + padding: 4px 6px; color: #EEF2F7; } @@ -186,7 +186,7 @@ QComboBox:focus, QSpinBox:focus, QDoubleSpinBox:focus { background-color: #111824; - border-color: #7C5CFC; + border-color: #4C8DFF; } QLineEdit:disabled, @@ -213,9 +213,9 @@ QComboBox::drop-down { QComboBox QAbstractItemView { background-color: #171E29; border: 1px solid #344156; - border-radius: 6px; - padding: 4px; - selection-background-color: #2B2455; + border-radius: 4px; + padding: 3px; + selection-background-color: #182C4A; } QAbstractSpinBox::up-button, @@ -249,8 +249,8 @@ QSlider::groove:horizontal { } QSlider::handle:horizontal { - background-color: #8A70FF; - border: 2px solid #C8BCFF; + background-color: #4C8DFF; + border: 2px solid #A9C8F5; width: 12px; margin: -5px 0; border-radius: 7px; @@ -259,14 +259,14 @@ QSlider::handle:horizontal { QProgressBar { background-color: #151C26; border: 1px solid #293446; - border-radius: 5px; + border-radius: 3px; height: 8px; text-align: center; } QProgressBar::chunk { - background-color: #7C5CFC; - border-radius: 4px; + background-color: #4C8DFF; + border-radius: 3px; } QTreeView, @@ -287,8 +287,8 @@ QListWidget::item, QTableView::item, QTableWidget::item { border: 1px solid transparent; - border-radius: 4px; - padding: 4px 6px; + border-radius: 3px; + padding: 3px 5px; } QTreeView::item:hover, @@ -305,8 +305,8 @@ QListView::item:selected, QListWidget::item:selected, QTableView::item:selected, QTableWidget::item:selected { - background-color: #2A2452; - border-color: #6F55E8; + background-color: #172A46; + border-color: #3F78D8; color: #FFFFFF; } @@ -319,7 +319,7 @@ QHeaderView::section { border: none; border-right: 1px solid #283243; border-bottom: 1px solid #283243; - padding: 7px 9px; + padding: 5px 7px; color: #98A4B7; font-weight: 600; } @@ -327,7 +327,7 @@ QHeaderView::section { QTabWidget::pane { background-color: #10151C; border: 1px solid #273141; - border-radius: 0 0 5px 5px; + border-radius: 0 0 3px 3px; } QTabBar::tab { @@ -337,7 +337,7 @@ QTabBar::tab { border-bottom: 1px solid #273141; color: #7F8B9D; min-width: 88px; - padding: 7px 12px; + padding: 5px 9px; } QTabBar::tab:hover { @@ -348,7 +348,7 @@ QTabBar::tab:hover { QTabBar::tab:selected { background-color: #151C26; color: #F2F5F9; - border-bottom: 2px solid #7C5CFC; + border-bottom: 2px solid #4C8DFF; } QMenuBar#atlasMenuBar { @@ -361,7 +361,7 @@ QMenuBar#atlasMenuBar::item { background: transparent; color: #B8C2D0; padding: 5px 9px; - border-radius: 4px; + border-radius: 3px; } QMenuBar#atlasMenuBar::item:selected, @@ -373,19 +373,19 @@ QMenuBar#atlasMenuBar::item:pressed { QMenu { background-color: #171E29; border: 1px solid #344156; - border-radius: 7px; - padding: 5px; + border-radius: 4px; + padding: 3px; } QMenu::item { background: transparent; - border-radius: 4px; - padding: 7px 34px 7px 10px; + border-radius: 3px; + padding: 5px 30px 5px 8px; color: #DCE3EC; } QMenu::item:selected { - background-color: #2A2452; + background-color: #172A46; color: #FFFFFF; } @@ -412,7 +412,7 @@ QSplitter::handle:vertical { } QSplitter::handle:hover { - background-color: #7C5CFC; + background-color: #4C8DFF; } QStatusBar { @@ -451,7 +451,7 @@ QStatusBar { border: none; border-bottom: 1px solid #273141; spacing: 3px; - padding: 4px 7px 4px 0; + padding: 2px 5px 2px 0; } #workspaceIdentity { @@ -477,9 +477,9 @@ QStatusBar { #workspaceModeButton { background-color: transparent; border: 1px solid transparent; - border-radius: 5px; + border-radius: 3px; color: #94A0B2; - padding: 5px 9px; + padding: 4px 8px; margin: 0 1px; } @@ -489,8 +489,8 @@ QStatusBar { } #workspaceModeButton:checked { - background-color: #25203F; - border-color: #4E3C8D; + background-color: #17263B; + border-color: #31577F; color: #FFFFFF; } @@ -498,6 +498,13 @@ QStatusBar { background: transparent; border-color: transparent; min-width: 26px; + padding: 3px 5px; +} + +#workspaceBuildButton, +#workspaceLaunchButton { + min-width: 26px; + padding: 3px 5px; } #workspaceBuildButton { @@ -532,14 +539,14 @@ QStatusBar { background-color: #111720; border-right: 1px solid #252E3B; color: #7F8B9D; - min-width: 128px; - padding: 6px 12px; + min-width: 112px; + padding: 5px 10px; } #sceneTabs::tab:selected { background-color: #171E29; color: #F3F6FA; - border-bottom: 2px solid #55C2FF; + border-bottom: 2px solid #4CB7D8; } #viewportTools { @@ -553,7 +560,8 @@ QStatusBar { #viewportPlaybackButton, #viewportModeButton, -#viewportOptionButton { +#viewportOptionButton, +#viewportShadingButton { background-color: #171E29; border-color: #283345; min-width: 25px; @@ -563,23 +571,20 @@ QStatusBar { #viewportPlaybackButton:hover, #viewportModeButton:hover, -#viewportOptionButton:hover { +#viewportOptionButton:hover, +#viewportShadingButton:hover { background-color: #222C3C; border-color: #46536A; } -#viewportModeButton:checked { - background-color: #2A2452; - border-color: #7C5CFC; -} - -#viewportShadingMode { - min-width: 104px; - background-color: #111720; +#viewportModeButton:checked, +#viewportShadingButton:checked { + background-color: #172A46; + border-color: #4C8DFF; } #viewportFpsLabel { - color: #6EDB8C; + color: #73C58A; font-size: 10px; font-weight: 650; } @@ -589,7 +594,7 @@ QStatusBar { border-top: 1px solid #202836; color: #68758A; font-size: 10px; - padding: 5px 9px; + padding: 3px 7px; } #panelToolbar, @@ -598,15 +603,15 @@ QStatusBar { #workspaceToolbar { background-color: #131922; border-bottom: 1px solid #283243; - padding: 4px; + padding: 3px; } #panelAddButton, #materialSaveButton, #workspaceApplyButton { - background-color: #2A2452; - border-color: #5946AD; - color: #E8E2FF; + background-color: #172A46; + border-color: #35628F; + color: #DCE9FA; } #panelMoreButton, @@ -646,21 +651,21 @@ QTreeView#hierarchyTree::item { } QTreeView#hierarchyTree::item:selected { - background-color: #2A2452; - border-left: 2px solid #A78BFA; + background-color: #172A46; + border-left: 2px solid #6BA3FF; } QListView#contentGrid { background-color: #0D1218; border-top: 1px solid #202836; - padding: 8px; + padding: 6px; } QListView#contentGrid::item { background-color: #121923; border: 1px solid #202A38; - border-radius: 7px; - padding: 10px; + border-radius: 4px; + padding: 7px; color: #BCC6D4; } @@ -670,8 +675,8 @@ QListView#contentGrid::item:hover { } QListView#contentGrid::item:selected { - background-color: #29234B; - border-color: #7C5CFC; + background-color: #17283F; + border-color: #4C8DFF; color: #FFFFFF; } @@ -686,15 +691,15 @@ QScrollArea#inspectorScroll, #inspectorHeader { background-color: #141B25; border: 1px solid #273243; - border-radius: 7px; - padding: 8px; + border-radius: 4px; + padding: 6px; } #inspectorObjectIcon { background-color: #20283A; border: 1px solid #38455B; - border-radius: 7px; - padding: 6px; + border-radius: 4px; + padding: 4px; } #inspectorNameField { @@ -720,14 +725,14 @@ QScrollArea#inspectorScroll, #inspectorComponent { background-color: #141A23; border: 1px solid #252F3E; - border-radius: 7px; - margin-top: 5px; + border-radius: 4px; + margin-top: 3px; } #inspectorComponentHeaderRow { background-color: #171E29; border-bottom: 1px solid #252F3E; - border-radius: 7px 7px 0 0; + border-radius: 4px 4px 0 0; } #inspectorComponentHeader { @@ -736,7 +741,7 @@ QScrollArea#inspectorScroll, color: #E8ECF2; font-weight: 650; text-align: left; - padding: 7px 8px; + padding: 5px 7px; } #inspectorComponentHeader:hover { @@ -774,7 +779,7 @@ QScrollArea#inspectorScroll, #inspectorNumericField { background-color: #0F141B; border: 1px solid #263142; - border-radius: 5px; + border-radius: 3px; } #inspectorVectorField QDoubleSpinBox, @@ -819,9 +824,9 @@ QScrollArea#inspectorScroll, #inspectorNestedGroup { background-color: #111720; border: 1px solid #222C3A; - border-radius: 6px; + border-radius: 4px; margin: 3px 0; - padding: 6px; + padding: 5px; } #inspectorNestedTitle, @@ -847,18 +852,18 @@ QScrollArea#inspectorScroll, background-color: #1B2431; border: 1px dashed #46536A; color: #C7D0DD; - padding: 8px; + padding: 6px; } #inspectorAddComponentButton:hover { - background-color: #29234B; - border-color: #7C5CFC; + background-color: #17283F; + border-color: #4C8DFF; color: #FFFFFF; } #inspectorAudioControls { background-color: #111720; - border-radius: 5px; + border-radius: 3px; } #materialEditorTitle, @@ -882,21 +887,21 @@ QScrollArea#inspectorScroll, #materialPreview { background-color: #090D12; border: 1px solid #2B3648; - border-radius: 8px; + border-radius: 4px; } #materialTextureSlot { background-color: #121923; border: 1px solid #263142; - border-radius: 7px; - padding: 5px; + border-radius: 4px; + padding: 4px; } #materialTexturePreview { background-color: #0D1218; border: 1px solid #344156; - border-radius: 6px; - color: #F472B6; + border-radius: 4px; + color: #D9825B; font-weight: 750; } @@ -919,17 +924,17 @@ QScrollArea#inspectorScroll, QListWidget#environmentCategories { background-color: #0E131A; border-right: 1px solid #273141; - padding: 7px; + padding: 5px; } QListWidget#environmentCategories::item { - padding: 8px 10px; + padding: 6px 8px; margin: 2px 0; } QListWidget#environmentCategories::item:selected { - background-color: #2A2452; - border-left: 2px solid #A78BFA; + background-color: #172A46; + border-left: 2px solid #6BA3FF; } #environmentPageTitle { @@ -960,7 +965,7 @@ ads--CDockContainerWidget ads--CDockSplitter::handle { } ads--CDockContainerWidget ads--CDockSplitter::handle:hover { - background-color: #7C5CFC; + background-color: #4C8DFF; } ads--CDockAreaWidget { @@ -975,7 +980,7 @@ ads--CDockAreaWidget[focused="true"] { ads--CDockAreaTitleBar { background-color: #111720; border-bottom: 1px solid #273141; - min-height: 30px; + min-height: 26px; } ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { @@ -989,7 +994,7 @@ ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { ads--CTitleBarButton { background: transparent; border: none; - border-radius: 4px; + border-radius: 3px; min-width: 22px; min-height: 22px; padding: 2px; @@ -1004,7 +1009,7 @@ ads--CDockWidgetTab { border: none; border-right: 1px solid #252E3B; border-bottom: 1px solid #273141; - padding: 2px 7px; + padding: 1px 5px; } ads--CDockWidgetTab:hover { @@ -1013,7 +1018,7 @@ ads--CDockWidgetTab:hover { ads--CDockWidgetTab[activeTab="true"] { background-color: #171E29; - border-bottom: 2px solid #7C5CFC; + border-bottom: 2px solid #4C8DFF; } ads--CDockWidgetTab[focused="true"] { @@ -1065,13 +1070,13 @@ ads--CAutoHideTab { background-color: #111720; border: 1px solid #263142; color: #7F8B9D; - padding: 5px; + padding: 4px; } ads--CAutoHideTab:hover, ads--CAutoHideTab[activeTab="true"] { - background-color: #2A2452; - border-color: #6F55E8; + background-color: #172A46; + border-color: #3F78D8; color: #FFFFFF; } @@ -1098,16 +1103,16 @@ ads--CAutoHideTab[activeTab="true"] { } #projectNavSelected { - background-color: #24203F; - border: 1px solid #493A86; - border-left: 3px solid #8F76FF; - color: #EEE9FF; - padding: 8px 11px; + background-color: #17263B; + border: 1px solid #2F527D; + border-left: 3px solid #6BA3FF; + color: #DCE9FA; + padding: 6px 9px; text-align: left; } #projectNavSelected:disabled { - color: #EEE9FF; + color: #DCE9FA; } #projectBrowserTitle, @@ -1127,13 +1132,13 @@ ads--CAutoHideTab[activeTab="true"] { #projectSearch { background-color: #111720; border: 1px solid #2A3547; - border-radius: 7px; - padding: 9px 12px; + border-radius: 4px; + padding: 7px 9px; font-size: 13px; } #projectSearch:focus { - border-color: #7C5CFC; + border-color: #4C8DFF; } #projectList { @@ -1150,7 +1155,7 @@ ads--CAutoHideTab[activeTab="true"] { #projectRow { background-color: #141A23; border: 1px solid #252F3E; - border-radius: 8px; + border-radius: 5px; } #projectRow:hover { @@ -1167,7 +1172,7 @@ ads--CAutoHideTab[activeTab="true"] { #templateIcon { background-color: #1D2532; border: 1px solid #334056; - border-radius: 7px; + border-radius: 4px; } #projectName { @@ -1185,7 +1190,7 @@ ads--CAutoHideTab[activeTab="true"] { #rendererBadge { background-color: #1C3527; border: 1px solid #2C6340; - border-radius: 5px; + border-radius: 3px; color: #8DE2A5; padding: 3px 7px; font-size: 9px; @@ -1205,7 +1210,7 @@ ads--CAutoHideTab[activeTab="true"] { #projectEmptyState { background-color: #10151C; border: 1px dashed #2F3A4D; - border-radius: 9px; + border-radius: 5px; } #emptyStateTitle { @@ -1221,7 +1226,7 @@ ads--CAutoHideTab[activeTab="true"] { QFrame[templateCard="true"] { background-color: #141A23; border: 1px solid #293445; - border-radius: 8px; + border-radius: 5px; } QFrame[templateCard="true"]:hover { @@ -1230,8 +1235,8 @@ QFrame[templateCard="true"]:hover { } QFrame[templateCard="true"][selected="true"] { - background-color: #29234B; - border-color: #7C5CFC; + background-color: #17283F; + border-color: #4C8DFF; } #templateOption { @@ -1268,15 +1273,15 @@ QPushButton[secondary="true"]:hover { #dialogHero { background-color: #141A23; border: 1px solid #293445; - border-radius: 8px; - padding: 7px; + border-radius: 5px; + padding: 6px; } #dialogHeroIcon { - background-color: #211C3B; - border: 1px solid #493A86; - border-radius: 7px; - padding: 8px; + background-color: #15253A; + border: 1px solid #2F527D; + border-radius: 4px; + padding: 6px; } #dialogHeroTitle { @@ -1293,8 +1298,8 @@ QPushButton[secondary="true"]:hover { #exportSummary { background-color: #121923; border: 1px solid #273141; - border-radius: 6px; - padding: 8px; + border-radius: 4px; + padding: 6px; } #exportLog { @@ -1309,21 +1314,21 @@ QPushButton[secondary="true"]:hover { #globalSearchDialog { background-color: #111720; border: 1px solid #46536A; - border-radius: 10px; + border-radius: 5px; } #commandPaletteSearch, #globalSearchField { background-color: #0D1218; border: 1px solid #3A465A; - border-radius: 7px; - padding: 10px 12px; + border-radius: 4px; + padding: 7px 9px; font-size: 14px; } #commandPaletteSearch:focus, #globalSearchField:focus { - border-color: #8F76FF; + border-color: #6BA3FF; } #commandPaletteList, diff --git a/editor/styling/icons.cpp b/editor/styling/icons.cpp index 773f6df1..eecef77d 100644 --- a/editor/styling/icons.cpp +++ b/editor/styling/icons.cpp @@ -54,12 +54,16 @@ ushort codepoint(styling::Icon icon) { return 0xE1DA; case styling::Icon::CubeFocus: return 0xED0A; + case styling::Icon::CubeTransparent: + return 0xEC7C; case styling::Icon::CursorClick: return 0xE7C8; case styling::Icon::Database: return 0xE1DE; case styling::Icon::DotsVertical: return 0xE208; + case styling::Icon::DotsNine: + return 0xE1FC; case styling::Icon::Export: return 0xEAF0; case styling::Icon::Eye: diff --git a/editor/styling/theme.cpp b/editor/styling/theme.cpp index 7aa7588c..7d4a44ee 100644 --- a/editor/styling/theme.cpp +++ b/editor/styling/theme.cpp @@ -21,7 +21,7 @@ void styling::applyColorPalette(QApplication& app) { const QColor panel2 = QColor("#10151C"); const QColor text = QColor("#E7ECF3"); const QColor mutedText = QColor("#8490A4"); - const QColor accent = QColor("#7C5CFC"); + const QColor accent = QColor("#4C8DFF"); p.setColor(QPalette::Window, bg); p.setColor(QPalette::WindowText, text); @@ -47,7 +47,7 @@ void styling::applyColorPalette(QApplication& app) { p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#566174")); p.setColor(QPalette::Disabled, QPalette::Button, QColor("#131922")); p.setColor(QPalette::Disabled, QPalette::Base, QColor("#11161D")); - p.setColor(QPalette::Disabled, QPalette::Highlight, QColor("#332A5E")); + p.setColor(QPalette::Disabled, QPalette::Highlight, QColor("#213958")); app.setPalette(p); } diff --git a/editor/views/editor/editor.cpp b/editor/views/editor/editor.cpp index 9982a933..c59a548c 100644 --- a/editor/views/editor/editor.cpp +++ b/editor/views/editor/editor.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -81,50 +83,50 @@ #include "editor/views/viewportTools.h" namespace { -constexpr int DockStateVersion = 8; -constexpr auto DockStateKey = "docking/state/v8"; +constexpr int DockStateVersion = 9; +constexpr auto DockStateKey = "docking/state/v9"; QIcon commandIcon(const QString &name) { const QString command = name.toLower(); if (command.contains("save")) - return styling::icon(styling::Icon::FloppyDisk, "#F5B942"); + return styling::icon(styling::Icon::FloppyDisk, "#D9A441"); if (command.contains("open")) - return styling::icon(styling::Icon::FolderOpen, "#55C2FF"); + return styling::icon(styling::Icon::FolderOpen, "#4CB7D8"); if (command.contains("new") || command.contains("create") || command.contains("add")) - return styling::icon(styling::Icon::Plus, "#A78BFA"); + return styling::icon(styling::Icon::Plus, "#6BA3FF"); if (command.contains("export")) - return styling::icon(styling::Icon::Export, "#55C2FF"); + return styling::icon(styling::Icon::Export, "#4CB7D8"); if (command.contains("build")) - return styling::icon(styling::Icon::Package, "#F5B942"); + return styling::icon(styling::Icon::Package, "#D9A441"); if (command.contains("run") || command.contains("play")) - return styling::icon(styling::Icon::RocketLaunch, "#52D273"); + return styling::icon(styling::Icon::RocketLaunch, "#5EBB78"); if (command.contains("stop")) - return styling::icon(styling::Icon::Stop, "#FF6B7A"); + return styling::icon(styling::Icon::Stop, "#D86470"); if (command.contains("reload") || command.contains("refresh") || command.contains("undo")) - return styling::icon(styling::Icon::ArrowCounterClockwise, "#55C2FF"); + return styling::icon(styling::Icon::ArrowCounterClockwise, "#4CB7D8"); if (command.contains("redo")) - return styling::icon(styling::Icon::ArrowClockwise, "#55C2FF"); + return styling::icon(styling::Icon::ArrowClockwise, "#4CB7D8"); if (command.contains("settings")) - return styling::icon(styling::Icon::Gear, "#A78BFA"); + return styling::icon(styling::Icon::Gear, "#6BA3FF"); if (command.contains("find") || command.contains("search") || command.contains("palette")) - return styling::icon(styling::Icon::MagnifyingGlass, "#55C2FF"); + return styling::icon(styling::Icon::MagnifyingGlass, "#4CB7D8"); if (command.contains("screenshot")) - return styling::icon(styling::Icon::Camera, "#F472B6"); + return styling::icon(styling::Icon::Camera, "#D9825B"); if (command.contains("delete") || command.contains("remove")) - return styling::icon(styling::Icon::Trash, "#FF6B7A"); + return styling::icon(styling::Icon::Trash, "#D86470"); if (command.contains("layout") || command.contains("window")) - return styling::icon(styling::Icon::Layout, "#A78BFA"); + return styling::icon(styling::Icon::Layout, "#6BA3FF"); if (command.contains("close") || command.contains("quit")) - return styling::icon(styling::Icon::Close, "#FF6B7A"); + return styling::icon(styling::Icon::Close, "#D86470"); if (command.contains("camera")) - return styling::icon(styling::Icon::Camera, "#F472B6"); + return styling::icon(styling::Icon::Camera, "#D9825B"); if (command.contains("light")) - return styling::icon(styling::Icon::Lightbulb, "#F5B942"); + return styling::icon(styling::Icon::Lightbulb, "#D9A441"); if (command.contains("object")) - return styling::icon(styling::Icon::Cube, "#A78BFA"); + return styling::icon(styling::Icon::Cube, "#6BA3FF"); return {}; } @@ -305,7 +307,7 @@ void EditorWindow::setupMenus() { addCommand(fileMenu, "Open Scene…", "Meta+O", [this] { openScene(); }); auto *saveAction = fileMenu->addAction("Save Scene"); saveAction->setIcon( - styling::icon(styling::Icon::FloppyDisk, "#F5B942")); + styling::icon(styling::Icon::FloppyDisk, "#D9A441")); saveAction->setShortcut(QKeySequence::Save); saveAction->setShortcutContext(Qt::ApplicationShortcut); connect(saveAction, &QAction::triggered, this, [this] { @@ -338,7 +340,7 @@ void EditorWindow::setupMenus() { auto *editMenu = menuBar()->addMenu("Edit"); auto *undoAction = editMenu->addAction("Undo"); undoAction->setIcon( - styling::icon(styling::Icon::ArrowCounterClockwise, "#55C2FF")); + styling::icon(styling::Icon::ArrowCounterClockwise, "#4CB7D8")); undoAction->setShortcut(QKeySequence::Undo); undoAction->setShortcutContext(Qt::ApplicationShortcut); connect(undoAction, &QAction::triggered, this, [this] { @@ -354,7 +356,7 @@ void EditorWindow::setupMenus() { }); auto *redoAction = editMenu->addAction("Redo"); redoAction->setIcon( - styling::icon(styling::Icon::ArrowClockwise, "#55C2FF")); + styling::icon(styling::Icon::ArrowClockwise, "#4CB7D8")); redoAction->setShortcut(QKeySequence::Redo); redoAction->setShortcutContext(Qt::ApplicationShortcut); connect(redoAction, &QAction::triggered, this, [this] { @@ -479,14 +481,14 @@ void EditorWindow::setupMenus() { viewMenu = menuBar()->addMenu("View"); auto *resetLayoutAction = viewMenu->addAction("Reset Layout"); resetLayoutAction->setIcon( - styling::icon(styling::Icon::Layout, "#A78BFA")); + styling::icon(styling::Icon::Layout, "#6BA3FF")); connect(resetLayoutAction, &QAction::triggered, this, [this] { if (coreManager != nullptr && !defaultDockState.isEmpty()) { restoringLayout = true; coreManager->restoreState(defaultDockState, DockStateVersion); restoringLayout = false; configureDockSplitters(); - if (auto *dock = dockManager->panel("viewport")) + if (auto *dock = dockManager->panel("workspace")) dock->setAsCurrentTab(); scheduleLayoutSave(); } @@ -562,7 +564,7 @@ void EditorWindow::setupMenus() { QStringLiteral("Atlas Engine %1\nby Neutral Software") .arg(QStringLiteral(ATLAS_VERSION))); }); - aboutAction->setIcon(styling::icon(styling::Icon::Info, "#55C2FF")); + aboutAction->setIcon(styling::icon(styling::Icon::Info, "#4CB7D8")); aboutAction->setMenuRole(QAction::AboutRole); } @@ -580,12 +582,21 @@ void EditorWindow::setupDocks() { emit startupReady(success, message); }); viewportTools = new ViewportTools(viewportPanel, projectFile); - auto *viewportDock = dockManager->addPanel( - {.id = "viewport", - .title = "Viewport", - .widget = viewportTools, + materialEditorPanel = new MaterialEditorPanel(viewportPanel); + postProcessingPanel = new PostProcessingPanel(viewportPanel); + workspaceStack = new QStackedWidget(this); + workspaceStack->setObjectName("editorWorkspaceStack"); + workspaceStack->addWidget(viewportTools); + workspaceStack->addWidget(materialEditorPanel); + workspaceStack->addWidget(postProcessingPanel); + workspaceStack->setCurrentIndex(0); + auto *workspaceDock = dockManager->addPanel( + {.id = "workspace", + .title = "Workspace", + .widget = workspaceStack, .area = EditorDockArea::Center, - .icon = styling::icon(styling::Icon::CubeFocus, "#55C2FF")}); + .icon = styling::icon(styling::Icon::CubeFocus, "#4CB7D8")}); + workspaceDock->setFeature(ads::CDockWidget::NoTab, true); hierarchyPanel = new HierarchyPanel(viewportPanel); auto *hierarchyDock = dockManager->addPanel( @@ -593,7 +604,7 @@ void EditorWindow::setupDocks() { .title = "Scene", .widget = hierarchyPanel, .area = EditorDockArea::Left, - .icon = styling::icon(styling::Icon::TreeStructure, "#A78BFA")}); + .icon = styling::icon(styling::Icon::TreeStructure, "#6BA3FF")}); inspectorPanel = new InspectorPanel(viewportPanel, projectFile); auto *inspectorDock = dockManager->addPanel( @@ -601,7 +612,7 @@ void EditorWindow::setupDocks() { .title = "Inspector", .widget = inspectorPanel, .area = EditorDockArea::Right, - .icon = styling::icon(styling::Icon::SlidersHorizontal, "#F5B942")}); + .icon = styling::icon(styling::Icon::SlidersHorizontal, "#D9A441")}); contentBrowser = new ContentBrowserPanel(projectFile); auto *contentDock = dockManager->addPanel( @@ -609,34 +620,13 @@ void EditorWindow::setupDocks() { .title = "Content Browser", .widget = contentBrowser, .area = EditorDockArea::Bottom, - .icon = styling::icon(styling::Icon::FolderOpen, "#55C2FF")}); - - materialEditorPanel = new MaterialEditorPanel(viewportPanel); - auto *materialDock = dockManager->addPanel( - {.id = "materialEditor", - .title = "Material Editor", - .widget = materialEditorPanel, - .area = EditorDockArea::Right, - .icon = styling::icon(styling::Icon::Material, "#F472B6")}); - coreManager->addDockWidgetTabToArea(materialDock, - viewportDock->dockAreaWidget()); + .icon = styling::icon(styling::Icon::FolderOpen, "#4CB7D8")}); - postProcessingPanel = new PostProcessingPanel(viewportPanel); - auto *postProcessingDock = dockManager->addPanel( - {.id = "postProcessing", - .title = "Post Processing", - .widget = postProcessingPanel, - .area = EditorDockArea::Right, - .icon = styling::icon(styling::Icon::Sparkle, "#52D273")}); - coreManager->addDockWidgetTabToArea(postProcessingDock, - viewportDock->dockAreaWidget()); - - viewportDock->setAsCurrentTab(); + workspaceDock->setAsCurrentTab(); defaultDockState = coreManager->saveState(DockStateVersion); const QList managedDocks{ - viewportDock, hierarchyDock, inspectorDock, contentDock, - materialDock, postProcessingDock}; + workspaceDock, hierarchyDock, inspectorDock, contentDock}; for (ads::CDockWidget *dock : managedDocks) { connect(dock, &ads::CDockWidget::topLevelChanged, this, [this](bool) { scheduleLayoutSave(); }); @@ -657,15 +647,12 @@ void EditorWindow::setupDocks() { windowMenu->addAction(dock->toggleViewAction()); } windowMenu->addSeparator(); - const QList> workspaces{ - {"Viewport", viewportDock}, - {"Material Editor", materialDock}, - {"Post Processing", postProcessingDock}, - {"Hierarchy", hierarchyDock}, + const QList> panels{ + {"Workspace", workspaceDock}, {"Hierarchy", hierarchyDock}, {"Inspector", inspectorDock}, {"Content Browser", contentDock}}; - for (int index = 0; index < workspaces.size(); ++index) { - const auto &[name, dock] = workspaces.at(index); + for (int index = 0; index < panels.size(); ++index) { + const auto &[name, dock] = panels.at(index); auto *action = windowMenu->addAction( QStringLiteral("Focus %1").arg(name), this, [dock] { dock->toggleView(true); @@ -677,6 +664,27 @@ void EditorWindow::setupDocks() { QStringLiteral("Ctrl+%1").arg(index + 1))); action->setShortcutContext(Qt::ApplicationShortcut); } + windowMenu->addSeparator(); + const QList> workspaceModes{ + {"Scene", 0}, {"Shading", 1}, {"Post-Processing", 2}}; + for (const auto &[name, index] : workspaceModes) { + auto *action = windowMenu->addAction( + QStringLiteral("Open %1 Workspace").arg(name), this, + [this, workspaceDock, index] { + activateWorkspace(index); + workspaceDock->toggleView(true); + workspaceDock->setAsCurrentTab(); + workspaceDock->raise(); + }); + action->setIcon(index == 0 + ? styling::icon(styling::Icon::CubeFocus, + "#4CB7D8") + : index == 1 + ? styling::icon(styling::Icon::Material, + "#D9A441") + : styling::icon(styling::Icon::FilmStrip, + "#5EBB78")); + } } connect(hierarchyPanel, &HierarchyPanel::objectActivated, inspectorPanel, @@ -701,10 +709,9 @@ void EditorWindow::setupDocks() { this->inspectorPanel->inspectFile(path); }); connect(contentBrowser, &ContentBrowserPanel::assetActivated, this, - [this, materialDock](const QString &path) { + [this](const QString &path) { materialEditorPanel->openMaterial(path); - materialDock->toggleView(true); - materialDock->raise(); + activateWorkspace(1); }); connect(contentBrowser, &ContentBrowserPanel::sceneActivated, this, [this](const QString &path) { @@ -742,13 +749,11 @@ void EditorWindow::setupWorkspaceBar() { identityLayout->addWidget(project); bar->addWidget(identity); - auto *modes = new QButtonGroup(bar); - modes->setExclusive(true); - auto addMode = [this, bar, modes](const QString &text, - styling::Icon icon, - const QColor &color, - const QString &dockId, - bool selected = false) { + workspaceModeGroup = new QButtonGroup(bar); + workspaceModeGroup->setExclusive(true); + auto addMode = [this, bar](const QString &text, styling::Icon icon, + const QColor &color, int index, + bool selected = false) { auto *button = new QToolButton(bar); button->setObjectName("workspaceModeButton"); button->setText(text); @@ -756,23 +761,14 @@ void EditorWindow::setupWorkspaceBar() { button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setCheckable(true); button->setChecked(selected); - modes->addButton(button); + workspaceModeGroup->addButton(button, index); bar->addWidget(button); connect(button, &QToolButton::clicked, this, - [this, dockId] { - if (auto *dock = dockManager->panel(dockId)) { - dock->toggleView(true); - dock->setAsCurrentTab(); - dock->raise(); - } - }); + [this, index] { activateWorkspace(index); }); }; - addMode("Layout", styling::Icon::Layout, "#A78BFA", "viewport", true); - addMode("Materials", styling::Icon::Material, "#F472B6", - "materialEditor"); - addMode("Look Dev", styling::Icon::Sparkle, "#52D273", - "postProcessing"); - addMode("Assets", styling::Icon::FolderOpen, "#55C2FF", "fileExplorer"); + addMode("Scene", styling::Icon::CubeFocus, "#4CB7D8", 0, true); + addMode("Shading", styling::Icon::Material, "#D9A441", 1); + addMode("Post-Processing", styling::Icon::FilmStrip, "#5EBB78", 2); auto *spacer = new QWidget(bar); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -780,7 +776,7 @@ void EditorWindow::setupWorkspaceBar() { auto *save = new QToolButton(bar); save->setObjectName("workspaceUtilityButton"); - save->setIcon(styling::icon(styling::Icon::FloppyDisk, "#F5B942")); + save->setIcon(styling::icon(styling::Icon::FloppyDisk, "#D9A441")); save->setToolTip("Save Scene"); bar->addWidget(save); connect(save, &QToolButton::clicked, this, [this] { @@ -792,9 +788,7 @@ void EditorWindow::setupWorkspaceBar() { auto *build = new QToolButton(bar); build->setObjectName("workspaceBuildButton"); - build->setText("Build"); - build->setIcon(styling::icon(styling::Icon::Package, "#F5B942")); - build->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + build->setIcon(styling::icon(styling::Icon::Package, "#D9A441")); build->setToolTip("Build Project"); bar->addWidget(build); connect(build, &QToolButton::clicked, this, @@ -802,9 +796,7 @@ void EditorWindow::setupWorkspaceBar() { auto *launch = new QToolButton(bar); launch->setObjectName("workspaceLaunchButton"); - launch->setText("Launch"); - launch->setIcon(styling::icon(styling::Icon::RocketLaunch, "#52D273")); - launch->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + launch->setIcon(styling::icon(styling::Icon::RocketLaunch, "#5EBB78")); launch->setToolTip("Run Project"); bar->addWidget(launch); connect(launch, &QToolButton::clicked, this, @@ -815,7 +807,7 @@ void EditorWindow::setupWorkspaceBar() { auto *runtimeIcon = new QLabel(statusBar()); runtimeIcon->setObjectName("statusRuntimeIcon"); runtimeIcon->setPixmap( - styling::icon(styling::Icon::Check, "#52D273").pixmap(14, 14)); + styling::icon(styling::Icon::Check, "#5EBB78").pixmap(14, 14)); auto *renderer = new QLabel(statusBar()); renderer->setObjectName("statusRenderer"); const auto projectInfo = ProjectStore::projectInfo(projectFile); @@ -830,7 +822,7 @@ void EditorWindow::setupWorkspaceBar() { [this, runtimeIcon](bool available) { runtimeIcon->setPixmap(styling::icon( available ? styling::Icon::Check : styling::Icon::Warning, - available ? QColor("#52D273") : QColor("#F5B942")) + available ? QColor("#5EBB78") : QColor("#D9A441")) .pixmap(14, 14)); statusBar()->showMessage(available ? "Runtime ready" : "Runtime unavailable", @@ -838,6 +830,17 @@ void EditorWindow::setupWorkspaceBar() { }); } +void EditorWindow::activateWorkspace(int index) { + if (workspaceStack == nullptr || index < 0 || + index >= workspaceStack->count()) + return; + workspaceStack->setCurrentIndex(index); + if (workspaceModeGroup != nullptr) { + if (auto *button = workspaceModeGroup->button(index)) + button->setChecked(true); + } +} + void EditorWindow::createScene() { const QString root = QFileInfo(projectFile).absolutePath(); QString path = QFileDialog::getSaveFileName( @@ -914,7 +917,7 @@ void EditorWindow::showProjectSettings() { auto *headerIcon = new QLabel(header); headerIcon->setObjectName("dialogHeroIcon"); headerIcon->setPixmap( - styling::icon(styling::Icon::Gear, "#A78BFA").pixmap(28, 28)); + styling::icon(styling::Icon::Gear, "#6BA3FF").pixmap(28, 28)); auto *headerCopy = new QVBoxLayout(); auto *headerTitle = new QLabel("Project Settings", header); headerTitle->setObjectName("dialogHeroTitle"); @@ -941,7 +944,7 @@ void EditorWindow::showProjectSettings() { tabs->addTab(page, styling::icon(icon, color), name); return form; }; - auto *general = addPage("General", styling::Icon::Gear, "#A78BFA"); + auto *general = addPage("General", styling::Icon::Gear, "#6BA3FF"); auto *defaultScene = new QComboBox(&dialog); QDirIterator sceneIterator(QFileInfo(projectFile).absolutePath(), {"*.ascene"}, QDir::Files, @@ -979,7 +982,7 @@ void EditorWindow::showProjectSettings() { general->addRow("Window height", windowHeight); general->addRow(QString(), fullscreen); auto *rendering = - addPage("Rendering", styling::Icon::Aperture, "#F472B6"); + addPage("Rendering", styling::Icon::Aperture, "#D9825B"); auto *renderer = new QComboBox(&dialog); renderer->addItems({"PBR", "PBR + DDGI", "Path Tracing"}); renderer->setCurrentText(settings.value("project/renderer", "PBR").toString()); @@ -988,25 +991,25 @@ void EditorWindow::showProjectSettings() { frameLimit->setValue(settings.value("project/frameLimit", 0).toInt()); rendering->addRow("Renderer", renderer); rendering->addRow("Frame limit (0 = unlimited)", frameLimit); - auto *physics = addPage("Physics", styling::Icon::Wrench, "#F5B942"); + auto *physics = addPage("Physics", styling::Icon::Wrench, "#D9A441"); auto *gravity = new QLineEdit(settings.value("project/gravity", "0, -9.81, 0").toString(), &dialog); auto *fixedStep = new QLineEdit(settings.value("project/fixedStep", "0.0166667").toString(), &dialog); physics->addRow("Gravity", gravity); physics->addRow("Fixed timestep", fixedStep); auto *input = - addPage("Input", styling::Icon::GameController, "#52D273"); + addPage("Input", styling::Icon::GameController, "#5EBB78"); auto *inputMap = new QLineEdit(settings.value("project/inputMap", "input.json").toString(), &dialog); auto *controller = new QComboBox(&dialog); controller->addItems({"Automatic", "Keyboard + Mouse", "Gamepad"}); controller->setCurrentText(settings.value("project/controller", "Automatic").toString()); input->addRow("Input map", inputMap); input->addRow("Primary controller", controller); - auto *build = addPage("Build & Run", styling::Icon::Package, "#F5B942"); + auto *build = addPage("Build & Run", styling::Icon::Package, "#D9A441"); auto *buildCommand = new QLineEdit(settings.value("project/buildCommand", "atlas pack --backend METAL").toString(), &dialog); auto *runCommand = new QLineEdit(settings.value("project/runCommand", "atlas run project.atlas").toString(), &dialog); build->addRow("Build command", buildCommand); build->addRow("Run command", runCommand); - auto *editor = addPage("Editor", styling::Icon::Layout, "#55C2FF"); + auto *editor = addPage("Editor", styling::Icon::Layout, "#4CB7D8"); auto *autosave = new QSpinBox(&dialog); autosave->setRange(0, 120); autosave->setValue(settings.value("project/autosaveMinutes", 5).toInt()); @@ -1014,7 +1017,7 @@ void EditorWindow::showProjectSettings() { editor->addRow("Autosave interval (minutes)", autosave); editor->addRow("Transform snapping", snap); auto *packaging = - addPage("Packaging", styling::Icon::Export, "#A78BFA"); + addPage("Packaging", styling::Icon::Export, "#6BA3FF"); auto *identifier = new QLineEdit( settings.value("project/bundleIdentifier", "org.atlasengine." + projectName.toLower().replace(' ', '-')) @@ -1033,7 +1036,7 @@ void EditorWindow::showProjectSettings() { auto *buttons = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Save, &dialog); buttons->button(QDialogButtonBox::Save) - ->setIcon(styling::icon(styling::Icon::FloppyDisk, "#F5B942")); + ->setIcon(styling::icon(styling::Icon::FloppyDisk, "#D9A441")); layout->addWidget(buttons); connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); @@ -1112,7 +1115,7 @@ void EditorWindow::showExportDialog() { auto *headerIcon = new QLabel(header); headerIcon->setObjectName("dialogHeroIcon"); headerIcon->setPixmap( - styling::icon(styling::Icon::Export, "#52D273").pixmap(28, 28)); + styling::icon(styling::Icon::Export, "#5EBB78").pixmap(28, 28)); auto *headerCopy = new QVBoxLayout(); auto *headerTitle = new QLabel("Export Project", header); headerTitle->setObjectName("dialogHeroTitle"); @@ -1156,7 +1159,7 @@ void EditorWindow::showExportDialog() { &dialog); auto *browse = new QPushButton("Choose…", &dialog); browse->setIcon( - styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); auto *outputRow = new QWidget(&dialog); auto *outputLayout = new QHBoxLayout(outputRow); outputLayout->setContentsMargins(0, 0, 0, 0); @@ -1185,10 +1188,10 @@ void EditorWindow::showExportDialog() { auto *buttons = new QDialogButtonBox(QDialogButtonBox::Cancel, &dialog); auto *exportButton = buttons->addButton("Export", QDialogButtonBox::AcceptRole); exportButton->setIcon( - styling::icon(styling::Icon::RocketLaunch, "#52D273")); + styling::icon(styling::Icon::RocketLaunch, "#5EBB78")); auto *revealButton = buttons->addButton("Reveal Export", QDialogButtonBox::ActionRole); revealButton->setIcon( - styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); revealButton->setEnabled(false); layout->addWidget(buttons); connect(browse, &QPushButton::clicked, &dialog, [&dialog, output] { @@ -1431,7 +1434,7 @@ void EditorWindow::showGlobalSearch() { continue; auto *item = new QListWidgetItem( QStringLiteral("Asset %1").arg(relative), results); - item->setIcon(styling::icon(styling::Icon::File, "#55C2FF")); + item->setIcon(styling::icon(styling::Icon::File, "#4CB7D8")); item->setToolTip(path); item->setData(SearchKindRole, 0); item->setData(SearchValueRole, path); @@ -1451,7 +1454,7 @@ void EditorWindow::showGlobalSearch() { auto *item = new QListWidgetItem( QStringLiteral("Object %1").arg(name), results); item->setIcon( - styling::icon(styling::Icon::Cube, "#A78BFA")); + styling::icon(styling::Icon::Cube, "#6BA3FF")); item->setToolTip(object.value("type").toString()); item->setData(SearchKindRole, 1); item->setData(SearchValueRole, id); diff --git a/editor/views/editor/hierarchy.cpp b/editor/views/editor/hierarchy.cpp index 53abb4be..30bf9366 100644 --- a/editor/views/editor/hierarchy.cpp +++ b/editor/views/editor/hierarchy.cpp @@ -44,24 +44,24 @@ constexpr int ObjectTypeRole = Qt::UserRole + 2; QIcon hierarchyIcon(QWidget *, const QString &type) { const QString normalized = type.toLower(); if (normalized == "scene") - return styling::icon(styling::Icon::CubeFocus, "#55C2FF"); + return styling::icon(styling::Icon::CubeFocus, "#4CB7D8"); if (normalized == "compound" || normalized == "group") return styling::icon(styling::Icon::Folder, "#8490A4"); if (normalized == "camera") - return styling::icon(styling::Icon::Camera, "#F472B6"); + return styling::icon(styling::Icon::Camera, "#D9825B"); if (normalized == "environment") - return styling::icon(styling::Icon::Globe, "#55C2FF"); + return styling::icon(styling::Icon::Globe, "#4CB7D8"); if (normalized.contains("light") || normalized == "sun") - return styling::icon(styling::Icon::Lightbulb, "#F5B942"); + return styling::icon(styling::Icon::Lightbulb, "#D9A441"); if (normalized == "terrain" || normalized == "landscape") - return styling::icon(styling::Icon::Mountains, "#52D273"); + return styling::icon(styling::Icon::Mountains, "#5EBB78"); if (normalized == "particleemitter" || normalized == "particles") - return styling::icon(styling::Icon::Sparkle, "#A78BFA"); + return styling::icon(styling::Icon::Sparkle, "#6BA3FF"); if (normalized == "model") - return styling::icon(styling::Icon::Cube, "#55C2FF"); + return styling::icon(styling::Icon::Cube, "#4CB7D8"); if (normalized == "sphere") - return styling::icon(styling::Icon::Sphere, "#A78BFA"); - return styling::icon(styling::Icon::Cube, "#A78BFA"); + return styling::icon(styling::Icon::Sphere, "#6BA3FF"); + return styling::icon(styling::Icon::Cube, "#6BA3FF"); } QString objectSignature(const QJsonArray &objects) { @@ -94,7 +94,7 @@ HierarchyPanel::HierarchyPanel(ViewportPanel *viewport, QWidget *parent) addButton = new QToolButton(toolbar); addButton->setObjectName("panelAddButton"); - addButton->setIcon(styling::icon(styling::Icon::Plus, "#A78BFA")); + addButton->setIcon(styling::icon(styling::Icon::Plus, "#6BA3FF")); addButton->setText("Add"); addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addButton->setPopupMode(QToolButton::InstantPopup); @@ -432,15 +432,15 @@ void HierarchyPanel::showContextMenu(const QPoint &position) { } if (index.isValid() && selectedObjectId() >= 0) { menu.addSeparator(); - menu.addAction(styling::icon(styling::Icon::Crosshair, "#55C2FF"), + menu.addAction(styling::icon(styling::Icon::Crosshair, "#4CB7D8"), "Focus", this, &HierarchyPanel::focusSelectedObject); - menu.addAction(styling::icon(styling::Icon::File, "#A78BFA"), + menu.addAction(styling::icon(styling::Icon::File, "#6BA3FF"), "Rename", this, &HierarchyPanel::renameSelectedObject); - menu.addAction(styling::icon(styling::Icon::TreeStructure, "#52D273"), + menu.addAction(styling::icon(styling::Icon::TreeStructure, "#5EBB78"), "Move to Scene Root", this, &HierarchyPanel::moveSelectedObjectToRoot); menu.addSeparator(); - menu.addAction(styling::icon(styling::Icon::Trash, "#FF6B7A"), + menu.addAction(styling::icon(styling::Icon::Trash, "#D86470"), "Delete", this, &HierarchyPanel::deleteSelectedObject); } menu.exec(treeView->viewport()->mapToGlobal(position)); diff --git a/editor/views/editor/inspector.cpp b/editor/views/editor/inspector.cpp index 6cdefc81..0efbe61f 100644 --- a/editor/views/editor/inspector.cpp +++ b/editor/views/editor/inspector.cpp @@ -174,32 +174,32 @@ bool isColorProperty(const QString &name, const QJsonArray &array) { QIcon inspectorIcon(QWidget *, const QString &type) { const QString normalized = type.toLower(); if (normalized == "folder") - return styling::icon(styling::Icon::Folder, "#55C2FF"); + return styling::icon(styling::Icon::Folder, "#4CB7D8"); if (normalized.contains("camera")) - return styling::icon(styling::Icon::Camera, "#F472B6"); + return styling::icon(styling::Icon::Camera, "#D9825B"); if (normalized.contains("environment") || normalized.contains("atmosphere")) - return styling::icon(styling::Icon::Globe, "#55C2FF"); + return styling::icon(styling::Icon::Globe, "#4CB7D8"); if (normalized.contains("light") || normalized == "sun") - return styling::icon(styling::Icon::Lightbulb, "#F5B942"); + return styling::icon(styling::Icon::Lightbulb, "#D9A441"); if (normalized.contains("terrain")) - return styling::icon(styling::Icon::Mountains, "#52D273"); + return styling::icon(styling::Icon::Mountains, "#5EBB78"); if (normalized.contains("particle")) - return styling::icon(styling::Icon::Sparkle, "#A78BFA"); + return styling::icon(styling::Icon::Sparkle, "#6BA3FF"); if (normalized.contains("audio") || normalized == "wav" || normalized == "mp3" || normalized == "ogg" || normalized == "flac") - return styling::icon(styling::Icon::MusicNote, "#52D273"); + return styling::icon(styling::Icon::MusicNote, "#5EBB78"); if (normalized.contains("material")) - return styling::icon(styling::Icon::Material, "#F472B6"); + return styling::icon(styling::Icon::Material, "#D9825B"); if (normalized.contains("script") || normalized == "ts" || normalized == "js") - return styling::icon(styling::Icon::FileCode, "#55C2FF"); + return styling::icon(styling::Icon::FileCode, "#4CB7D8"); if (normalized.contains("rigidbody") || normalized.contains("joint")) - return styling::icon(styling::Icon::Wrench, "#F5B942"); + return styling::icon(styling::Icon::Wrench, "#D9A441"); if (normalized == "sphere") - return styling::icon(styling::Icon::Sphere, "#A78BFA"); - return styling::icon(styling::Icon::Cube, "#A78BFA"); + return styling::icon(styling::Icon::Sphere, "#6BA3FF"); + return styling::icon(styling::Icon::Cube, "#6BA3FF"); } QString componentTitle(const QString &type) { @@ -611,7 +611,7 @@ void addSyncPicker(QHBoxLayout *layout, const QString &path, auto *button = new QToolButton(parent); button->setObjectName("inspectorSyncButton"); button->setIcon( - styling::icon(styling::Icon::ArrowCounterClockwise, "#52D273")); + styling::icon(styling::Icon::ArrowCounterClockwise, "#5EBB78")); button->setToolTip("Match this value with another property"); button->setPopupMode(QToolButton::InstantPopup); auto showMatch = [button, valueEditor](const QString &name) { @@ -975,7 +975,7 @@ void addPropertyRows(QVBoxLayout *layout, const QJsonObject &properties, auto *add = new QToolButton(heading); add->setObjectName("inspectorArrayButton"); add->setIcon( - styling::icon(styling::Icon::Plus, "#A78BFA")); + styling::icon(styling::Icon::Plus, "#6BA3FF")); add->setToolTip("Add item"); add->setToolTip(QStringLiteral("Add %1").arg(humanize(key))); headingLayout->addWidget(title, 1); @@ -1007,7 +1007,7 @@ void addPropertyRows(QVBoxLayout *layout, const QJsonObject &properties, auto *remove = new QToolButton(itemHeading); remove->setObjectName("inspectorArrayButton"); remove->setIcon( - styling::icon(styling::Icon::Trash, "#FF6B7A")); + styling::icon(styling::Icon::Trash, "#D86470")); remove->setToolTip("Remove item"); remove->setToolTip("Remove"); itemHeadingLayout->addWidget(itemTitle, 1); @@ -1169,7 +1169,7 @@ QFrame *componentCard(const QString &title, const QJsonObject &properties, auto *removeButton = new QToolButton(headerRow); removeButton->setObjectName("inspectorComponentRemoveButton"); removeButton->setIcon( - styling::icon(styling::Icon::Trash, "#FF6B7A")); + styling::icon(styling::Icon::Trash, "#D86470")); removeButton->setToolTip(QStringLiteral("Remove %1").arg(title)); headerLayout->addWidget(removeButton); QObject::connect(removeButton, &QToolButton::clicked, card, remove); @@ -1514,7 +1514,7 @@ void InspectorPanel::showObject(const QJsonObject &object) { styling::Icon::Play, styling::Icon::Pause, styling::Icon::Stop}; const QList audioColors{ - QColor("#52D273"), QColor("#F5B942"), QColor("#FF6B7A")}; + QColor("#5EBB78"), QColor("#D9A441"), QColor("#D86470")}; for (int actionIndex = 0; actionIndex < audioActions.size(); ++actionIndex) { const QString &action = audioActions.at(actionIndex); @@ -1538,7 +1538,7 @@ void InspectorPanel::showObject(const QJsonObject &object) { auto *addComponent = new QToolButton(content); addComponent->setObjectName("inspectorAddComponentButton"); addComponent->setIcon( - styling::icon(styling::Icon::Plus, "#A78BFA")); + styling::icon(styling::Icon::Plus, "#6BA3FF")); addComponent->setText("Add Component"); addComponent->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addComponent->setPopupMode(QToolButton::InstantPopup); diff --git a/editor/views/editor/materialEditor.cpp b/editor/views/editor/materialEditor.cpp index a65e77ce..1cdb9d75 100644 --- a/editor/views/editor/materialEditor.cpp +++ b/editor/views/editor/materialEditor.cpp @@ -365,11 +365,11 @@ MaterialEditorPanel::MaterialEditorPanel(ViewportPanel *viewport, auto *saveButton = new QPushButton("Save", header); saveButton->setObjectName("materialSaveButton"); saveButton->setIcon( - styling::icon(styling::Icon::FloppyDisk, "#F5B942")); + styling::icon(styling::Icon::FloppyDisk, "#D9A441")); auto *assignButton = new QPushButton("Assign to Selected", header); assignButton->setObjectName("materialAssignButton"); assignButton->setIcon( - styling::icon(styling::Icon::Assign, "#F472B6")); + styling::icon(styling::Icon::Assign, "#D9825B")); headerLayout->addWidget(titleLabel, 1); headerLayout->addWidget(statusLabel); headerLayout->addWidget(assignButton); @@ -608,10 +608,10 @@ void MaterialEditorPanel::showMaterial() { auto *choose = new QToolButton(row); choose->setText("Choose…"); choose->setIcon( - styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); choose->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); auto *clear = new QToolButton(row); - clear->setIcon(styling::icon(styling::Icon::Close, "#FF6B7A")); + clear->setIcon(styling::icon(styling::Icon::Close, "#D86470")); clear->setToolTip("Remove texture"); auto *identity = new QWidget(row); auto *identityLayout = new QVBoxLayout(identity); diff --git a/editor/views/editor/postProcessing.cpp b/editor/views/editor/postProcessing.cpp index d4411577..8e321068 100644 --- a/editor/views/editor/postProcessing.cpp +++ b/editor/views/editor/postProcessing.cpp @@ -105,16 +105,16 @@ PostProcessingPanel::PostProcessingPanel(ViewportPanel *viewport, targetSelector->setMinimumWidth(180); auto *addTargetButton = new QToolButton(toolbar); addTargetButton->setIcon( - styling::icon(styling::Icon::Plus, "#A78BFA")); + styling::icon(styling::Icon::Plus, "#6BA3FF")); addTargetButton->setText("Target"); addTargetButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); removeTargetButton = new QToolButton(toolbar); removeTargetButton->setText("Remove"); removeTargetButton->setIcon( - styling::icon(styling::Icon::Trash, "#FF6B7A")); + styling::icon(styling::Icon::Trash, "#D86470")); auto *applyButton = new QPushButton("Apply to Preview", toolbar); applyButton->setIcon( - styling::icon(styling::Icon::Sparkle, "#52D273")); + styling::icon(styling::Icon::Sparkle, "#5EBB78")); statusLabel = new QLabel(toolbar); statusLabel->setObjectName("postProcessingStatus"); toolbarLayout->addWidget(title); @@ -245,7 +245,7 @@ void PostProcessingPanel::rebuildEditor() { effectsTitle->setObjectName("postProcessingSectionTitle"); auto *addEffectButton = new QToolButton(effectsHeading); addEffectButton->setIcon( - styling::icon(styling::Icon::Plus, "#A78BFA")); + styling::icon(styling::Icon::Plus, "#6BA3FF")); addEffectButton->setText("Add Effect"); addEffectButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addEffectButton->setPopupMode(QToolButton::InstantPopup); @@ -258,7 +258,7 @@ void PostProcessingPanel::rebuildEditor() { "film_grain"}; for (const QString &effect : effects) { effectMenu->addAction( - styling::icon(styling::Icon::Sparkle, "#52D273"), + styling::icon(styling::Icon::Sparkle, "#5EBB78"), effectTitle(effect), this, [this, effect] { addEffect(effect); }); } @@ -330,19 +330,19 @@ void PostProcessingPanel::rebuildEditor() { auto *moveUp = new QToolButton(actions); moveUp->setText("Move Up"); moveUp->setIcon( - styling::icon(styling::Icon::CaretUp, "#55C2FF")); + styling::icon(styling::Icon::CaretUp, "#4CB7D8")); moveUp->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); moveUp->setEnabled(effectIndex > 0); auto *moveDown = new QToolButton(actions); moveDown->setText("Move Down"); moveDown->setIcon( - styling::icon(styling::Icon::CaretDown, "#55C2FF")); + styling::icon(styling::Icon::CaretDown, "#4CB7D8")); moveDown->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); moveDown->setEnabled(effectIndex + 1 < effectStack.size()); auto *remove = new QToolButton(actions); remove->setText("Remove Effect"); remove->setIcon( - styling::icon(styling::Icon::Trash, "#FF6B7A")); + styling::icon(styling::Icon::Trash, "#D86470")); remove->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); actionsLayout->addStretch(); actionsLayout->addWidget(moveUp); diff --git a/editor/views/editor/viewport.cpp b/editor/views/editor/viewport.cpp index 0d0fd3a1..9163a3ed 100644 --- a/editor/views/editor/viewport.cpp +++ b/editor/views/editor/viewport.cpp @@ -74,9 +74,10 @@ int runtimeMouseButton(Qt::MouseButton button) { } } -int activeRuntimeMouseButton(Qt::MouseButtons buttons) { +int activeRuntimeMouseButton(Qt::MouseButtons buttons, + int rightDragRuntimeButton) { if (buttons.testFlag(Qt::RightButton)) { - return runtimeMouseButton(Qt::RightButton); + return rightDragRuntimeButton; } if (buttons.testFlag(Qt::MiddleButton)) { return runtimeMouseButton(Qt::MiddleButton); @@ -412,9 +413,16 @@ void ViewportPanel::mousePressEvent(QMouseEvent *event) { .toArray(), selected); } + int pointerButton = runtimeMouseButton(event->button()); + if (event->button() == Qt::RightButton) { + rightDragRuntimeButton = + event->modifiers().testFlag(Qt::ShiftModifier) + ? runtimeMouseButton(Qt::RightButton) + : runtimeMouseButton(Qt::MiddleButton); + pointerButton = rightDragRuntimeButton; + } sendPointerEvent(0, static_cast(event->position().x()), - static_cast(event->position().y()), - runtimeMouseButton(event->button())); + static_cast(event->position().y()), pointerButton); if (event->button() == Qt::LeftButton && runtimeContext != nullptr) { emit runtimeObjectActivated(runtimeContext->selectedObjectId()); } @@ -426,7 +434,8 @@ void ViewportPanel::mouseMoveEvent(QMouseEvent *event) { leftPointerMoved = true; sendPointerEvent(1, static_cast(event->position().x()), static_cast(event->position().y()), - activeRuntimeMouseButton(event->buttons())); + activeRuntimeMouseButton(event->buttons(), + rightDragRuntimeButton)); if (keyboardTransformActive) { const QRect bounds(mapToGlobal(QPoint(0, 0)), size()); QPoint cursor = event->globalPosition().toPoint(); @@ -452,9 +461,11 @@ void ViewportPanel::mouseMoveEvent(QMouseEvent *event) { } void ViewportPanel::mouseReleaseEvent(QMouseEvent *event) { + const int pointerButton = event->button() == Qt::RightButton + ? rightDragRuntimeButton + : runtimeMouseButton(event->button()); sendPointerEvent(2, static_cast(event->position().x()), - static_cast(event->position().y()), - runtimeMouseButton(event->button())); + static_cast(event->position().y()), pointerButton); if (event->button() == Qt::LeftButton && leftPointerMoved && runtimeContext != nullptr && selectedRuntimeObjectId() >= 0) { const int selected = selectedRuntimeObjectId(); @@ -466,6 +477,8 @@ void ViewportPanel::mouseReleaseEvent(QMouseEvent *event) { emit runtimeObjectActivated(selected); } leftPointerMoved = false; + if (event->button() == Qt::RightButton) + rightDragRuntimeButton = 0; event->accept(); } diff --git a/editor/views/editor/viewportTools.cpp b/editor/views/editor/viewportTools.cpp index e8d168b9..fd581928 100644 --- a/editor/views/editor/viewportTools.cpp +++ b/editor/views/editor/viewportTools.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -42,38 +41,30 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, playButton = new QToolButton(toolbar); playButton->setObjectName("viewportPlaybackButton"); - playButton->setIcon(styling::icon(styling::Icon::Play, "#52D273")); + playButton->setIcon(styling::icon(styling::Icon::Play, "#5EBB78")); playButton->setToolTip("Play"); pauseButton = new QToolButton(toolbar); pauseButton->setObjectName("viewportPlaybackButton"); - pauseButton->setIcon(styling::icon(styling::Icon::Pause, "#F5B942")); + pauseButton->setIcon(styling::icon(styling::Icon::Pause, "#D9A441")); pauseButton->setToolTip("Pause"); stepButton = new QToolButton(toolbar); stepButton->setObjectName("viewportPlaybackButton"); stepButton->setIcon( - styling::icon(styling::Icon::SkipForward, "#55C2FF")); + styling::icon(styling::Icon::SkipForward, "#4CB7D8")); stepButton->setToolTip("Step one frame"); stopButton = new QToolButton(toolbar); stopButton->setObjectName("viewportPlaybackButton"); - stopButton->setIcon(styling::icon(styling::Icon::Stop, "#FF6B7A")); + stopButton->setIcon(styling::icon(styling::Icon::Stop, "#D86470")); stopButton->setToolTip("Stop and restore the scene"); reloadButton = new QToolButton(toolbar); reloadButton->setObjectName("viewportPlaybackButton"); reloadButton->setIcon( - styling::icon(styling::Icon::ArrowCounterClockwise, "#A78BFA")); + styling::icon(styling::Icon::ArrowCounterClockwise, "#4C8DFF")); reloadButton->setToolTip("Reload runtime"); playButton->setShortcut(QKeySequence("Ctrl+P")); pauseButton->setShortcut(QKeySequence("Ctrl+Shift+P")); stepButton->setShortcut(QKeySequence("Ctrl+Alt+P")); - tools->addStretch(); - tools->addWidget(playButton); - tools->addWidget(pauseButton); - tools->addWidget(stepButton); - tools->addWidget(stopButton); - tools->addWidget(reloadButton); - tools->addSpacing(10); - auto *transformGroup = new QActionGroup(toolbar); transformGroup->setExclusive(true); const QStringList transformNames{"Select", "Move", "Rotate", "Scale"}; @@ -81,16 +72,17 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, styling::Icon::CursorClick, styling::Icon::ArrowsOutCardinal, styling::Icon::ArrowClockwise, styling::Icon::BoundingBox}; const QList transformColors{ - QColor("#55C2FF"), QColor("#52D273"), QColor("#F5B942"), - QColor("#F472B6")}; + QColor("#4CB7D8"), QColor("#5EBB78"), QColor("#D9A441"), + QColor("#4C8DFF")}; for (int index = 0; index < transformNames.size(); ++index) { auto *button = new QToolButton(toolbar); button->setObjectName("viewportModeButton"); - button->setIcon( - styling::icon(transformIcons.at(index), transformColors.at(index))); - button->setToolTip(transformNames.at(index) + " tool"); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); button->setCheckable(true); auto *action = new QAction(transformNames.at(index), button); + action->setIcon( + styling::icon(transformIcons.at(index), transformColors.at(index))); + action->setToolTip(transformNames.at(index) + " tool"); action->setCheckable(true); action->setData(index); button->setDefaultAction(action); @@ -104,45 +96,59 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, tools->addSpacing(10); spaceButton = new QToolButton(toolbar); spaceButton->setObjectName("viewportOptionButton"); - spaceButton->setText("World"); - spaceButton->setIcon(styling::icon(styling::Icon::Globe, "#55C2FF")); - spaceButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - spaceButton->setToolTip("Transform space (Shift+T)"); + spaceButton->setIcon(styling::icon(styling::Icon::Globe, "#4CB7D8")); + spaceButton->setToolTip("World transform space · Shift+T"); tools->addWidget(spaceButton); - tools->addSpacing(10); - auto *shading = new QComboBox(toolbar); - shading->setObjectName("viewportShadingMode"); - shading->addItems({"Lit", "Wireframe", "Points"}); - shading->setToolTip("Viewport shading"); - auto *shadingIcon = new QLabel(toolbar); - shadingIcon->setObjectName("viewportShadingIcon"); - shadingIcon->setPixmap( - styling::icon(styling::Icon::Sphere, "#F472B6").pixmap(17, 17)); - shadingIcon->setToolTip("Viewport shading"); - tools->addWidget(shadingIcon); - tools->addWidget(shading); + tools->addStretch(); + tools->addWidget(playButton); + tools->addWidget(pauseButton); + tools->addWidget(stepButton); + tools->addWidget(stopButton); + tools->addWidget(reloadButton); + tools->addStretch(); + + auto *shadingGroup = new QActionGroup(toolbar); + shadingGroup->setExclusive(true); + const QStringList shadingNames{"Lit", "Wireframe", "Points"}; + const QList shadingIcons{ + styling::Icon::Sphere, styling::Icon::CubeTransparent, + styling::Icon::DotsNine}; + for (int index = 0; index < shadingNames.size(); ++index) { + auto *button = new QToolButton(toolbar); + button->setObjectName("viewportShadingButton"); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); + button->setCheckable(true); + auto *action = new QAction(shadingNames.at(index), button); + action->setIcon( + styling::icon(shadingIcons.at(index), "#9AA6B8")); + action->setToolTip(shadingNames.at(index) + " shading"); + action->setCheckable(true); + action->setData(index); + button->setDefaultAction(action); + shadingGroup->addAction(action); + tools->addWidget(button); + if (index == 0) + action->setChecked(true); + } auto *fpsButton = new QToolButton(toolbar); fpsButton->setObjectName("viewportOptionButton"); fpsButton->setIcon( - styling::icon(styling::Icon::Monitor, "#52D273")); - fpsButton->setText("FPS"); - fpsButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + styling::icon(styling::Icon::Monitor, "#5EBB78")); fpsButton->setCheckable(true); fpsButton->setChecked(true); - fpsButton->setToolTip("Show frame rate"); + fpsButton->setToolTip("Toggle frame rate"); fpsLabel = new QLabel("-- FPS", toolbar); fpsLabel->setObjectName("viewportFpsLabel"); fpsLabel->setMinimumWidth(62); tools->addWidget(fpsButton); tools->addWidget(fpsLabel); - tools->addStretch(); layout->addWidget(toolbar); layout->addWidget(viewport, 1); shortcutHint = new QLabel( - "Tab Frame · Right-Drag Pan · Middle-Drag Orbit · G Move · R Rotate · S Scale", + "Tab Frame · Right-Drag Orbit · Shift + Right-Drag Pan · G Move · R Rotate · S Scale", this); shortcutHint->setObjectName("viewportShortcutHint"); shortcutHint->setTextInteractionFlags(Qt::NoTextInteraction); @@ -162,16 +168,20 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, [viewport](QAction *action) { viewport->setRuntimeControlMode(action->data().toInt()); }); - connect(shading, &QComboBox::currentIndexChanged, viewport, - &ViewportPanel::setRuntimeShadingMode); + connect(shadingGroup, &QActionGroup::triggered, this, + [viewport](QAction *action) { + viewport->setRuntimeShadingMode(action->data().toInt()); + }); connect(spaceButton, &QToolButton::clicked, viewport, &ViewportPanel::toggleTransformSpace); connect(viewport, &ViewportPanel::transformSpaceChanged, this, [this](bool local) { - spaceButton->setText(local ? "Local" : "World"); spaceButton->setIcon(styling::icon( local ? styling::Icon::Cube : styling::Icon::Globe, - local ? QColor("#A78BFA") : QColor("#55C2FF"))); + local ? QColor("#4C8DFF") : QColor("#4CB7D8"))); + spaceButton->setToolTip( + local ? "Local transform space · Shift+T" + : "World transform space · Shift+T"); }); connect(fpsButton, &QToolButton::toggled, fpsLabel, &QWidget::setVisible); connect(viewport, &ViewportPanel::frameRateChanged, this, diff --git a/editor/views/general/contentBrowser.cpp b/editor/views/general/contentBrowser.cpp index ec3ad44c..e2aaba9b 100644 --- a/editor/views/general/contentBrowser.cpp +++ b/editor/views/general/contentBrowser.cpp @@ -99,27 +99,27 @@ class AtlasFileIconProvider : public QFileIconProvider { public: QIcon icon(const QFileInfo &info) const override { if (info.isDir()) - return styling::icon(styling::Icon::Folder, "#55C2FF"); + return styling::icon(styling::Icon::Folder, "#4CB7D8"); const QString suffix = info.suffix().toLower(); if (suffix == "ascene") - return styling::icon(styling::Icon::CubeFocus, "#A78BFA"); + return styling::icon(styling::Icon::CubeFocus, "#6BA3FF"); if (suffix == "amat" || suffix == "material") - return styling::icon(styling::Icon::Material, "#F472B6"); + return styling::icon(styling::Icon::Material, "#D9825B"); if (suffix == "ts" || suffix == "js" || suffix == "cpp" || suffix == "h" || suffix == "json") - return styling::icon(styling::Icon::FileCode, "#55C2FF"); + return styling::icon(styling::Icon::FileCode, "#4CB7D8"); if (suffix == "png" || suffix == "jpg" || suffix == "jpeg" || suffix == "hdr") - return styling::icon(styling::Icon::Image, "#F5B942"); + return styling::icon(styling::Icon::Image, "#D9A441"); if (suffix == "wav" || suffix == "mp3" || suffix == "ogg" || suffix == "flac") - return styling::icon(styling::Icon::MusicNote, "#52D273"); + return styling::icon(styling::Icon::MusicNote, "#5EBB78"); return styling::icon(styling::Icon::File, "#8490A4"); } QIcon icon(IconType type) const override { if (type == Folder || type == Drive) - return styling::icon(styling::Icon::Folder, "#55C2FF"); + return styling::icon(styling::Icon::Folder, "#4CB7D8"); return styling::icon(styling::Icon::File, "#8490A4"); } }; @@ -174,7 +174,7 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, createButton = new QToolButton(toolbar); createButton->setObjectName("panelAddButton"); - createButton->setIcon(styling::icon(styling::Icon::Plus, "#A78BFA")); + createButton->setIcon(styling::icon(styling::Icon::Plus, "#6BA3FF")); createButton->setText("Create"); createButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); createButton->setPopupMode(QToolButton::InstantPopup); @@ -182,7 +182,7 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, revealButton = new QToolButton(toolbar); revealButton->setObjectName("browserRevealButton"); revealButton->setIcon( - styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); revealButton->setToolTip("Reveal in Finder"); moreButton = new QToolButton(toolbar); @@ -231,34 +231,34 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, layout->addWidget(gridView, 1); auto *createMenu = new QMenu(createButton); - createMenu->addAction(styling::icon(styling::Icon::Folder, "#55C2FF"), "Folder", + createMenu->addAction(styling::icon(styling::Icon::Folder, "#4CB7D8"), "Folder", this, &ContentBrowserPanel::createFolder); createMenu->addSeparator(); - createMenu->addAction(styling::icon(styling::Icon::CubeFocus, "#A78BFA"), "Scene", + createMenu->addAction(styling::icon(styling::Icon::CubeFocus, "#6BA3FF"), "Scene", this, &ContentBrowserPanel::createScene); - createMenu->addAction(styling::icon(styling::Icon::Material, "#F472B6"), + createMenu->addAction(styling::icon(styling::Icon::Material, "#D9825B"), "Material", this, &ContentBrowserPanel::createMaterial); - createMenu->addAction(styling::icon(styling::Icon::FileCode, "#55C2FF"), + createMenu->addAction(styling::icon(styling::Icon::FileCode, "#4CB7D8"), "TypeScript Script", this, &ContentBrowserPanel::createScript); createButton->setMenu(createMenu); auto *moreMenu = new QMenu(moreButton); moreMenu->addAction( - styling::icon(styling::Icon::FolderOpen, "#55C2FF"), "Open", this, [this] { + styling::icon(styling::Icon::FolderOpen, "#4CB7D8"), "Open", this, [this] { if (gridView->currentIndex().isValid()) { openIndex(gridView->currentIndex()); } }); - moreMenu->addAction(styling::icon(styling::Icon::File, "#A78BFA"), + moreMenu->addAction(styling::icon(styling::Icon::File, "#6BA3FF"), "Rename", this, &ContentBrowserPanel::renameSelection); - moreMenu->addAction(styling::icon(styling::Icon::Trash, "#FF6B7A"), + moreMenu->addAction(styling::icon(styling::Icon::Trash, "#D86470"), "Delete", this, &ContentBrowserPanel::deleteSelection); moreMenu->addSeparator(); - moreMenu->addAction(styling::icon(styling::Icon::FolderOpen, "#55C2FF"), + moreMenu->addAction(styling::icon(styling::Icon::FolderOpen, "#4CB7D8"), "Reveal in Finder", this, &ContentBrowserPanel::revealSelection); moreMenu->addAction(styling::icon(styling::Icon::FileCode, "#8490A4"), diff --git a/editor/views/general/projectBrowser.cpp b/editor/views/general/projectBrowser.cpp index 32b68d31..ca05b82a 100644 --- a/editor/views/general/projectBrowser.cpp +++ b/editor/views/general/projectBrowser.cpp @@ -126,15 +126,15 @@ class CreateProjectDialog : public QDialog { templateGroup->setExclusive(true); auto* pbr = new TemplateCard( "PBR", "Deferred physically based rendering for most 3D projects.", - styling::Icon::Cube, "#A78BFA", this); + styling::Icon::Cube, "#6BA3FF", this); auto* ddgi = new TemplateCard( "PBR + DDGI", "PBR with dynamic diffuse global illumination enabled.", - styling::Icon::Sun, "#F5B942", this); + styling::Icon::Sun, "#D9A441", this); auto* pathTracing = new TemplateCard( "Path Tracing", "Progressive ray-traced lighting for high-fidelity scenes.", - styling::Icon::Aperture, "#F472B6", this); + styling::Icon::Aperture, "#D9825B", this); templateGroup->addButton(pbr->button(), static_cast(AtlasProjectTemplate::Pbr)); templateGroup->addButton( @@ -173,7 +173,7 @@ class CreateProjectDialog : public QDialog { auto* browse = new QPushButton("Browse…", this); browse->setProperty("secondary", true); browse->setIcon( - styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); locationLayout->addWidget(browse); fields->addLayout(locationLayout); root->addLayout(fields); @@ -259,7 +259,7 @@ class ProjectRow : public QFrame { auto* projectIcon = new QLabel(this); projectIcon->setObjectName("projectIcon"); projectIcon->setPixmap( - styling::icon(styling::Icon::GameController, "#A78BFA") + styling::icon(styling::Icon::GameController, "#6BA3FF") .pixmap(30, 30)); projectIcon->setFixedSize(36, 36); projectIcon->setAlignment(Qt::AlignCenter); @@ -354,7 +354,7 @@ void ProjectBrowser::setupUi() { auto* projectsNav = new QPushButton("Projects", sidebar); projectsNav->setObjectName("projectNavSelected"); projectsNav->setIcon( - styling::icon(styling::Icon::SquaresFour, "#A78BFA")); + styling::icon(styling::Icon::SquaresFour, "#6BA3FF")); projectsNav->setEnabled(false); sidebarLayout->addWidget(projectsNav); sidebarLayout->addStretch(); @@ -382,7 +382,7 @@ void ProjectBrowser::setupUi() { auto* openButton = new QPushButton("Open existing", content); openButton->setProperty("secondary", true); openButton->setIcon( - styling::icon(styling::Icon::FolderOpen, "#55C2FF")); + styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); headingLayout->addWidget(openButton); auto* createButton = new QPushButton("New project", content); createButton->setObjectName("primaryAction"); @@ -540,16 +540,16 @@ void ProjectBrowser::showProjectMenu(const QPoint& position) { QMenu menu(this); QAction* open = menu.addAction( - styling::icon(styling::Icon::GameController, "#A78BFA"), + styling::icon(styling::Icon::GameController, "#6BA3FF"), "Open project"); open->setEnabled(available); QAction* reveal = menu.addAction( - styling::icon(styling::Icon::FolderOpen, "#55C2FF"), + styling::icon(styling::Icon::FolderOpen, "#4CB7D8"), "Show in Finder"); reveal->setEnabled(QFileInfo::exists(QFileInfo(projectFile).absolutePath())); menu.addSeparator(); QAction* remove = menu.addAction( - styling::icon(styling::Icon::Trash, "#FF6B7A"), + styling::icon(styling::Icon::Trash, "#D86470"), "Remove from list"); QAction* selected = menu.exec(projectList->viewport()->mapToGlobal(position)); if (selected == open) { diff --git a/editor/views/general/splashScreen.cpp b/editor/views/general/splashScreen.cpp index 36bc8cbf..19fa1f16 100644 --- a/editor/views/general/splashScreen.cpp +++ b/editor/views/general/splashScreen.cpp @@ -124,7 +124,7 @@ SplashScreen::SplashScreen(QWidget *parent) } #splashVersion { background: transparent; - color: #A78BFA; + color: #6BA3FF; font-size: 14px; font-weight: 700; } @@ -147,7 +147,7 @@ SplashScreen::SplashScreen(QWidget *parent) border-radius: 2px; } #splashProgress::chunk { - background: #7C5CFC; + background: #4C8DFF; border-radius: 2px; } #splashWarning { diff --git a/include/editor/core/themes.h b/include/editor/core/themes.h index 1e614f2b..fad8eff3 100644 --- a/include/editor/core/themes.h +++ b/include/editor/core/themes.h @@ -3,109 +3,97 @@ // This file is generated. Do not edit manually. // Generated from .qss theme files. -// Source: /Users/maxvdec/Coding/Projects/Atlas/editor/styling/dark.qss +// Source: editor/styling/dark.qss inline constexpr const char* DARK_THEME = "* {\n" -" font-family: \"Helvetica Neue\", \"Segoe UI\", Arial, sans-serif;\n" +" font-family: \"Manrope\";\n" " font-size: 12px;\n" -" color: #DCE2E5;\n" -" selection-background-color: #3D8BFF;\n" +" color: #E7ECF3;\n" +" selection-background-color: #3F78D8;\n" " selection-color: #FFFFFF;\n" "}\n" "\n" "QWidget {\n" -" background-color: #222526;\n" -" color: #DCE2E5;\n" +" background-color: #0D1117;\n" +" color: #E7ECF3;\n" "}\n" "\n" "QMainWindow,\n" "QDialog,\n" "QFrame {\n" -" background-color: #222526;\n" -"}\n" -"\n" -"QToolTip {\n" -" background-color: #151819;\n" -" color: #F4F7F8;\n" -" border: 1px solid #3C4245;\n" -" border-radius: 3px;\n" -" padding: 4px 6px;\n" +" background-color: #0D1117;\n" "}\n" "\n" "QLabel {\n" -" background-color: transparent;\n" -" color: #DCE2E5;\n" +" background: transparent;\n" "}\n" "\n" "QLabel:disabled {\n" -" color: #727B80;\n" +" color: #566174;\n" "}\n" "\n" -"QGroupBox {\n" -" background-color: #222526;\n" -" border: 1px solid #3A4144;\n" +"QToolTip {\n" +" background-color: #202838;\n" +" color: #F7F9FC;\n" +" border: 1px solid #3A465A;\n" " border-radius: 3px;\n" -" margin-top: 15px;\n" +" padding: 4px 6px;\n" +"}\n" +"\n" +"QGroupBox {\n" +" background-color: #141A23;\n" +" border: 1px solid #252E3C;\n" +" border-radius: 4px;\n" +" margin-top: 14px;\n" " padding: 8px;\n" -" color: #E7ECEF;\n" -" font-weight: 600;\n" +" color: #F1F4F8;\n" +" font-weight: 650;\n" "}\n" "\n" "QGroupBox::title {\n" " subcontrol-origin: margin;\n" " subcontrol-position: top left;\n" -" left: 7px;\n" -" padding: 0 4px;\n" -" color: #AEB8BE;\n" -" background-color: #222526;\n" -"}\n" -"\n" -"QGroupBox > QWidget {\n" -" background-color: #222526;\n" +" left: 9px;\n" +" padding: 0 6px;\n" +" color: #AEB8C8;\n" +" background-color: #141A23;\n" "}\n" "\n" "QScrollArea,\n" "QAbstractScrollArea {\n" -" background-color: #222526;\n" -" border: 1px solid #343A3D;\n" -" border-radius: 3px;\n" +" background-color: #10151C;\n" +" border: none;\n" "}\n" "\n" "QAbstractScrollArea::corner {\n" -" background-color: #222526;\n" +" background-color: #10151C;\n" "}\n" "\n" "QScrollBar:vertical {\n" -" background-color: #1E2122;\n" -" width: 10px;\n" -" margin: 0;\n" +" background-color: transparent;\n" +" width: 9px;\n" +" margin: 2px;\n" " border: none;\n" "}\n" "\n" "QScrollBar:horizontal {\n" -" background-color: #1E2122;\n" -" height: 10px;\n" -" margin: 0;\n" +" background-color: transparent;\n" +" height: 9px;\n" +" margin: 2px;\n" " border: none;\n" "}\n" "\n" "QScrollBar::handle:vertical,\n" "QScrollBar::handle:horizontal {\n" -" background-color: #444C50;\n" -" border: 2px solid #1E2122;\n" -" border-radius: 4px;\n" -" min-height: 28px;\n" -" min-width: 28px;\n" +" background-color: #364154;\n" +" border-radius: 3px;\n" +" min-height: 30px;\n" +" min-width: 30px;\n" "}\n" "\n" "QScrollBar::handle:vertical:hover,\n" "QScrollBar::handle:horizontal:hover {\n" -" background-color: #5A6469;\n" -"}\n" -"\n" -"QScrollBar::handle:vertical:pressed,\n" -"QScrollBar::handle:horizontal:pressed {\n" -" background-color: #6A757B;\n" +" background-color: #536078;\n" "}\n" "\n" "QScrollBar::add-line,\n" @@ -120,194 +108,59 @@ inline constexpr const char* DARK_THEME = "\n" "QPushButton,\n" "QToolButton {\n" -" background-color: #303538;\n" -" border: 1px solid #444B4F;\n" +" background-color: #1A2230;\n" +" border: 1px solid #2D3849;\n" " border-radius: 3px;\n" " padding: 3px 7px;\n" -" color: #EEF3F5;\n" +" color: #E9EDF4;\n" " min-height: 18px;\n" +" font-weight: 550;\n" "}\n" "\n" "QPushButton:hover,\n" "QToolButton:hover {\n" -" background-color: #394045;\n" -" border-color: #59656C;\n" +" background-color: #222C3C;\n" +" border-color: #46536A;\n" "}\n" "\n" "QPushButton:pressed,\n" "QToolButton:pressed {\n" -" background-color: #24282A;\n" -" border-color: #3D8BFF;\n" +" background-color: #121923;\n" +" border-color: #4C8DFF;\n" "}\n" "\n" "QPushButton:checked,\n" "QToolButton:checked {\n" -" background-color: #22496D;\n" -" border-color: #5FB3FF;\n" +" background-color: #182C4A;\n" +" border-color: #4C8DFF;\n" " color: #FFFFFF;\n" "}\n" "\n" -"QPushButton:default {\n" -" background-color: #346FA8;\n" -" border-color: #68BFFF;\n" +"QPushButton:default,\n" +"#primaryAction {\n" +" background-color: #3F78D8;\n" +" border-color: #6BA3FF;\n" " color: #FFFFFF;\n" +" font-weight: 650;\n" +"}\n" +"\n" +"QPushButton:default:hover,\n" +"#primaryAction:hover {\n" +" background-color: #4C8DFF;\n" +" border-color: #78A9F2;\n" "}\n" "\n" "QPushButton:disabled,\n" "QToolButton:disabled {\n" -" background-color: #292D2F;\n" -" border-color: #33393C;\n" -" color: #6F787D;\n" +" background-color: #121820;\n" +" border-color: #1D2531;\n" +" color: #566174;\n" "}\n" "\n" "QToolButton::menu-indicator {\n" " image: none;\n" "}\n" "\n" -"#viewportToolbar {\n" -" background-color: #1B1E20;\n" -" border-bottom: 1px solid #353B3E;\n" -"}\n" -"\n" -"#viewportPlaybackButton,\n" -"#viewportModeButton,\n" -"#viewportOptionButton {\n" -" min-width: 22px;\n" -" min-height: 20px;\n" -" padding: 2px 4px;\n" -"}\n" -"\n" -"#viewportPlaybackButton {\n" -" border-radius: 3px;\n" -"}\n" -"\n" -"#viewportShadingMode {\n" -" min-width: 92px;\n" -" padding-top: 2px;\n" -" padding-bottom: 2px;\n" -"}\n" -"\n" -"#viewportFpsLabel {\n" -" color: #9DA8AE;\n" -"}\n" -"\n" -"#viewportShortcutHint {\n" -" background-color: #181B1D;\n" -" border-top: 1px solid #303639;\n" -" color: #8F9AA0;\n" -" font-size: 10px;\n" -" padding: 4px 8px;\n" -"}\n" -"\n" -"#sceneTabs {\n" -" background-color: #171A1C;\n" -" border-bottom: 1px solid #343A3E;\n" -"}\n" -"\n" -"#sceneTabs::tab {\n" -" background-color: #202427;\n" -" border-right: 1px solid #343A3E;\n" -" color: #98A3A9;\n" -" min-width: 120px;\n" -" padding: 5px 10px;\n" -"}\n" -"\n" -"#sceneTabs::tab:selected {\n" -" background-color: #2B3134;\n" -" color: #EDF2F4;\n" -" border-bottom: 2px solid #4EA4E8;\n" -"}\n" -"\n" -"#sceneTabs::close-button {\n" -" subcontrol-position: right;\n" -"}\n" -"\n" -"#materialEditorHeader {\n" -" background-color: #1B1E20;\n" -" border-bottom: 1px solid #363C3F;\n" -"}\n" -"\n" -"#materialEditorTitle {\n" -" color: #F3F6F7;\n" -" font-size: 14px;\n" -" font-weight: 650;\n" -"}\n" -"\n" -"#materialEditorStatus {\n" -" color: #89959B;\n" -"}\n" -"\n" -"#materialEditorScroll,\n" -"#materialEditorBody {\n" -" border: none;\n" -" background-color: #202324;\n" -"}\n" -"\n" -"#materialPreview {\n" -" background-color: #191C1D;\n" -" border: 1px solid #3A4144;\n" -" border-radius: 3px;\n" -"}\n" -"\n" -"#materialEditorEmpty {\n" -" color: #879299;\n" -" padding: 40px;\n" -"}\n" -"\n" -"#postProcessingToolbar {\n" -" background-color: #1B1E20;\n" -" border-bottom: 1px solid #363C3F;\n" -"}\n" -"\n" -"#postProcessingTitle,\n" -"#postProcessingSectionTitle,\n" -"#inspectorCameraTitle {\n" -" color: #F3F6F7;\n" -" font-size: 14px;\n" -" font-weight: 650;\n" -"}\n" -"\n" -"#postProcessingStatus {\n" -" color: #89959B;\n" -"}\n" -"\n" -"#postProcessingScroll,\n" -"#postProcessingBody {\n" -" border: none;\n" -" background-color: #202324;\n" -"}\n" -"\n" -"#postProcessingEmpty {\n" -" color: #879299;\n" -" padding: 40px;\n" -"}\n" -"\n" -"#materialTextureSlot {\n" -" background-color: #1B1E20;\n" -" border: 1px solid #343B3E;\n" -" border-radius: 3px;\n" -"}\n" -"\n" -"#materialTexturePreview {\n" -" background-color: #25292B;\n" -" border: 1px solid #41494D;\n" -" border-radius: 3px;\n" -" color: #EF8C7B;\n" -" font-weight: 700;\n" -" qproperty-alignment: AlignCenter;\n" -"}\n" -"\n" -"#materialTextureLabel {\n" -" color: #CDD4D8;\n" -" font-weight: 600;\n" -"}\n" -"\n" -"#materialTexturePath {\n" -" color: #8F9AA0;\n" -" padding-top: 3px;\n" -" padding-bottom: 3px;\n" -"}\n" -"\n" "QLineEdit,\n" "QTextEdit,\n" "QPlainTextEdit,\n" @@ -317,16 +170,11 @@ inline constexpr const char* DARK_THEME = "QDateEdit,\n" "QTimeEdit,\n" "QDateTimeEdit {\n" -" background-color: #1A1D1E;\n" -" border: 1px solid #363D41;\n" +" background-color: #0F141B;\n" +" border: 1px solid #273141;\n" " border-radius: 3px;\n" -" padding: 3px 6px;\n" -" color: #EDF2F4;\n" -"}\n" -"\n" -"QTextEdit,\n" -"QPlainTextEdit {\n" -" selection-background-color: #315D90;\n" +" padding: 4px 6px;\n" +" color: #EEF2F7;\n" "}\n" "\n" "QLineEdit:hover,\n" @@ -334,11 +182,8 @@ inline constexpr const char* DARK_THEME = "QPlainTextEdit:hover,\n" "QComboBox:hover,\n" "QSpinBox:hover,\n" -"QDoubleSpinBox:hover,\n" -"QDateEdit:hover,\n" -"QTimeEdit:hover,\n" -"QDateTimeEdit:hover {\n" -" border-color: #4A555B;\n" +"QDoubleSpinBox:hover {\n" +" border-color: #3D4A60;\n" "}\n" "\n" "QLineEdit:focus,\n" @@ -346,1392 +191,1163 @@ inline constexpr const char* DARK_THEME = "QPlainTextEdit:focus,\n" "QComboBox:focus,\n" "QSpinBox:focus,\n" -"QDoubleSpinBox:focus,\n" -"QDateEdit:focus,\n" -"QTimeEdit:focus,\n" -"QDateTimeEdit:focus {\n" -" border-color: #5FB3FF;\n" -" background-color: #171A1B;\n" +"QDoubleSpinBox:focus {\n" +" background-color: #111824;\n" +" border-color: #4C8DFF;\n" "}\n" "\n" "QLineEdit:disabled,\n" "QTextEdit:disabled,\n" -"QPlainTextEdit:disabled,\n" "QComboBox:disabled,\n" "QSpinBox:disabled,\n" -"QDoubleSpinBox:disabled,\n" -"QDateEdit:disabled,\n" -"QTimeEdit:disabled,\n" -"QDateTimeEdit:disabled {\n" -" background-color: #25292B;\n" -" border-color: #303638;\n" -" color: #727B80;\n" +"QDoubleSpinBox:disabled {\n" +" background-color: #11161D;\n" +" border-color: #1D2530;\n" +" color: #566174;\n" "}\n" "\n" "QComboBox {\n" -" padding-right: 23px;\n" +" padding-right: 24px;\n" "}\n" "\n" "QComboBox::drop-down {\n" " subcontrol-origin: padding;\n" " subcontrol-position: top right;\n" " width: 22px;\n" -" border-left: 1px solid #343B3F;\n" -" border-top-right-radius: 3px;\n" -" border-bottom-right-radius: 3px;\n" -" background-color: #252A2C;\n" -"}\n" -"\n" -"QComboBox::down-arrow {\n" -" image: none;\n" -" width: 0;\n" -" height: 0;\n" -" border-left: 4px solid transparent;\n" -" border-right: 4px solid transparent;\n" -" border-top: 5px solid #AEB8BE;\n" +" border-left: 1px solid #273141;\n" "}\n" "\n" "QComboBox QAbstractItemView {\n" -" background-color: #1C2021;\n" -" border: 1px solid #444D52;\n" -" border-radius: 3px;\n" +" background-color: #171E29;\n" +" border: 1px solid #344156;\n" +" border-radius: 4px;\n" " padding: 3px;\n" -" color: #E8EEF1;\n" -" selection-background-color: #315D90;\n" +" selection-background-color: #182C4A;\n" "}\n" "\n" "QAbstractSpinBox::up-button,\n" "QAbstractSpinBox::down-button {\n" -" background-color: #252A2C;\n" -" border-left: 1px solid #343B3F;\n" +" background-color: #171F2B;\n" +" border: none;\n" " width: 16px;\n" "}\n" "\n" "QAbstractSpinBox::up-button:hover,\n" "QAbstractSpinBox::down-button:hover {\n" -" background-color: #333A3E;\n" -"}\n" -"\n" -"QAbstractSpinBox::up-arrow {\n" -" image: none;\n" -" width: 0;\n" -" height: 0;\n" -" border-left: 4px solid transparent;\n" -" border-right: 4px solid transparent;\n" -" border-bottom: 5px solid #AEB8BE;\n" -"}\n" -"\n" -"QAbstractSpinBox::down-arrow {\n" -" image: none;\n" -" width: 0;\n" -" height: 0;\n" -" border-left: 4px solid transparent;\n" -" border-right: 4px solid transparent;\n" -" border-top: 5px solid #AEB8BE;\n" +" background-color: #263144;\n" "}\n" "\n" "QCheckBox,\n" "QRadioButton {\n" -" spacing: 6px;\n" -" background-color: transparent;\n" -" color: #DCE2E5;\n" +" spacing: 7px;\n" +" color: #C9D1DE;\n" "}\n" "\n" "QCheckBox::indicator,\n" "QRadioButton::indicator {\n" -" width: 13px;\n" -" height: 13px;\n" -" background-color: #171A1B;\n" -" border: 1px solid #515B61;\n" -"}\n" -"\n" -"QCheckBox::indicator {\n" -" border-radius: 2px;\n" -"}\n" -"\n" -"QRadioButton::indicator {\n" -" border-radius: 7px;\n" -"}\n" -"\n" -"QCheckBox::indicator:hover,\n" -"QRadioButton::indicator:hover {\n" -" border-color: #6FBFFF;\n" -" background-color: #1D252B;\n" -"}\n" -"\n" -"QCheckBox::indicator:checked {\n" -" background-color: #3D8BFF;\n" -" border-color: #72C7FF;\n" -" border-radius: 2px;\n" -"}\n" -"\n" -"QRadioButton::indicator:checked {\n" -" background-color: #3D8BFF;\n" -" border: 4px solid #171A1B;\n" -"}\n" -"\n" -"QCheckBox::indicator:disabled,\n" -"QRadioButton::indicator:disabled {\n" -" background-color: #2A2F31;\n" -" border-color: #3A4145;\n" +" width: 15px;\n" +" height: 15px;\n" "}\n" "\n" "QSlider::groove:horizontal {\n" +" background-color: #202A38;\n" " height: 4px;\n" -" background-color: #171A1B;\n" -" border-radius: 2px;\n" -"}\n" -"\n" -"QSlider::groove:vertical {\n" -" width: 4px;\n" -" background-color: #171A1B;\n" -" border-radius: 2px;\n" -"}\n" -"\n" -"QSlider::sub-page:horizontal,\n" -"QSlider::add-page:vertical {\n" -" background-color: #3D8BFF;\n" " border-radius: 2px;\n" "}\n" "\n" "QSlider::handle:horizontal {\n" -" width: 16px;\n" -" height: 16px;\n" -" margin: -6px 0;\n" -" background-color: #DCE2E5;\n" -" border: 1px solid #FFFFFF;\n" -" border-radius: 8px;\n" -"}\n" -"\n" -"QSlider::handle:vertical {\n" -" width: 16px;\n" -" height: 16px;\n" -" margin: 0 -6px;\n" -" background-color: #DCE2E5;\n" -" border: 1px solid #FFFFFF;\n" -" border-radius: 8px;\n" -"}\n" -"\n" -"QSlider::handle:horizontal:hover,\n" -"QSlider::handle:vertical:hover {\n" -" background-color: #FFFFFF;\n" -" border-color: #72C7FF;\n" +" background-color: #4C8DFF;\n" +" border: 2px solid #A9C8F5;\n" +" width: 12px;\n" +" margin: -5px 0;\n" +" border-radius: 7px;\n" "}\n" "\n" "QProgressBar {\n" -" background-color: #171A1B;\n" -" border: 1px solid #343B3F;\n" -" border-radius: 5px;\n" +" background-color: #151C26;\n" +" border: 1px solid #293446;\n" +" border-radius: 3px;\n" +" height: 8px;\n" " text-align: center;\n" -" color: #DCE2E5;\n" -" min-height: 8px;\n" "}\n" "\n" "QProgressBar::chunk {\n" -" background-color: #3D8BFF;\n" -" border-radius: 4px;\n" +" background-color: #4C8DFF;\n" +" border-radius: 3px;\n" "}\n" "\n" +"QTreeView,\n" "QListView,\n" "QListWidget,\n" -"QTreeView,\n" -"QTreeWidget,\n" "QTableView,\n" "QTableWidget {\n" -" background-color: #1C2021;\n" -" alternate-background-color: #202526;\n" -" border: 1px solid #343B3F;\n" -" border-radius: 3px;\n" -" padding: 2px;\n" -" color: #DCE2E5;\n" -" gridline-color: #303638;\n" +" background-color: #10151C;\n" +" alternate-background-color: #121923;\n" +" border: none;\n" +" color: #DCE3EC;\n" +" show-decoration-selected: 1;\n" "}\n" "\n" +"QTreeView::item,\n" "QListView::item,\n" "QListWidget::item,\n" -"QTreeView::item,\n" -"QTreeWidget::item,\n" "QTableView::item,\n" "QTableWidget::item {\n" -" min-height: 20px;\n" -" padding: 2px 6px;\n" +" border: 1px solid transparent;\n" " border-radius: 3px;\n" +" padding: 3px 5px;\n" "}\n" "\n" +"QTreeView::item:hover,\n" "QListView::item:hover,\n" "QListWidget::item:hover,\n" -"QTreeView::item:hover,\n" -"QTreeWidget::item:hover,\n" "QTableView::item:hover,\n" "QTableWidget::item:hover {\n" -" background-color: #2D363B;\n" +" background-color: #1A2230;\n" +" border-color: #293548;\n" "}\n" "\n" +"QTreeView::item:selected,\n" "QListView::item:selected,\n" "QListWidget::item:selected,\n" -"QTreeView::item:selected,\n" -"QTreeWidget::item:selected,\n" "QTableView::item:selected,\n" "QTableWidget::item:selected {\n" -" background-color: #315D90;\n" +" background-color: #172A46;\n" +" border-color: #3F78D8;\n" " color: #FFFFFF;\n" "}\n" "\n" -"#panelToolbar {\n" -" background-color: #222526;\n" -" border: none;\n" +"QHeaderView {\n" +" background-color: #111720;\n" "}\n" "\n" -"#panelAddButton {\n" -" background-color: #2C3235;\n" -" border-color: #414A4F;\n" -" padding: 2px 7px;\n" -" min-height: 19px;\n" +"QHeaderView::section {\n" +" background-color: #171E29;\n" +" border: none;\n" +" border-right: 1px solid #283243;\n" +" border-bottom: 1px solid #283243;\n" +" padding: 5px 7px;\n" +" color: #98A4B7;\n" " font-weight: 600;\n" "}\n" "\n" -"#panelMoreButton,\n" -"#browserRevealButton,\n" -"#browserNavigationButton {\n" -" background-color: transparent;\n" -" border-color: transparent;\n" -" padding: 2px;\n" -" min-width: 20px;\n" -" min-height: 19px;\n" +"QTabWidget::pane {\n" +" background-color: #10151C;\n" +" border: 1px solid #273141;\n" +" border-radius: 0 0 3px 3px;\n" "}\n" "\n" -"#panelMoreButton:hover,\n" -"#browserRevealButton:hover,\n" -"#browserNavigationButton:hover {\n" -" background-color: #30373A;\n" -" border-color: #424B50;\n" +"QTabBar::tab {\n" +" background-color: #111720;\n" +" border: none;\n" +" border-right: 1px solid #232C3A;\n" +" border-bottom: 1px solid #273141;\n" +" color: #7F8B9D;\n" +" min-width: 88px;\n" +" padding: 5px 9px;\n" "}\n" "\n" -"#contentPathField {\n" -" background-color: #191D1F;\n" -" border-color: #30373B;\n" -" color: #AEB8BE;\n" -" padding: 2px 6px;\n" -" min-height: 19px;\n" +"QTabBar::tab:hover {\n" +" background-color: #18202B;\n" +" color: #C8D1DF;\n" "}\n" "\n" -"#contentSearchField {\n" +"QTabBar::tab:selected {\n" +" background-color: #151C26;\n" +" color: #F2F5F9;\n" +" border-bottom: 2px solid #4C8DFF;\n" +"}\n" +"\n" +"QMenuBar#atlasMenuBar {\n" +" background-color: #090D12;\n" +" border-bottom: 1px solid #202836;\n" " padding: 2px 6px;\n" -" min-height: 19px;\n" "}\n" "\n" -"QTreeView#hierarchyTree {\n" -" background-color: #1B1F20;\n" -" border: none;\n" +"QMenuBar#atlasMenuBar::item {\n" +" background: transparent;\n" +" color: #B8C2D0;\n" +" padding: 5px 9px;\n" +" border-radius: 3px;\n" +"}\n" +"\n" +"QMenuBar#atlasMenuBar::item:selected,\n" +"QMenuBar#atlasMenuBar::item:pressed {\n" +" background-color: #202838;\n" +" color: #FFFFFF;\n" +"}\n" +"\n" +"QMenu {\n" +" background-color: #171E29;\n" +" border: 1px solid #344156;\n" " border-radius: 4px;\n" " padding: 3px;\n" -" show-decoration-selected: 1;\n" "}\n" "\n" -"QTreeView#hierarchyTree::item {\n" -" min-height: 20px;\n" -" padding: 2px 5px;\n" +"QMenu::item {\n" +" background: transparent;\n" +" border-radius: 3px;\n" +" padding: 5px 30px 5px 8px;\n" +" color: #DCE3EC;\n" "}\n" "\n" -"QListView#contentGrid {\n" -" background-color: #1B1F20;\n" -" border: none;\n" -" border-radius: 4px;\n" -" padding: 8px;\n" +"QMenu::item:selected {\n" +" background-color: #172A46;\n" +" color: #FFFFFF;\n" "}\n" "\n" -"QListView#contentGrid::item {\n" -" min-height: 88px;\n" -" padding: 6px;\n" -" margin: 2px;\n" -" border: 1px solid transparent;\n" -" border-radius: 7px;\n" +"QMenu::item:disabled {\n" +" color: #596477;\n" "}\n" "\n" -"QListView#contentGrid::item:hover {\n" -" background-color: #272E31;\n" -" border-color: #353F44;\n" +"QMenu::separator {\n" +" background-color: #2A3444;\n" +" height: 1px;\n" +" margin: 5px 8px;\n" "}\n" "\n" -"QListView#contentGrid::item:selected {\n" -" background-color: #284E73;\n" -" border-color: #579FE3;\n" -" color: #FFFFFF;\n" +"QSplitter::handle {\n" +" background-color: #080C11;\n" "}\n" "\n" -"QScrollArea#inspectorScroll {\n" -" background-color: #1B1F20;\n" -" border: none;\n" -" border-radius: 0;\n" +"QSplitter::handle:horizontal {\n" +" width: 4px;\n" "}\n" "\n" -"#inspectorContent {\n" -" background-color: #1B1F20;\n" +"QSplitter::handle:vertical {\n" +" height: 4px;\n" "}\n" "\n" -"#inspectorHeader {\n" -" background-color: #24292B;\n" -" border: 1px solid #353D41;\n" -" border-radius: 3px;\n" +"QSplitter::handle:hover {\n" +" background-color: #4C8DFF;\n" "}\n" "\n" -"#inspectorObjectIcon {\n" -" background-color: #1C2022;\n" -" border: 1px solid #3B4449;\n" -" border-radius: 3px;\n" -" padding: 2px;\n" +"QStatusBar {\n" +" background-color: #090D12;\n" +" border-top: 1px solid #202836;\n" +" color: #8490A4;\n" "}\n" "\n" -"#inspectorNameField {\n" -" background-color: transparent;\n" -" border: 1px solid transparent;\n" -" border-radius: 4px;\n" -" color: #F4F7F8;\n" -" font-size: 14px;\n" -" font-weight: 650;\n" -" padding: 2px 4px;\n" -" min-height: 20px;\n" -"}\n" -"\n" -"#inspectorNameField:hover {\n" -" background-color: #1D2123;\n" -" border-color: #3C464B;\n" -"}\n" -"\n" -"#inspectorNameField:focus {\n" -" background-color: #171A1B;\n" -" border-color: #5FB3FF;\n" -"}\n" -"\n" -"#inspectorTypeLabel {\n" -" color: #879299;\n" -" padding-left: 5px;\n" -" font-size: 11px;\n" -"}\n" -"\n" -"#inspectorComponent {\n" -" background-color: #23282A;\n" -" border: 1px solid #363E42;\n" -" border-radius: 3px;\n" -"}\n" -"\n" -"#inspectorComponentHeaderRow {\n" -" background-color: #2A3033;\n" -" border: none;\n" -" border-bottom: 1px solid #343D41;\n" -" border-radius: 3px;\n" -"}\n" -"\n" -"#inspectorComponentHeader {\n" -" background-color: transparent;\n" -" border: none;\n" -" border-radius: 3px;\n" -" padding: 4px 7px;\n" -" color: #EEF2F4;\n" -" font-weight: 650;\n" -" text-align: left;\n" -"}\n" -"\n" -"#inspectorComponentHeader:hover {\n" -" background-color: #30373A;\n" -"}\n" -"\n" -"#inspectorComponentRemoveButton {\n" -" background-color: transparent;\n" -" border-color: transparent;\n" -" min-width: 20px;\n" -" min-height: 20px;\n" -" padding: 1px;\n" -"}\n" -"\n" -"#inspectorComponentRemoveButton:hover {\n" -" background-color: #543136;\n" -" border-color: #78444C;\n" -"}\n" -"\n" -"#inspectorComponentBody {\n" -" background-color: transparent;\n" -"}\n" -"\n" -"#inspectorPropertyRow {\n" -" background-color: transparent;\n" -" border: none;\n" +"#atlasStatusBar {\n" +" min-height: 21px;\n" +" padding: 0 6px;\n" "}\n" "\n" -"#inspectorPropertyLabel {\n" -" color: #ABB5BA;\n" -" font-size: 12px;\n" -"}\n" -"\n" -"#inspectorVectorField,\n" -"#inspectorColorField,\n" -"#inspectorNumericField {\n" -" background-color: #191C1D;\n" -" border: 1px solid #363D41;\n" -" border-radius: 3px;\n" +"#statusRuntimeIcon {\n" +" padding: 0 4px;\n" "}\n" "\n" -"#inspectorAxisLabel {\n" -" color: #748088;\n" -" font-size: 10px;\n" +"#statusRenderer {\n" +" background-color: #192B22;\n" +" border: 1px solid #2C573B;\n" +" border-radius: 4px;\n" +" color: #8DE2A5;\n" +" font-size: 9px;\n" " font-weight: 700;\n" -" min-width: 10px;\n" -"}\n" -"\n" -"#inspectorVectorField QDoubleSpinBox {\n" -" background-color: transparent;\n" -" border: none;\n" -" border-radius: 0;\n" -" padding: 2px;\n" -"}\n" -"\n" -"#inspectorNumericField QDoubleSpinBox {\n" -" background-color: transparent;\n" -" border: none;\n" -"}\n" -"\n" -"#inspectorSyncButton {\n" -" background-color: transparent;\n" -" border: none;\n" -" min-width: 20px;\n" -" min-height: 20px;\n" -" padding: 1px;\n" -"}\n" -"\n" -"#inspectorSyncButton:hover {\n" -" background-color: #30373A;\n" -"}\n" -"\n" -"#inspectorSyncButton[matched=\"true\"] {\n" -" background-color: #242A2D;\n" -" border: 1px solid #465158;\n" -" color: #D5DDE1;\n" " padding: 2px 6px;\n" -" text-align: left;\n" "}\n" "\n" -"#inspectorSyncButton[matched=\"true\"]:hover {\n" -" background-color: #30383C;\n" -" border-color: #5B6A72;\n" +"#statusVersion {\n" +" color: #68758A;\n" +" font-size: 9px;\n" +" padding: 0 6px;\n" "}\n" "\n" -"#inspectorColorSwatch {\n" -" border: 1px solid #566167;\n" -" border-radius: 4px;\n" -" padding: 0;\n" -" min-height: 18px;\n" +"#workspaceBar {\n" +" background-color: #10151C;\n" +" border: none;\n" +" border-bottom: 1px solid #273141;\n" +" spacing: 3px;\n" +" padding: 2px 5px 2px 0;\n" "}\n" "\n" -"#inspectorColorText {\n" -" background-color: transparent;\n" -" border: none;\n" -" padding: 3px;\n" +"#workspaceIdentity {\n" +" background: transparent;\n" +" border-right: 1px solid #2A3444;\n" "}\n" "\n" -"#inspectorNestedGroup {\n" -" background-color: #202426;\n" -" border-top: 1px solid #30373A;\n" -" border-bottom: 1px solid #30373A;\n" +"#workspaceMark {\n" +" background: transparent;\n" "}\n" "\n" -"#inspectorNestedTitle {\n" -" color: #D1D8DC;\n" -" font-weight: 650;\n" -" padding: 2px 1px 4px 1px;\n" +"#workspaceBrand {\n" +" color: #F5F7FA;\n" +" font-size: 12px;\n" +" font-weight: 800;\n" "}\n" "\n" -"#inspectorArrayTitle {\n" -" color: #7FB9EC;\n" +"#workspaceProject {\n" +" color: #7F8B9D;\n" " font-size: 11px;\n" -" font-weight: 650;\n" -" padding: 5px 2px 1px 2px;\n" "}\n" "\n" -"#inspectorArrayButton {\n" +"#workspaceModeButton {\n" " background-color: transparent;\n" " border: 1px solid transparent;\n" -" border-radius: 4px;\n" -" color: #AEB8BE;\n" -" min-width: 20px;\n" -" min-height: 18px;\n" -" padding: 1px 4px;\n" -"}\n" -"\n" -"#inspectorArrayButton:hover {\n" -" background-color: #30373A;\n" -" border-color: #465157;\n" -" color: #FFFFFF;\n" -"}\n" -"\n" -"#inspectorEmptyTitle {\n" -" color: #DDE3E6;\n" -" font-size: 15px;\n" -" font-weight: 650;\n" -"}\n" -"\n" -"#inspectorEmptyHint {\n" -" color: #77838A;\n" -" font-size: 12px;\n" -"}\n" -"\n" -"#inspectorOpenAssetButton {\n" -" min-height: 24px;\n" -"}\n" -"\n" -"#inspectorAddComponentButton {\n" -" background-color: #2B3235;\n" -" border: 1px solid #465158;\n" " border-radius: 3px;\n" -" color: #E9EEF0;\n" -" font-weight: 600;\n" -" min-height: 20px;\n" -" padding: 3px 8px;\n" -"}\n" -"\n" -"#inspectorAddComponentButton:hover {\n" -" background-color: #343C40;\n" -" border-color: #5B6970;\n" +" color: #94A0B2;\n" +" padding: 4px 8px;\n" +" margin: 0 1px;\n" "}\n" "\n" -"#inspectorAudioControls {\n" -" background-color: #202426;\n" -" border: 1px solid #343D41;\n" -" border-top: none;\n" -" border-bottom-left-radius: 7px;\n" -" border-bottom-right-radius: 7px;\n" +"#workspaceModeButton:hover {\n" +" background-color: #1B2431;\n" +" color: #DDE4ED;\n" "}\n" "\n" -"QHeaderView {\n" -" background-color: #252A2C;\n" -" border: none;\n" +"#workspaceModeButton:checked {\n" +" background-color: #17263B;\n" +" border-color: #31577F;\n" +" color: #FFFFFF;\n" "}\n" "\n" -"QHeaderView::section {\n" -" background-color: #252A2C;\n" -" color: #AEB8BE;\n" -" border: none;\n" -" border-right: 1px solid #343B3F;\n" -" border-bottom: 1px solid #343B3F;\n" -" padding: 4px 6px;\n" -" font-weight: 600;\n" +"#workspaceUtilityButton {\n" +" background: transparent;\n" +" border-color: transparent;\n" +" min-width: 26px;\n" +" padding: 3px 5px;\n" "}\n" "\n" -"QHeaderView::section:hover {\n" -" background-color: #2E3538;\n" -" color: #EAF0F2;\n" +"#workspaceBuildButton,\n" +"#workspaceLaunchButton {\n" +" min-width: 26px;\n" +" padding: 3px 5px;\n" "}\n" "\n" -"QTabWidget::pane {\n" -" background-color: #222526;\n" -" border: 1px solid #343B3F;\n" -" border-radius: 3px;\n" -" top: -1px;\n" +"#workspaceBuildButton {\n" +" background-color: #2C2618;\n" +" border-color: #5D4B23;\n" +" color: #F5D184;\n" "}\n" "\n" -"QTabBar::tab {\n" -" background-color: #252A2C;\n" -" color: #9EA9AF;\n" -" border: 1px solid #343B3F;\n" -" border-bottom-color: #343B3F;\n" -" border-top-left-radius: 3px;\n" -" border-top-right-radius: 3px;\n" -" padding: 4px 9px;\n" -" min-width: 46px;\n" +"#workspaceLaunchButton {\n" +" background-color: #183020;\n" +" border-color: #285A38;\n" +" color: #92E6A9;\n" +" margin-left: 3px;\n" "}\n" "\n" -"QTabBar::tab:first {\n" -" border-top-left-radius: 5px;\n" +"#workspaceBuildButton:hover {\n" +" background-color: #3A311D;\n" +" border-color: #80682D;\n" "}\n" "\n" -"QTabBar::tab:last {\n" -" border-top-right-radius: 5px;\n" +"#workspaceLaunchButton:hover {\n" +" background-color: #20412A;\n" +" border-color: #3A7A4B;\n" "}\n" "\n" -"QTabBar::tab:hover {\n" -" background-color: #30383B;\n" -" color: #E3EAED;\n" +"#sceneTabs {\n" +" background-color: #0C1117;\n" +" border-bottom: 1px solid #273141;\n" "}\n" "\n" -"QTabBar::tab:selected {\n" -" background-color: #303638;\n" -" color: #FFFFFF;\n" -" border-top: 1px solid #343B3F;\n" -" border-bottom-color: #303638;\n" +"#sceneTabs::tab {\n" +" background-color: #111720;\n" +" border-right: 1px solid #252E3B;\n" +" color: #7F8B9D;\n" +" min-width: 112px;\n" +" padding: 5px 10px;\n" "}\n" "\n" -"QMenuBar {\n" -" background-color: #222526;\n" -" color: #CCD4D8;\n" -" border-bottom: none;\n" +"#sceneTabs::tab:selected {\n" +" background-color: #171E29;\n" +" color: #F3F6FA;\n" +" border-bottom: 2px solid #4CB7D8;\n" "}\n" "\n" -"QMenuBar::item {\n" -" background-color: transparent;\n" -" padding: 4px 8px;\n" +"#viewportTools {\n" +" background-color: #090D12;\n" "}\n" "\n" -"QMenuBar::item:selected {\n" -" background-color: #30383B;\n" -" color: #FFFFFF;\n" +"#viewportToolbar {\n" +" background-color: #111720;\n" +" border-bottom: 1px solid #273141;\n" "}\n" "\n" -"QMenu {\n" -" background-color: #1B1F20;\n" -" color: #E5ECEF;\n" -" border: 1px solid #3D454A;\n" -" border-radius: 3px;\n" -" padding: 3px;\n" +"#viewportPlaybackButton,\n" +"#viewportModeButton,\n" +"#viewportOptionButton,\n" +"#viewportShadingButton {\n" +" background-color: #171E29;\n" +" border-color: #283345;\n" +" min-width: 25px;\n" +" min-height: 22px;\n" +" padding: 3px 5px;\n" "}\n" "\n" -"QMenu::item {\n" -" padding: 4px 24px 4px 8px;\n" -" border-radius: 3px;\n" +"#viewportPlaybackButton:hover,\n" +"#viewportModeButton:hover,\n" +"#viewportOptionButton:hover,\n" +"#viewportShadingButton:hover {\n" +" background-color: #222C3C;\n" +" border-color: #46536A;\n" "}\n" "\n" -"QMenu::item:selected {\n" -" background-color: #315D90;\n" -" color: #FFFFFF;\n" +"#viewportModeButton:checked,\n" +"#viewportShadingButton:checked {\n" +" background-color: #172A46;\n" +" border-color: #4C8DFF;\n" "}\n" "\n" -"QMenu::separator {\n" -" height: 1px;\n" -" background-color: #343B3F;\n" -" margin: 3px 5px;\n" +"#viewportFpsLabel {\n" +" color: #73C58A;\n" +" font-size: 10px;\n" +" font-weight: 650;\n" "}\n" "\n" -"QSplitter::handle {\n" -" background-color: #222526;\n" +"#viewportShortcutHint {\n" +" background-color: #090D12;\n" +" border-top: 1px solid #202836;\n" +" color: #68758A;\n" +" font-size: 10px;\n" +" padding: 3px 7px;\n" "}\n" "\n" -"QSplitter::handle:horizontal {\n" -" width: 6px;\n" +"#panelToolbar,\n" +"#materialEditorHeader,\n" +"#postProcessingToolbar,\n" +"#workspaceToolbar {\n" +" background-color: #131922;\n" +" border-bottom: 1px solid #283243;\n" +" padding: 3px;\n" "}\n" "\n" -"QSplitter::handle:vertical {\n" -" height: 6px;\n" +"#panelAddButton,\n" +"#materialSaveButton,\n" +"#workspaceApplyButton {\n" +" background-color: #172A46;\n" +" border-color: #35628F;\n" +" color: #DCE9FA;\n" "}\n" "\n" -"QSplitter::handle:hover {\n" -" background-color: #4FAAFF;\n" +"#panelMoreButton,\n" +"#browserNavigationButton,\n" +"#browserRevealButton {\n" +" background-color: transparent;\n" +" border-color: transparent;\n" +" min-width: 24px;\n" "}\n" "\n" -"QStatusBar {\n" -" background-color: #1B1E1F;\n" -" color: #AEB8BE;\n" -" border-top: 1px solid #303638;\n" +"#panelMoreButton:hover,\n" +"#browserNavigationButton:hover,\n" +"#browserRevealButton:hover {\n" +" background-color: #202A38;\n" +" border-color: #334056;\n" "}\n" "\n" -"QStatusBar::item {\n" -" border: none;\n" +"#contentPathField {\n" +" background-color: #0E131A;\n" +" color: #8490A4;\n" +" font-size: 11px;\n" "}\n" "\n" -"ads--CDockContainerWidget {\n" -" background-color: #222526;\n" +"#contentSearchField {\n" +" min-width: 130px;\n" "}\n" "\n" -"ads--CDockContainerWidget > QSplitter {\n" -" padding: 1px;\n" +"QTreeView#hierarchyTree {\n" +" background-color: #10151C;\n" +" border-top: 1px solid #202836;\n" +" padding: 5px 3px;\n" "}\n" "\n" -"ads--CDockSplitter::handle,\n" -"ads--CDockContainerWidget ads--CDockSplitter::handle {\n" -" background-color: #222526;\n" +"QTreeView#hierarchyTree::item {\n" +" min-height: 24px;\n" +" padding: 3px 5px;\n" "}\n" "\n" -"ads--CDockSplitter::handle:hover,\n" -"ads--CDockContainerWidget ads--CDockSplitter::handle:hover {\n" -" background-color: #4FAAFF;\n" +"QTreeView#hierarchyTree::item:selected {\n" +" background-color: #172A46;\n" +" border-left: 2px solid #6BA3FF;\n" "}\n" "\n" -"ads--CDockAreaWidget {\n" -" background-color: #222526;\n" -" border: none;\n" -" border-radius: 0;\n" +"QListView#contentGrid {\n" +" background-color: #0D1218;\n" +" border-top: 1px solid #202836;\n" +" padding: 6px;\n" "}\n" "\n" -"ads--CDockAreaWidget[focused=\"true\"] {\n" -" border: none;\n" +"QListView#contentGrid::item {\n" +" background-color: #121923;\n" +" border: 1px solid #202A38;\n" +" border-radius: 4px;\n" +" padding: 7px;\n" +" color: #BCC6D4;\n" "}\n" "\n" -"ads--CDockAreaTitleBar {\n" -" background-color: #222526;\n" -" border-bottom: none;\n" -" border-radius: 0;\n" -" padding: 0;\n" +"QListView#contentGrid::item:hover {\n" +" background-color: #182130;\n" +" border-color: #3A465A;\n" "}\n" "\n" -"ads--CDockAreaWidget[focused=\"true\"] ads--CDockAreaTitleBar {\n" -" background-color: #222526;\n" -" border-bottom: none;\n" +"QListView#contentGrid::item:selected {\n" +" background-color: #17283F;\n" +" border-color: #4C8DFF;\n" +" color: #FFFFFF;\n" "}\n" "\n" -"ads--CDockAreaTabBar,\n" -"#tabsContainerWidget {\n" -" background-color: #222526;\n" +"QScrollArea#inspectorScroll,\n" +"#inspectorContent,\n" +"#materialEditorBody,\n" +"#postProcessingBody {\n" +" background-color: #10151C;\n" " border: none;\n" -" border-radius: 0;\n" "}\n" "\n" -"ads--CTitleBarButton {\n" -" background-color: transparent;\n" -" border: none;\n" +"#inspectorHeader {\n" +" background-color: #141B25;\n" +" border: 1px solid #273243;\n" " border-radius: 4px;\n" -" padding: 2px;\n" -" margin: 2px;\n" -" min-width: 18px;\n" -" min-height: 18px;\n" -"}\n" -"\n" -"ads--CTitleBarButton:hover {\n" -" background-color: #394045;\n" -"}\n" -"\n" -"ads--CTitleBarButton:pressed {\n" -" background-color: #1A1D1E;\n" +" padding: 6px;\n" "}\n" "\n" -"#tabsMenuButton::menu-indicator {\n" -" image: none;\n" +"#inspectorObjectIcon {\n" +" background-color: #20283A;\n" +" border: 1px solid #38455B;\n" +" border-radius: 4px;\n" +" padding: 4px;\n" "}\n" "\n" -"#tabsMenuButton {\n" -" qproperty-icon: url(:/ads/images/tabs-menu-button_dark.svg);\n" -" qproperty-iconSize: 16px;\n" +"#inspectorNameField {\n" +" background: transparent;\n" +" border: 1px solid transparent;\n" +" color: #F3F6FA;\n" +" font-size: 14px;\n" +" font-weight: 700;\n" "}\n" "\n" -"#dockAreaCloseButton {\n" -" qproperty-icon: url(:/ads/images/close-button_dark.svg), url(:/ads/images/close-button-disabled_dark.svg) disabled;\n" -" qproperty-iconSize: 16px;\n" +"#inspectorNameField:hover,\n" +"#inspectorNameField:focus {\n" +" background-color: #10151C;\n" +" border-color: #46536A;\n" "}\n" "\n" -"#detachGroupButton {\n" -" qproperty-icon: url(:/ads/images/detach-button_dark.svg), url(:/ads/images/detach-button-disabled_dark.svg) disabled;\n" -" qproperty-iconSize: 16px;\n" +"#inspectorTypeLabel {\n" +" color: #7E8A9E;\n" +" font-size: 10px;\n" +" font-weight: 600;\n" "}\n" "\n" -"#dockAreaAutoHideButton {\n" -" qproperty-icon: url(:/ads/images/vs-pin-button_dark.svg), url(:/ads/images/vs-pin-button-disabled_dark.svg) disabled;\n" -" qproperty-iconSize: 16px;\n" +"#inspectorComponent {\n" +" background-color: #141A23;\n" +" border: 1px solid #252F3E;\n" +" border-radius: 4px;\n" +" margin-top: 3px;\n" "}\n" "\n" -"#dockAreaMinimizeButton {\n" -" qproperty-icon: url(:/ads/images/minimize-button-focused_dark.svg);\n" -" qproperty-iconSize: 16px;\n" +"#inspectorComponentHeaderRow {\n" +" background-color: #171E29;\n" +" border-bottom: 1px solid #252F3E;\n" +" border-radius: 4px 4px 0 0;\n" "}\n" "\n" -"ads--CDockWidgetTab {\n" -" background-color: #252A2C;\n" +"#inspectorComponentHeader {\n" +" background: transparent;\n" " border: none;\n" -" border-right: 1px solid #303638;\n" -" border-top-left-radius: 3px;\n" -" border-top-right-radius: 3px;\n" -" margin: 2px 1px 0 0;\n" -" padding: 0 7px;\n" -" qproperty-iconSize: 14px 14px;\n" -"}\n" -"\n" -"ads--CDockWidgetTab:hover {\n" -" background-color: #30383B;\n" -"}\n" -"\n" -"ads--CDockWidgetTab[activeTab=\"true\"] {\n" -" background-color: #303638;\n" -" border-top: none;\n" -" border-right: 1px solid #343B3F;\n" -"}\n" -"\n" -"ads--CDockWidgetTab[focused=\"true\"] {\n" -" background-color: #303638;\n" -" border-top: none;\n" -"}\n" -"\n" -"ads--CDockWidgetTab QLabel,\n" -"ads--CDockWidgetTab #dockWidgetTabLabel {\n" -" color: #9EA9AF;\n" -" background-color: transparent;\n" -"}\n" -"\n" -"ads--CDockWidgetTab:hover QLabel,\n" -"ads--CDockWidgetTab:hover #dockWidgetTabLabel {\n" -" color: #E3EAED;\n" +" color: #E8ECF2;\n" +" font-weight: 650;\n" +" text-align: left;\n" +" padding: 5px 7px;\n" "}\n" "\n" -"ads--CDockWidgetTab[activeTab=\"true\"] QLabel,\n" -"ads--CDockWidgetTab[activeTab=\"true\"] #dockWidgetTabLabel,\n" -"ads--CDockWidgetTab[focused=\"true\"] QLabel,\n" -"ads--CDockWidgetTab[focused=\"true\"] #dockWidgetTabLabel {\n" -" color: #FFFFFF;\n" +"#inspectorComponentHeader:hover {\n" +" background-color: #1D2634;\n" "}\n" "\n" -"#tabCloseButton {\n" -" background-color: transparent;\n" +"#inspectorComponentRemoveButton {\n" +" background: transparent;\n" " border: none;\n" -" border-radius: 4px;\n" -" padding: 1px;\n" -" margin: 2px 0 2px 4px;\n" -" qproperty-icon: url(:/ads/images/close-button_dark.svg), url(:/ads/images/close-button-disabled_dark.svg) disabled;\n" -" qproperty-iconSize: 16px;\n" -"}\n" -"\n" -"#tabCloseButton:hover {\n" -" background-color: #3D454A;\n" +" min-width: 22px;\n" "}\n" "\n" -"#tabCloseButton:pressed {\n" -" background-color: #16191A;\n" +"#inspectorComponentRemoveButton:hover {\n" +" background-color: #43212A;\n" +" border: 1px solid #713141;\n" "}\n" "\n" -"ads--CDockWidgetTab[focused=\"true\"] > #tabCloseButton {\n" -" qproperty-icon: url(:/ads/images/close-button-focused_dark.svg);\n" +"#inspectorComponentBody {\n" +" background-color: #141A23;\n" +" padding: 5px;\n" "}\n" "\n" -"ads--CDockWidget {\n" -" background-color: #222526;\n" -" border-top: 1px solid #303638;\n" +"#inspectorPropertyRow {\n" +" background: transparent;\n" +" min-height: 27px;\n" "}\n" "\n" -"QScrollArea#dockWidgetScrollArea {\n" -" background-color: #222526;\n" -" border: none;\n" -" border-radius: 0;\n" -" padding: 0;\n" +"#inspectorPropertyLabel {\n" +" color: #929EB0;\n" +" font-size: 11px;\n" "}\n" "\n" -"QWidget[dockWidgetContent=\"true\"] {\n" -" background-color: #222526;\n" +"#inspectorVectorField,\n" +"#inspectorColorField,\n" +"#inspectorNumericField {\n" +" background-color: #0F141B;\n" +" border: 1px solid #263142;\n" +" border-radius: 3px;\n" "}\n" "\n" -"QWidget#collapsibleSection {\n" -" background-color: #222526;\n" +"#inspectorVectorField QDoubleSpinBox,\n" +"#inspectorNumericField QDoubleSpinBox {\n" +" background: transparent;\n" " border: none;\n" -" border-radius: 0;\n" "}\n" "\n" -"QToolButton#collapsibleHeader {\n" -" background-color: transparent;\n" -" border: none;\n" -" border-radius: 0;\n" -" padding: 4px 0;\n" -" color: #E7ECEF;\n" -" font-weight: 600;\n" -" text-align: left;\n" -"}\n" -"\n" -"QToolButton#collapsibleHeader:hover {\n" -" background-color: transparent;\n" -" color: #FFFFFF;\n" -"}\n" -"\n" -"QToolButton#collapsibleHeader:checked {\n" -" background-color: transparent;\n" -"}\n" -"\n" -"QToolButton#collapsibleHeader::menu-indicator {\n" -" image: none;\n" -"}\n" -"\n" -"QWidget#collapsibleBody {\n" -" background-color: #222526;\n" -" border: none;\n" -" border-radius: 0;\n" +"#inspectorAxisLabel {\n" +" background-color: #202A38;\n" +" border-radius: 3px;\n" +" color: #AAB5C5;\n" +" font-size: 9px;\n" +" font-weight: 750;\n" +" padding: 2px 4px;\n" "}\n" "\n" -"#autoHideTitleLabel {\n" -" color: #EAF0F2;\n" -" background-color: transparent;\n" -" padding-left: 6px;\n" -" font-weight: 600;\n" +"#inspectorSyncButton,\n" +"#inspectorArrayButton {\n" +" background: transparent;\n" +" border-color: transparent;\n" +" min-width: 22px;\n" "}\n" "\n" -"ads--CAutoHideSideBar {\n" -" background-color: #1B1E1F;\n" -" border: none;\n" -" qproperty-spacing: 8;\n" +"#inspectorSyncButton[matched=\"true\"] {\n" +" background-color: #1C3827;\n" +" border-color: #2F6841;\n" +" color: #8FE1A6;\n" "}\n" "\n" -"#sideTabsContainerWidget {\n" -" background-color: transparent;\n" +"#inspectorColorSwatch {\n" +" border: 1px solid #4A566A;\n" +" border-radius: 4px;\n" "}\n" "\n" -"ads--CAutoHideSideBar[sideBarLocation=\"0\"] {\n" -" border-bottom: 1px solid #303638;\n" +"#inspectorColorText {\n" +" color: #9CA8BA;\n" +" font-family: \"Menlo\";\n" +" font-size: 10px;\n" "}\n" "\n" -"ads--CAutoHideSideBar[sideBarLocation=\"1\"] {\n" -" border-right: 1px solid #303638;\n" +"#inspectorNestedGroup {\n" +" background-color: #111720;\n" +" border: 1px solid #222C3A;\n" +" border-radius: 4px;\n" +" margin: 3px 0;\n" +" padding: 5px;\n" "}\n" "\n" -"ads--CAutoHideSideBar[sideBarLocation=\"2\"] {\n" -" border-left: 1px solid #303638;\n" +"#inspectorNestedTitle,\n" +"#inspectorArrayTitle {\n" +" color: #AEB8C8;\n" +" font-weight: 650;\n" "}\n" "\n" -"ads--CAutoHideSideBar[sideBarLocation=\"3\"] {\n" -" border-top: 1px solid #303638;\n" +"#inspectorEmptyTitle,\n" +"#materialEditorEmpty,\n" +"#postProcessingEmpty {\n" +" color: #C4CDDA;\n" +" font-size: 14px;\n" +" font-weight: 650;\n" "}\n" "\n" -"ads--CAutoHideTab {\n" -" background-color: transparent;\n" -" border: none;\n" -" color: #AEB8BE;\n" -" padding: 4px 6px;\n" -" min-height: 24px;\n" -" qproperty-iconSize: 16px 16px;\n" +"#inspectorEmptyHint {\n" +" color: #728096;\n" "}\n" "\n" -"ads--CAutoHideTab:hover {\n" -" background-color: #30383B;\n" -" color: #FFFFFF;\n" +"#inspectorOpenAssetButton,\n" +"#inspectorAddComponentButton {\n" +" background-color: #1B2431;\n" +" border: 1px dashed #46536A;\n" +" color: #C7D0DD;\n" +" padding: 6px;\n" "}\n" "\n" -"ads--CAutoHideTab[activeTab=\"true\"] {\n" -" background-color: #303638;\n" +"#inspectorAddComponentButton:hover {\n" +" background-color: #17283F;\n" +" border-color: #4C8DFF;\n" " color: #FFFFFF;\n" "}\n" "\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"0\"],\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"2\"],\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"0\"] {\n" -" border-top: 3px solid #465157;\n" -"}\n" -"\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"1\"],\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"3\"],\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"3\"] {\n" -" border-bottom: 3px solid #465157;\n" +"#inspectorAudioControls {\n" +" background-color: #111720;\n" +" border-radius: 3px;\n" "}\n" "\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"1\"] {\n" -" border-left: 3px solid #465157;\n" +"#materialEditorTitle,\n" +"#postProcessingTitle,\n" +"#postProcessingSectionTitle,\n" +"#inspectorCameraTitle,\n" +"#workspaceTitle {\n" +" color: #F3F6FA;\n" +" font-size: 13px;\n" +" font-weight: 700;\n" "}\n" "\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"2\"] {\n" -" border-right: 3px solid #465157;\n" +"#materialEditorStatus,\n" +"#postProcessingStatus,\n" +"#workspaceStatus,\n" +"#workspaceAutoApply {\n" +" color: #7E8A9E;\n" +" font-size: 10px;\n" "}\n" "\n" -"ads--CAutoHideTab:hover[iconOnly=\"false\"][sideBarLocation=\"0\"],\n" -"ads--CAutoHideTab:hover[iconOnly=\"false\"][sideBarLocation=\"2\"],\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"0\"][activeTab=\"true\"],\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"2\"][activeTab=\"true\"],\n" -"ads--CAutoHideTab:hover[iconOnly=\"true\"][sideBarLocation=\"0\"],\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"0\"][activeTab=\"true\"] {\n" -" border-top: 3px solid #AEB8BE;\n" +"#materialPreview {\n" +" background-color: #090D12;\n" +" border: 1px solid #2B3648;\n" +" border-radius: 4px;\n" "}\n" "\n" -"ads--CAutoHideTab:hover[iconOnly=\"false\"][sideBarLocation=\"1\"],\n" -"ads--CAutoHideTab:hover[iconOnly=\"false\"][sideBarLocation=\"3\"],\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"1\"][activeTab=\"true\"],\n" -"ads--CAutoHideTab[iconOnly=\"false\"][sideBarLocation=\"3\"][activeTab=\"true\"],\n" -"ads--CAutoHideTab:hover[iconOnly=\"true\"][sideBarLocation=\"3\"],\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"3\"][activeTab=\"true\"] {\n" -" border-bottom: 3px solid #AEB8BE;\n" +"#materialTextureSlot {\n" +" background-color: #121923;\n" +" border: 1px solid #263142;\n" +" border-radius: 4px;\n" +" padding: 4px;\n" "}\n" "\n" -"ads--CAutoHideTab:hover[iconOnly=\"true\"][sideBarLocation=\"1\"],\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"1\"][activeTab=\"true\"] {\n" -" border-left: 3px solid #AEB8BE;\n" +"#materialTexturePreview {\n" +" background-color: #0D1218;\n" +" border: 1px solid #344156;\n" +" border-radius: 4px;\n" +" color: #D9825B;\n" +" font-weight: 750;\n" "}\n" "\n" -"ads--CAutoHideTab:hover[iconOnly=\"true\"][sideBarLocation=\"2\"],\n" -"ads--CAutoHideTab[iconOnly=\"true\"][sideBarLocation=\"2\"][activeTab=\"true\"] {\n" -" border-right: 3px solid #AEB8BE;\n" +"#materialTextureLabel {\n" +" color: #D6DDE7;\n" +" font-weight: 650;\n" "}\n" "\n" -"ads--CAutoHideDockContainer {\n" -" background-color: #222526;\n" -" border: 1px solid #6A7479;\n" +"#materialTexturePath {\n" +" color: #7D899C;\n" "}\n" "\n" -"ads--CAutoHideDockContainer ads--CDockAreaTitleBar,\n" -"ads--CAutoHideDockContainer ads--CDockAreaWidget[focused=\"true\"] ads--CDockAreaTitleBar {\n" -" background-color: #2B3032;\n" +"#environmentPages,\n" +"#environmentWorkspace,\n" +"#environmentPage {\n" +" background-color: #10151C;\n" " border: none;\n" -" padding: 0;\n" "}\n" "\n" -"ads--CAutoHideDockContainer #autoHideTitleLabel {\n" -" color: #FFFFFF;\n" +"QListWidget#environmentCategories {\n" +" background-color: #0E131A;\n" +" border-right: 1px solid #273141;\n" +" padding: 5px;\n" "}\n" "\n" -"ads--CAutoHideDockContainer #dockAreaAutoHideButton {\n" -" qproperty-icon: url(:/ads/images/vs-pin-button-pinned-focused_dark.svg);\n" -" qproperty-iconSize: 16px;\n" +"QListWidget#environmentCategories::item {\n" +" padding: 6px 8px;\n" +" margin: 2px 0;\n" "}\n" "\n" -"ads--CAutoHideDockContainer #dockAreaCloseButton {\n" -" qproperty-icon: url(:/ads/images/close-button-focused_dark.svg);\n" +"QListWidget#environmentCategories::item:selected {\n" +" background-color: #172A46;\n" +" border-left: 2px solid #6BA3FF;\n" "}\n" "\n" -"ads--CAutoHideDockContainer ads--CTitleBarButton:hover {\n" -" background-color: #34536A;\n" +"#environmentPageTitle {\n" +" color: #F3F6FA;\n" +" font-size: 17px;\n" +" font-weight: 750;\n" "}\n" "\n" -"ads--CAutoHideDockContainer ads--CTitleBarButton:pressed {\n" -" background-color: #17222A;\n" +"#environmentPageSubtitle {\n" +" color: #778499;\n" "}\n" "\n" -"ads--CResizeHandle {\n" -" background-color: #1B1E1F;\n" +"QGroupBox#environmentSection {\n" +" background-color: #141A23;\n" +" border-color: #273141;\n" "}\n" "\n" -"ads--CAutoHideDockContainer[sideBarLocation=\"0\"] ads--CResizeHandle,\n" -"ads--CAutoHideDockContainer[sideBarLocation=\"3\"] ads--CResizeHandle {\n" -" border-top: 1px solid #6A7479;\n" +"ads--CDockContainerWidget {\n" +" background-color: #080C11;\n" "}\n" "\n" -"ads--CAutoHideDockContainer[sideBarLocation=\"1\"] ads--CResizeHandle {\n" -" border-left: 1px solid #6A7479;\n" +"ads--CDockContainerWidget > QSplitter {\n" +" background-color: #080C11;\n" "}\n" "\n" -"ads--CAutoHideDockContainer[sideBarLocation=\"2\"] ads--CResizeHandle {\n" -" border-right: 1px solid #6A7479;\n" +"ads--CDockContainerWidget ads--CDockSplitter::handle {\n" +" background-color: #080C11;\n" "}\n" "\n" -"#DockWidgetAreaLabel {\n" -" background-color: rgba(61, 139, 255, 64);\n" -" border: 1px solid rgba(114, 199, 255, 190);\n" -" border-radius: 6px;\n" +"ads--CDockContainerWidget ads--CDockSplitter::handle:hover {\n" +" background-color: #4C8DFF;\n" "}\n" "\n" -"#workspaceToolbar {\n" -" background-color: #191C1D;\n" -" border-bottom: 1px solid #32383B;\n" +"ads--CDockAreaWidget {\n" +" background-color: #10151C;\n" +" border: 1px solid #202A38;\n" "}\n" "\n" -"#workspaceTitle {\n" -" color: #F2F5F6;\n" -" font-size: 14px;\n" -" font-weight: 650;\n" +"ads--CDockAreaWidget[focused=\"true\"] {\n" +" border-color: #39465B;\n" "}\n" "\n" -"#workspaceStatus,\n" -"#workspaceAutoApply {\n" -" color: #89949A;\n" -" font-size: 11px;\n" +"ads--CDockAreaTitleBar {\n" +" background-color: #111720;\n" +" border-bottom: 1px solid #273141;\n" +" min-height: 26px;\n" "}\n" "\n" -"#workspaceApplyButton {\n" -" background-color: #293238;\n" -" border-color: #3C4C55;\n" -" min-height: 19px;\n" -" padding: 2px 7px;\n" +"ads--CDockAreaWidget[focused=\"true\"] ads--CDockAreaTitleBar {\n" +" background-color: #151C27;\n" "}\n" "\n" -"#environmentWorkspace,\n" -"#environmentPages {\n" -" background-color: #202324;\n" -" border: none;\n" +"#tabsContainerWidget {\n" +" background-color: transparent;\n" "}\n" "\n" -"QListWidget#environmentCategories {\n" -" background-color: #191C1D;\n" +"ads--CTitleBarButton {\n" +" background: transparent;\n" " border: none;\n" -" border-right: 1px solid #32383B;\n" -" border-radius: 0;\n" -" padding: 5px 3px;\n" -" outline: none;\n" +" border-radius: 3px;\n" +" min-width: 22px;\n" +" min-height: 22px;\n" +" padding: 2px;\n" "}\n" "\n" -"QListWidget#environmentCategories::item {\n" -" min-height: 26px;\n" -" padding: 3px 6px;\n" -" border: 1px solid transparent;\n" -" border-radius: 3px;\n" +"ads--CTitleBarButton:hover {\n" +" background-color: #263144;\n" "}\n" "\n" -"QListWidget#environmentCategories::item:hover {\n" -" background-color: #282E31;\n" +"ads--CDockWidgetTab {\n" +" background-color: #111720;\n" +" border: none;\n" +" border-right: 1px solid #252E3B;\n" +" border-bottom: 1px solid #273141;\n" +" padding: 1px 5px;\n" "}\n" "\n" -"QListWidget#environmentCategories::item:selected {\n" -" background-color: #303A40;\n" -" border-color: #46545C;\n" -" color: #FFFFFF;\n" +"ads--CDockWidgetTab:hover {\n" +" background-color: #18212D;\n" "}\n" "\n" -"QScrollArea#environmentScroll,\n" -"#environmentPage {\n" -" background-color: #202324;\n" -" border: none;\n" -" border-radius: 0;\n" +"ads--CDockWidgetTab[activeTab=\"true\"] {\n" +" background-color: #171E29;\n" +" border-bottom: 2px solid #4C8DFF;\n" "}\n" "\n" -"#environmentPageTitle {\n" -" color: #F0F3F4;\n" -" font-size: 17px;\n" -" font-weight: 650;\n" +"ads--CDockWidgetTab[focused=\"true\"] {\n" +" background-color: #1A2230;\n" "}\n" "\n" -"#environmentPageSubtitle {\n" -" color: #838E94;\n" +"ads--CDockWidgetTab #dockWidgetTabLabel {\n" +" color: #7F8B9D;\n" " font-size: 11px;\n" +" padding: 4px 2px;\n" "}\n" "\n" -"QGroupBox#environmentSection {\n" -" background-color: #242829;\n" -" border: 1px solid #363D40;\n" -" border-radius: 3px;\n" -" margin-top: 15px;\n" -" padding: 7px;\n" +"ads--CDockWidgetTab[activeTab=\"true\"] #dockWidgetTabLabel,\n" +"ads--CDockWidgetTab[focused=\"true\"] #dockWidgetTabLabel {\n" +" color: #F1F4F8;\n" "}\n" "\n" -"QGroupBox#environmentSection::title {\n" -" background-color: #242829;\n" -" color: #BDC6CA;\n" -" left: 7px;\n" -" padding: 0 4px;\n" +"#tabCloseButton,\n" +"#dockAreaCloseButton,\n" +"#detachGroupButton,\n" +"#dockAreaAutoHideButton,\n" +"#dockAreaMinimizeButton,\n" +"#tabsMenuButton {\n" +" background: transparent;\n" +" border: none;\n" +" min-width: 20px;\n" +" min-height: 20px;\n" "}\n" "\n" -"#compactVectorField {\n" -" background-color: #191C1D;\n" -" border: 1px solid #363D41;\n" -" border-radius: 3px;\n" +"#tabCloseButton:hover,\n" +"#dockAreaCloseButton:hover,\n" +"#detachGroupButton:hover,\n" +"#dockAreaAutoHideButton:hover,\n" +"#dockAreaMinimizeButton:hover,\n" +"#tabsMenuButton:hover {\n" +" background-color: #2A3444;\n" "}\n" "\n" -"#compactAxisLabel {\n" -" color: #718087;\n" -" font-size: 10px;\n" -" font-weight: 700;\n" -" min-width: 9px;\n" +"ads--CDockWidget {\n" +" background-color: #10151C;\n" "}\n" "\n" -"#compactVectorField QDoubleSpinBox {\n" -" background-color: transparent;\n" -" border: none;\n" -" border-radius: 0;\n" -" padding: 2px 1px;\n" +"ads--CAutoHideSideBar,\n" +"#sideTabsContainerWidget {\n" +" background-color: #090D12;\n" +"}\n" +"\n" +"ads--CAutoHideTab {\n" +" background-color: #111720;\n" +" border: 1px solid #263142;\n" +" color: #7F8B9D;\n" +" padding: 4px;\n" "}\n" "\n" -"#compactColorButton {\n" -" border: 1px solid #566167;\n" +"ads--CAutoHideTab:hover,\n" +"ads--CAutoHideTab[activeTab=\"true\"] {\n" +" background-color: #172A46;\n" +" border-color: #3F78D8;\n" " color: #FFFFFF;\n" -" font-weight: 650;\n" -" text-align: left;\n" "}\n" "\n" "#projectBrowserRoot,\n" -"#projectBrowserContent,\n" -"#createProjectDialog {\n" -" background-color: #181B1D;\n" -" font-family: \"Manrope\", \"Helvetica Neue\", sans-serif;\n" +"#projectBrowserContent {\n" +" background-color: #0D1117;\n" "}\n" "\n" "#projectSidebar {\n" -" background-color: #111315;\n" -" border-right: 1px solid #2A2E31;\n" +" background-color: #0A0E13;\n" +" border-right: 1px solid #202836;\n" "}\n" "\n" "#projectBrand {\n" -" background: transparent;\n" -" color: #F4F7F8;\n" -" font-size: 22px;\n" -" font-weight: 700;\n" +" color: #F5F7FA;\n" +" font-size: 16px;\n" +" font-weight: 750;\n" +"}\n" +"\n" +"#projectSidebarVersion {\n" +" color: #68758A;\n" +" font-size: 10px;\n" +" font-weight: 600;\n" "}\n" "\n" "#projectNavSelected {\n" -" background-color: #252A2D;\n" -" border: 1px solid #32383C;\n" -" border-radius: 8px;\n" -" color: #F4F7F8;\n" -" padding: 9px 12px;\n" +" background-color: #17263B;\n" +" border: 1px solid #2F527D;\n" +" border-left: 3px solid #6BA3FF;\n" +" color: #DCE9FA;\n" +" padding: 6px 9px;\n" " text-align: left;\n" "}\n" "\n" "#projectNavSelected:disabled {\n" -" background-color: #252A2D;\n" -" border-color: #32383C;\n" -" color: #F4F7F8;\n" -"}\n" -"\n" -"#projectSidebarVersion {\n" -" background: transparent;\n" -" color: #697277;\n" -" font-size: 11px;\n" +" color: #DCE9FA;\n" "}\n" "\n" "#projectBrowserTitle,\n" "#dialogTitle {\n" -" background: transparent;\n" -" color: #F7F9FA;\n" -" font-size: 28px;\n" -" font-weight: 700;\n" +" color: #F4F6FA;\n" +" font-size: 24px;\n" +" font-weight: 750;\n" "}\n" "\n" "#projectBrowserSubtitle,\n" "#dialogSubtitle,\n" -"#emptyStateSubtitle {\n" -" background: transparent;\n" -" color: #889197;\n" -" font-size: 13px;\n" -"}\n" -"\n" -"#primaryAction {\n" -" background-color: #2F85F5;\n" -" border: 1px solid #55A0FF;\n" -" border-radius: 7px;\n" -" color: #FFFFFF;\n" -" font-weight: 600;\n" -" padding: 8px 14px;\n" -"}\n" -"\n" -"#primaryAction:hover {\n" -" background-color: #3B91FF;\n" -" border-color: #72B1FF;\n" -"}\n" -"\n" -"#primaryAction:pressed {\n" -" background-color: #2876DA;\n" -"}\n" -"\n" -"#primaryAction:disabled {\n" -" background-color: #2A3034;\n" -" border-color: #363D41;\n" -" color: #697277;\n" -"}\n" -"\n" -"QPushButton[secondary=\"true\"] {\n" -" background-color: #252A2D;\n" -" border: 1px solid #3A4145;\n" -" border-radius: 7px;\n" -" color: #DDE3E6;\n" -" padding: 8px 14px;\n" -"}\n" -"\n" -"QPushButton[secondary=\"true\"]:hover {\n" -" background-color: #2D3337;\n" -" border-color: #4A5358;\n" +"#emptyStateSubtitle,\n" +"#templateDescription {\n" +" color: #7F8B9D;\n" "}\n" "\n" "#projectSearch {\n" -" background-color: #222629;\n" -" border: 1px solid #343A3E;\n" -" border-radius: 8px;\n" -" color: #EEF2F4;\n" -" padding: 9px 12px;\n" +" background-color: #111720;\n" +" border: 1px solid #2A3547;\n" +" border-radius: 4px;\n" +" padding: 7px 9px;\n" +" font-size: 13px;\n" "}\n" "\n" "#projectSearch:focus {\n" -" border-color: #4B9EFF;\n" +" border-color: #4C8DFF;\n" "}\n" "\n" "#projectList {\n" -" background: transparent;\n" +" background-color: transparent;\n" " border: none;\n" -" outline: none;\n" "}\n" "\n" "#projectList::item {\n" " background: transparent;\n" " border: none;\n" +" padding: 0;\n" "}\n" "\n" "#projectRow {\n" -" background-color: #222629;\n" -" border: 1px solid #30363A;\n" -" border-radius: 10px;\n" +" background-color: #141A23;\n" +" border: 1px solid #252F3E;\n" +" border-radius: 5px;\n" "}\n" "\n" "#projectRow:hover {\n" -" background-color: #282D31;\n" -" border-color: #465057;\n" +" background-color: #18212D;\n" +" border-color: #40506A;\n" "}\n" "\n" "#projectRow[available=\"false\"] {\n" -" background-color: #1D2022;\n" -" border-color: #532F34;\n" +" background-color: #11161D;\n" +" border-color: #1D2530;\n" +"}\n" +"\n" +"#projectIcon,\n" +"#templateIcon {\n" +" background-color: #1D2532;\n" +" border: 1px solid #334056;\n" +" border-radius: 4px;\n" "}\n" "\n" "#projectName {\n" -" background: transparent;\n" -" color: #F0F4F5;\n" +" color: #EEF2F7;\n" " font-size: 14px;\n" -" font-weight: 650;\n" +" font-weight: 700;\n" "}\n" "\n" "#projectPath,\n" "#projectDate {\n" -" background: transparent;\n" -" color: #788187;\n" -" font-size: 11px;\n" +" color: #768398;\n" +" font-size: 10px;\n" "}\n" "\n" "#rendererBadge {\n" -" background-color: #243B51;\n" -" border: 1px solid #31536E;\n" -" border-radius: 9px;\n" -" color: #9ED1FF;\n" -" font-size: 10px;\n" -" font-weight: 600;\n" -" padding: 3px 8px;\n" +" background-color: #1C3527;\n" +" border: 1px solid #2C6340;\n" +" border-radius: 3px;\n" +" color: #8DE2A5;\n" +" padding: 3px 7px;\n" +" font-size: 9px;\n" +" font-weight: 700;\n" "}\n" "\n" "#projectMoreButton {\n" " background: transparent;\n" -" border: none;\n" -" color: #98A2A8;\n" -" font-size: 14px;\n" -" padding: 6px;\n" +" border-color: transparent;\n" "}\n" "\n" "#projectMoreButton:hover {\n" -" background-color: #363D41;\n" -" border-radius: 6px;\n" -" color: #FFFFFF;\n" +" background-color: #253044;\n" +" border-color: #3B4860;\n" "}\n" "\n" "#projectEmptyState {\n" -" background-color: #1D2022;\n" -" border: 1px dashed #343A3E;\n" -" border-radius: 12px;\n" +" background-color: #10151C;\n" +" border: 1px dashed #2F3A4D;\n" +" border-radius: 5px;\n" "}\n" "\n" "#emptyStateTitle {\n" -" background: transparent;\n" -" color: #E9EEF0;\n" -" font-size: 17px;\n" -" font-weight: 650;\n" +" color: #CDD5E1;\n" +" font-size: 16px;\n" +" font-weight: 700;\n" +"}\n" +"\n" +"#createProjectDialog {\n" +" background-color: #10151C;\n" "}\n" "\n" "QFrame[templateCard=\"true\"] {\n" -" background-color: #222629;\n" -" border: 1px solid #343A3E;\n" -" border-radius: 10px;\n" +" background-color: #141A23;\n" +" border: 1px solid #293445;\n" +" border-radius: 5px;\n" "}\n" "\n" "QFrame[templateCard=\"true\"]:hover {\n" -" background-color: #282E32;\n" -" border-color: #4B5961;\n" +" background-color: #1A2230;\n" +" border-color: #46536A;\n" "}\n" "\n" "QFrame[templateCard=\"true\"][selected=\"true\"] {\n" -" background-color: #20354A;\n" -" border: 2px solid #4B9EFF;\n" +" background-color: #17283F;\n" +" border-color: #4C8DFF;\n" "}\n" "\n" "#templateOption {\n" -" background: transparent;\n" -" color: #F3F6F7;\n" -" font-size: 14px;\n" +" color: #E7ECF3;\n" " font-weight: 650;\n" "}\n" "\n" -"#templateDescription {\n" -" background: transparent;\n" -" color: #879096;\n" +"#fieldLabel {\n" +" color: #AAB5C5;\n" " font-size: 11px;\n" +" font-weight: 650;\n" "}\n" "\n" -"#fieldLabel {\n" -" background: transparent;\n" -" color: #B3BCC1;\n" +"#dialogError {\n" +" color: #FF7D8A;\n" " font-size: 11px;\n" -" font-weight: 600;\n" "}\n" "\n" -"#dialogError {\n" -" background-color: #41262A;\n" -" border: 1px solid #704048;\n" -" border-radius: 7px;\n" -" color: #FFB4BE;\n" -" padding: 8px 10px;\n" +"QPushButton[secondary=\"true\"] {\n" +" background-color: #171E29;\n" +" border-color: #344156;\n" +"}\n" +"\n" +"QPushButton[secondary=\"true\"]:hover {\n" +" background-color: #222C3C;\n" +" border-color: #4A5870;\n" +"}\n" +"\n" +"#projectSettingsDialog,\n" +"#exportDialog {\n" +" background-color: #0D1117;\n" +"}\n" +"\n" +"#dialogHero {\n" +" background-color: #141A23;\n" +" border: 1px solid #293445;\n" +" border-radius: 5px;\n" +" padding: 6px;\n" +"}\n" +"\n" +"#dialogHeroIcon {\n" +" background-color: #15253A;\n" +" border: 1px solid #2F527D;\n" +" border-radius: 4px;\n" +" padding: 6px;\n" +"}\n" +"\n" +"#dialogHeroTitle {\n" +" color: #F3F6FA;\n" +" font-size: 17px;\n" +" font-weight: 750;\n" +"}\n" +"\n" +"#dialogHeroSubtitle,\n" +"#exportSummary {\n" +" color: #7F8B9D;\n" +"}\n" +"\n" +"#exportSummary {\n" +" background-color: #121923;\n" +" border: 1px solid #273141;\n" +" border-radius: 4px;\n" +" padding: 6px;\n" +"}\n" +"\n" +"#exportLog {\n" +" background-color: #090D12;\n" +" border-color: #263142;\n" +" color: #9CE2AF;\n" +" font-family: \"Menlo\";\n" +" font-size: 10px;\n" +"}\n" +"\n" +"#commandPaletteDialog,\n" +"#globalSearchDialog {\n" +" background-color: #111720;\n" +" border: 1px solid #46536A;\n" +" border-radius: 5px;\n" +"}\n" +"\n" +"#commandPaletteSearch,\n" +"#globalSearchField {\n" +" background-color: #0D1218;\n" +" border: 1px solid #3A465A;\n" +" border-radius: 4px;\n" +" padding: 7px 9px;\n" +" font-size: 14px;\n" +"}\n" +"\n" +"#commandPaletteSearch:focus,\n" +"#globalSearchField:focus {\n" +" border-color: #6BA3FF;\n" +"}\n" +"\n" +"#commandPaletteList,\n" +"#globalSearchResults {\n" +" background-color: #111720;\n" +" border: none;\n" +" padding: 5px;\n" +"}\n" +"\n" +"#commandPaletteList::item,\n" +"#globalSearchResults::item {\n" +" min-height: 30px;\n" +" padding: 6px 8px;\n" "}\n" ; diff --git a/include/editor/styling/icons.h b/include/editor/styling/icons.h index e2d23562..c3c093b6 100644 --- a/include/editor/styling/icons.h +++ b/include/editor/styling/icons.h @@ -28,9 +28,11 @@ enum class Icon { Crosshair, Cube, CubeFocus, + CubeTransparent, CursorClick, Database, DotsVertical, + DotsNine, Export, Eye, EyeSlash, diff --git a/include/editor/views/editorWindow.h b/include/editor/views/editorWindow.h index c9dffdbe..f6bf24c1 100644 --- a/include/editor/views/editorWindow.h +++ b/include/editor/views/editorWindow.h @@ -29,6 +29,8 @@ class ViewportTools; class MaterialEditorPanel; class PostProcessingPanel; class QMenu; +class QButtonGroup; +class QStackedWidget; class QShowEvent; class QTimer; class QFileSystemWatcher; @@ -50,6 +52,7 @@ class EditorWindow : public QMainWindow { void setupMenus(); void setupDocks(); void setupWorkspaceBar(); + void activateWorkspace(int index); void saveLayout(); void restoreLayout(); @@ -77,6 +80,8 @@ class EditorWindow : public QMainWindow { HierarchyPanel* hierarchyPanel = nullptr; ContentBrowserPanel* contentBrowser = nullptr; ViewportTools* viewportTools = nullptr; + QStackedWidget* workspaceStack = nullptr; + QButtonGroup* workspaceModeGroup = nullptr; QMenu* viewMenu = nullptr; QMenu* windowMenu = nullptr; QTimer* layoutSaveTimer = nullptr; diff --git a/include/editor/views/viewport.h b/include/editor/views/viewport.h index 6892b622..c0935f8c 100644 --- a/include/editor/views/viewport.h +++ b/include/editor/views/viewport.h @@ -168,6 +168,7 @@ class ViewportPanel : public QWidget { int keyboardTransformAxes = 7; int playbackState = 0; int shadingMode = 0; + int rightDragRuntimeButton = 0; }; #endif // ATLAS_VIEWPORT_H From d4b0859c01a6143bcdc0f889dab70c026307c061 Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:38:54 +0200 Subject: [PATCH 5/7] Simplified the editor visual system --- editor/styling/dark.qss | 626 ++++++++++++------------ editor/styling/icons.cpp | 29 ++ editor/styling/theme.cpp | 28 +- editor/views/editor/editor.cpp | 106 ++-- editor/views/editor/hierarchy.cpp | 28 +- editor/views/editor/inspector.cpp | 44 +- editor/views/editor/materialEditor.cpp | 22 +- editor/views/editor/postProcessing.cpp | 16 +- editor/views/editor/viewportTools.cpp | 20 +- editor/views/general/contentBrowser.cpp | 34 +- editor/views/general/projectBrowser.cpp | 20 +- editor/views/general/splashScreen.cpp | 10 +- include/editor/core/themes.h | 626 ++++++++++++------------ include/editor/styling/icons.h | 2 + 14 files changed, 842 insertions(+), 769 deletions(-) diff --git a/editor/styling/dark.qss b/editor/styling/dark.qss index 8f6f34e3..e45929f7 100644 --- a/editor/styling/dark.qss +++ b/editor/styling/dark.qss @@ -2,19 +2,19 @@ font-family: "Manrope"; font-size: 12px; color: #E7ECF3; - selection-background-color: #3F78D8; + selection-background-color: #647B8D; selection-color: #FFFFFF; } QWidget { - background-color: #0D1117; + background-color: #18191B; color: #E7ECF3; } QMainWindow, QDialog, QFrame { - background-color: #0D1117; + background-color: #18191B; } QLabel { @@ -26,17 +26,17 @@ QLabel:disabled { } QToolTip { - background-color: #202838; + background-color: #34373A; color: #F7F9FC; - border: 1px solid #3A465A; - border-radius: 3px; + border: 1px solid #505459; + border-radius: 8px; padding: 4px 6px; } QGroupBox { - background-color: #141A23; - border: 1px solid #252E3C; - border-radius: 4px; + background-color: #242628; + border: 1px solid #3A3D40; + border-radius: 10px; margin-top: 14px; padding: 8px; color: #F1F4F8; @@ -49,17 +49,17 @@ QGroupBox::title { left: 9px; padding: 0 6px; color: #AEB8C8; - background-color: #141A23; + background-color: #242628; } QScrollArea, QAbstractScrollArea { - background-color: #10151C; + background-color: #1E2022; border: none; } QAbstractScrollArea::corner { - background-color: #10151C; + background-color: #1E2022; } QScrollBar:vertical { @@ -78,15 +78,15 @@ QScrollBar:horizontal { QScrollBar::handle:vertical, QScrollBar::handle:horizontal { - background-color: #364154; - border-radius: 3px; + background-color: #505357; + border-radius: 4px; min-height: 30px; min-width: 30px; } QScrollBar::handle:vertical:hover, QScrollBar::handle:horizontal:hover { - background-color: #536078; + background-color: #65696E; } QScrollBar::add-line, @@ -101,10 +101,10 @@ QScrollBar::sub-page { QPushButton, QToolButton { - background-color: #1A2230; - border: 1px solid #2D3849; - border-radius: 3px; - padding: 3px 7px; + background-color: #2B2E31; + border: 1px solid #45494D; + border-radius: 8px; + padding: 4px 8px; color: #E9EDF4; min-height: 18px; font-weight: 550; @@ -112,41 +112,41 @@ QToolButton { QPushButton:hover, QToolButton:hover { - background-color: #222C3C; - border-color: #46536A; + background-color: #363A3E; + border-color: #5A5F65; } QPushButton:pressed, QToolButton:pressed { - background-color: #121923; - border-color: #4C8DFF; + background-color: #232527; + border-color: #6F7B84; } QPushButton:checked, QToolButton:checked { - background-color: #182C4A; - border-color: #4C8DFF; + background-color: #3A4248; + border-color: #6F7B84; color: #FFFFFF; } QPushButton:default, #primaryAction { - background-color: #3F78D8; - border-color: #6BA3FF; + background-color: #596A76; + border-color: #73838E; color: #FFFFFF; font-weight: 650; } QPushButton:default:hover, #primaryAction:hover { - background-color: #4C8DFF; - border-color: #78A9F2; + background-color: #667985; + border-color: #82919B; } QPushButton:disabled, QToolButton:disabled { - background-color: #121820; - border-color: #1D2531; + background-color: #202224; + border-color: #303235; color: #566174; } @@ -163,9 +163,9 @@ QDoubleSpinBox, QDateEdit, QTimeEdit, QDateTimeEdit { - background-color: #0F141B; - border: 1px solid #273141; - border-radius: 3px; + background-color: #1B1D1F; + border: 1px solid #3B3E42; + border-radius: 8px; padding: 4px 6px; color: #EEF2F7; } @@ -176,7 +176,7 @@ QPlainTextEdit:hover, QComboBox:hover, QSpinBox:hover, QDoubleSpinBox:hover { - border-color: #3D4A60; + border-color: #54585D; } QLineEdit:focus, @@ -185,8 +185,8 @@ QPlainTextEdit:focus, QComboBox:focus, QSpinBox:focus, QDoubleSpinBox:focus { - background-color: #111824; - border-color: #4C8DFF; + background-color: #222426; + border-color: #71808A; } QLineEdit:disabled, @@ -194,8 +194,8 @@ QTextEdit:disabled, QComboBox:disabled, QSpinBox:disabled, QDoubleSpinBox:disabled { - background-color: #11161D; - border-color: #1D2530; + background-color: #202224; + border-color: #303235; color: #566174; } @@ -207,27 +207,27 @@ QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 22px; - border-left: 1px solid #273141; + border-left: 1px solid #3B3E42; } QComboBox QAbstractItemView { - background-color: #171E29; - border: 1px solid #344156; - border-radius: 4px; + background-color: #292C2F; + border: 1px solid #494D52; + border-radius: 10px; padding: 3px; - selection-background-color: #182C4A; + selection-background-color: #3A4248; } QAbstractSpinBox::up-button, QAbstractSpinBox::down-button { - background-color: #171F2B; + background-color: #292C2F; border: none; width: 16px; } QAbstractSpinBox::up-button:hover, QAbstractSpinBox::down-button:hover { - background-color: #263144; + background-color: #3E4246; } QCheckBox, @@ -240,33 +240,47 @@ QCheckBox::indicator, QRadioButton::indicator { width: 15px; height: 15px; + background-color: #1B1D1F; + border: 1px solid #55595D; + border-radius: 5px; +} + +QCheckBox::indicator:hover, +QRadioButton::indicator:hover { + border-color: #747B81; +} + +QCheckBox::indicator:checked, +QRadioButton::indicator:checked { + background-color: #71808A; + border-color: #89969F; } QSlider::groove:horizontal { - background-color: #202A38; + background-color: #34373A; height: 4px; border-radius: 2px; } QSlider::handle:horizontal { - background-color: #4C8DFF; - border: 2px solid #A9C8F5; + background-color: #7D8991; + border: 2px solid #A8AFB4; width: 12px; margin: -5px 0; border-radius: 7px; } QProgressBar { - background-color: #151C26; - border: 1px solid #293446; - border-radius: 3px; + background-color: #26282B; + border: 1px solid #42464A; + border-radius: 6px; height: 8px; text-align: center; } QProgressBar::chunk { - background-color: #4C8DFF; - border-radius: 3px; + background-color: #71808A; + border-radius: 6px; } QTreeView, @@ -274,8 +288,8 @@ QListView, QListWidget, QTableView, QTableWidget { - background-color: #10151C; - alternate-background-color: #121923; + background-color: #1E2022; + alternate-background-color: #232527; border: none; color: #DCE3EC; show-decoration-selected: 1; @@ -287,7 +301,7 @@ QListWidget::item, QTableView::item, QTableWidget::item { border: 1px solid transparent; - border-radius: 3px; + border-radius: 7px; padding: 3px 5px; } @@ -296,8 +310,8 @@ QListView::item:hover, QListWidget::item:hover, QTableView::item:hover, QTableWidget::item:hover { - background-color: #1A2230; - border-color: #293548; + background-color: #2B2E31; + border-color: #43474B; } QTreeView::item:selected, @@ -305,55 +319,57 @@ QListView::item:selected, QListWidget::item:selected, QTableView::item:selected, QTableWidget::item:selected { - background-color: #172A46; - border-color: #3F78D8; + background-color: #393F44; + border-color: #66737C; color: #FFFFFF; } QHeaderView { - background-color: #111720; + background-color: #202224; } QHeaderView::section { - background-color: #171E29; + background-color: #292C2F; border: none; - border-right: 1px solid #283243; - border-bottom: 1px solid #283243; + border-right: 1px solid #404347; + border-bottom: 1px solid #404347; padding: 5px 7px; color: #98A4B7; font-weight: 600; } QTabWidget::pane { - background-color: #10151C; - border: 1px solid #273141; - border-radius: 0 0 3px 3px; + background-color: #1E2022; + border: 1px solid #3B3E42; + border-radius: 0 0 10px 10px; } QTabBar::tab { - background-color: #111720; + background-color: #202224; border: none; - border-right: 1px solid #232C3A; - border-bottom: 1px solid #273141; + border-right: 1px solid #383B3F; + border-bottom: 1px solid #3B3E42; color: #7F8B9D; min-width: 88px; - padding: 5px 9px; + padding: 5px 10px; + margin: 2px 1px; + border-radius: 8px; } QTabBar::tab:hover { - background-color: #18202B; + background-color: #2B2E31; color: #C8D1DF; } QTabBar::tab:selected { - background-color: #151C26; + background-color: #36393C; color: #F2F5F9; - border-bottom: 2px solid #4C8DFF; + border-bottom: 2px solid #78858E; } QMenuBar#atlasMenuBar { - background-color: #090D12; - border-bottom: 1px solid #202836; + background-color: #141517; + border-bottom: 1px solid #303236; padding: 2px 6px; } @@ -361,31 +377,31 @@ QMenuBar#atlasMenuBar::item { background: transparent; color: #B8C2D0; padding: 5px 9px; - border-radius: 3px; + border-radius: 7px; } QMenuBar#atlasMenuBar::item:selected, QMenuBar#atlasMenuBar::item:pressed { - background-color: #202838; + background-color: #34373A; color: #FFFFFF; } QMenu { - background-color: #171E29; - border: 1px solid #344156; - border-radius: 4px; + background-color: #292C2F; + border: 1px solid #494D52; + border-radius: 10px; padding: 3px; } QMenu::item { background: transparent; - border-radius: 3px; + border-radius: 7px; padding: 5px 30px 5px 8px; color: #DCE3EC; } QMenu::item:selected { - background-color: #172A46; + background-color: #3A3E42; color: #FFFFFF; } @@ -394,13 +410,13 @@ QMenu::item:disabled { } QMenu::separator { - background-color: #2A3444; + background-color: #424549; height: 1px; margin: 5px 8px; } QSplitter::handle { - background-color: #080C11; + background-color: #111214; } QSplitter::handle:horizontal { @@ -412,12 +428,12 @@ QSplitter::handle:vertical { } QSplitter::handle:hover { - background-color: #4C8DFF; + background-color: #71889A; } QStatusBar { - background-color: #090D12; - border-top: 1px solid #202836; + background-color: #141517; + border-top: 1px solid #303236; color: #8490A4; } @@ -431,10 +447,10 @@ QStatusBar { } #statusRenderer { - background-color: #192B22; - border: 1px solid #2C573B; - border-radius: 4px; - color: #8DE2A5; + background-color: #2B2E30; + border: 1px solid #45494D; + border-radius: 8px; + color: #B6BCB8; font-size: 9px; font-weight: 700; padding: 2px 6px; @@ -447,16 +463,16 @@ QStatusBar { } #workspaceBar { - background-color: #10151C; + background-color: #1E2022; border: none; - border-bottom: 1px solid #273141; + border-bottom: 1px solid #3B3E42; spacing: 3px; padding: 2px 5px 2px 0; } #workspaceIdentity { background: transparent; - border-right: 1px solid #2A3444; + border-right: 1px solid #424549; } #workspaceMark { @@ -477,20 +493,20 @@ QStatusBar { #workspaceModeButton { background-color: transparent; border: 1px solid transparent; - border-radius: 3px; + border-radius: 9px; color: #94A0B2; padding: 4px 8px; margin: 0 1px; } #workspaceModeButton:hover { - background-color: #1B2431; + background-color: #303336; color: #DDE4ED; } #workspaceModeButton:checked { - background-color: #17263B; - border-color: #31577F; + background-color: #3A3E42; + border-color: #5E656B; color: #FFFFFF; } @@ -505,65 +521,53 @@ QStatusBar { #workspaceLaunchButton { min-width: 26px; padding: 3px 5px; -} - -#workspaceBuildButton { - background-color: #2C2618; - border-color: #5D4B23; - color: #F5D184; -} - -#workspaceLaunchButton { - background-color: #183020; - border-color: #285A38; - color: #92E6A9; + background-color: #292C2F; + border-color: #45494D; margin-left: 3px; } -#workspaceBuildButton:hover { - background-color: #3A311D; - border-color: #80682D; -} - +#workspaceBuildButton:hover, #workspaceLaunchButton:hover { - background-color: #20412A; - border-color: #3A7A4B; + background-color: #363A3E; + border-color: #5A5F65; } #sceneTabs { - background-color: #0C1117; - border-bottom: 1px solid #273141; + background-color: #191A1C; + border-bottom: 1px solid #3B3E42; } #sceneTabs::tab { - background-color: #111720; - border-right: 1px solid #252E3B; + background-color: #202224; + border-right: 1px solid #3A3D40; color: #7F8B9D; min-width: 112px; padding: 5px 10px; + margin: 2px; + border-radius: 8px; } #sceneTabs::tab:selected { - background-color: #171E29; + background-color: #36393C; color: #F3F6FA; - border-bottom: 2px solid #4CB7D8; + border-bottom: 2px solid #78858E; } #viewportTools { - background-color: #090D12; + background-color: #141517; } #viewportToolbar { - background-color: #111720; - border-bottom: 1px solid #273141; + background-color: #202224; + border-bottom: 1px solid #3B3E42; } #viewportPlaybackButton, #viewportModeButton, #viewportOptionButton, #viewportShadingButton { - background-color: #171E29; - border-color: #283345; + background-color: #292C2F; + border-color: #414549; min-width: 25px; min-height: 22px; padding: 3px 5px; @@ -573,25 +577,25 @@ QStatusBar { #viewportModeButton:hover, #viewportOptionButton:hover, #viewportShadingButton:hover { - background-color: #222C3C; - border-color: #46536A; + background-color: #363A3E; + border-color: #5A5F65; } #viewportModeButton:checked, #viewportShadingButton:checked { - background-color: #172A46; - border-color: #4C8DFF; + background-color: #3A4248; + border-color: #6F7B84; } #viewportFpsLabel { - color: #73C58A; + color: #9CA5A0; font-size: 10px; font-weight: 650; } #viewportShortcutHint { - background-color: #090D12; - border-top: 1px solid #202836; + background-color: #141517; + border-top: 1px solid #303236; color: #68758A; font-size: 10px; padding: 3px 7px; @@ -601,17 +605,17 @@ QStatusBar { #materialEditorHeader, #postProcessingToolbar, #workspaceToolbar { - background-color: #131922; - border-bottom: 1px solid #283243; + background-color: #232527; + border-bottom: 1px solid #404347; padding: 3px; } #panelAddButton, #materialSaveButton, #workspaceApplyButton { - background-color: #172A46; - border-color: #35628F; - color: #DCE9FA; + background-color: #303438; + border-color: #4C5257; + color: #D8DBDE; } #panelMoreButton, @@ -625,12 +629,12 @@ QStatusBar { #panelMoreButton:hover, #browserNavigationButton:hover, #browserRevealButton:hover { - background-color: #202A38; - border-color: #334056; + background-color: #34373A; + border-color: #484C50; } #contentPathField { - background-color: #0E131A; + background-color: #1B1D1F; color: #8490A4; font-size: 11px; } @@ -640,8 +644,8 @@ QStatusBar { } QTreeView#hierarchyTree { - background-color: #10151C; - border-top: 1px solid #202836; + background-color: #1E2022; + border-top: 1px solid #303236; padding: 5px 3px; } @@ -651,32 +655,32 @@ QTreeView#hierarchyTree::item { } QTreeView#hierarchyTree::item:selected { - background-color: #172A46; - border-left: 2px solid #6BA3FF; + background-color: #343C43; + border-left: 2px solid #8498A8; } QListView#contentGrid { - background-color: #0D1218; - border-top: 1px solid #202836; + background-color: #1A1C1E; + border-top: 1px solid #303236; padding: 6px; } QListView#contentGrid::item { - background-color: #121923; - border: 1px solid #202A38; - border-radius: 4px; + background-color: #232527; + border: 1px solid #34373A; + border-radius: 11px; padding: 7px; color: #BCC6D4; } QListView#contentGrid::item:hover { - background-color: #182130; - border-color: #3A465A; + background-color: #2E3134; + border-color: #4B5055; } QListView#contentGrid::item:selected { - background-color: #17283F; - border-color: #4C8DFF; + background-color: #393F44; + border-color: #66737C; color: #FFFFFF; } @@ -684,21 +688,21 @@ QScrollArea#inspectorScroll, #inspectorContent, #materialEditorBody, #postProcessingBody { - background-color: #10151C; + background-color: #1E2022; border: none; } #inspectorHeader { - background-color: #141B25; - border: 1px solid #273243; - border-radius: 4px; + background-color: #25272A; + border: 1px solid #404347; + border-radius: 12px; padding: 6px; } #inspectorObjectIcon { - background-color: #20283A; - border: 1px solid #38455B; - border-radius: 4px; + background-color: #34373B; + border: 1px solid #4E5257; + border-radius: 10px; padding: 4px; } @@ -712,8 +716,8 @@ QScrollArea#inspectorScroll, #inspectorNameField:hover, #inspectorNameField:focus { - background-color: #10151C; - border-color: #46536A; + background-color: #1E2022; + border-color: #5A5F65; } #inspectorTypeLabel { @@ -723,16 +727,16 @@ QScrollArea#inspectorScroll, } #inspectorComponent { - background-color: #141A23; - border: 1px solid #252F3E; - border-radius: 4px; + background-color: #242628; + border: 1px solid #3B3E41; + border-radius: 11px; margin-top: 3px; } #inspectorComponentHeaderRow { - background-color: #171E29; - border-bottom: 1px solid #252F3E; - border-radius: 4px 4px 0 0; + background-color: #292C2F; + border-bottom: 1px solid #3B3E41; + border-radius: 11px 11px 0 0; } #inspectorComponentHeader { @@ -745,7 +749,7 @@ QScrollArea#inspectorScroll, } #inspectorComponentHeader:hover { - background-color: #1D2634; + background-color: #303337; } #inspectorComponentRemoveButton { @@ -755,12 +759,12 @@ QScrollArea#inspectorScroll, } #inspectorComponentRemoveButton:hover { - background-color: #43212A; - border: 1px solid #713141; + background-color: #3A3031; + border: 1px solid #695556; } #inspectorComponentBody { - background-color: #141A23; + background-color: #242628; padding: 5px; } @@ -777,9 +781,9 @@ QScrollArea#inspectorScroll, #inspectorVectorField, #inspectorColorField, #inspectorNumericField { - background-color: #0F141B; - border: 1px solid #263142; - border-radius: 3px; + background-color: #1B1D1F; + border: 1px solid #404448; + border-radius: 9px; } #inspectorVectorField QDoubleSpinBox, @@ -789,8 +793,8 @@ QScrollArea#inspectorScroll, } #inspectorAxisLabel { - background-color: #202A38; - border-radius: 3px; + background-color: #34373A; + border-radius: 7px; color: #AAB5C5; font-size: 9px; font-weight: 750; @@ -805,14 +809,16 @@ QScrollArea#inspectorScroll, } #inspectorSyncButton[matched="true"] { - background-color: #1C3827; - border-color: #2F6841; - color: #8FE1A6; + background-color: #343936; + border-color: #555F59; + color: #B6BEB9; } #inspectorColorSwatch { - border: 1px solid #4A566A; - border-radius: 4px; + background-color: #292C2F; + border: 1px solid #4D5155; + border-radius: 8px; + padding: 2px; } #inspectorColorText { @@ -822,9 +828,9 @@ QScrollArea#inspectorScroll, } #inspectorNestedGroup { - background-color: #111720; - border: 1px solid #222C3A; - border-radius: 4px; + background-color: #202224; + border: 1px solid #383B3F; + border-radius: 10px; margin: 3px 0; padding: 5px; } @@ -849,21 +855,21 @@ QScrollArea#inspectorScroll, #inspectorOpenAssetButton, #inspectorAddComponentButton { - background-color: #1B2431; - border: 1px dashed #46536A; + background-color: #292C2F; + border: 1px dashed #5A5F65; color: #C7D0DD; padding: 6px; } #inspectorAddComponentButton:hover { - background-color: #17283F; - border-color: #4C8DFF; + background-color: #363A3E; + border-color: #646B70; color: #FFFFFF; } #inspectorAudioControls { - background-color: #111720; - border-radius: 3px; + background-color: #202224; + border-radius: 9px; } #materialEditorTitle, @@ -885,23 +891,37 @@ QScrollArea#inspectorScroll, } #materialPreview { - background-color: #090D12; - border: 1px solid #2B3648; - border-radius: 4px; + background-color: #141517; + border: 1px solid #44484C; + border-radius: 12px; +} + +#materialColorButton { + background-color: #292C2F; + border-color: #45494D; + border-radius: 9px; + color: #C9CDD0; + text-align: left; + padding: 4px 8px; +} + +#materialColorButton:hover { + background-color: #34383B; + border-color: #5A5F65; } #materialTextureSlot { - background-color: #121923; - border: 1px solid #263142; - border-radius: 4px; + background-color: #232527; + border: 1px solid #404448; + border-radius: 10px; padding: 4px; } #materialTexturePreview { - background-color: #0D1218; - border: 1px solid #344156; - border-radius: 4px; - color: #D9825B; + background-color: #1A1C1E; + border: 1px solid #494D52; + border-radius: 9px; + color: #9E897D; font-weight: 750; } @@ -917,13 +937,13 @@ QScrollArea#inspectorScroll, #environmentPages, #environmentWorkspace, #environmentPage { - background-color: #10151C; + background-color: #1E2022; border: none; } QListWidget#environmentCategories { - background-color: #0E131A; - border-right: 1px solid #273141; + background-color: #1B1D1F; + border-right: 1px solid #3B3E42; padding: 5px; } @@ -933,8 +953,8 @@ QListWidget#environmentCategories::item { } QListWidget#environmentCategories::item:selected { - background-color: #172A46; - border-left: 2px solid #6BA3FF; + background-color: #343C43; + border-left: 2px solid #8498A8; } #environmentPageTitle { @@ -948,43 +968,43 @@ QListWidget#environmentCategories::item:selected { } QGroupBox#environmentSection { - background-color: #141A23; - border-color: #273141; + background-color: #242628; + border-color: #3B3E42; } ads--CDockContainerWidget { - background-color: #080C11; + background-color: #111214; } ads--CDockContainerWidget > QSplitter { - background-color: #080C11; + background-color: #111214; } ads--CDockContainerWidget ads--CDockSplitter::handle { - background-color: #080C11; + background-color: #111214; } ads--CDockContainerWidget ads--CDockSplitter::handle:hover { - background-color: #4C8DFF; + background-color: #71889A; } ads--CDockAreaWidget { - background-color: #10151C; - border: 1px solid #202A38; + background-color: #1E2022; + border: 1px solid #34373A; } ads--CDockAreaWidget[focused="true"] { - border-color: #39465B; + border-color: #50545A; } ads--CDockAreaTitleBar { - background-color: #111720; - border-bottom: 1px solid #273141; + background-color: #202224; + border-bottom: 1px solid #3B3E42; min-height: 26px; } ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { - background-color: #151C27; + background-color: #26282B; } #tabsContainerWidget { @@ -994,35 +1014,37 @@ ads--CDockAreaWidget[focused="true"] ads--CDockAreaTitleBar { ads--CTitleBarButton { background: transparent; border: none; - border-radius: 3px; + border-radius: 7px; min-width: 22px; min-height: 22px; padding: 2px; } ads--CTitleBarButton:hover { - background-color: #263144; + background-color: #3E4246; } ads--CDockWidgetTab { - background-color: #111720; + background-color: #202224; border: none; - border-right: 1px solid #252E3B; - border-bottom: 1px solid #273141; + border-right: 1px solid #3A3D40; + border-bottom: 1px solid #3B3E42; padding: 1px 5px; + margin: 2px 1px; + border-radius: 7px; } ads--CDockWidgetTab:hover { - background-color: #18212D; + background-color: #2C2F32; } ads--CDockWidgetTab[activeTab="true"] { - background-color: #171E29; - border-bottom: 2px solid #4C8DFF; + background-color: #373A3D; + border-bottom: 2px solid #78858E; } ads--CDockWidgetTab[focused="true"] { - background-color: #1A2230; + background-color: #2B2E31; } ads--CDockWidgetTab #dockWidgetTabLabel { @@ -1054,40 +1076,41 @@ ads--CDockWidgetTab[focused="true"] #dockWidgetTabLabel { #dockAreaAutoHideButton:hover, #dockAreaMinimizeButton:hover, #tabsMenuButton:hover { - background-color: #2A3444; + background-color: #424549; } ads--CDockWidget { - background-color: #10151C; + background-color: #1E2022; } ads--CAutoHideSideBar, #sideTabsContainerWidget { - background-color: #090D12; + background-color: #141517; } ads--CAutoHideTab { - background-color: #111720; - border: 1px solid #263142; + background-color: #202224; + border: 1px solid #404448; color: #7F8B9D; padding: 4px; + border-radius: 8px; } ads--CAutoHideTab:hover, ads--CAutoHideTab[activeTab="true"] { - background-color: #172A46; - border-color: #3F78D8; + background-color: #393F44; + border-color: #66737C; color: #FFFFFF; } #projectBrowserRoot, #projectBrowserContent { - background-color: #0D1117; + background-color: #18191B; } #projectSidebar { - background-color: #0A0E13; - border-right: 1px solid #202836; + background-color: #151618; + border-right: 1px solid #303236; } #projectBrand { @@ -1103,9 +1126,10 @@ ads--CAutoHideTab[activeTab="true"] { } #projectNavSelected { - background-color: #17263B; - border: 1px solid #2F527D; - border-left: 3px solid #6BA3FF; + background-color: #34383C; + border: 1px solid #51575C; + border-left: 3px solid #79868F; + border-radius: 10px; color: #DCE9FA; padding: 6px 9px; text-align: left; @@ -1130,15 +1154,15 @@ ads--CAutoHideTab[activeTab="true"] { } #projectSearch { - background-color: #111720; - border: 1px solid #2A3547; - border-radius: 4px; + background-color: #202224; + border: 1px solid #43474B; + border-radius: 11px; padding: 7px 9px; font-size: 13px; } #projectSearch:focus { - border-color: #4C8DFF; + border-color: #71808A; } #projectList { @@ -1153,26 +1177,26 @@ ads--CAutoHideTab[activeTab="true"] { } #projectRow { - background-color: #141A23; - border: 1px solid #252F3E; - border-radius: 5px; + background-color: #242628; + border: 1px solid #3B3E41; + border-radius: 13px; } #projectRow:hover { - background-color: #18212D; - border-color: #40506A; + background-color: #2C2F32; + border-color: #565B61; } #projectRow[available="false"] { - background-color: #11161D; - border-color: #1D2530; + background-color: #202224; + border-color: #303235; } #projectIcon, #templateIcon { - background-color: #1D2532; - border: 1px solid #334056; - border-radius: 4px; + background-color: #303337; + border: 1px solid #484C50; + border-radius: 10px; } #projectName { @@ -1188,10 +1212,10 @@ ads--CAutoHideTab[activeTab="true"] { } #rendererBadge { - background-color: #1C3527; - border: 1px solid #2C6340; - border-radius: 3px; - color: #8DE2A5; + background-color: #2C302E; + border: 1px solid #494F4B; + border-radius: 8px; + color: #B4BBB6; padding: 3px 7px; font-size: 9px; font-weight: 700; @@ -1203,14 +1227,14 @@ ads--CAutoHideTab[activeTab="true"] { } #projectMoreButton:hover { - background-color: #253044; - border-color: #3B4860; + background-color: #3E4246; + border-color: #51565B; } #projectEmptyState { - background-color: #10151C; - border: 1px dashed #2F3A4D; - border-radius: 5px; + background-color: #1E2022; + border: 1px dashed #484C51; + border-radius: 14px; } #emptyStateTitle { @@ -1220,23 +1244,23 @@ ads--CAutoHideTab[activeTab="true"] { } #createProjectDialog { - background-color: #10151C; + background-color: #1E2022; } QFrame[templateCard="true"] { - background-color: #141A23; - border: 1px solid #293445; - border-radius: 5px; + background-color: #242628; + border: 1px solid #42464A; + border-radius: 13px; } QFrame[templateCard="true"]:hover { - background-color: #1A2230; - border-color: #46536A; + background-color: #2B2E31; + border-color: #5A5F65; } QFrame[templateCard="true"][selected="true"] { - background-color: #17283F; - border-color: #4C8DFF; + background-color: #393F44; + border-color: #66737C; } #templateOption { @@ -1256,31 +1280,31 @@ QFrame[templateCard="true"][selected="true"] { } QPushButton[secondary="true"] { - background-color: #171E29; - border-color: #344156; + background-color: #292C2F; + border-color: #494D52; } QPushButton[secondary="true"]:hover { - background-color: #222C3C; - border-color: #4A5870; + background-color: #363A3E; + border-color: #5D6268; } #projectSettingsDialog, #exportDialog { - background-color: #0D1117; + background-color: #18191B; } #dialogHero { - background-color: #141A23; - border: 1px solid #293445; - border-radius: 5px; + background-color: #242628; + border: 1px solid #42464A; + border-radius: 13px; padding: 6px; } #dialogHeroIcon { - background-color: #15253A; - border: 1px solid #2F527D; - border-radius: 4px; + background-color: #2B3034; + border: 1px solid #50575C; + border-radius: 10px; padding: 6px; } @@ -1296,44 +1320,44 @@ QPushButton[secondary="true"]:hover { } #exportSummary { - background-color: #121923; - border: 1px solid #273141; - border-radius: 4px; + background-color: #232527; + border: 1px solid #3B3E42; + border-radius: 10px; padding: 6px; } #exportLog { - background-color: #090D12; - border-color: #263142; - color: #9CE2AF; + background-color: #141517; + border-color: #404448; + color: #B7BDBC; font-family: "Menlo"; font-size: 10px; } #commandPaletteDialog, #globalSearchDialog { - background-color: #111720; - border: 1px solid #46536A; - border-radius: 5px; + background-color: #202224; + border: 1px solid #5A5F65; + border-radius: 14px; } #commandPaletteSearch, #globalSearchField { - background-color: #0D1218; - border: 1px solid #3A465A; - border-radius: 4px; + background-color: #1A1C1E; + border: 1px solid #505459; + border-radius: 11px; padding: 7px 9px; font-size: 14px; } #commandPaletteSearch:focus, #globalSearchField:focus { - border-color: #6BA3FF; + border-color: #71808A; } #commandPaletteList, #globalSearchResults { - background-color: #111720; + background-color: #202224; border: none; padding: 5px; } diff --git a/editor/styling/icons.cpp b/editor/styling/icons.cpp index eecef77d..7eaadb58 100644 --- a/editor/styling/icons.cpp +++ b/editor/styling/icons.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -211,3 +212,31 @@ QIcon styling::icon(Icon icon, const QColor &color) { } return result; } + +QIcon styling::colorSwatch(const QColor &color, const QSize &size) { + const QSize swatchSize = size.expandedTo(QSize(8, 8)); + QPixmap pixmap(swatchSize); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + const QRectF bounds = QRectF(pixmap.rect()).adjusted(0.5, 0.5, -0.5, -0.5); + painter.setPen(Qt::NoPen); + painter.setBrush(QColor("#D0D0D0")); + painter.drawRoundedRect(bounds, 4.0, 4.0); + painter.save(); + QPainterPath clip; + clip.addRoundedRect(bounds, 4.0, 4.0); + painter.setClipPath(clip); + painter.fillRect(QRectF(bounds.left(), bounds.top(), bounds.width() / 2.0, + bounds.height() / 2.0), + QColor("#8A8A8A")); + painter.fillRect(QRectF(bounds.center().x(), bounds.center().y(), + bounds.width() / 2.0, bounds.height() / 2.0), + QColor("#8A8A8A")); + painter.fillRect(bounds, color); + painter.restore(); + painter.setBrush(Qt::NoBrush); + painter.setPen(QColor("#5B5D60")); + painter.drawRoundedRect(bounds, 4.0, 4.0); + return QIcon(pixmap); +} diff --git a/editor/styling/theme.cpp b/editor/styling/theme.cpp index 7d4a44ee..13440703 100644 --- a/editor/styling/theme.cpp +++ b/editor/styling/theme.cpp @@ -16,12 +16,12 @@ void styling::applyColorPalette(QApplication& app) { QPalette p; - const QColor bg = QColor("#0D1117"); - const QColor panel = QColor("#151B24"); - const QColor panel2 = QColor("#10151C"); + const QColor bg = QColor("#18191B"); + const QColor panel = QColor("#25272A"); + const QColor panel2 = QColor("#1E2022"); const QColor text = QColor("#E7ECF3"); - const QColor mutedText = QColor("#8490A4"); - const QColor accent = QColor("#4C8DFF"); + const QColor mutedText = QColor("#8D9094"); + const QColor accent = QColor("#71808A"); p.setColor(QPalette::Window, bg); p.setColor(QPalette::WindowText, text); @@ -30,14 +30,14 @@ void styling::applyColorPalette(QApplication& app) { p.setColor(QPalette::ToolTipBase, panel2); p.setColor(QPalette::ToolTipText, text); p.setColor(QPalette::Text, text); - p.setColor(QPalette::Button, QColor("#1A2230")); + p.setColor(QPalette::Button, QColor("#2B2E31")); p.setColor(QPalette::ButtonText, text); p.setColor(QPalette::BrightText, QColor("#FFFFFF")); - p.setColor(QPalette::Light, QColor("#364154")); - p.setColor(QPalette::Midlight, QColor("#2A3444")); - p.setColor(QPalette::Mid, QColor("#222B39")); - p.setColor(QPalette::Dark, QColor("#090C11")); - p.setColor(QPalette::Shadow, QColor("#05070A")); + p.setColor(QPalette::Light, QColor("#505357")); + p.setColor(QPalette::Midlight, QColor("#424549")); + p.setColor(QPalette::Mid, QColor("#34373A")); + p.setColor(QPalette::Dark, QColor("#141517")); + p.setColor(QPalette::Shadow, QColor("#0D0E0F")); p.setColor(QPalette::Highlight, accent); p.setColor(QPalette::HighlightedText, QColor("#FFFFFF")); p.setColor(QPalette::PlaceholderText, mutedText); @@ -45,9 +45,9 @@ void styling::applyColorPalette(QApplication& app) { p.setColor(QPalette::Disabled, QPalette::WindowText, QColor("#566174")); p.setColor(QPalette::Disabled, QPalette::Text, QColor("#566174")); p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#566174")); - p.setColor(QPalette::Disabled, QPalette::Button, QColor("#131922")); - p.setColor(QPalette::Disabled, QPalette::Base, QColor("#11161D")); - p.setColor(QPalette::Disabled, QPalette::Highlight, QColor("#213958")); + p.setColor(QPalette::Disabled, QPalette::Button, QColor("#232527")); + p.setColor(QPalette::Disabled, QPalette::Base, QColor("#202224")); + p.setColor(QPalette::Disabled, QPalette::Highlight, QColor("#3A4146")); app.setPalette(p); } diff --git a/editor/views/editor/editor.cpp b/editor/views/editor/editor.cpp index c59a548c..a0229f9a 100644 --- a/editor/views/editor/editor.cpp +++ b/editor/views/editor/editor.cpp @@ -89,44 +89,44 @@ constexpr auto DockStateKey = "docking/state/v9"; QIcon commandIcon(const QString &name) { const QString command = name.toLower(); if (command.contains("save")) - return styling::icon(styling::Icon::FloppyDisk, "#D9A441"); + return styling::icon(styling::Icon::FloppyDisk, "#A1957D"); if (command.contains("open")) - return styling::icon(styling::Icon::FolderOpen, "#4CB7D8"); + return styling::icon(styling::Icon::FolderOpen, "#7E929C"); if (command.contains("new") || command.contains("create") || command.contains("add")) - return styling::icon(styling::Icon::Plus, "#6BA3FF"); + return styling::icon(styling::Icon::Plus, "#8498A8"); if (command.contains("export")) - return styling::icon(styling::Icon::Export, "#4CB7D8"); + return styling::icon(styling::Icon::Export, "#7E929C"); if (command.contains("build")) - return styling::icon(styling::Icon::Package, "#D9A441"); + return styling::icon(styling::Icon::Package, "#A1957D"); if (command.contains("run") || command.contains("play")) - return styling::icon(styling::Icon::RocketLaunch, "#5EBB78"); + return styling::icon(styling::Icon::RocketLaunch, "#849589"); if (command.contains("stop")) - return styling::icon(styling::Icon::Stop, "#D86470"); + return styling::icon(styling::Icon::Stop, "#A17F7F"); if (command.contains("reload") || command.contains("refresh") || command.contains("undo")) - return styling::icon(styling::Icon::ArrowCounterClockwise, "#4CB7D8"); + return styling::icon(styling::Icon::ArrowCounterClockwise, "#7E929C"); if (command.contains("redo")) - return styling::icon(styling::Icon::ArrowClockwise, "#4CB7D8"); + return styling::icon(styling::Icon::ArrowClockwise, "#7E929C"); if (command.contains("settings")) - return styling::icon(styling::Icon::Gear, "#6BA3FF"); + return styling::icon(styling::Icon::Gear, "#8498A8"); if (command.contains("find") || command.contains("search") || command.contains("palette")) - return styling::icon(styling::Icon::MagnifyingGlass, "#4CB7D8"); + return styling::icon(styling::Icon::MagnifyingGlass, "#7E929C"); if (command.contains("screenshot")) - return styling::icon(styling::Icon::Camera, "#D9825B"); + return styling::icon(styling::Icon::Camera, "#9E897D"); if (command.contains("delete") || command.contains("remove")) - return styling::icon(styling::Icon::Trash, "#D86470"); + return styling::icon(styling::Icon::Trash, "#A17F7F"); if (command.contains("layout") || command.contains("window")) - return styling::icon(styling::Icon::Layout, "#6BA3FF"); + return styling::icon(styling::Icon::Layout, "#8498A8"); if (command.contains("close") || command.contains("quit")) - return styling::icon(styling::Icon::Close, "#D86470"); + return styling::icon(styling::Icon::Close, "#A17F7F"); if (command.contains("camera")) - return styling::icon(styling::Icon::Camera, "#D9825B"); + return styling::icon(styling::Icon::Camera, "#9E897D"); if (command.contains("light")) - return styling::icon(styling::Icon::Lightbulb, "#D9A441"); + return styling::icon(styling::Icon::Lightbulb, "#A1957D"); if (command.contains("object")) - return styling::icon(styling::Icon::Cube, "#6BA3FF"); + return styling::icon(styling::Icon::Cube, "#8498A8"); return {}; } @@ -307,7 +307,7 @@ void EditorWindow::setupMenus() { addCommand(fileMenu, "Open Scene…", "Meta+O", [this] { openScene(); }); auto *saveAction = fileMenu->addAction("Save Scene"); saveAction->setIcon( - styling::icon(styling::Icon::FloppyDisk, "#D9A441")); + styling::icon(styling::Icon::FloppyDisk, "#A1957D")); saveAction->setShortcut(QKeySequence::Save); saveAction->setShortcutContext(Qt::ApplicationShortcut); connect(saveAction, &QAction::triggered, this, [this] { @@ -340,7 +340,7 @@ void EditorWindow::setupMenus() { auto *editMenu = menuBar()->addMenu("Edit"); auto *undoAction = editMenu->addAction("Undo"); undoAction->setIcon( - styling::icon(styling::Icon::ArrowCounterClockwise, "#4CB7D8")); + styling::icon(styling::Icon::ArrowCounterClockwise, "#7E929C")); undoAction->setShortcut(QKeySequence::Undo); undoAction->setShortcutContext(Qt::ApplicationShortcut); connect(undoAction, &QAction::triggered, this, [this] { @@ -356,7 +356,7 @@ void EditorWindow::setupMenus() { }); auto *redoAction = editMenu->addAction("Redo"); redoAction->setIcon( - styling::icon(styling::Icon::ArrowClockwise, "#4CB7D8")); + styling::icon(styling::Icon::ArrowClockwise, "#7E929C")); redoAction->setShortcut(QKeySequence::Redo); redoAction->setShortcutContext(Qt::ApplicationShortcut); connect(redoAction, &QAction::triggered, this, [this] { @@ -481,7 +481,7 @@ void EditorWindow::setupMenus() { viewMenu = menuBar()->addMenu("View"); auto *resetLayoutAction = viewMenu->addAction("Reset Layout"); resetLayoutAction->setIcon( - styling::icon(styling::Icon::Layout, "#6BA3FF")); + styling::icon(styling::Icon::Layout, "#8498A8")); connect(resetLayoutAction, &QAction::triggered, this, [this] { if (coreManager != nullptr && !defaultDockState.isEmpty()) { restoringLayout = true; @@ -564,7 +564,7 @@ void EditorWindow::setupMenus() { QStringLiteral("Atlas Engine %1\nby Neutral Software") .arg(QStringLiteral(ATLAS_VERSION))); }); - aboutAction->setIcon(styling::icon(styling::Icon::Info, "#4CB7D8")); + aboutAction->setIcon(styling::icon(styling::Icon::Info, "#7E929C")); aboutAction->setMenuRole(QAction::AboutRole); } @@ -595,7 +595,7 @@ void EditorWindow::setupDocks() { .title = "Workspace", .widget = workspaceStack, .area = EditorDockArea::Center, - .icon = styling::icon(styling::Icon::CubeFocus, "#4CB7D8")}); + .icon = styling::icon(styling::Icon::CubeFocus, "#7E929C")}); workspaceDock->setFeature(ads::CDockWidget::NoTab, true); hierarchyPanel = new HierarchyPanel(viewportPanel); @@ -604,7 +604,7 @@ void EditorWindow::setupDocks() { .title = "Scene", .widget = hierarchyPanel, .area = EditorDockArea::Left, - .icon = styling::icon(styling::Icon::TreeStructure, "#6BA3FF")}); + .icon = styling::icon(styling::Icon::TreeStructure, "#8498A8")}); inspectorPanel = new InspectorPanel(viewportPanel, projectFile); auto *inspectorDock = dockManager->addPanel( @@ -612,7 +612,7 @@ void EditorWindow::setupDocks() { .title = "Inspector", .widget = inspectorPanel, .area = EditorDockArea::Right, - .icon = styling::icon(styling::Icon::SlidersHorizontal, "#D9A441")}); + .icon = styling::icon(styling::Icon::SlidersHorizontal, "#A1957D")}); contentBrowser = new ContentBrowserPanel(projectFile); auto *contentDock = dockManager->addPanel( @@ -620,7 +620,7 @@ void EditorWindow::setupDocks() { .title = "Content Browser", .widget = contentBrowser, .area = EditorDockArea::Bottom, - .icon = styling::icon(styling::Icon::FolderOpen, "#4CB7D8")}); + .icon = styling::icon(styling::Icon::FolderOpen, "#7E929C")}); workspaceDock->setAsCurrentTab(); defaultDockState = coreManager->saveState(DockStateVersion); @@ -678,12 +678,12 @@ void EditorWindow::setupDocks() { }); action->setIcon(index == 0 ? styling::icon(styling::Icon::CubeFocus, - "#4CB7D8") + "#7E929C") : index == 1 ? styling::icon(styling::Icon::Material, - "#D9A441") + "#A1957D") : styling::icon(styling::Icon::FilmStrip, - "#5EBB78")); + "#849589")); } } @@ -766,9 +766,9 @@ void EditorWindow::setupWorkspaceBar() { connect(button, &QToolButton::clicked, this, [this, index] { activateWorkspace(index); }); }; - addMode("Scene", styling::Icon::CubeFocus, "#4CB7D8", 0, true); - addMode("Shading", styling::Icon::Material, "#D9A441", 1); - addMode("Post-Processing", styling::Icon::FilmStrip, "#5EBB78", 2); + addMode("Scene", styling::Icon::CubeFocus, "#7E929C", 0, true); + addMode("Shading", styling::Icon::Material, "#A1957D", 1); + addMode("Post-Processing", styling::Icon::FilmStrip, "#849589", 2); auto *spacer = new QWidget(bar); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -776,7 +776,7 @@ void EditorWindow::setupWorkspaceBar() { auto *save = new QToolButton(bar); save->setObjectName("workspaceUtilityButton"); - save->setIcon(styling::icon(styling::Icon::FloppyDisk, "#D9A441")); + save->setIcon(styling::icon(styling::Icon::FloppyDisk, "#A1957D")); save->setToolTip("Save Scene"); bar->addWidget(save); connect(save, &QToolButton::clicked, this, [this] { @@ -788,7 +788,7 @@ void EditorWindow::setupWorkspaceBar() { auto *build = new QToolButton(bar); build->setObjectName("workspaceBuildButton"); - build->setIcon(styling::icon(styling::Icon::Package, "#D9A441")); + build->setIcon(styling::icon(styling::Icon::Package, "#A1957D")); build->setToolTip("Build Project"); bar->addWidget(build); connect(build, &QToolButton::clicked, this, @@ -796,7 +796,7 @@ void EditorWindow::setupWorkspaceBar() { auto *launch = new QToolButton(bar); launch->setObjectName("workspaceLaunchButton"); - launch->setIcon(styling::icon(styling::Icon::RocketLaunch, "#5EBB78")); + launch->setIcon(styling::icon(styling::Icon::RocketLaunch, "#849589")); launch->setToolTip("Run Project"); bar->addWidget(launch); connect(launch, &QToolButton::clicked, this, @@ -807,7 +807,7 @@ void EditorWindow::setupWorkspaceBar() { auto *runtimeIcon = new QLabel(statusBar()); runtimeIcon->setObjectName("statusRuntimeIcon"); runtimeIcon->setPixmap( - styling::icon(styling::Icon::Check, "#5EBB78").pixmap(14, 14)); + styling::icon(styling::Icon::Check, "#849589").pixmap(14, 14)); auto *renderer = new QLabel(statusBar()); renderer->setObjectName("statusRenderer"); const auto projectInfo = ProjectStore::projectInfo(projectFile); @@ -822,7 +822,7 @@ void EditorWindow::setupWorkspaceBar() { [this, runtimeIcon](bool available) { runtimeIcon->setPixmap(styling::icon( available ? styling::Icon::Check : styling::Icon::Warning, - available ? QColor("#5EBB78") : QColor("#D9A441")) + available ? QColor("#849589") : QColor("#A1957D")) .pixmap(14, 14)); statusBar()->showMessage(available ? "Runtime ready" : "Runtime unavailable", @@ -917,7 +917,7 @@ void EditorWindow::showProjectSettings() { auto *headerIcon = new QLabel(header); headerIcon->setObjectName("dialogHeroIcon"); headerIcon->setPixmap( - styling::icon(styling::Icon::Gear, "#6BA3FF").pixmap(28, 28)); + styling::icon(styling::Icon::Gear, "#8498A8").pixmap(28, 28)); auto *headerCopy = new QVBoxLayout(); auto *headerTitle = new QLabel("Project Settings", header); headerTitle->setObjectName("dialogHeroTitle"); @@ -944,7 +944,7 @@ void EditorWindow::showProjectSettings() { tabs->addTab(page, styling::icon(icon, color), name); return form; }; - auto *general = addPage("General", styling::Icon::Gear, "#6BA3FF"); + auto *general = addPage("General", styling::Icon::Gear, "#8498A8"); auto *defaultScene = new QComboBox(&dialog); QDirIterator sceneIterator(QFileInfo(projectFile).absolutePath(), {"*.ascene"}, QDir::Files, @@ -982,7 +982,7 @@ void EditorWindow::showProjectSettings() { general->addRow("Window height", windowHeight); general->addRow(QString(), fullscreen); auto *rendering = - addPage("Rendering", styling::Icon::Aperture, "#D9825B"); + addPage("Rendering", styling::Icon::Aperture, "#9E897D"); auto *renderer = new QComboBox(&dialog); renderer->addItems({"PBR", "PBR + DDGI", "Path Tracing"}); renderer->setCurrentText(settings.value("project/renderer", "PBR").toString()); @@ -991,25 +991,25 @@ void EditorWindow::showProjectSettings() { frameLimit->setValue(settings.value("project/frameLimit", 0).toInt()); rendering->addRow("Renderer", renderer); rendering->addRow("Frame limit (0 = unlimited)", frameLimit); - auto *physics = addPage("Physics", styling::Icon::Wrench, "#D9A441"); + auto *physics = addPage("Physics", styling::Icon::Wrench, "#A1957D"); auto *gravity = new QLineEdit(settings.value("project/gravity", "0, -9.81, 0").toString(), &dialog); auto *fixedStep = new QLineEdit(settings.value("project/fixedStep", "0.0166667").toString(), &dialog); physics->addRow("Gravity", gravity); physics->addRow("Fixed timestep", fixedStep); auto *input = - addPage("Input", styling::Icon::GameController, "#5EBB78"); + addPage("Input", styling::Icon::GameController, "#849589"); auto *inputMap = new QLineEdit(settings.value("project/inputMap", "input.json").toString(), &dialog); auto *controller = new QComboBox(&dialog); controller->addItems({"Automatic", "Keyboard + Mouse", "Gamepad"}); controller->setCurrentText(settings.value("project/controller", "Automatic").toString()); input->addRow("Input map", inputMap); input->addRow("Primary controller", controller); - auto *build = addPage("Build & Run", styling::Icon::Package, "#D9A441"); + auto *build = addPage("Build & Run", styling::Icon::Package, "#A1957D"); auto *buildCommand = new QLineEdit(settings.value("project/buildCommand", "atlas pack --backend METAL").toString(), &dialog); auto *runCommand = new QLineEdit(settings.value("project/runCommand", "atlas run project.atlas").toString(), &dialog); build->addRow("Build command", buildCommand); build->addRow("Run command", runCommand); - auto *editor = addPage("Editor", styling::Icon::Layout, "#4CB7D8"); + auto *editor = addPage("Editor", styling::Icon::Layout, "#7E929C"); auto *autosave = new QSpinBox(&dialog); autosave->setRange(0, 120); autosave->setValue(settings.value("project/autosaveMinutes", 5).toInt()); @@ -1017,7 +1017,7 @@ void EditorWindow::showProjectSettings() { editor->addRow("Autosave interval (minutes)", autosave); editor->addRow("Transform snapping", snap); auto *packaging = - addPage("Packaging", styling::Icon::Export, "#6BA3FF"); + addPage("Packaging", styling::Icon::Export, "#8498A8"); auto *identifier = new QLineEdit( settings.value("project/bundleIdentifier", "org.atlasengine." + projectName.toLower().replace(' ', '-')) @@ -1036,7 +1036,7 @@ void EditorWindow::showProjectSettings() { auto *buttons = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Save, &dialog); buttons->button(QDialogButtonBox::Save) - ->setIcon(styling::icon(styling::Icon::FloppyDisk, "#D9A441")); + ->setIcon(styling::icon(styling::Icon::FloppyDisk, "#A1957D")); layout->addWidget(buttons); connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); @@ -1115,7 +1115,7 @@ void EditorWindow::showExportDialog() { auto *headerIcon = new QLabel(header); headerIcon->setObjectName("dialogHeroIcon"); headerIcon->setPixmap( - styling::icon(styling::Icon::Export, "#5EBB78").pixmap(28, 28)); + styling::icon(styling::Icon::Export, "#849589").pixmap(28, 28)); auto *headerCopy = new QVBoxLayout(); auto *headerTitle = new QLabel("Export Project", header); headerTitle->setObjectName("dialogHeroTitle"); @@ -1159,7 +1159,7 @@ void EditorWindow::showExportDialog() { &dialog); auto *browse = new QPushButton("Choose…", &dialog); browse->setIcon( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); + styling::icon(styling::Icon::FolderOpen, "#7E929C")); auto *outputRow = new QWidget(&dialog); auto *outputLayout = new QHBoxLayout(outputRow); outputLayout->setContentsMargins(0, 0, 0, 0); @@ -1188,10 +1188,10 @@ void EditorWindow::showExportDialog() { auto *buttons = new QDialogButtonBox(QDialogButtonBox::Cancel, &dialog); auto *exportButton = buttons->addButton("Export", QDialogButtonBox::AcceptRole); exportButton->setIcon( - styling::icon(styling::Icon::RocketLaunch, "#5EBB78")); + styling::icon(styling::Icon::RocketLaunch, "#849589")); auto *revealButton = buttons->addButton("Reveal Export", QDialogButtonBox::ActionRole); revealButton->setIcon( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); + styling::icon(styling::Icon::FolderOpen, "#7E929C")); revealButton->setEnabled(false); layout->addWidget(buttons); connect(browse, &QPushButton::clicked, &dialog, [&dialog, output] { @@ -1434,7 +1434,7 @@ void EditorWindow::showGlobalSearch() { continue; auto *item = new QListWidgetItem( QStringLiteral("Asset %1").arg(relative), results); - item->setIcon(styling::icon(styling::Icon::File, "#4CB7D8")); + item->setIcon(styling::icon(styling::Icon::File, "#7E929C")); item->setToolTip(path); item->setData(SearchKindRole, 0); item->setData(SearchValueRole, path); @@ -1454,7 +1454,7 @@ void EditorWindow::showGlobalSearch() { auto *item = new QListWidgetItem( QStringLiteral("Object %1").arg(name), results); item->setIcon( - styling::icon(styling::Icon::Cube, "#6BA3FF")); + styling::icon(styling::Icon::Cube, "#8498A8")); item->setToolTip(object.value("type").toString()); item->setData(SearchKindRole, 1); item->setData(SearchValueRole, id); diff --git a/editor/views/editor/hierarchy.cpp b/editor/views/editor/hierarchy.cpp index 30bf9366..27c08682 100644 --- a/editor/views/editor/hierarchy.cpp +++ b/editor/views/editor/hierarchy.cpp @@ -44,24 +44,24 @@ constexpr int ObjectTypeRole = Qt::UserRole + 2; QIcon hierarchyIcon(QWidget *, const QString &type) { const QString normalized = type.toLower(); if (normalized == "scene") - return styling::icon(styling::Icon::CubeFocus, "#4CB7D8"); + return styling::icon(styling::Icon::CubeFocus, "#7E929C"); if (normalized == "compound" || normalized == "group") return styling::icon(styling::Icon::Folder, "#8490A4"); if (normalized == "camera") - return styling::icon(styling::Icon::Camera, "#D9825B"); + return styling::icon(styling::Icon::Camera, "#9E897D"); if (normalized == "environment") - return styling::icon(styling::Icon::Globe, "#4CB7D8"); + return styling::icon(styling::Icon::Globe, "#7E929C"); if (normalized.contains("light") || normalized == "sun") - return styling::icon(styling::Icon::Lightbulb, "#D9A441"); + return styling::icon(styling::Icon::Lightbulb, "#A1957D"); if (normalized == "terrain" || normalized == "landscape") - return styling::icon(styling::Icon::Mountains, "#5EBB78"); + return styling::icon(styling::Icon::Mountains, "#849589"); if (normalized == "particleemitter" || normalized == "particles") - return styling::icon(styling::Icon::Sparkle, "#6BA3FF"); + return styling::icon(styling::Icon::Sparkle, "#8498A8"); if (normalized == "model") - return styling::icon(styling::Icon::Cube, "#4CB7D8"); + return styling::icon(styling::Icon::Cube, "#7E929C"); if (normalized == "sphere") - return styling::icon(styling::Icon::Sphere, "#6BA3FF"); - return styling::icon(styling::Icon::Cube, "#6BA3FF"); + return styling::icon(styling::Icon::Sphere, "#8498A8"); + return styling::icon(styling::Icon::Cube, "#8498A8"); } QString objectSignature(const QJsonArray &objects) { @@ -94,7 +94,7 @@ HierarchyPanel::HierarchyPanel(ViewportPanel *viewport, QWidget *parent) addButton = new QToolButton(toolbar); addButton->setObjectName("panelAddButton"); - addButton->setIcon(styling::icon(styling::Icon::Plus, "#6BA3FF")); + addButton->setIcon(styling::icon(styling::Icon::Plus, "#8498A8")); addButton->setText("Add"); addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addButton->setPopupMode(QToolButton::InstantPopup); @@ -432,15 +432,15 @@ void HierarchyPanel::showContextMenu(const QPoint &position) { } if (index.isValid() && selectedObjectId() >= 0) { menu.addSeparator(); - menu.addAction(styling::icon(styling::Icon::Crosshair, "#4CB7D8"), + menu.addAction(styling::icon(styling::Icon::Crosshair, "#7E929C"), "Focus", this, &HierarchyPanel::focusSelectedObject); - menu.addAction(styling::icon(styling::Icon::File, "#6BA3FF"), + menu.addAction(styling::icon(styling::Icon::File, "#8498A8"), "Rename", this, &HierarchyPanel::renameSelectedObject); - menu.addAction(styling::icon(styling::Icon::TreeStructure, "#5EBB78"), + menu.addAction(styling::icon(styling::Icon::TreeStructure, "#849589"), "Move to Scene Root", this, &HierarchyPanel::moveSelectedObjectToRoot); menu.addSeparator(); - menu.addAction(styling::icon(styling::Icon::Trash, "#D86470"), + menu.addAction(styling::icon(styling::Icon::Trash, "#A17F7F"), "Delete", this, &HierarchyPanel::deleteSelectedObject); } menu.exec(treeView->viewport()->mapToGlobal(position)); diff --git a/editor/views/editor/inspector.cpp b/editor/views/editor/inspector.cpp index 0efbe61f..c5294485 100644 --- a/editor/views/editor/inspector.cpp +++ b/editor/views/editor/inspector.cpp @@ -174,32 +174,32 @@ bool isColorProperty(const QString &name, const QJsonArray &array) { QIcon inspectorIcon(QWidget *, const QString &type) { const QString normalized = type.toLower(); if (normalized == "folder") - return styling::icon(styling::Icon::Folder, "#4CB7D8"); + return styling::icon(styling::Icon::Folder, "#7E929C"); if (normalized.contains("camera")) - return styling::icon(styling::Icon::Camera, "#D9825B"); + return styling::icon(styling::Icon::Camera, "#9E897D"); if (normalized.contains("environment") || normalized.contains("atmosphere")) - return styling::icon(styling::Icon::Globe, "#4CB7D8"); + return styling::icon(styling::Icon::Globe, "#7E929C"); if (normalized.contains("light") || normalized == "sun") - return styling::icon(styling::Icon::Lightbulb, "#D9A441"); + return styling::icon(styling::Icon::Lightbulb, "#A1957D"); if (normalized.contains("terrain")) - return styling::icon(styling::Icon::Mountains, "#5EBB78"); + return styling::icon(styling::Icon::Mountains, "#849589"); if (normalized.contains("particle")) - return styling::icon(styling::Icon::Sparkle, "#6BA3FF"); + return styling::icon(styling::Icon::Sparkle, "#8498A8"); if (normalized.contains("audio") || normalized == "wav" || normalized == "mp3" || normalized == "ogg" || normalized == "flac") - return styling::icon(styling::Icon::MusicNote, "#5EBB78"); + return styling::icon(styling::Icon::MusicNote, "#849589"); if (normalized.contains("material")) - return styling::icon(styling::Icon::Material, "#D9825B"); + return styling::icon(styling::Icon::Material, "#9E897D"); if (normalized.contains("script") || normalized == "ts" || normalized == "js") - return styling::icon(styling::Icon::FileCode, "#4CB7D8"); + return styling::icon(styling::Icon::FileCode, "#7E929C"); if (normalized.contains("rigidbody") || normalized.contains("joint")) - return styling::icon(styling::Icon::Wrench, "#D9A441"); + return styling::icon(styling::Icon::Wrench, "#A1957D"); if (normalized == "sphere") - return styling::icon(styling::Icon::Sphere, "#6BA3FF"); - return styling::icon(styling::Icon::Cube, "#6BA3FF"); + return styling::icon(styling::Icon::Sphere, "#8498A8"); + return styling::icon(styling::Icon::Cube, "#8498A8"); } QString componentTitle(const QString &type) { @@ -611,7 +611,7 @@ void addSyncPicker(QHBoxLayout *layout, const QString &path, auto *button = new QToolButton(parent); button->setObjectName("inspectorSyncButton"); button->setIcon( - styling::icon(styling::Icon::ArrowCounterClockwise, "#5EBB78")); + styling::icon(styling::Icon::ArrowCounterClockwise, "#849589")); button->setToolTip("Match this value with another property"); button->setPopupMode(QToolButton::InstantPopup); auto showMatch = [button, valueEditor](const QString &name) { @@ -792,12 +792,8 @@ QWidget *colorField(const QJsonArray &value, const PropertyChanged &changed, auto *text = new QLineEdit(field); text->setObjectName("inspectorColorText"); auto updateDisplay = [swatch, text](const QColor &next) { - swatch->setStyleSheet( - QStringLiteral("background-color: rgba(%1,%2,%3,%4);") - .arg(next.red()) - .arg(next.green()) - .arg(next.blue()) - .arg(next.alpha())); + swatch->setIcon(styling::colorSwatch(next, QSize(22, 14))); + swatch->setIconSize(QSize(22, 14)); text->setText(next.name(QColor::HexArgb).toUpper()); }; updateDisplay(color); @@ -975,7 +971,7 @@ void addPropertyRows(QVBoxLayout *layout, const QJsonObject &properties, auto *add = new QToolButton(heading); add->setObjectName("inspectorArrayButton"); add->setIcon( - styling::icon(styling::Icon::Plus, "#6BA3FF")); + styling::icon(styling::Icon::Plus, "#8498A8")); add->setToolTip("Add item"); add->setToolTip(QStringLiteral("Add %1").arg(humanize(key))); headingLayout->addWidget(title, 1); @@ -1007,7 +1003,7 @@ void addPropertyRows(QVBoxLayout *layout, const QJsonObject &properties, auto *remove = new QToolButton(itemHeading); remove->setObjectName("inspectorArrayButton"); remove->setIcon( - styling::icon(styling::Icon::Trash, "#D86470")); + styling::icon(styling::Icon::Trash, "#A17F7F")); remove->setToolTip("Remove item"); remove->setToolTip("Remove"); itemHeadingLayout->addWidget(itemTitle, 1); @@ -1169,7 +1165,7 @@ QFrame *componentCard(const QString &title, const QJsonObject &properties, auto *removeButton = new QToolButton(headerRow); removeButton->setObjectName("inspectorComponentRemoveButton"); removeButton->setIcon( - styling::icon(styling::Icon::Trash, "#D86470")); + styling::icon(styling::Icon::Trash, "#A17F7F")); removeButton->setToolTip(QStringLiteral("Remove %1").arg(title)); headerLayout->addWidget(removeButton); QObject::connect(removeButton, &QToolButton::clicked, card, remove); @@ -1514,7 +1510,7 @@ void InspectorPanel::showObject(const QJsonObject &object) { styling::Icon::Play, styling::Icon::Pause, styling::Icon::Stop}; const QList audioColors{ - QColor("#5EBB78"), QColor("#D9A441"), QColor("#D86470")}; + QColor("#849589"), QColor("#A1957D"), QColor("#A17F7F")}; for (int actionIndex = 0; actionIndex < audioActions.size(); ++actionIndex) { const QString &action = audioActions.at(actionIndex); @@ -1538,7 +1534,7 @@ void InspectorPanel::showObject(const QJsonObject &object) { auto *addComponent = new QToolButton(content); addComponent->setObjectName("inspectorAddComponentButton"); addComponent->setIcon( - styling::icon(styling::Icon::Plus, "#6BA3FF")); + styling::icon(styling::Icon::Plus, "#8498A8")); addComponent->setText("Add Component"); addComponent->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addComponent->setPopupMode(QToolButton::InstantPopup); diff --git a/editor/views/editor/materialEditor.cpp b/editor/views/editor/materialEditor.cpp index 1cdb9d75..4bae91be 100644 --- a/editor/views/editor/materialEditor.cpp +++ b/editor/views/editor/materialEditor.cpp @@ -60,14 +60,12 @@ QJsonArray colorJson(const QColor &color) { void displayColor(QPushButton *button, const QColor &color) { button->setProperty("materialColor", color); - button->setText(color.name(QColor::HexRgb).toUpper()); - button->setStyleSheet( - QStringLiteral("background-color: rgba(%1,%2,%3,%4); color: %5;") - .arg(color.red()) - .arg(color.green()) - .arg(color.blue()) - .arg(color.alpha()) - .arg(color.lightnessF() > 0.55 ? "#111111" : "#FFFFFF")); + button->setObjectName("materialColorButton"); + button->setText(color.name(color.alpha() < 255 ? QColor::HexArgb + : QColor::HexRgb) + .toUpper()); + button->setIcon(styling::colorSwatch(color, QSize(18, 18))); + button->setIconSize(QSize(18, 18)); } QDoubleSpinBox *scalarField(double minimum, double maximum, double step, @@ -365,11 +363,11 @@ MaterialEditorPanel::MaterialEditorPanel(ViewportPanel *viewport, auto *saveButton = new QPushButton("Save", header); saveButton->setObjectName("materialSaveButton"); saveButton->setIcon( - styling::icon(styling::Icon::FloppyDisk, "#D9A441")); + styling::icon(styling::Icon::FloppyDisk, "#A1957D")); auto *assignButton = new QPushButton("Assign to Selected", header); assignButton->setObjectName("materialAssignButton"); assignButton->setIcon( - styling::icon(styling::Icon::Assign, "#D9825B")); + styling::icon(styling::Icon::Assign, "#9E897D")); headerLayout->addWidget(titleLabel, 1); headerLayout->addWidget(statusLabel); headerLayout->addWidget(assignButton); @@ -608,10 +606,10 @@ void MaterialEditorPanel::showMaterial() { auto *choose = new QToolButton(row); choose->setText("Choose…"); choose->setIcon( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); + styling::icon(styling::Icon::FolderOpen, "#7E929C")); choose->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); auto *clear = new QToolButton(row); - clear->setIcon(styling::icon(styling::Icon::Close, "#D86470")); + clear->setIcon(styling::icon(styling::Icon::Close, "#A17F7F")); clear->setToolTip("Remove texture"); auto *identity = new QWidget(row); auto *identityLayout = new QVBoxLayout(identity); diff --git a/editor/views/editor/postProcessing.cpp b/editor/views/editor/postProcessing.cpp index 8e321068..1e86d178 100644 --- a/editor/views/editor/postProcessing.cpp +++ b/editor/views/editor/postProcessing.cpp @@ -105,16 +105,16 @@ PostProcessingPanel::PostProcessingPanel(ViewportPanel *viewport, targetSelector->setMinimumWidth(180); auto *addTargetButton = new QToolButton(toolbar); addTargetButton->setIcon( - styling::icon(styling::Icon::Plus, "#6BA3FF")); + styling::icon(styling::Icon::Plus, "#8498A8")); addTargetButton->setText("Target"); addTargetButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); removeTargetButton = new QToolButton(toolbar); removeTargetButton->setText("Remove"); removeTargetButton->setIcon( - styling::icon(styling::Icon::Trash, "#D86470")); + styling::icon(styling::Icon::Trash, "#A17F7F")); auto *applyButton = new QPushButton("Apply to Preview", toolbar); applyButton->setIcon( - styling::icon(styling::Icon::Sparkle, "#5EBB78")); + styling::icon(styling::Icon::Sparkle, "#849589")); statusLabel = new QLabel(toolbar); statusLabel->setObjectName("postProcessingStatus"); toolbarLayout->addWidget(title); @@ -245,7 +245,7 @@ void PostProcessingPanel::rebuildEditor() { effectsTitle->setObjectName("postProcessingSectionTitle"); auto *addEffectButton = new QToolButton(effectsHeading); addEffectButton->setIcon( - styling::icon(styling::Icon::Plus, "#6BA3FF")); + styling::icon(styling::Icon::Plus, "#8498A8")); addEffectButton->setText("Add Effect"); addEffectButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); addEffectButton->setPopupMode(QToolButton::InstantPopup); @@ -258,7 +258,7 @@ void PostProcessingPanel::rebuildEditor() { "film_grain"}; for (const QString &effect : effects) { effectMenu->addAction( - styling::icon(styling::Icon::Sparkle, "#5EBB78"), + styling::icon(styling::Icon::Sparkle, "#849589"), effectTitle(effect), this, [this, effect] { addEffect(effect); }); } @@ -330,19 +330,19 @@ void PostProcessingPanel::rebuildEditor() { auto *moveUp = new QToolButton(actions); moveUp->setText("Move Up"); moveUp->setIcon( - styling::icon(styling::Icon::CaretUp, "#4CB7D8")); + styling::icon(styling::Icon::CaretUp, "#7E929C")); moveUp->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); moveUp->setEnabled(effectIndex > 0); auto *moveDown = new QToolButton(actions); moveDown->setText("Move Down"); moveDown->setIcon( - styling::icon(styling::Icon::CaretDown, "#4CB7D8")); + styling::icon(styling::Icon::CaretDown, "#7E929C")); moveDown->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); moveDown->setEnabled(effectIndex + 1 < effectStack.size()); auto *remove = new QToolButton(actions); remove->setText("Remove Effect"); remove->setIcon( - styling::icon(styling::Icon::Trash, "#D86470")); + styling::icon(styling::Icon::Trash, "#A17F7F")); remove->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); actionsLayout->addStretch(); actionsLayout->addWidget(moveUp); diff --git a/editor/views/editor/viewportTools.cpp b/editor/views/editor/viewportTools.cpp index fd581928..8616c1ce 100644 --- a/editor/views/editor/viewportTools.cpp +++ b/editor/views/editor/viewportTools.cpp @@ -41,25 +41,25 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, playButton = new QToolButton(toolbar); playButton->setObjectName("viewportPlaybackButton"); - playButton->setIcon(styling::icon(styling::Icon::Play, "#5EBB78")); + playButton->setIcon(styling::icon(styling::Icon::Play, "#849589")); playButton->setToolTip("Play"); pauseButton = new QToolButton(toolbar); pauseButton->setObjectName("viewportPlaybackButton"); - pauseButton->setIcon(styling::icon(styling::Icon::Pause, "#D9A441")); + pauseButton->setIcon(styling::icon(styling::Icon::Pause, "#A1957D")); pauseButton->setToolTip("Pause"); stepButton = new QToolButton(toolbar); stepButton->setObjectName("viewportPlaybackButton"); stepButton->setIcon( - styling::icon(styling::Icon::SkipForward, "#4CB7D8")); + styling::icon(styling::Icon::SkipForward, "#7E929C")); stepButton->setToolTip("Step one frame"); stopButton = new QToolButton(toolbar); stopButton->setObjectName("viewportPlaybackButton"); - stopButton->setIcon(styling::icon(styling::Icon::Stop, "#D86470")); + stopButton->setIcon(styling::icon(styling::Icon::Stop, "#A17F7F")); stopButton->setToolTip("Stop and restore the scene"); reloadButton = new QToolButton(toolbar); reloadButton->setObjectName("viewportPlaybackButton"); reloadButton->setIcon( - styling::icon(styling::Icon::ArrowCounterClockwise, "#4C8DFF")); + styling::icon(styling::Icon::ArrowCounterClockwise, "#71889A")); reloadButton->setToolTip("Reload runtime"); playButton->setShortcut(QKeySequence("Ctrl+P")); pauseButton->setShortcut(QKeySequence("Ctrl+Shift+P")); @@ -72,8 +72,8 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, styling::Icon::CursorClick, styling::Icon::ArrowsOutCardinal, styling::Icon::ArrowClockwise, styling::Icon::BoundingBox}; const QList transformColors{ - QColor("#4CB7D8"), QColor("#5EBB78"), QColor("#D9A441"), - QColor("#4C8DFF")}; + QColor("#7E929C"), QColor("#849589"), QColor("#A1957D"), + QColor("#71889A")}; for (int index = 0; index < transformNames.size(); ++index) { auto *button = new QToolButton(toolbar); button->setObjectName("viewportModeButton"); @@ -96,7 +96,7 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, tools->addSpacing(10); spaceButton = new QToolButton(toolbar); spaceButton->setObjectName("viewportOptionButton"); - spaceButton->setIcon(styling::icon(styling::Icon::Globe, "#4CB7D8")); + spaceButton->setIcon(styling::icon(styling::Icon::Globe, "#7E929C")); spaceButton->setToolTip("World transform space · Shift+T"); tools->addWidget(spaceButton); @@ -135,7 +135,7 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, auto *fpsButton = new QToolButton(toolbar); fpsButton->setObjectName("viewportOptionButton"); fpsButton->setIcon( - styling::icon(styling::Icon::Monitor, "#5EBB78")); + styling::icon(styling::Icon::Monitor, "#849589")); fpsButton->setCheckable(true); fpsButton->setChecked(true); fpsButton->setToolTip("Toggle frame rate"); @@ -178,7 +178,7 @@ ViewportTools::ViewportTools(ViewportPanel *viewport, [this](bool local) { spaceButton->setIcon(styling::icon( local ? styling::Icon::Cube : styling::Icon::Globe, - local ? QColor("#4C8DFF") : QColor("#4CB7D8"))); + local ? QColor("#71889A") : QColor("#7E929C"))); spaceButton->setToolTip( local ? "Local transform space · Shift+T" : "World transform space · Shift+T"); diff --git a/editor/views/general/contentBrowser.cpp b/editor/views/general/contentBrowser.cpp index e2aaba9b..85a1bef9 100644 --- a/editor/views/general/contentBrowser.cpp +++ b/editor/views/general/contentBrowser.cpp @@ -99,27 +99,27 @@ class AtlasFileIconProvider : public QFileIconProvider { public: QIcon icon(const QFileInfo &info) const override { if (info.isDir()) - return styling::icon(styling::Icon::Folder, "#4CB7D8"); + return styling::icon(styling::Icon::Folder, "#7E929C"); const QString suffix = info.suffix().toLower(); if (suffix == "ascene") - return styling::icon(styling::Icon::CubeFocus, "#6BA3FF"); + return styling::icon(styling::Icon::CubeFocus, "#8498A8"); if (suffix == "amat" || suffix == "material") - return styling::icon(styling::Icon::Material, "#D9825B"); + return styling::icon(styling::Icon::Material, "#9E897D"); if (suffix == "ts" || suffix == "js" || suffix == "cpp" || suffix == "h" || suffix == "json") - return styling::icon(styling::Icon::FileCode, "#4CB7D8"); + return styling::icon(styling::Icon::FileCode, "#7E929C"); if (suffix == "png" || suffix == "jpg" || suffix == "jpeg" || suffix == "hdr") - return styling::icon(styling::Icon::Image, "#D9A441"); + return styling::icon(styling::Icon::Image, "#A1957D"); if (suffix == "wav" || suffix == "mp3" || suffix == "ogg" || suffix == "flac") - return styling::icon(styling::Icon::MusicNote, "#5EBB78"); + return styling::icon(styling::Icon::MusicNote, "#849589"); return styling::icon(styling::Icon::File, "#8490A4"); } QIcon icon(IconType type) const override { if (type == Folder || type == Drive) - return styling::icon(styling::Icon::Folder, "#4CB7D8"); + return styling::icon(styling::Icon::Folder, "#7E929C"); return styling::icon(styling::Icon::File, "#8490A4"); } }; @@ -174,7 +174,7 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, createButton = new QToolButton(toolbar); createButton->setObjectName("panelAddButton"); - createButton->setIcon(styling::icon(styling::Icon::Plus, "#6BA3FF")); + createButton->setIcon(styling::icon(styling::Icon::Plus, "#8498A8")); createButton->setText("Create"); createButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); createButton->setPopupMode(QToolButton::InstantPopup); @@ -182,7 +182,7 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, revealButton = new QToolButton(toolbar); revealButton->setObjectName("browserRevealButton"); revealButton->setIcon( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); + styling::icon(styling::Icon::FolderOpen, "#7E929C")); revealButton->setToolTip("Reveal in Finder"); moreButton = new QToolButton(toolbar); @@ -231,34 +231,34 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile, layout->addWidget(gridView, 1); auto *createMenu = new QMenu(createButton); - createMenu->addAction(styling::icon(styling::Icon::Folder, "#4CB7D8"), "Folder", + createMenu->addAction(styling::icon(styling::Icon::Folder, "#7E929C"), "Folder", this, &ContentBrowserPanel::createFolder); createMenu->addSeparator(); - createMenu->addAction(styling::icon(styling::Icon::CubeFocus, "#6BA3FF"), "Scene", + createMenu->addAction(styling::icon(styling::Icon::CubeFocus, "#8498A8"), "Scene", this, &ContentBrowserPanel::createScene); - createMenu->addAction(styling::icon(styling::Icon::Material, "#D9825B"), + createMenu->addAction(styling::icon(styling::Icon::Material, "#9E897D"), "Material", this, &ContentBrowserPanel::createMaterial); - createMenu->addAction(styling::icon(styling::Icon::FileCode, "#4CB7D8"), + createMenu->addAction(styling::icon(styling::Icon::FileCode, "#7E929C"), "TypeScript Script", this, &ContentBrowserPanel::createScript); createButton->setMenu(createMenu); auto *moreMenu = new QMenu(moreButton); moreMenu->addAction( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8"), "Open", this, [this] { + styling::icon(styling::Icon::FolderOpen, "#7E929C"), "Open", this, [this] { if (gridView->currentIndex().isValid()) { openIndex(gridView->currentIndex()); } }); - moreMenu->addAction(styling::icon(styling::Icon::File, "#6BA3FF"), + moreMenu->addAction(styling::icon(styling::Icon::File, "#8498A8"), "Rename", this, &ContentBrowserPanel::renameSelection); - moreMenu->addAction(styling::icon(styling::Icon::Trash, "#D86470"), + moreMenu->addAction(styling::icon(styling::Icon::Trash, "#A17F7F"), "Delete", this, &ContentBrowserPanel::deleteSelection); moreMenu->addSeparator(); - moreMenu->addAction(styling::icon(styling::Icon::FolderOpen, "#4CB7D8"), + moreMenu->addAction(styling::icon(styling::Icon::FolderOpen, "#7E929C"), "Reveal in Finder", this, &ContentBrowserPanel::revealSelection); moreMenu->addAction(styling::icon(styling::Icon::FileCode, "#8490A4"), diff --git a/editor/views/general/projectBrowser.cpp b/editor/views/general/projectBrowser.cpp index ca05b82a..0c5924f0 100644 --- a/editor/views/general/projectBrowser.cpp +++ b/editor/views/general/projectBrowser.cpp @@ -126,15 +126,15 @@ class CreateProjectDialog : public QDialog { templateGroup->setExclusive(true); auto* pbr = new TemplateCard( "PBR", "Deferred physically based rendering for most 3D projects.", - styling::Icon::Cube, "#6BA3FF", this); + styling::Icon::Cube, "#8498A8", this); auto* ddgi = new TemplateCard( "PBR + DDGI", "PBR with dynamic diffuse global illumination enabled.", - styling::Icon::Sun, "#D9A441", this); + styling::Icon::Sun, "#A1957D", this); auto* pathTracing = new TemplateCard( "Path Tracing", "Progressive ray-traced lighting for high-fidelity scenes.", - styling::Icon::Aperture, "#D9825B", this); + styling::Icon::Aperture, "#9E897D", this); templateGroup->addButton(pbr->button(), static_cast(AtlasProjectTemplate::Pbr)); templateGroup->addButton( @@ -173,7 +173,7 @@ class CreateProjectDialog : public QDialog { auto* browse = new QPushButton("Browse…", this); browse->setProperty("secondary", true); browse->setIcon( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); + styling::icon(styling::Icon::FolderOpen, "#7E929C")); locationLayout->addWidget(browse); fields->addLayout(locationLayout); root->addLayout(fields); @@ -259,7 +259,7 @@ class ProjectRow : public QFrame { auto* projectIcon = new QLabel(this); projectIcon->setObjectName("projectIcon"); projectIcon->setPixmap( - styling::icon(styling::Icon::GameController, "#6BA3FF") + styling::icon(styling::Icon::GameController, "#8498A8") .pixmap(30, 30)); projectIcon->setFixedSize(36, 36); projectIcon->setAlignment(Qt::AlignCenter); @@ -354,7 +354,7 @@ void ProjectBrowser::setupUi() { auto* projectsNav = new QPushButton("Projects", sidebar); projectsNav->setObjectName("projectNavSelected"); projectsNav->setIcon( - styling::icon(styling::Icon::SquaresFour, "#6BA3FF")); + styling::icon(styling::Icon::SquaresFour, "#8498A8")); projectsNav->setEnabled(false); sidebarLayout->addWidget(projectsNav); sidebarLayout->addStretch(); @@ -382,7 +382,7 @@ void ProjectBrowser::setupUi() { auto* openButton = new QPushButton("Open existing", content); openButton->setProperty("secondary", true); openButton->setIcon( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8")); + styling::icon(styling::Icon::FolderOpen, "#7E929C")); headingLayout->addWidget(openButton); auto* createButton = new QPushButton("New project", content); createButton->setObjectName("primaryAction"); @@ -540,16 +540,16 @@ void ProjectBrowser::showProjectMenu(const QPoint& position) { QMenu menu(this); QAction* open = menu.addAction( - styling::icon(styling::Icon::GameController, "#6BA3FF"), + styling::icon(styling::Icon::GameController, "#8498A8"), "Open project"); open->setEnabled(available); QAction* reveal = menu.addAction( - styling::icon(styling::Icon::FolderOpen, "#4CB7D8"), + styling::icon(styling::Icon::FolderOpen, "#7E929C"), "Show in Finder"); reveal->setEnabled(QFileInfo::exists(QFileInfo(projectFile).absolutePath())); menu.addSeparator(); QAction* remove = menu.addAction( - styling::icon(styling::Icon::Trash, "#D86470"), + styling::icon(styling::Icon::Trash, "#A17F7F"), "Remove from list"); QAction* selected = menu.exec(projectList->viewport()->mapToGlobal(position)); if (selected == open) { diff --git a/editor/views/general/splashScreen.cpp b/editor/views/general/splashScreen.cpp index 19fa1f16..54e7b4e7 100644 --- a/editor/views/general/splashScreen.cpp +++ b/editor/views/general/splashScreen.cpp @@ -112,8 +112,8 @@ SplashScreen::SplashScreen(QWidget *parent) background: transparent; } #splashCard { - background: #111720; - border: 1px solid #344156; + background: #202224; + border: 1px solid #494D52; border-radius: 18px; } #splashTitle { @@ -124,7 +124,7 @@ SplashScreen::SplashScreen(QWidget *parent) } #splashVersion { background: transparent; - color: #6BA3FF; + color: #8498A8; font-size: 14px; font-weight: 700; } @@ -142,12 +142,12 @@ SplashScreen::SplashScreen(QWidget *parent) font-weight: 550; } #splashProgress { - background: #202A38; + background: #34373A; border: none; border-radius: 2px; } #splashProgress::chunk { - background: #4C8DFF; + background: #71889A; border-radius: 2px; } #splashWarning { diff --git a/include/editor/core/themes.h b/include/editor/core/themes.h index fad8eff3..b95a4472 100644 --- a/include/editor/core/themes.h +++ b/include/editor/core/themes.h @@ -9,19 +9,19 @@ inline constexpr const char* DARK_THEME = " font-family: \"Manrope\";\n" " font-size: 12px;\n" " color: #E7ECF3;\n" -" selection-background-color: #3F78D8;\n" +" selection-background-color: #647B8D;\n" " selection-color: #FFFFFF;\n" "}\n" "\n" "QWidget {\n" -" background-color: #0D1117;\n" +" background-color: #18191B;\n" " color: #E7ECF3;\n" "}\n" "\n" "QMainWindow,\n" "QDialog,\n" "QFrame {\n" -" background-color: #0D1117;\n" +" background-color: #18191B;\n" "}\n" "\n" "QLabel {\n" @@ -33,17 +33,17 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QToolTip {\n" -" background-color: #202838;\n" +" background-color: #34373A;\n" " color: #F7F9FC;\n" -" border: 1px solid #3A465A;\n" -" border-radius: 3px;\n" +" border: 1px solid #505459;\n" +" border-radius: 8px;\n" " padding: 4px 6px;\n" "}\n" "\n" "QGroupBox {\n" -" background-color: #141A23;\n" -" border: 1px solid #252E3C;\n" -" border-radius: 4px;\n" +" background-color: #242628;\n" +" border: 1px solid #3A3D40;\n" +" border-radius: 10px;\n" " margin-top: 14px;\n" " padding: 8px;\n" " color: #F1F4F8;\n" @@ -56,17 +56,17 @@ inline constexpr const char* DARK_THEME = " left: 9px;\n" " padding: 0 6px;\n" " color: #AEB8C8;\n" -" background-color: #141A23;\n" +" background-color: #242628;\n" "}\n" "\n" "QScrollArea,\n" "QAbstractScrollArea {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" " border: none;\n" "}\n" "\n" "QAbstractScrollArea::corner {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" "}\n" "\n" "QScrollBar:vertical {\n" @@ -85,15 +85,15 @@ inline constexpr const char* DARK_THEME = "\n" "QScrollBar::handle:vertical,\n" "QScrollBar::handle:horizontal {\n" -" background-color: #364154;\n" -" border-radius: 3px;\n" +" background-color: #505357;\n" +" border-radius: 4px;\n" " min-height: 30px;\n" " min-width: 30px;\n" "}\n" "\n" "QScrollBar::handle:vertical:hover,\n" "QScrollBar::handle:horizontal:hover {\n" -" background-color: #536078;\n" +" background-color: #65696E;\n" "}\n" "\n" "QScrollBar::add-line,\n" @@ -108,10 +108,10 @@ inline constexpr const char* DARK_THEME = "\n" "QPushButton,\n" "QToolButton {\n" -" background-color: #1A2230;\n" -" border: 1px solid #2D3849;\n" -" border-radius: 3px;\n" -" padding: 3px 7px;\n" +" background-color: #2B2E31;\n" +" border: 1px solid #45494D;\n" +" border-radius: 8px;\n" +" padding: 4px 8px;\n" " color: #E9EDF4;\n" " min-height: 18px;\n" " font-weight: 550;\n" @@ -119,41 +119,41 @@ inline constexpr const char* DARK_THEME = "\n" "QPushButton:hover,\n" "QToolButton:hover {\n" -" background-color: #222C3C;\n" -" border-color: #46536A;\n" +" background-color: #363A3E;\n" +" border-color: #5A5F65;\n" "}\n" "\n" "QPushButton:pressed,\n" "QToolButton:pressed {\n" -" background-color: #121923;\n" -" border-color: #4C8DFF;\n" +" background-color: #232527;\n" +" border-color: #6F7B84;\n" "}\n" "\n" "QPushButton:checked,\n" "QToolButton:checked {\n" -" background-color: #182C4A;\n" -" border-color: #4C8DFF;\n" +" background-color: #3A4248;\n" +" border-color: #6F7B84;\n" " color: #FFFFFF;\n" "}\n" "\n" "QPushButton:default,\n" "#primaryAction {\n" -" background-color: #3F78D8;\n" -" border-color: #6BA3FF;\n" +" background-color: #596A76;\n" +" border-color: #73838E;\n" " color: #FFFFFF;\n" " font-weight: 650;\n" "}\n" "\n" "QPushButton:default:hover,\n" "#primaryAction:hover {\n" -" background-color: #4C8DFF;\n" -" border-color: #78A9F2;\n" +" background-color: #667985;\n" +" border-color: #82919B;\n" "}\n" "\n" "QPushButton:disabled,\n" "QToolButton:disabled {\n" -" background-color: #121820;\n" -" border-color: #1D2531;\n" +" background-color: #202224;\n" +" border-color: #303235;\n" " color: #566174;\n" "}\n" "\n" @@ -170,9 +170,9 @@ inline constexpr const char* DARK_THEME = "QDateEdit,\n" "QTimeEdit,\n" "QDateTimeEdit {\n" -" background-color: #0F141B;\n" -" border: 1px solid #273141;\n" -" border-radius: 3px;\n" +" background-color: #1B1D1F;\n" +" border: 1px solid #3B3E42;\n" +" border-radius: 8px;\n" " padding: 4px 6px;\n" " color: #EEF2F7;\n" "}\n" @@ -183,7 +183,7 @@ inline constexpr const char* DARK_THEME = "QComboBox:hover,\n" "QSpinBox:hover,\n" "QDoubleSpinBox:hover {\n" -" border-color: #3D4A60;\n" +" border-color: #54585D;\n" "}\n" "\n" "QLineEdit:focus,\n" @@ -192,8 +192,8 @@ inline constexpr const char* DARK_THEME = "QComboBox:focus,\n" "QSpinBox:focus,\n" "QDoubleSpinBox:focus {\n" -" background-color: #111824;\n" -" border-color: #4C8DFF;\n" +" background-color: #222426;\n" +" border-color: #71808A;\n" "}\n" "\n" "QLineEdit:disabled,\n" @@ -201,8 +201,8 @@ inline constexpr const char* DARK_THEME = "QComboBox:disabled,\n" "QSpinBox:disabled,\n" "QDoubleSpinBox:disabled {\n" -" background-color: #11161D;\n" -" border-color: #1D2530;\n" +" background-color: #202224;\n" +" border-color: #303235;\n" " color: #566174;\n" "}\n" "\n" @@ -214,27 +214,27 @@ inline constexpr const char* DARK_THEME = " subcontrol-origin: padding;\n" " subcontrol-position: top right;\n" " width: 22px;\n" -" border-left: 1px solid #273141;\n" +" border-left: 1px solid #3B3E42;\n" "}\n" "\n" "QComboBox QAbstractItemView {\n" -" background-color: #171E29;\n" -" border: 1px solid #344156;\n" -" border-radius: 4px;\n" +" background-color: #292C2F;\n" +" border: 1px solid #494D52;\n" +" border-radius: 10px;\n" " padding: 3px;\n" -" selection-background-color: #182C4A;\n" +" selection-background-color: #3A4248;\n" "}\n" "\n" "QAbstractSpinBox::up-button,\n" "QAbstractSpinBox::down-button {\n" -" background-color: #171F2B;\n" +" background-color: #292C2F;\n" " border: none;\n" " width: 16px;\n" "}\n" "\n" "QAbstractSpinBox::up-button:hover,\n" "QAbstractSpinBox::down-button:hover {\n" -" background-color: #263144;\n" +" background-color: #3E4246;\n" "}\n" "\n" "QCheckBox,\n" @@ -247,33 +247,47 @@ inline constexpr const char* DARK_THEME = "QRadioButton::indicator {\n" " width: 15px;\n" " height: 15px;\n" +" background-color: #1B1D1F;\n" +" border: 1px solid #55595D;\n" +" border-radius: 5px;\n" +"}\n" +"\n" +"QCheckBox::indicator:hover,\n" +"QRadioButton::indicator:hover {\n" +" border-color: #747B81;\n" +"}\n" +"\n" +"QCheckBox::indicator:checked,\n" +"QRadioButton::indicator:checked {\n" +" background-color: #71808A;\n" +" border-color: #89969F;\n" "}\n" "\n" "QSlider::groove:horizontal {\n" -" background-color: #202A38;\n" +" background-color: #34373A;\n" " height: 4px;\n" " border-radius: 2px;\n" "}\n" "\n" "QSlider::handle:horizontal {\n" -" background-color: #4C8DFF;\n" -" border: 2px solid #A9C8F5;\n" +" background-color: #7D8991;\n" +" border: 2px solid #A8AFB4;\n" " width: 12px;\n" " margin: -5px 0;\n" " border-radius: 7px;\n" "}\n" "\n" "QProgressBar {\n" -" background-color: #151C26;\n" -" border: 1px solid #293446;\n" -" border-radius: 3px;\n" +" background-color: #26282B;\n" +" border: 1px solid #42464A;\n" +" border-radius: 6px;\n" " height: 8px;\n" " text-align: center;\n" "}\n" "\n" "QProgressBar::chunk {\n" -" background-color: #4C8DFF;\n" -" border-radius: 3px;\n" +" background-color: #71808A;\n" +" border-radius: 6px;\n" "}\n" "\n" "QTreeView,\n" @@ -281,8 +295,8 @@ inline constexpr const char* DARK_THEME = "QListWidget,\n" "QTableView,\n" "QTableWidget {\n" -" background-color: #10151C;\n" -" alternate-background-color: #121923;\n" +" background-color: #1E2022;\n" +" alternate-background-color: #232527;\n" " border: none;\n" " color: #DCE3EC;\n" " show-decoration-selected: 1;\n" @@ -294,7 +308,7 @@ inline constexpr const char* DARK_THEME = "QTableView::item,\n" "QTableWidget::item {\n" " border: 1px solid transparent;\n" -" border-radius: 3px;\n" +" border-radius: 7px;\n" " padding: 3px 5px;\n" "}\n" "\n" @@ -303,8 +317,8 @@ inline constexpr const char* DARK_THEME = "QListWidget::item:hover,\n" "QTableView::item:hover,\n" "QTableWidget::item:hover {\n" -" background-color: #1A2230;\n" -" border-color: #293548;\n" +" background-color: #2B2E31;\n" +" border-color: #43474B;\n" "}\n" "\n" "QTreeView::item:selected,\n" @@ -312,55 +326,57 @@ inline constexpr const char* DARK_THEME = "QListWidget::item:selected,\n" "QTableView::item:selected,\n" "QTableWidget::item:selected {\n" -" background-color: #172A46;\n" -" border-color: #3F78D8;\n" +" background-color: #393F44;\n" +" border-color: #66737C;\n" " color: #FFFFFF;\n" "}\n" "\n" "QHeaderView {\n" -" background-color: #111720;\n" +" background-color: #202224;\n" "}\n" "\n" "QHeaderView::section {\n" -" background-color: #171E29;\n" +" background-color: #292C2F;\n" " border: none;\n" -" border-right: 1px solid #283243;\n" -" border-bottom: 1px solid #283243;\n" +" border-right: 1px solid #404347;\n" +" border-bottom: 1px solid #404347;\n" " padding: 5px 7px;\n" " color: #98A4B7;\n" " font-weight: 600;\n" "}\n" "\n" "QTabWidget::pane {\n" -" background-color: #10151C;\n" -" border: 1px solid #273141;\n" -" border-radius: 0 0 3px 3px;\n" +" background-color: #1E2022;\n" +" border: 1px solid #3B3E42;\n" +" border-radius: 0 0 10px 10px;\n" "}\n" "\n" "QTabBar::tab {\n" -" background-color: #111720;\n" +" background-color: #202224;\n" " border: none;\n" -" border-right: 1px solid #232C3A;\n" -" border-bottom: 1px solid #273141;\n" +" border-right: 1px solid #383B3F;\n" +" border-bottom: 1px solid #3B3E42;\n" " color: #7F8B9D;\n" " min-width: 88px;\n" -" padding: 5px 9px;\n" +" padding: 5px 10px;\n" +" margin: 2px 1px;\n" +" border-radius: 8px;\n" "}\n" "\n" "QTabBar::tab:hover {\n" -" background-color: #18202B;\n" +" background-color: #2B2E31;\n" " color: #C8D1DF;\n" "}\n" "\n" "QTabBar::tab:selected {\n" -" background-color: #151C26;\n" +" background-color: #36393C;\n" " color: #F2F5F9;\n" -" border-bottom: 2px solid #4C8DFF;\n" +" border-bottom: 2px solid #78858E;\n" "}\n" "\n" "QMenuBar#atlasMenuBar {\n" -" background-color: #090D12;\n" -" border-bottom: 1px solid #202836;\n" +" background-color: #141517;\n" +" border-bottom: 1px solid #303236;\n" " padding: 2px 6px;\n" "}\n" "\n" @@ -368,31 +384,31 @@ inline constexpr const char* DARK_THEME = " background: transparent;\n" " color: #B8C2D0;\n" " padding: 5px 9px;\n" -" border-radius: 3px;\n" +" border-radius: 7px;\n" "}\n" "\n" "QMenuBar#atlasMenuBar::item:selected,\n" "QMenuBar#atlasMenuBar::item:pressed {\n" -" background-color: #202838;\n" +" background-color: #34373A;\n" " color: #FFFFFF;\n" "}\n" "\n" "QMenu {\n" -" background-color: #171E29;\n" -" border: 1px solid #344156;\n" -" border-radius: 4px;\n" +" background-color: #292C2F;\n" +" border: 1px solid #494D52;\n" +" border-radius: 10px;\n" " padding: 3px;\n" "}\n" "\n" "QMenu::item {\n" " background: transparent;\n" -" border-radius: 3px;\n" +" border-radius: 7px;\n" " padding: 5px 30px 5px 8px;\n" " color: #DCE3EC;\n" "}\n" "\n" "QMenu::item:selected {\n" -" background-color: #172A46;\n" +" background-color: #3A3E42;\n" " color: #FFFFFF;\n" "}\n" "\n" @@ -401,13 +417,13 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QMenu::separator {\n" -" background-color: #2A3444;\n" +" background-color: #424549;\n" " height: 1px;\n" " margin: 5px 8px;\n" "}\n" "\n" "QSplitter::handle {\n" -" background-color: #080C11;\n" +" background-color: #111214;\n" "}\n" "\n" "QSplitter::handle:horizontal {\n" @@ -419,12 +435,12 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QSplitter::handle:hover {\n" -" background-color: #4C8DFF;\n" +" background-color: #71889A;\n" "}\n" "\n" "QStatusBar {\n" -" background-color: #090D12;\n" -" border-top: 1px solid #202836;\n" +" background-color: #141517;\n" +" border-top: 1px solid #303236;\n" " color: #8490A4;\n" "}\n" "\n" @@ -438,10 +454,10 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#statusRenderer {\n" -" background-color: #192B22;\n" -" border: 1px solid #2C573B;\n" -" border-radius: 4px;\n" -" color: #8DE2A5;\n" +" background-color: #2B2E30;\n" +" border: 1px solid #45494D;\n" +" border-radius: 8px;\n" +" color: #B6BCB8;\n" " font-size: 9px;\n" " font-weight: 700;\n" " padding: 2px 6px;\n" @@ -454,16 +470,16 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#workspaceBar {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" " border: none;\n" -" border-bottom: 1px solid #273141;\n" +" border-bottom: 1px solid #3B3E42;\n" " spacing: 3px;\n" " padding: 2px 5px 2px 0;\n" "}\n" "\n" "#workspaceIdentity {\n" " background: transparent;\n" -" border-right: 1px solid #2A3444;\n" +" border-right: 1px solid #424549;\n" "}\n" "\n" "#workspaceMark {\n" @@ -484,20 +500,20 @@ inline constexpr const char* DARK_THEME = "#workspaceModeButton {\n" " background-color: transparent;\n" " border: 1px solid transparent;\n" -" border-radius: 3px;\n" +" border-radius: 9px;\n" " color: #94A0B2;\n" " padding: 4px 8px;\n" " margin: 0 1px;\n" "}\n" "\n" "#workspaceModeButton:hover {\n" -" background-color: #1B2431;\n" +" background-color: #303336;\n" " color: #DDE4ED;\n" "}\n" "\n" "#workspaceModeButton:checked {\n" -" background-color: #17263B;\n" -" border-color: #31577F;\n" +" background-color: #3A3E42;\n" +" border-color: #5E656B;\n" " color: #FFFFFF;\n" "}\n" "\n" @@ -512,65 +528,53 @@ inline constexpr const char* DARK_THEME = "#workspaceLaunchButton {\n" " min-width: 26px;\n" " padding: 3px 5px;\n" -"}\n" -"\n" -"#workspaceBuildButton {\n" -" background-color: #2C2618;\n" -" border-color: #5D4B23;\n" -" color: #F5D184;\n" -"}\n" -"\n" -"#workspaceLaunchButton {\n" -" background-color: #183020;\n" -" border-color: #285A38;\n" -" color: #92E6A9;\n" +" background-color: #292C2F;\n" +" border-color: #45494D;\n" " margin-left: 3px;\n" "}\n" "\n" -"#workspaceBuildButton:hover {\n" -" background-color: #3A311D;\n" -" border-color: #80682D;\n" -"}\n" -"\n" +"#workspaceBuildButton:hover,\n" "#workspaceLaunchButton:hover {\n" -" background-color: #20412A;\n" -" border-color: #3A7A4B;\n" +" background-color: #363A3E;\n" +" border-color: #5A5F65;\n" "}\n" "\n" "#sceneTabs {\n" -" background-color: #0C1117;\n" -" border-bottom: 1px solid #273141;\n" +" background-color: #191A1C;\n" +" border-bottom: 1px solid #3B3E42;\n" "}\n" "\n" "#sceneTabs::tab {\n" -" background-color: #111720;\n" -" border-right: 1px solid #252E3B;\n" +" background-color: #202224;\n" +" border-right: 1px solid #3A3D40;\n" " color: #7F8B9D;\n" " min-width: 112px;\n" " padding: 5px 10px;\n" +" margin: 2px;\n" +" border-radius: 8px;\n" "}\n" "\n" "#sceneTabs::tab:selected {\n" -" background-color: #171E29;\n" +" background-color: #36393C;\n" " color: #F3F6FA;\n" -" border-bottom: 2px solid #4CB7D8;\n" +" border-bottom: 2px solid #78858E;\n" "}\n" "\n" "#viewportTools {\n" -" background-color: #090D12;\n" +" background-color: #141517;\n" "}\n" "\n" "#viewportToolbar {\n" -" background-color: #111720;\n" -" border-bottom: 1px solid #273141;\n" +" background-color: #202224;\n" +" border-bottom: 1px solid #3B3E42;\n" "}\n" "\n" "#viewportPlaybackButton,\n" "#viewportModeButton,\n" "#viewportOptionButton,\n" "#viewportShadingButton {\n" -" background-color: #171E29;\n" -" border-color: #283345;\n" +" background-color: #292C2F;\n" +" border-color: #414549;\n" " min-width: 25px;\n" " min-height: 22px;\n" " padding: 3px 5px;\n" @@ -580,25 +584,25 @@ inline constexpr const char* DARK_THEME = "#viewportModeButton:hover,\n" "#viewportOptionButton:hover,\n" "#viewportShadingButton:hover {\n" -" background-color: #222C3C;\n" -" border-color: #46536A;\n" +" background-color: #363A3E;\n" +" border-color: #5A5F65;\n" "}\n" "\n" "#viewportModeButton:checked,\n" "#viewportShadingButton:checked {\n" -" background-color: #172A46;\n" -" border-color: #4C8DFF;\n" +" background-color: #3A4248;\n" +" border-color: #6F7B84;\n" "}\n" "\n" "#viewportFpsLabel {\n" -" color: #73C58A;\n" +" color: #9CA5A0;\n" " font-size: 10px;\n" " font-weight: 650;\n" "}\n" "\n" "#viewportShortcutHint {\n" -" background-color: #090D12;\n" -" border-top: 1px solid #202836;\n" +" background-color: #141517;\n" +" border-top: 1px solid #303236;\n" " color: #68758A;\n" " font-size: 10px;\n" " padding: 3px 7px;\n" @@ -608,17 +612,17 @@ inline constexpr const char* DARK_THEME = "#materialEditorHeader,\n" "#postProcessingToolbar,\n" "#workspaceToolbar {\n" -" background-color: #131922;\n" -" border-bottom: 1px solid #283243;\n" +" background-color: #232527;\n" +" border-bottom: 1px solid #404347;\n" " padding: 3px;\n" "}\n" "\n" "#panelAddButton,\n" "#materialSaveButton,\n" "#workspaceApplyButton {\n" -" background-color: #172A46;\n" -" border-color: #35628F;\n" -" color: #DCE9FA;\n" +" background-color: #303438;\n" +" border-color: #4C5257;\n" +" color: #D8DBDE;\n" "}\n" "\n" "#panelMoreButton,\n" @@ -632,12 +636,12 @@ inline constexpr const char* DARK_THEME = "#panelMoreButton:hover,\n" "#browserNavigationButton:hover,\n" "#browserRevealButton:hover {\n" -" background-color: #202A38;\n" -" border-color: #334056;\n" +" background-color: #34373A;\n" +" border-color: #484C50;\n" "}\n" "\n" "#contentPathField {\n" -" background-color: #0E131A;\n" +" background-color: #1B1D1F;\n" " color: #8490A4;\n" " font-size: 11px;\n" "}\n" @@ -647,8 +651,8 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QTreeView#hierarchyTree {\n" -" background-color: #10151C;\n" -" border-top: 1px solid #202836;\n" +" background-color: #1E2022;\n" +" border-top: 1px solid #303236;\n" " padding: 5px 3px;\n" "}\n" "\n" @@ -658,32 +662,32 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QTreeView#hierarchyTree::item:selected {\n" -" background-color: #172A46;\n" -" border-left: 2px solid #6BA3FF;\n" +" background-color: #343C43;\n" +" border-left: 2px solid #8498A8;\n" "}\n" "\n" "QListView#contentGrid {\n" -" background-color: #0D1218;\n" -" border-top: 1px solid #202836;\n" +" background-color: #1A1C1E;\n" +" border-top: 1px solid #303236;\n" " padding: 6px;\n" "}\n" "\n" "QListView#contentGrid::item {\n" -" background-color: #121923;\n" -" border: 1px solid #202A38;\n" -" border-radius: 4px;\n" +" background-color: #232527;\n" +" border: 1px solid #34373A;\n" +" border-radius: 11px;\n" " padding: 7px;\n" " color: #BCC6D4;\n" "}\n" "\n" "QListView#contentGrid::item:hover {\n" -" background-color: #182130;\n" -" border-color: #3A465A;\n" +" background-color: #2E3134;\n" +" border-color: #4B5055;\n" "}\n" "\n" "QListView#contentGrid::item:selected {\n" -" background-color: #17283F;\n" -" border-color: #4C8DFF;\n" +" background-color: #393F44;\n" +" border-color: #66737C;\n" " color: #FFFFFF;\n" "}\n" "\n" @@ -691,21 +695,21 @@ inline constexpr const char* DARK_THEME = "#inspectorContent,\n" "#materialEditorBody,\n" "#postProcessingBody {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" " border: none;\n" "}\n" "\n" "#inspectorHeader {\n" -" background-color: #141B25;\n" -" border: 1px solid #273243;\n" -" border-radius: 4px;\n" +" background-color: #25272A;\n" +" border: 1px solid #404347;\n" +" border-radius: 12px;\n" " padding: 6px;\n" "}\n" "\n" "#inspectorObjectIcon {\n" -" background-color: #20283A;\n" -" border: 1px solid #38455B;\n" -" border-radius: 4px;\n" +" background-color: #34373B;\n" +" border: 1px solid #4E5257;\n" +" border-radius: 10px;\n" " padding: 4px;\n" "}\n" "\n" @@ -719,8 +723,8 @@ inline constexpr const char* DARK_THEME = "\n" "#inspectorNameField:hover,\n" "#inspectorNameField:focus {\n" -" background-color: #10151C;\n" -" border-color: #46536A;\n" +" background-color: #1E2022;\n" +" border-color: #5A5F65;\n" "}\n" "\n" "#inspectorTypeLabel {\n" @@ -730,16 +734,16 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#inspectorComponent {\n" -" background-color: #141A23;\n" -" border: 1px solid #252F3E;\n" -" border-radius: 4px;\n" +" background-color: #242628;\n" +" border: 1px solid #3B3E41;\n" +" border-radius: 11px;\n" " margin-top: 3px;\n" "}\n" "\n" "#inspectorComponentHeaderRow {\n" -" background-color: #171E29;\n" -" border-bottom: 1px solid #252F3E;\n" -" border-radius: 4px 4px 0 0;\n" +" background-color: #292C2F;\n" +" border-bottom: 1px solid #3B3E41;\n" +" border-radius: 11px 11px 0 0;\n" "}\n" "\n" "#inspectorComponentHeader {\n" @@ -752,7 +756,7 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#inspectorComponentHeader:hover {\n" -" background-color: #1D2634;\n" +" background-color: #303337;\n" "}\n" "\n" "#inspectorComponentRemoveButton {\n" @@ -762,12 +766,12 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#inspectorComponentRemoveButton:hover {\n" -" background-color: #43212A;\n" -" border: 1px solid #713141;\n" +" background-color: #3A3031;\n" +" border: 1px solid #695556;\n" "}\n" "\n" "#inspectorComponentBody {\n" -" background-color: #141A23;\n" +" background-color: #242628;\n" " padding: 5px;\n" "}\n" "\n" @@ -784,9 +788,9 @@ inline constexpr const char* DARK_THEME = "#inspectorVectorField,\n" "#inspectorColorField,\n" "#inspectorNumericField {\n" -" background-color: #0F141B;\n" -" border: 1px solid #263142;\n" -" border-radius: 3px;\n" +" background-color: #1B1D1F;\n" +" border: 1px solid #404448;\n" +" border-radius: 9px;\n" "}\n" "\n" "#inspectorVectorField QDoubleSpinBox,\n" @@ -796,8 +800,8 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#inspectorAxisLabel {\n" -" background-color: #202A38;\n" -" border-radius: 3px;\n" +" background-color: #34373A;\n" +" border-radius: 7px;\n" " color: #AAB5C5;\n" " font-size: 9px;\n" " font-weight: 750;\n" @@ -812,14 +816,16 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#inspectorSyncButton[matched=\"true\"] {\n" -" background-color: #1C3827;\n" -" border-color: #2F6841;\n" -" color: #8FE1A6;\n" +" background-color: #343936;\n" +" border-color: #555F59;\n" +" color: #B6BEB9;\n" "}\n" "\n" "#inspectorColorSwatch {\n" -" border: 1px solid #4A566A;\n" -" border-radius: 4px;\n" +" background-color: #292C2F;\n" +" border: 1px solid #4D5155;\n" +" border-radius: 8px;\n" +" padding: 2px;\n" "}\n" "\n" "#inspectorColorText {\n" @@ -829,9 +835,9 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#inspectorNestedGroup {\n" -" background-color: #111720;\n" -" border: 1px solid #222C3A;\n" -" border-radius: 4px;\n" +" background-color: #202224;\n" +" border: 1px solid #383B3F;\n" +" border-radius: 10px;\n" " margin: 3px 0;\n" " padding: 5px;\n" "}\n" @@ -856,21 +862,21 @@ inline constexpr const char* DARK_THEME = "\n" "#inspectorOpenAssetButton,\n" "#inspectorAddComponentButton {\n" -" background-color: #1B2431;\n" -" border: 1px dashed #46536A;\n" +" background-color: #292C2F;\n" +" border: 1px dashed #5A5F65;\n" " color: #C7D0DD;\n" " padding: 6px;\n" "}\n" "\n" "#inspectorAddComponentButton:hover {\n" -" background-color: #17283F;\n" -" border-color: #4C8DFF;\n" +" background-color: #363A3E;\n" +" border-color: #646B70;\n" " color: #FFFFFF;\n" "}\n" "\n" "#inspectorAudioControls {\n" -" background-color: #111720;\n" -" border-radius: 3px;\n" +" background-color: #202224;\n" +" border-radius: 9px;\n" "}\n" "\n" "#materialEditorTitle,\n" @@ -892,23 +898,37 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#materialPreview {\n" -" background-color: #090D12;\n" -" border: 1px solid #2B3648;\n" -" border-radius: 4px;\n" +" background-color: #141517;\n" +" border: 1px solid #44484C;\n" +" border-radius: 12px;\n" +"}\n" +"\n" +"#materialColorButton {\n" +" background-color: #292C2F;\n" +" border-color: #45494D;\n" +" border-radius: 9px;\n" +" color: #C9CDD0;\n" +" text-align: left;\n" +" padding: 4px 8px;\n" +"}\n" +"\n" +"#materialColorButton:hover {\n" +" background-color: #34383B;\n" +" border-color: #5A5F65;\n" "}\n" "\n" "#materialTextureSlot {\n" -" background-color: #121923;\n" -" border: 1px solid #263142;\n" -" border-radius: 4px;\n" +" background-color: #232527;\n" +" border: 1px solid #404448;\n" +" border-radius: 10px;\n" " padding: 4px;\n" "}\n" "\n" "#materialTexturePreview {\n" -" background-color: #0D1218;\n" -" border: 1px solid #344156;\n" -" border-radius: 4px;\n" -" color: #D9825B;\n" +" background-color: #1A1C1E;\n" +" border: 1px solid #494D52;\n" +" border-radius: 9px;\n" +" color: #9E897D;\n" " font-weight: 750;\n" "}\n" "\n" @@ -924,13 +944,13 @@ inline constexpr const char* DARK_THEME = "#environmentPages,\n" "#environmentWorkspace,\n" "#environmentPage {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" " border: none;\n" "}\n" "\n" "QListWidget#environmentCategories {\n" -" background-color: #0E131A;\n" -" border-right: 1px solid #273141;\n" +" background-color: #1B1D1F;\n" +" border-right: 1px solid #3B3E42;\n" " padding: 5px;\n" "}\n" "\n" @@ -940,8 +960,8 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QListWidget#environmentCategories::item:selected {\n" -" background-color: #172A46;\n" -" border-left: 2px solid #6BA3FF;\n" +" background-color: #343C43;\n" +" border-left: 2px solid #8498A8;\n" "}\n" "\n" "#environmentPageTitle {\n" @@ -955,43 +975,43 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QGroupBox#environmentSection {\n" -" background-color: #141A23;\n" -" border-color: #273141;\n" +" background-color: #242628;\n" +" border-color: #3B3E42;\n" "}\n" "\n" "ads--CDockContainerWidget {\n" -" background-color: #080C11;\n" +" background-color: #111214;\n" "}\n" "\n" "ads--CDockContainerWidget > QSplitter {\n" -" background-color: #080C11;\n" +" background-color: #111214;\n" "}\n" "\n" "ads--CDockContainerWidget ads--CDockSplitter::handle {\n" -" background-color: #080C11;\n" +" background-color: #111214;\n" "}\n" "\n" "ads--CDockContainerWidget ads--CDockSplitter::handle:hover {\n" -" background-color: #4C8DFF;\n" +" background-color: #71889A;\n" "}\n" "\n" "ads--CDockAreaWidget {\n" -" background-color: #10151C;\n" -" border: 1px solid #202A38;\n" +" background-color: #1E2022;\n" +" border: 1px solid #34373A;\n" "}\n" "\n" "ads--CDockAreaWidget[focused=\"true\"] {\n" -" border-color: #39465B;\n" +" border-color: #50545A;\n" "}\n" "\n" "ads--CDockAreaTitleBar {\n" -" background-color: #111720;\n" -" border-bottom: 1px solid #273141;\n" +" background-color: #202224;\n" +" border-bottom: 1px solid #3B3E42;\n" " min-height: 26px;\n" "}\n" "\n" "ads--CDockAreaWidget[focused=\"true\"] ads--CDockAreaTitleBar {\n" -" background-color: #151C27;\n" +" background-color: #26282B;\n" "}\n" "\n" "#tabsContainerWidget {\n" @@ -1001,35 +1021,37 @@ inline constexpr const char* DARK_THEME = "ads--CTitleBarButton {\n" " background: transparent;\n" " border: none;\n" -" border-radius: 3px;\n" +" border-radius: 7px;\n" " min-width: 22px;\n" " min-height: 22px;\n" " padding: 2px;\n" "}\n" "\n" "ads--CTitleBarButton:hover {\n" -" background-color: #263144;\n" +" background-color: #3E4246;\n" "}\n" "\n" "ads--CDockWidgetTab {\n" -" background-color: #111720;\n" +" background-color: #202224;\n" " border: none;\n" -" border-right: 1px solid #252E3B;\n" -" border-bottom: 1px solid #273141;\n" +" border-right: 1px solid #3A3D40;\n" +" border-bottom: 1px solid #3B3E42;\n" " padding: 1px 5px;\n" +" margin: 2px 1px;\n" +" border-radius: 7px;\n" "}\n" "\n" "ads--CDockWidgetTab:hover {\n" -" background-color: #18212D;\n" +" background-color: #2C2F32;\n" "}\n" "\n" "ads--CDockWidgetTab[activeTab=\"true\"] {\n" -" background-color: #171E29;\n" -" border-bottom: 2px solid #4C8DFF;\n" +" background-color: #373A3D;\n" +" border-bottom: 2px solid #78858E;\n" "}\n" "\n" "ads--CDockWidgetTab[focused=\"true\"] {\n" -" background-color: #1A2230;\n" +" background-color: #2B2E31;\n" "}\n" "\n" "ads--CDockWidgetTab #dockWidgetTabLabel {\n" @@ -1061,40 +1083,41 @@ inline constexpr const char* DARK_THEME = "#dockAreaAutoHideButton:hover,\n" "#dockAreaMinimizeButton:hover,\n" "#tabsMenuButton:hover {\n" -" background-color: #2A3444;\n" +" background-color: #424549;\n" "}\n" "\n" "ads--CDockWidget {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" "}\n" "\n" "ads--CAutoHideSideBar,\n" "#sideTabsContainerWidget {\n" -" background-color: #090D12;\n" +" background-color: #141517;\n" "}\n" "\n" "ads--CAutoHideTab {\n" -" background-color: #111720;\n" -" border: 1px solid #263142;\n" +" background-color: #202224;\n" +" border: 1px solid #404448;\n" " color: #7F8B9D;\n" " padding: 4px;\n" +" border-radius: 8px;\n" "}\n" "\n" "ads--CAutoHideTab:hover,\n" "ads--CAutoHideTab[activeTab=\"true\"] {\n" -" background-color: #172A46;\n" -" border-color: #3F78D8;\n" +" background-color: #393F44;\n" +" border-color: #66737C;\n" " color: #FFFFFF;\n" "}\n" "\n" "#projectBrowserRoot,\n" "#projectBrowserContent {\n" -" background-color: #0D1117;\n" +" background-color: #18191B;\n" "}\n" "\n" "#projectSidebar {\n" -" background-color: #0A0E13;\n" -" border-right: 1px solid #202836;\n" +" background-color: #151618;\n" +" border-right: 1px solid #303236;\n" "}\n" "\n" "#projectBrand {\n" @@ -1110,9 +1133,10 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#projectNavSelected {\n" -" background-color: #17263B;\n" -" border: 1px solid #2F527D;\n" -" border-left: 3px solid #6BA3FF;\n" +" background-color: #34383C;\n" +" border: 1px solid #51575C;\n" +" border-left: 3px solid #79868F;\n" +" border-radius: 10px;\n" " color: #DCE9FA;\n" " padding: 6px 9px;\n" " text-align: left;\n" @@ -1137,15 +1161,15 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#projectSearch {\n" -" background-color: #111720;\n" -" border: 1px solid #2A3547;\n" -" border-radius: 4px;\n" +" background-color: #202224;\n" +" border: 1px solid #43474B;\n" +" border-radius: 11px;\n" " padding: 7px 9px;\n" " font-size: 13px;\n" "}\n" "\n" "#projectSearch:focus {\n" -" border-color: #4C8DFF;\n" +" border-color: #71808A;\n" "}\n" "\n" "#projectList {\n" @@ -1160,26 +1184,26 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#projectRow {\n" -" background-color: #141A23;\n" -" border: 1px solid #252F3E;\n" -" border-radius: 5px;\n" +" background-color: #242628;\n" +" border: 1px solid #3B3E41;\n" +" border-radius: 13px;\n" "}\n" "\n" "#projectRow:hover {\n" -" background-color: #18212D;\n" -" border-color: #40506A;\n" +" background-color: #2C2F32;\n" +" border-color: #565B61;\n" "}\n" "\n" "#projectRow[available=\"false\"] {\n" -" background-color: #11161D;\n" -" border-color: #1D2530;\n" +" background-color: #202224;\n" +" border-color: #303235;\n" "}\n" "\n" "#projectIcon,\n" "#templateIcon {\n" -" background-color: #1D2532;\n" -" border: 1px solid #334056;\n" -" border-radius: 4px;\n" +" background-color: #303337;\n" +" border: 1px solid #484C50;\n" +" border-radius: 10px;\n" "}\n" "\n" "#projectName {\n" @@ -1195,10 +1219,10 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#rendererBadge {\n" -" background-color: #1C3527;\n" -" border: 1px solid #2C6340;\n" -" border-radius: 3px;\n" -" color: #8DE2A5;\n" +" background-color: #2C302E;\n" +" border: 1px solid #494F4B;\n" +" border-radius: 8px;\n" +" color: #B4BBB6;\n" " padding: 3px 7px;\n" " font-size: 9px;\n" " font-weight: 700;\n" @@ -1210,14 +1234,14 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#projectMoreButton:hover {\n" -" background-color: #253044;\n" -" border-color: #3B4860;\n" +" background-color: #3E4246;\n" +" border-color: #51565B;\n" "}\n" "\n" "#projectEmptyState {\n" -" background-color: #10151C;\n" -" border: 1px dashed #2F3A4D;\n" -" border-radius: 5px;\n" +" background-color: #1E2022;\n" +" border: 1px dashed #484C51;\n" +" border-radius: 14px;\n" "}\n" "\n" "#emptyStateTitle {\n" @@ -1227,23 +1251,23 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#createProjectDialog {\n" -" background-color: #10151C;\n" +" background-color: #1E2022;\n" "}\n" "\n" "QFrame[templateCard=\"true\"] {\n" -" background-color: #141A23;\n" -" border: 1px solid #293445;\n" -" border-radius: 5px;\n" +" background-color: #242628;\n" +" border: 1px solid #42464A;\n" +" border-radius: 13px;\n" "}\n" "\n" "QFrame[templateCard=\"true\"]:hover {\n" -" background-color: #1A2230;\n" -" border-color: #46536A;\n" +" background-color: #2B2E31;\n" +" border-color: #5A5F65;\n" "}\n" "\n" "QFrame[templateCard=\"true\"][selected=\"true\"] {\n" -" background-color: #17283F;\n" -" border-color: #4C8DFF;\n" +" background-color: #393F44;\n" +" border-color: #66737C;\n" "}\n" "\n" "#templateOption {\n" @@ -1263,31 +1287,31 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "QPushButton[secondary=\"true\"] {\n" -" background-color: #171E29;\n" -" border-color: #344156;\n" +" background-color: #292C2F;\n" +" border-color: #494D52;\n" "}\n" "\n" "QPushButton[secondary=\"true\"]:hover {\n" -" background-color: #222C3C;\n" -" border-color: #4A5870;\n" +" background-color: #363A3E;\n" +" border-color: #5D6268;\n" "}\n" "\n" "#projectSettingsDialog,\n" "#exportDialog {\n" -" background-color: #0D1117;\n" +" background-color: #18191B;\n" "}\n" "\n" "#dialogHero {\n" -" background-color: #141A23;\n" -" border: 1px solid #293445;\n" -" border-radius: 5px;\n" +" background-color: #242628;\n" +" border: 1px solid #42464A;\n" +" border-radius: 13px;\n" " padding: 6px;\n" "}\n" "\n" "#dialogHeroIcon {\n" -" background-color: #15253A;\n" -" border: 1px solid #2F527D;\n" -" border-radius: 4px;\n" +" background-color: #2B3034;\n" +" border: 1px solid #50575C;\n" +" border-radius: 10px;\n" " padding: 6px;\n" "}\n" "\n" @@ -1303,44 +1327,44 @@ inline constexpr const char* DARK_THEME = "}\n" "\n" "#exportSummary {\n" -" background-color: #121923;\n" -" border: 1px solid #273141;\n" -" border-radius: 4px;\n" +" background-color: #232527;\n" +" border: 1px solid #3B3E42;\n" +" border-radius: 10px;\n" " padding: 6px;\n" "}\n" "\n" "#exportLog {\n" -" background-color: #090D12;\n" -" border-color: #263142;\n" -" color: #9CE2AF;\n" +" background-color: #141517;\n" +" border-color: #404448;\n" +" color: #B7BDBC;\n" " font-family: \"Menlo\";\n" " font-size: 10px;\n" "}\n" "\n" "#commandPaletteDialog,\n" "#globalSearchDialog {\n" -" background-color: #111720;\n" -" border: 1px solid #46536A;\n" -" border-radius: 5px;\n" +" background-color: #202224;\n" +" border: 1px solid #5A5F65;\n" +" border-radius: 14px;\n" "}\n" "\n" "#commandPaletteSearch,\n" "#globalSearchField {\n" -" background-color: #0D1218;\n" -" border: 1px solid #3A465A;\n" -" border-radius: 4px;\n" +" background-color: #1A1C1E;\n" +" border: 1px solid #505459;\n" +" border-radius: 11px;\n" " padding: 7px 9px;\n" " font-size: 14px;\n" "}\n" "\n" "#commandPaletteSearch:focus,\n" "#globalSearchField:focus {\n" -" border-color: #6BA3FF;\n" +" border-color: #71808A;\n" "}\n" "\n" "#commandPaletteList,\n" "#globalSearchResults {\n" -" background-color: #111720;\n" +" background-color: #202224;\n" " border: none;\n" " padding: 5px;\n" "}\n" diff --git a/include/editor/styling/icons.h b/include/editor/styling/icons.h index c3c093b6..784290bb 100644 --- a/include/editor/styling/icons.h +++ b/include/editor/styling/icons.h @@ -3,6 +3,7 @@ #include #include +#include namespace styling { @@ -85,6 +86,7 @@ enum class Icon { bool loadIconFont(); QIcon icon(Icon icon, const QColor &color = QColor("#AAB4C4")); +QIcon colorSwatch(const QColor &color, const QSize &size = QSize(18, 18)); } From c0fbf39c0a0eb7be3263989f1dbe72d750cedd26 Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:38:54 +0200 Subject: [PATCH 6/7] Used the native macOS menu bar --- editor/views/editor/editor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/views/editor/editor.cpp b/editor/views/editor/editor.cpp index a0229f9a..62b98f67 100644 --- a/editor/views/editor/editor.cpp +++ b/editor/views/editor/editor.cpp @@ -243,7 +243,7 @@ void EditorWindow::setupWindow() { updateWindowTitle(false); setMinimumSize(1100, 700); resize(1440, 900); - menuBar()->setNativeMenuBar(false); + menuBar()->setNativeMenuBar(true); menuBar()->setObjectName("atlasMenuBar"); ads::CDockManager::setConfigFlag(ads::CDockManager::OpaqueSplitterResize, From d9636d44d391b4f2ce591b33621e77d818d1ad62 Mon Sep 17 00:00:00 2001 From: Max Van den Eynde Date: Sat, 18 Jul 2026 16:38:54 +0200 Subject: [PATCH 7/7] Finished the editor's first iteration --- .gitignore | 2 - Cargo.lock | 2444 ++++++++++++++++++++++++++++++++++ include/editor/core/themes.h | 2 +- 3 files changed, 2445 insertions(+), 3 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 6a3cea84..823592fe 100644 --- a/.gitignore +++ b/.gitignore @@ -16,10 +16,8 @@ libhydra.a lib/* build .vscode -Cargo.lock target cli/target -cli/Cargo.lock libfinewave.a _deps docs/html diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..1c052834 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2444 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "atlas-cli" +version = "0.1.0" +dependencies = [ + "clap", + "colored", + "dialoguer", + "indicatif", + "openssl", + "reqwest", + "serde", + "serde_json", + "tokio", + "toml", + "zip", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link 0.2.0", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "cc" +version = "1.2.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.59.0", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deflate64" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2" + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dialoguer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" +dependencies = [ + "console", + "shell-words", + "tempfile", + "thiserror 1.0.69", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.1", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width", + "web-time", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-src" +version = "300.5.2+3.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d270b79e2926f5150189d475bc7e9d2c69f9c4697b185fa917d5a32b792d21b4" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.0", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.1", +] + +[[package]] +name = "rustls" +version = "0.23.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.1", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.61.1", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "slab", + "socket2", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link 0.1.3", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.4", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link 0.2.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +dependencies = [ + "windows-link 0.2.0", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zip" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "getrandom 0.3.3", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "thiserror 2.0.18", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/include/editor/core/themes.h b/include/editor/core/themes.h index b95a4472..b3f15739 100644 --- a/include/editor/core/themes.h +++ b/include/editor/core/themes.h @@ -3,7 +3,7 @@ // This file is generated. Do not edit manually. // Generated from .qss theme files. -// Source: editor/styling/dark.qss +// Source: /Users/maxvdec/Coding/Projects/Atlas/editor/styling/dark.qss inline constexpr const char* DARK_THEME = "* {\n" " font-family: \"Manrope\";\n"