feat(rog-control-center): Major UI/UX improvements and new features

- Add software RGB animations for static-only keyboards (rainbow, color cycle)
- Add custom fan curve control via direct sysfs for unsupported laptops
- Add real-time system status bar (CPU/GPU temps, fan speeds, power draw)
- Add tray icon tooltip with live system stats
- Add power profile change notifications (Fn+F5)
- Add dGPU status notifications
- Add ROG theme with dark palette and accent colors
- Add Screenpad, Slash, and SuperGFX page stubs
- Improve fan curve graph UI
- Various UI refinements and fixes

Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
mihai2mn
2026-01-15 20:09:40 +01:00
parent 5303bfc1ad
commit 3d0caa39e1
40 changed files with 2790 additions and 692 deletions
+179 -88
View File
@@ -1,9 +1,12 @@
import { Palette, Button, VerticalBox } from "std-widgets.slint";
import { Button, VerticalBox } from "std-widgets.slint";
import { AppSize } from "globals.slint";
import { PageSystem, SystemPageData, AttrMinMax } from "pages/system.slint";
import { SideBar } from "widgets/sidebar.slint";
import { PageAbout } from "pages/about.slint";
import { PageFans } from "pages/fans.slint";
import { PageSlash, SlashPageData } from "pages/slash.slint";
import { PageSupergfx, SupergfxPageData } from "pages/supergfx.slint";
import { PageScreenpad, ScreenpadPageData } from "pages/screenpad.slint";
import { PageAnime, AnimePageData } from "pages/anime.slint";
import { RogItem } from "widgets/common.slint";
import { PageAura } from "pages/aura.slint";
@@ -14,8 +17,18 @@ export { FanPageData, FanType, Profile }
import { AuraPageData, AuraDevType, LaptopAuraPower, AuraPowerState, PowerZones, AuraEffect } from "types/aura_types.slint";
export { AuraPageData, AuraDevType, LaptopAuraPower, AuraPowerState, PowerZones, AuraEffect }
import { PageAppSettings, AppSettingsPageData } from "pages/app_settings.slint";
import { StatusBar, SystemStatus } from "widgets/status_bar.slint";
import { TrayTooltip } from "windows/tray_tooltip.slint";
export { TrayTooltip }
export { AppSize, AttrMinMax, SystemPageData, AnimePageData, AppSettingsPageData }
import { RogPalette } from "themes/rog_theme.slint";
export { AppSize, AttrMinMax, SystemPageData, AnimePageData, AppSettingsPageData, SystemStatus, SlashPageData, SupergfxPageData, ScreenpadPageData }
export global SomeError {
in property <string> error_message: "";
in property <string> error_help: "";
}
export component MainWindow inherits Window {
title: "ROG Control";
@@ -24,93 +37,133 @@ export component MainWindow inherits Window {
default-font-size: 14px;
default-font-weight: 400;
icon: @image-url("../data/rog-control-center.png");
in property <[bool]> sidebar_items_avilable: [true, true, true, true, true, true];
in property <[bool]> sidebar_items_avilable: [true, true, true, true, true, true, true, true, true];
private property <bool> show_notif;
private property <bool> fade_cover;
private property <bool> toast: false;
private property <string> toast_text: "I show when something is waiting";
callback show_toast(string);
callback start_toast_timer();
callback hide_toast();
hide_toast() => {
toast = false;
}
show_toast(text) => {
toast = text != "";
toast_text = text;
if (toast) {
start_toast_timer();
}
}
callback exit-app();
callback show_notification(bool);
show_notification(yes) => {
show_notif = yes;
fade_cover = yes;
}
callback external_colour_change();
external_colour_change() => {
aura.external_colour_change();
aura.external_colour_change();
}
min-height: AppSize.height;
min-width: AppSize.width;
background: Colors.black;
HorizontalLayout {
padding: 0px;
VerticalLayout {
side-bar := SideBar {
title: @tr("ROG");
model: [
@tr("Menu1" => "System Control"),
@tr("Menu2" => "Keyboard Aura"),
@tr("Menu3" => "AniMe Matrix"),
@tr("Menu4" => "Fan Curves"),
@tr("Menu5" => "App Settings"),
@tr("Menu6" => "About"),
];
available: root.sidebar_items_avilable;
}
background: RogPalette.background;
Rectangle {
max-height: 40px;
width: side-bar.width;
background: Palette.control-background;
Text {
vertical-alignment: center;
horizontal-alignment: center;
text: @tr("Quit App");
VerticalLayout {
HorizontalLayout {
padding: 0px;
// Left Column: Sidebar + Quit Button
VerticalLayout {
side-bar := SideBar {
title: @tr("ROG");
model: [
@tr("Menu1" => "System Control"),
@tr("Menu2" => "Keyboard Aura"),
@tr("Menu3" => "AniMe Matrix"),
@tr("Menu7" => "Slash Lighting"),
@tr("Menu8" => "Graphics Control"),
@tr("Menu9" => "Screenpad Control"),
@tr("Menu4" => "Fan Curves"),
@tr("Menu5" => "App Settings"),
@tr("Menu6" => "About"),
];
available: root.sidebar_items_avilable;
}
TouchArea {
clicked => {
root.exit-app();
Rectangle {
max-height: 40px;
width: side-bar.width;
background: RogPalette.control-background;
Text {
vertical-alignment: center;
horizontal-alignment: center;
text: @tr("Quit App");
color: RogPalette.text-primary;
}
TouchArea {
clicked => {
root.exit-app();
}
}
}
}
}
Rectangle {
background: Palette.background;
if(side-bar.current-item == 0): page := PageSystem {
width: root.width - side-bar.width;
height: root.height + 12px;
}
// Right Column: Content Pages
Rectangle {
background: RogPalette.background;
if(side-bar.current-item == 0): page := PageSystem {
width: root.width - side-bar.width;
height: root.height + 12px;
}
aura := PageAura {
width: root.width - side-bar.width;
visible: side-bar.current-item == 1;
}
aura := PageAura {
width: root.width - side-bar.width;
visible: side-bar.current-item == 1;
}
if(side-bar.current-item == 2): PageAnime {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 2): PageAnime {
width: root.width - side-bar.width;
}
fans := PageFans {
width: root.width - side-bar.width;
visible: side-bar.current-item == 3;
}
if(side-bar.current-item == 3): PageSlash {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 4): PageAppSettings {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 4): PageSupergfx {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 5): PageAbout {
width: root.width - side-bar.width;
if(side-bar.current-item == 5): PageScreenpad {
width: root.width - side-bar.width;
}
fans := PageFans {
width: root.width - side-bar.width;
visible: side-bar.current-item == 6;
}
if(side-bar.current-item == 7): PageAppSettings {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 8): PageAbout {
width: root.width - side-bar.width;
}
}
}
// Bottom: Status Bar
StatusBar {}
}
if fade_cover: Rectangle {
@@ -118,7 +171,7 @@ export component MainWindow inherits Window {
y: 0px;
width: root.width;
height: root.height;
background: Colors.rgba(25,33,23,20);
background: Colors.rgba(0,0,0,0.7);
opacity: 0.7;
TouchArea {
height: 100%;
@@ -133,13 +186,24 @@ export component MainWindow inherits Window {
}
}
if toast: Rectangle {
x: 0px;
y: 0px;
width: root.width;
height: 32px;
opacity: 1.0;
background: Colors.grey;
// Modern floating toast/snackbar notification
// Shows at the bottom center, non-intrusive
Rectangle {
visible: self.opacity > 0;
opacity: root.toast ? 1 : 0;
animate opacity { duration: 300ms; }
x: (root.width - 400px) / 2; // Center horizontally
y: root.height - 80px; // Bottom padding
width: 400px;
height: 48px;
border-radius: RogPalette.border-radius;
border-width: 1px;
border-color: RogPalette.accent;
background: RogPalette.control-background;
drop-shadow-blur: 10px;
drop-shadow-color: Colors.black;
TouchArea {
height: 100%;
width: 100%;
@@ -148,13 +212,23 @@ export component MainWindow inherits Window {
}
}
Rectangle {
height: 100%;
width: 100%;
background: Palette.control-background;
HorizontalLayout {
padding-left: 16px;
padding-right: 16px;
alignment: space-between;
Text {
color: Palette.control-foreground;
vertical-alignment: center;
color: RogPalette.text-primary;
text: root.toast_text;
overflow: elide;
}
Text {
vertical-alignment: center;
text: "Dismiss";
color: RogPalette.text-secondary;
font-size: 12px;
}
}
}
@@ -174,13 +248,20 @@ export component MainWindow inherits Window {
}
}
// TODO: add properties to display
Rectangle {
height: 100%;
width: 100%;
background: Palette.background;
Text {
text: "Click here to exit";
background: RogPalette.control-background;
border-radius: 8px;
VerticalLayout {
alignment: center;
Text {
horizontal-alignment: center;
text: "Click here to exit";
color: RogPalette.text-primary;
font-size: 16px;
}
}
}
}
@@ -190,35 +271,45 @@ export component MainWindow inherits Window {
y: 0px;
width: root.width;
height: root.height;
//padding only has effect on layout elements
//padding: 10px;
background: Palette.background;
border-color: Palette.border;
border-width: 3px;
border-radius: 10px;
background: RogPalette.background;
border-color: RogPalette.accent;
border-width: 2px;
border-radius: 8px;
VerticalBox {
RogItem {
min-height: 50px;
max-height: 100px;
padding: 20px;
spacing: 15px;
alignment: center;
Text {
text: "Error";
font-size: 22px;
font-weight: 700;
color: RogPalette.accent;
horizontal-alignment: center;
}
Rectangle {
background: RogPalette.control-background;
border-radius: 8px;
min-height: 60px;
Text {
text <=> SomeError.error_message;
font-size: 18px;
font-size: 16px;
color: RogPalette.text-primary;
horizontal-alignment: center;
vertical-alignment: center;
}
}
Text {
text <=> SomeError.error_help;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
color: RogPalette.text-secondary;
horizontal-alignment: center;
vertical-alignment: center;
}
}
}
}
export global SomeError {
in property <string> error_message: "";
in property <string> error_help: "";
}
+107 -41
View File
@@ -1,62 +1,128 @@
import { AboutSlint, VerticalBox, HorizontalBox } from "std-widgets.slint";
import { VerticalBox, HorizontalBox, ScrollView } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export component PageAbout inherits VerticalLayout {
padding: 10px;
spacing: 10px;
Text {
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
text: "A UI for asusctl made with slint";
font-size: 22px;
}
export component PageAbout inherits Rectangle {
background: RogPalette.background;
HorizontalBox {
alignment: LayoutAlignment.center;
ScrollView {
VerticalBox {
alignment: LayoutAlignment.center;
padding: 30px;
spacing: 20px;
alignment: center;
// Title
Text {
wrap: TextWrap.word-wrap;
text: "You need to use kernel version 6.19 to use this software";
horizontal-alignment: center;
text: "ROG Control Center";
font-size: 28px;
font-weight: 800;
color: RogPalette.accent;
}
Text {
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
text: "Todo:";
font-size: 22px;
horizontal-alignment: center;
text: "A modern UI for asusctl built with Slint";
font-size: 16px;
color: RogPalette.text-secondary;
}
Text {
text: "- [ ] Theme the widgets";
// Version info
Rectangle {
height: 60px;
background: RogPalette.control-background;
border-radius: 8px;
border-width: 1px;
border-color: RogPalette.control-border;
HorizontalBox {
padding: 15px;
alignment: center;
Text {
text: "Version 6.3.0";
font-size: 14px;
color: RogPalette.text-primary;
}
Text {
text: " | ";
color: RogPalette.text-secondary;
}
Text {
text: "Requires kernel 6.10+";
font-size: 14px;
color: RogPalette.text-secondary;
}
}
}
Text {
text: "- [ ] Add a cpu/gpu temp/fan speed info bar";
// Features section
Rectangle {
background: RogPalette.control-background;
border-radius: 8px;
border-width: 1px;
border-color: RogPalette.control-border;
VerticalBox {
padding: 20px;
spacing: 12px;
Text {
text: "Features";
font-size: 18px;
font-weight: 700;
color: RogPalette.accent;
}
// Completed features
Text { text: "[x] ROG-themed dark UI"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] System status bar (CPU/GPU temps & fan speeds)"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Power profile management"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Aura RGB keyboard lighting"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] AniMe Matrix display"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Slash LED control"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Supergfx graphics switching"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Screenpad brightness & gamma"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Custom fan curves"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] Desktop notifications (KDE OSD)"; color: RogPalette.text-primary; font-size: 13px; }
Text { text: "[x] System tray integration"; color: RogPalette.text-primary; font-size: 13px; }
// Pending features
Rectangle { height: 10px; }
Text { text: "Planned:"; font-size: 14px; font-weight: 600; color: RogPalette.text-secondary; }
Text { text: "[ ] ROG Ally specific settings"; color: RogPalette.text-secondary; font-size: 13px; }
Text { text: "[ ] Advanced Aura zone editing"; color: RogPalette.text-secondary; font-size: 13px; }
}
}
Text {
text: "- [ ] Include fan speeds, temps in a bottom bar";
}
// Credits
Rectangle {
background: RogPalette.control-background;
border-radius: 8px;
border-width: 1px;
border-color: RogPalette.control-border;
Text {
text: "- [ ] Slash control";
}
VerticalBox {
padding: 20px;
spacing: 8px;
Text {
text: "- [ ] Screenpad controls";
}
Text {
text: "Credits";
font-size: 18px;
font-weight: 700;
color: RogPalette.accent;
}
Text {
text: "- [ ] ROG Ally specific settings";
Text {
text: "asusctl & asusd by Luke Jones";
font-size: 13px;
color: RogPalette.text-primary;
}
Text {
text: "UI built with Slint";
font-size: 13px;
color: RogPalette.text-secondary;
}
}
}
}
}
Text {
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
text: "Work in progress";
font-size: 22px;
}
}
+4 -3
View File
@@ -1,5 +1,6 @@
import { SystemDropdown, SystemToggle } from "../widgets/common.slint";
import { Palette, GroupBox, VerticalBox, Button, HorizontalBox } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export global AnimePageData {
in-out property <[string]> brightness_names: [
@@ -109,7 +110,7 @@ export component PageAnime inherits Rectangle {
if root.show_fade_cover: Rectangle {
width: 100%;
height: 100%;
background: Palette.background;
background: RogPalette.background;
opacity: 0.8;
TouchArea {
height: 100%;
@@ -142,7 +143,7 @@ export component PageAnime inherits Rectangle {
alignment: LayoutAlignment.start;
Text {
font-size: 18px;
color: Palette.control-foreground;
color: RogPalette.text-primary;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("Set which builtin animations are played");
}
@@ -216,7 +217,7 @@ export component PageAnime inherits Rectangle {
alignment: LayoutAlignment.start;
Text {
font-size: 18px;
color: Palette.control-foreground;
color: RogPalette.text-primary;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("Advanced Display Settings");
}
+122 -43
View File
@@ -1,5 +1,6 @@
import { Palette } from "std-widgets.slint";
import { SystemToggle } from "../widgets/common.slint";
import { VerticalBox, ScrollView, HorizontalBox, Button } from "std-widgets.slint";
import { SystemToggle, RogItem } from "../widgets/common.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export global AppSettingsPageData {
in-out property <bool> run_in_background;
@@ -8,56 +9,134 @@ export global AppSettingsPageData {
callback set_startup_in_background(bool);
in-out property <bool> enable_tray_icon;
callback set_enable_tray_icon(bool);
in-out property <bool> enable_dgpu_notifications;
callback set_enable_dgpu_notifications(bool);
// Master notification toggle
in-out property <bool> notifications_enabled;
callback set_notifications_enabled(bool);
// Granular notification toggles
in-out property <bool> notify_gfx_switch;
callback set_notify_gfx_switch(bool);
in-out property <bool> notify_gfx_status;
callback set_notify_gfx_status(bool);
in-out property <bool> notify_platform_profile;
callback set_notify_platform_profile(bool);
}
export component PageAppSettings inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
//padding only has effect on layout elements
//padding: 8px;
export component PageAppSettings inherits Rectangle {
background: RogPalette.background;
ScrollView {
VerticalBox {
padding: 20px;
spacing: 20px;
alignment: start;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
SystemToggle {
text: @tr("Run in background after closing");
checked <=> AppSettingsPageData.run_in_background;
toggled => {
AppSettingsPageData.set_run_in_background(AppSettingsPageData.run_in_background)
// General Section
VerticalBox {
spacing: 10px;
padding: 0px;
Rectangle {
height: 30px;
background: RogPalette.control-background;
border-radius: 4px;
border-width: 1px;
border-color: RogPalette.control-border;
Text {
x: 10px;
vertical-alignment: center;
text: "General Settings";
color: RogPalette.accent;
font-weight: 700;
}
}
SystemToggle {
text: @tr("Run in background after closing");
checked <=> AppSettingsPageData.run_in_background;
toggled => {
AppSettingsPageData.set_run_in_background(AppSettingsPageData.run_in_background)
}
}
SystemToggle {
text: @tr("Start app in background (UI closed)");
checked <=> AppSettingsPageData.startup_in_background;
toggled => {
AppSettingsPageData.set_startup_in_background(AppSettingsPageData.startup_in_background)
}
}
SystemToggle {
text: @tr("Enable system tray icon");
checked <=> AppSettingsPageData.enable_tray_icon;
toggled => {
AppSettingsPageData.set_enable_tray_icon(AppSettingsPageData.enable_tray_icon)
}
}
}
SystemToggle {
text: @tr("Start app in background (UI closed)");
checked <=> AppSettingsPageData.startup_in_background;
toggled => {
AppSettingsPageData.set_startup_in_background(AppSettingsPageData.startup_in_background)
}
}
// Notifications Section
VerticalBox {
spacing: 10px;
padding: 0px;
SystemToggle {
text: @tr("Enable system tray icon");
checked <=> AppSettingsPageData.enable_tray_icon;
toggled => {
AppSettingsPageData.set_enable_tray_icon(AppSettingsPageData.enable_tray_icon)
}
}
Rectangle {
height: 30px;
background: RogPalette.control-background;
border-radius: 4px;
border-width: 1px;
border-color: RogPalette.control-border;
SystemToggle {
text: @tr("Enable dGPU notifications");
checked <=> AppSettingsPageData.enable_dgpu_notifications;
toggled => {
AppSettingsPageData.set_enable_dgpu_notifications(AppSettingsPageData.enable_dgpu_notifications)
Text {
x: 10px;
vertical-alignment: center;
text: "Notifications";
color: RogPalette.accent;
font-weight: 700;
}
}
SystemToggle {
text: @tr("Enable Notifications");
checked <=> AppSettingsPageData.notifications_enabled;
toggled => {
AppSettingsPageData.set_notifications_enabled(AppSettingsPageData.notifications_enabled)
}
}
// Sub-toggles container
VerticalBox {
padding-left: 30px; // Indent
spacing: 10px;
visible: AppSettingsPageData.notifications_enabled;
SystemToggle {
text: @tr("Notify on Graphics Switch");
checked <=> AppSettingsPageData.notify_gfx_switch;
toggled => {
AppSettingsPageData.set_notify_gfx_switch(AppSettingsPageData.notify_gfx_switch)
}
}
SystemToggle {
text: @tr("Notify on GPU Status Change");
checked <=> AppSettingsPageData.notify_gfx_status;
toggled => {
AppSettingsPageData.set_notify_gfx_status(AppSettingsPageData.notify_gfx_status)
}
}
SystemToggle {
text: @tr("Notify on Power Profile Change");
checked <=> AppSettingsPageData.notify_platform_profile;
toggled => {
AppSettingsPageData.set_notify_platform_profile(AppSettingsPageData.notify_platform_profile)
}
}
}
}
Text {
text: "WIP: some features like notifications are not complete";
}
}
}
+62 -3
View File
@@ -1,5 +1,6 @@
import { SystemDropdown, RogItem, SystemToggle, SystemToggleVert } from "../widgets/common.slint";
import { Palette, Button, ComboBox, VerticalBox, GroupBox } from "std-widgets.slint";
import { Button, ComboBox, VerticalBox, GroupBox } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
import { StyleMetrics, Slider, HorizontalBox, TextEdit, SpinBox, LineEdit, ScrollView } from "std-widgets.slint";
import { ColourSlider } from "../widgets/colour_picker.slint";
import { AuraPageData, AuraDevType, PowerZones, LaptopAuraPower, AuraEffect } from "../types/aura_types.slint";
@@ -183,6 +184,57 @@ export component PageAura inherits Rectangle {
}
}
// Software Animation Controls (for Static-only keyboards)
if AuraPageData.soft_animation_available: RogItem {
min-height: 100px;
VerticalLayout {
padding: 10px;
spacing: 8px;
Text {
text: @tr("Software Animation (Static-only keyboards)");
font-size: 14px;
font-weight: 600;
color: RogPalette.accent;
}
HorizontalLayout {
spacing: 20px;
VerticalLayout {
Text {
text: @tr("Animation Mode");
color: RogPalette.text-secondary;
}
ComboBox {
current_index <=> AuraPageData.soft_animation_mode;
current_value: AuraPageData.soft_animation_modes[self.current-index];
model <=> AuraPageData.soft_animation_modes;
selected => {
AuraPageData.cb_soft_animation_mode(AuraPageData.soft_animation_mode);
}
}
}
VerticalLayout {
horizontal-stretch: 1;
Text {
text: @tr("Speed: ") + Math.round(AuraPageData.soft_animation_speed) + "ms";
color: RogPalette.text-secondary;
}
Slider {
minimum: 150;
maximum: 1000;
value <=> AuraPageData.soft_animation_speed;
released => {
AuraPageData.cb_soft_animation_speed(Math.round(AuraPageData.soft_animation_speed));
}
}
}
}
}
}
HorizontalLayout {
Button {
text: @tr("Power Settings");
@@ -195,11 +247,15 @@ export component PageAura inherits Rectangle {
}
if root.show_fade_cover: Rectangle {
background: Palette.background;
background: RogPalette.background;
opacity: 0.8;
TouchArea {
height: 100%;
width: 100%;
clicked => {
root.show_fade_cover = false;
root.show_aura_power = false;
}
}
}
}
@@ -266,7 +322,10 @@ export component PageAura inherits Rectangle {
alignment: LayoutAlignment.start;
Text {
text: "TODO: In progress";
text: "LED Power Zones (Legacy)";
font-size: 16px;
font-weight: 600;
color: #ff0033;
}
for state[idx] in AuraPageData.led_power.states: old_zone := AuraPowerGroupOld {
+109 -7
View File
@@ -1,7 +1,10 @@
import { Palette, TabWidget, Button, CheckBox } from "std-widgets.slint";
import { Palette, TabWidget, Button, CheckBox, Slider } from "std-widgets.slint";
import { Graph, Node } from "../widgets/graph.slint";
import { SystemToggle } from "../widgets/common.slint";
import { Profile, FanType, FanPageData } from "../types/fan_types.slint";
import { RogPalette } from "../themes/rog_theme.slint";
component FanTab inherits Rectangle {
in-out property <bool> enabled: false;
@@ -16,10 +19,81 @@ component FanTab inherits Rectangle {
in-out property <[Node]> nodes;
VerticalLayout {
private property <bool> local_busy:
(root.fan_type == FanType.CPU && FanPageData.is_busy_cpu) ||
(root.fan_type == FanType.GPU && FanPageData.is_busy_gpu) ||
(root.fan_type == FanType.Middle && FanPageData.is_busy_mid);
if FanPageData.show_custom_warning: Rectangle {
background: RogPalette.control-background;
border-radius: 4px;
height: 48px;
HorizontalLayout {
padding: 10px;
Text {
color: #ffd700; // Gold/Yellow
text: @tr("Zero RPM Mode Enabled: Fans will take ~25s to spin down entirely.");
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
wrap: word-wrap;
}
}
}
HorizontalLayout {
spacing: 10px;
if root.tab_enabled: Graph {
nodes <=> root.nodes;
}
if root.tab_enabled: VerticalLayout {
width: 40px;
alignment: center;
spacing: 10px;
Button {
text: "+";
height: 40px;
width: 40px;
clicked => {
root.nodes = [
{ x: root.nodes[0].x, y: min(255px, root.nodes[0].y + 13px) },
{ x: root.nodes[1].x, y: min(255px, root.nodes[1].y + 13px) },
{ x: root.nodes[2].x, y: min(255px, root.nodes[2].y + 13px) },
{ x: root.nodes[3].x, y: min(255px, root.nodes[3].y + 13px) },
{ x: root.nodes[4].x, y: min(255px, root.nodes[4].y + 13px) },
{ x: root.nodes[5].x, y: min(255px, root.nodes[5].y + 13px) },
{ x: root.nodes[6].x, y: min(255px, root.nodes[6].y + 13px) },
{ x: root.nodes[7].x, y: min(255px, root.nodes[7].y + 13px) }
];
}
}
Text {
text: "All";
font-size: 10px;
horizontal-alignment: center;
color: white;
}
Button {
text: "-";
height: 40px;
width: 40px;
clicked => {
root.nodes = [
{ x: root.nodes[0].x, y: max(0px, root.nodes[0].y - 13px) },
{ x: root.nodes[1].x, y: max(0px, root.nodes[1].y - 13px) },
{ x: root.nodes[2].x, y: max(0px, root.nodes[2].y - 13px) },
{ x: root.nodes[3].x, y: max(0px, root.nodes[3].y - 13px) },
{ x: root.nodes[4].x, y: max(0px, root.nodes[4].y - 13px) },
{ x: root.nodes[5].x, y: max(0px, root.nodes[5].y - 13px) },
{ x: root.nodes[6].x, y: max(0px, root.nodes[6].y - 13px) },
{ x: root.nodes[7].x, y: max(0px, root.nodes[7].y - 13px) }
];
}
}
}
if !root.tab_enabled: Rectangle {
Text {
font-size: 24px;
@@ -29,19 +103,20 @@ component FanTab inherits Rectangle {
}
HorizontalLayout {
spacing: 20px;
alignment: LayoutAlignment.end;
CheckBox {
text: @tr("Enabled");
text: @tr("Enable Manual Control");
checked <=> root.enabled;
enabled <=> root.tab_enabled;
enabled: root.tab_enabled && !local_busy;
toggled => {
root.toggled();
}
}
Button {
text: @tr("Apply");
enabled <=> root.tab_enabled;
text: local_busy ? @tr("Applying...") : @tr("Apply Curve");
enabled: root.tab_enabled && root.enabled && !local_busy;
clicked => {
root.apply();
}
@@ -49,7 +124,7 @@ component FanTab inherits Rectangle {
Button {
text: @tr("Cancel");
enabled <=> root.tab_enabled;
enabled: root.tab_enabled && !local_busy;
clicked => {
root.cancel()
}
@@ -57,7 +132,7 @@ component FanTab inherits Rectangle {
Button {
text: @tr("Factory Default (all fans)");
enabled <=> root.tab_enabled;
enabled: root.tab_enabled && !local_busy;
clicked => {
root.default();
}
@@ -86,6 +161,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Balanced);
}
cancel => {
FanPageData.cancel(FanType.CPU, Profile.Balanced);
}
}
}
@@ -104,6 +182,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Balanced);
}
cancel => {
FanPageData.cancel(FanType.Middle, Profile.Balanced);
}
}
}
@@ -122,6 +203,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Balanced);
}
cancel => {
FanPageData.cancel(FanType.GPU, Profile.Balanced);
}
}
}
}
@@ -145,6 +229,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Performance);
}
cancel => {
FanPageData.cancel(FanType.CPU, Profile.Performance);
}
}
}
@@ -163,6 +250,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Performance);
}
cancel => {
FanPageData.cancel(FanType.Middle, Profile.Performance);
}
}
}
@@ -181,6 +271,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Performance);
}
cancel => {
FanPageData.cancel(FanType.GPU, Profile.Performance);
}
}
}
}
@@ -204,6 +297,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Quiet);
}
cancel => {
FanPageData.cancel(FanType.CPU, Profile.Quiet);
}
}
}
@@ -222,6 +318,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Quiet);
}
cancel => {
FanPageData.cancel(FanType.Middle, Profile.Quiet);
}
}
}
@@ -240,6 +339,9 @@ export component PageFans inherits VerticalLayout {
default => {
FanPageData.set_profile_default(Profile.Quiet);
}
cancel => {
FanPageData.cancel(FanType.GPU, Profile.Quiet);
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
import { Button, VerticalBox, Slider, Switch } from "std-widgets.slint";
import { ScreenpadPageData } from "../types/screenpad_types.slint";
import { RogPalette } from "../themes/rog_theme.slint";
import { RogItem, SystemSlider } from "../widgets/common.slint";
export { ScreenpadPageData }
export component PageScreenpad inherits Rectangle {
background: RogPalette.background;
VerticalBox {
alignment: LayoutAlignment.start;
padding: 20px;
spacing: 20px;
Text {
text: @tr("Screenpad Controls");
font-size: 24px;
font-weight: 700;
color: RogPalette.accent;
}
RogItem {
HorizontalLayout {
padding: 15px;
spacing: 20px;
alignment: LayoutAlignment.space-between;
Text {
text: @tr("Enable Screenpad");
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: RogPalette.text-primary;
}
Switch {
checked <=> ScreenpadPageData.power;
toggled => {
ScreenpadPageData.cb_power(self.checked);
}
}
}
}
VerticalLayout {
spacing: 15px;
// Brightness Slider
SystemSlider {
enabled: ScreenpadPageData.power;
text: @tr("Brightness");
minimum: 0;
maximum: 255;
value: ScreenpadPageData.brightness;
help_text: ScreenpadPageData.brightness == -1 ? @tr("Not available") : "";
released => {
ScreenpadPageData.cb_brightness(Math.round(self.value));
}
}
// Gamma Slider (New)
SystemSlider {
enabled: ScreenpadPageData.power;
text: @tr("Gamma");
minimum: 0.1;
maximum: 2.5;
value: ScreenpadPageData.gamma;
help_text: @tr("Adjust color intensity");
released => {
ScreenpadPageData.cb_gamma(self.value);
}
}
RogItem {
enabled: ScreenpadPageData.power;
HorizontalLayout {
padding: 15px;
spacing: 20px;
alignment: LayoutAlignment.space-between;
Text {
text: @tr("Sync with Primary Display");
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: RogPalette.text-primary;
}
Switch {
enabled: ScreenpadPageData.power;
checked <=> ScreenpadPageData.sync_with_primary;
toggled => {
ScreenpadPageData.cb_sync_with_primary(self.checked);
}
}
}
}
}
// Spacer
Rectangle {}
}
}
+114
View File
@@ -0,0 +1,114 @@
import { SystemToggle, SystemSlider, SystemDropdown, RogItem } from "../widgets/common.slint";
import { VerticalBox, ScrollView, GroupBox } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
import { SlashPageData } from "../types/slash_types.slint";
export { SlashPageData }
export component PageSlash inherits Rectangle {
background: RogPalette.background;
ScrollView {
VerticalBox {
padding: 20px;
spacing: 20px;
alignment: start;
// Header
Rectangle {
height: 40px;
background: RogPalette.control-background;
border-radius: RogPalette.border-radius;
border-width: 1px;
border-color: RogPalette.control-border;
Text {
text: @tr("Slash Lighting Control");
color: RogPalette.accent;
font-size: 18px;
font-weight: 700;
horizontal-alignment: center;
vertical-alignment: center;
}
}
// Main Control
RogItem {
VerticalBox {
SystemToggle {
text: @tr("Enable Slash Lighting");
checked <=> SlashPageData.enabled;
toggled => { SlashPageData.cb_enabled(self.checked); }
}
SystemDropdown {
text: @tr("Lighting Mode");
model <=> SlashPageData.modes;
current_index <=> SlashPageData.mode_index;
current_value: SlashPageData.modes[SlashPageData.mode_index];
selected => {
SlashPageData.cb_mode_index(self.current_index);
}
}
SystemSlider {
title: @tr("Brightness");
text: @tr("Brightness");
value <=> SlashPageData.brightness;
minimum: 0;
maximum: 255;
help_text: "";
released(val) => { SlashPageData.cb_brightness(val); }
}
SystemSlider {
title: @tr("Interval / Speed");
text: @tr("Interval / Speed");
value <=> SlashPageData.interval;
minimum: 0;
maximum: 255;
help_text: "";
released(val) => { SlashPageData.cb_interval(val); }
}
}
}
// Behaviors
GroupBox {
title: @tr("Behavior Settings");
VerticalBox {
SystemToggle {
text: @tr("Show Battery Warning");
checked <=> SlashPageData.show_battery_warning;
toggled => { SlashPageData.cb_show_battery_warning(self.checked); }
}
SystemToggle {
text: @tr("Active on Battery");
checked <=> SlashPageData.show_on_battery;
toggled => { SlashPageData.cb_show_on_battery(self.checked); }
}
SystemToggle {
text: @tr("Active on Boot");
checked <=> SlashPageData.show_on_boot;
toggled => { SlashPageData.cb_show_on_boot(self.checked); }
}
SystemToggle {
text: @tr("Active on Shutdown");
checked <=> SlashPageData.show_on_shutdown;
toggled => { SlashPageData.cb_show_on_shutdown(self.checked); }
}
SystemToggle {
text: @tr("Active on Sleep");
checked <=> SlashPageData.show_on_sleep;
toggled => { SlashPageData.cb_show_on_sleep(self.checked); }
}
SystemToggle {
text: @tr("Active when Lid Closed");
checked <=> SlashPageData.show_on_lid_closed;
toggled => { SlashPageData.cb_show_on_lid_closed(self.checked); }
}
}
}
}
}
}
@@ -0,0 +1,73 @@
import { SystemDropdown, RogItem } from "../widgets/common.slint";
import { VerticalBox, ScrollView, HorizontalBox } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
import { SupergfxPageData } from "../types/supergfx_types.slint";
export { SupergfxPageData }
export component PageSupergfx inherits Rectangle {
background: RogPalette.background;
ScrollView {
VerticalBox {
padding: 20px;
spacing: 20px;
alignment: start;
// Header
Rectangle {
height: 40px;
background: RogPalette.control-background;
border-radius: RogPalette.border-radius;
border-width: 1px;
border-color: RogPalette.control-border;
Text {
text: @tr("Graphics Control (supergfx)");
color: RogPalette.accent;
font-size: 18px;
font-weight: 700;
horizontal-alignment: center;
vertical-alignment: center;
}
}
RogItem {
HorizontalBox {
Text {
text: @tr("Vendor: ") + SupergfxPageData.vendor;
color: RogPalette.text-secondary;
vertical-alignment: center;
}
}
}
// Main Control
RogItem {
VerticalBox {
Text {
text: @tr("Current Mode: ") + SupergfxPageData.current_mode;
color: RogPalette.text-primary;
}
SystemDropdown {
text: @tr("Graphics Mode");
model <=> SupergfxPageData.supported_modes;
current_index <=> SupergfxPageData.selected_index;
current_value: SupergfxPageData.supported_modes[SupergfxPageData.selected_index];
selected => {
SupergfxPageData.set_mode(self.current_value);
}
}
Text {
text: @tr("Note: Changing modes requires a logout.");
color: RogPalette.text-secondary;
font-size: 12px;
wrap: word-wrap;
}
}
}
}
}
}
+23 -66
View File
@@ -1,5 +1,6 @@
import { SystemSlider, SystemDropdown, SystemToggle, SystemToggleInt, RogItem } from "../widgets/common.slint";
import { Palette, HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox, StandardButton} from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export struct AttrMinMax {
min: int,
@@ -66,13 +67,6 @@ export global SystemPageData {
in-out property <int> mini_led_mode;
callback cb_mini_led_mode(int);
in-out property <float> screenpad_gamma;
callback cb_screenpad_gamma(float);
// percentage
in-out property <int> screenpad_brightness: 50;
callback cb_screenpad_brightness(int);
in-out property <bool> screenpad_sync_with_primary: false;
callback cb_screenpad_sync_with_primary(bool);
in-out property <bool> asus_armoury_loaded: false;
@@ -157,18 +151,22 @@ export component PageSystem inherits Rectangle {
ScrollView {
VerticalLayout {
padding: 10px;
padding-top: 40px;
padding-bottom: 40px;
spacing: 10px;
alignment: LayoutAlignment.start;
Rectangle {
background: Palette.alternate-background;
border-color: Palette.accent-background;
border-width: 3px;
border-radius: 10px;
height: 40px;
background: RogPalette.control-background;
border-color: RogPalette.control-border;
border-width: 1px;
border-radius: 8px;
height: 46px;
Text {
font-size: 18px;
color: Palette.control-foreground;
color: RogPalette.accent;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
font-weight: 700;
text: @tr("Power settings");
}
}
@@ -207,62 +205,18 @@ export component PageSystem inherits Rectangle {
}
}
if SystemPageData.screenpad_brightness != -1: RogItem {
HorizontalLayout {
padding-left: 10px;
padding-right: 20px;
HorizontalLayout {
width: 38%;
alignment: LayoutAlignment.space-between;
padding-right: 15px;
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
text: @tr("Screenpad brightness");
}
}
HorizontalLayout {
width: 38%;
alignment: LayoutAlignment.stretch;
screen_bright := Slider {
enabled: true;
minimum: 0;
maximum: 100;
value: SystemPageData.screenpad_brightness;
released(value) => {
// SystemPageData.screenpad_brightness = self.value;
SystemPageData.cb_screenpad_brightness(Math.floor(self.value));
}
}
}
HorizontalLayout {
width: 20%;
padding-left: 10px;
alignment: LayoutAlignment.stretch;
Switch {
text: @tr("Sync with primary");
checked <=> SystemPageData.screenpad_sync_with_primary;
toggled => {
SystemPageData.cb_screenpad_sync_with_primary(self.checked);
}
}
}
}
}
Rectangle {
background: Palette.alternate-background;
border-color: Palette.accent-background;
border-width: 3px;
border-radius: 10px;
height: 40px;
background: RogPalette.control-background;
border-color: RogPalette.control-border;
border-width: 1px;
border-radius: 8px;
height: 46px;
Text {
font-size: 18px;
color: Palette.control-foreground;
color: RogPalette.accent;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
font-weight: 700;
text: @tr("Armoury settings");
}
}
@@ -377,6 +331,7 @@ export component PageSystem inherits Rectangle {
Text {
font-size: 16px;
text: @tr("ppt_warning" => "The following settings are not applied until the toggle is enabled.");
color: RogPalette.text-primary;
}
}
@@ -545,7 +500,7 @@ export component PageSystem inherits Rectangle {
if root.show_fade_cover: Rectangle {
width: 100%;
height: 100%;
background: Palette.background;
background: RogPalette.background;
opacity: 0.9;
TouchArea {
height: 100%;
@@ -578,6 +533,7 @@ export component PageSystem inherits Rectangle {
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
text: @tr("Energy Performance Preference linked to Throttle Policy");
color: RogPalette.text-primary;
}
SystemToggle {
@@ -628,6 +584,7 @@ export component PageSystem inherits Rectangle {
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
text: @tr("Throttle Policy for power state");
color: RogPalette.text-primary;
}
HorizontalLayout {
@@ -0,0 +1,13 @@
export global RogPalette {
out property <brush> background: #0a0a0a;
out property <brush> alternate-background: #111111;
out property <brush> control-background: #1e1e1e;
out property <brush> control-border: #333333;
out property <brush> control-border-hover: #555555;
out property <brush> control-border-checked: #ff0033; // ROG Red
out property <brush> text-primary: #ffffff;
out property <brush> text-secondary: #aaaaaa;
out property <brush> accent: #ff0033;
out property <brush> accent-hover: #d60000;
out property <length> border-radius: 4px;
}
@@ -8,6 +8,13 @@ export enum AuraDevType {
AnimeOrSlash,
}
// Software animation modes for keyboards that only support Static
export enum SoftAnimationMode {
None,
Rainbow,
ColorCycle,
}
export struct AuraEffect {
/// The effect type
mode: int,
@@ -166,4 +173,16 @@ export global AuraPageData {
}]
};
callback cb_led_power(LaptopAuraPower);
// Software animation properties (for Static-only keyboards)
in-out property <[string]> soft_animation_modes: [
@tr("Animation mode" => "None"),
@tr("Animation mode" => "Rainbow"),
@tr("Animation mode" => "Color Cycle"),
];
in-out property <int> soft_animation_mode: 0;
in-out property <float> soft_animation_speed: 200; // ms between updates
in-out property <bool> soft_animation_available: false; // Set true when only Static mode is supported
callback cb_soft_animation_mode(int);
callback cb_soft_animation_speed(int);
}
+38 -288
View File
@@ -35,314 +35,64 @@ export global FanPageData {
in-out property <bool> quiet_gpu_enabled: true;
in-out property <bool> quiet_mid_enabled: false;
in-out property <bool> is_busy_cpu: false;
in-out property <bool> is_busy_gpu: false;
in-out property <bool> is_busy_mid: false;
in-out property <bool> show_custom_warning: false;
callback set_fan_data(FanType, Profile, bool, [Node]);
callback set_profile_default(Profile);
callback set_is_busy(FanType, bool);
// Last applied cache for Cancel button
in-out property <[Node]> last_applied_cpu_balanced: [];
in-out property <[Node]> last_applied_gpu_balanced: [];
in-out property <[Node]> last_applied_mid_balanced: [];
in-out property <[Node]> last_applied_cpu_performance: [];
in-out property <[Node]> last_applied_gpu_performance: [];
in-out property <[Node]> last_applied_mid_performance: [];
in-out property <[Node]> last_applied_cpu_quiet: [];
in-out property <[Node]> last_applied_gpu_quiet: [];
in-out property <[Node]> last_applied_mid_quiet: [];
callback cancel(FanType, Profile);
in-out property <[Node]> balanced_cpu: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
{ x: 70px, y: 25px }, { x: 80px, y: 55px }, { x: 90px, y: 85px }, { x: 98px, y: 100px },
];
in-out property <[Node]> balanced_mid: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
{ x: 70px, y: 25px }, { x: 80px, y: 55px }, { x: 90px, y: 85px }, { x: 98px, y: 100px },
];
in-out property <[Node]> balanced_gpu: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
{ x: 70px, y: 25px }, { x: 80px, y: 55px }, { x: 90px, y: 85px }, { x: 98px, y: 100px },
];
in-out property <[Node]> performance_cpu: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 10px }, { x: 50px, y: 30px }, { x: 60px, y: 50px },
{ x: 70px, y: 70px }, { x: 80px, y: 85px }, { x: 90px, y: 95px }, { x: 98px, y: 100px },
];
in-out property <[Node]> performance_mid: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 10px }, { x: 50px, y: 30px }, { x: 60px, y: 50px },
{ x: 70px, y: 70px }, { x: 80px, y: 85px }, { x: 90px, y: 95px }, { x: 98px, y: 100px },
];
in-out property <[Node]> performance_gpu: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 10px }, { x: 50px, y: 30px }, { x: 60px, y: 50px },
{ x: 70px, y: 70px }, { x: 80px, y: 85px }, { x: 90px, y: 95px }, { x: 98px, y: 100px },
];
in-out property <[Node]> quiet_cpu: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
{ x: 70px, y: 20px }, { x: 80px, y: 40px }, { x: 90px, y: 70px }, { x: 98px, y: 90px },
];
in-out property <[Node]> quiet_mid: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
{ x: 70px, y: 20px }, { x: 80px, y: 40px }, { x: 90px, y: 70px }, { x: 98px, y: 90px },
];
in-out property <[Node]> quiet_gpu: [
{
x: 10px,
y: 10px,
},
{
x: 40px,
y: 30px,
},
{
x: 50px,
y: 50px,
},
{
x: 55px,
y: 50px,
},
{
x: 60px,
y: 60px,
},
{
x: 65px,
y: 70px,
},
{
x: 70px,
y: 80px,
},
{
x: 90px,
y: 100px,
},
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
{ x: 70px, y: 20px }, { x: 80px, y: 40px }, { x: 90px, y: 70px }, { x: 98px, y: 90px },
];
function set_fan(profile: Profile, fan: FanType, data: [Node]) {
@@ -0,0 +1,13 @@
import { RogPalette } from "../themes/rog_theme.slint";
export global ScreenpadPageData {
in-out property <int> brightness: -1;
in-out property <float> gamma: 1.0;
in-out property <bool> sync_with_primary: false;
in-out property <bool> power: true;
callback cb_brightness(int);
callback cb_gamma(float);
callback cb_sync_with_primary(bool);
callback cb_power(bool);
}
@@ -0,0 +1,49 @@
export global SlashPageData {
in-out property <bool> enabled;
callback cb_enabled(bool);
in-out property <float> brightness;
callback cb_brightness(float);
in-out property <float> interval;
callback cb_interval(float);
in-out property <[string]> modes: [
@tr("Static"),
@tr("Bounce"),
@tr("Slash"),
@tr("Loading"),
@tr("BitStream"),
@tr("Transmission"),
@tr("Flow"),
@tr("Flux"),
@tr("Phantom"),
@tr("Spectrum"),
@tr("Hazard"),
@tr("Interfacing"),
@tr("Ramp"),
@tr("GameOver"),
@tr("Start"),
@tr("Buzzer"),
];
in-out property <int> mode_index;
callback cb_mode_index(int);
in-out property <bool> show_battery_warning;
callback cb_show_battery_warning(bool);
in-out property <bool> show_on_battery;
callback cb_show_on_battery(bool);
in-out property <bool> show_on_boot;
callback cb_show_on_boot(bool);
in-out property <bool> show_on_shutdown;
callback cb_show_on_shutdown(bool);
in-out property <bool> show_on_sleep;
callback cb_show_on_sleep(bool);
in-out property <bool> show_on_lid_closed;
callback cb_show_on_lid_closed(bool);
}
@@ -0,0 +1,10 @@
export global SupergfxPageData {
in-out property <string> current_mode: "Hybrid";
in-out property <[string]> supported_modes: ["Hybrid", "Integrated"];
in-out property <int> selected_index: 0;
in-out property <string> vendor: "Unknown";
callback set_mode(string);
callback refresh();
}
+12 -9
View File
@@ -1,12 +1,14 @@
import { Palette, VerticalBox, HorizontalBox, GroupBox } from "std-widgets.slint";
import { VerticalBox, HorizontalBox, GroupBox } from "std-widgets.slint";
import { SystemToggleVert, SystemDropdown } from "common.slint";
import { PowerZones } from "../types/aura_types.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export component AuraPowerGroup inherits Rectangle {
min-width: row.min-width;
border-radius: 20px;
background: Palette.alternate-background;
opacity: 0.9;
border-radius: 8px;
background: RogPalette.control-background;
border-width: 1px;
border-color: RogPalette.control-border;
in-out property <string> group-title;
in-out property <bool> boot_checked;
in-out property <bool> awake_checked;
@@ -20,7 +22,7 @@ export component AuraPowerGroup inherits Rectangle {
spacing: 10px;
Text {
font-size: 18px;
color: Palette.alternate-foreground;
color: RogPalette.text-primary;
horizontal-alignment: TextHorizontalAlignment.center;
text <=> root.group-title;
}
@@ -72,9 +74,10 @@ export component AuraPowerGroup inherits Rectangle {
export component AuraPowerGroupOld inherits Rectangle {
min-width: row.min-width;
border-radius: 20px;
background: Palette.alternate-background;
opacity: 0.9;
border-radius: 8px;
background: RogPalette.control-background;
border-width: 1px;
border-color: RogPalette.control-border;
in-out property <int> current_zone;
in-out property <[int]> zones;
in-out property <[string]> zone_strings;
@@ -90,7 +93,7 @@ export component AuraPowerGroupOld inherits Rectangle {
spacing: 10px;
Text {
font-size: 18px;
color: Palette.alternate-foreground;
color: RogPalette.text-primary;
horizontal-alignment: TextHorizontalAlignment.center;
text <=> root.group-title;
}
+33 -27
View File
@@ -1,12 +1,15 @@
import { Palette, VerticalBox , StandardButton, Button, HorizontalBox, ComboBox, Switch, Slider} from "std-widgets.slint";
import { VerticalBox , StandardButton, Button, HorizontalBox, ComboBox, Switch, Slider} from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export component RogItem inherits Rectangle {
background: Palette.control-background;
border-color: Palette.border;
border-width: 3px;
border-radius: 10px;
in property <bool> enabled: true;
background: root.enabled ? RogPalette.control-background : RogPalette.control-background.darker(0.5);
border-color: root.enabled ? RogPalette.control-border : RogPalette.control-border.darker(0.3);
border-width: 1px; // Thinner border for modern look
border-radius: RogPalette.border-radius;
min-height: 48px;
max-height: 56px;
opacity: root.enabled ? 1.0 : 0.6;
}
export component SystemSlider inherits RogItem {
@@ -18,7 +21,6 @@ export component SystemSlider inherits RogItem {
callback released(float);
in property <string> help_text;
in property <bool> enabled: true;
in property <bool> has_reset: false;
callback cb_do_reset();
@@ -32,7 +34,7 @@ export component SystemSlider inherits RogItem {
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
color: RogPalette.text-primary;
text: root.text;
}
@@ -40,7 +42,7 @@ export component SystemSlider inherits RogItem {
font-size: 16px;
horizontal-alignment: TextHorizontalAlignment.right;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
color: RogPalette.accent;
text: "\{Math.round(root.value)}";
}
}
@@ -64,10 +66,11 @@ export component SystemSlider inherits RogItem {
y: help.y - self.height + help.height - 10px;
Rectangle {
drop-shadow-blur: 10px;
drop-shadow-color: black;
border-radius: 10px;
border-color: Palette.accent-background;
background: Palette.background;
drop-shadow-color: Colors.black;
border-radius: RogPalette.border-radius;
border-width: 1px;
border-color: RogPalette.accent;
background: RogPalette.control-background;
Dialog {
title: root.title;
VerticalBox {
@@ -77,12 +80,12 @@ export component SystemSlider inherits RogItem {
wrap: TextWrap.word-wrap;
horizontal-alignment: TextHorizontalAlignment.center;
text: root.title;
color: RogPalette.text-primary;
}
Rectangle {
height: 1px;
border-color: black;
border-width: 1px;
background: RogPalette.control-border;
}
Text {
@@ -90,6 +93,7 @@ export component SystemSlider inherits RogItem {
font-size: 16px;
wrap: TextWrap.word-wrap;
text: root.help_text;
color: RogPalette.text-secondary;
}
}
@@ -114,16 +118,18 @@ export component SystemSlider inherits RogItem {
y: reset.y - self.height + reset.height;
Rectangle {
drop-shadow-blur: 10px;
drop-shadow-color: black;
border-radius: 10px;
border-color: Palette.accent-background;
background: Palette.background;
drop-shadow-color: Colors.black;
border-radius: RogPalette.border-radius;
border-width: 1px;
border-color: RogPalette.accent;
background: RogPalette.control-background;
Dialog {
Text {
max-width: 420px;
font-size: 16px;
wrap: TextWrap.word-wrap;
text: @tr("confirm_reset" => "Are you sure you want to reset this?");
color: RogPalette.text-primary;
}
StandardButton {
@@ -164,7 +170,7 @@ export component SystemToggle inherits RogItem {
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
color: RogPalette.text-primary;
text: root.text;
}
}
@@ -195,7 +201,7 @@ export component SystemToggleInt inherits RogItem {
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
color: RogPalette.text-primary;
text: root.text;
}
}
@@ -226,7 +232,7 @@ export component SystemToggleVert inherits RogItem {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.bottom;
horizontal-alignment: TextHorizontalAlignment.center;
color: Palette.control-foreground;
color: RogPalette.text-primary;
text: root.text;
}
@@ -256,7 +262,7 @@ export component SystemDropdown inherits RogItem {
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
color: RogPalette.text-primary;
text: root.text;
}
}
@@ -288,9 +294,9 @@ export component PopupNotification {
height: root.height;
// TODO: add properties to display
Rectangle {
border-width: 2px;
border-color: Palette.accent-background;
background: Palette.background;
border-width: 1px;
border-color: RogPalette.accent;
background: RogPalette.background;
// TODO: drop shadows slow
// drop-shadow-offset-x: 7px;
// drop-shadow-offset-y: 7px;
@@ -302,14 +308,14 @@ export component PopupNotification {
alignment: start;
Text {
text: heading;
color: Palette.control-foreground;
color: RogPalette.text-primary;
font-size: 32px;
font-weight: 900;
}
Text {
text: content;
color: Palette.control-foreground;
color: RogPalette.text-secondary;
font-size: 18px;
}
}
+29 -18
View File
@@ -1,4 +1,5 @@
import { Palette } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
export struct Node { x: length, y: length}
@@ -44,7 +45,7 @@ export component Graph inherits Rectangle {
for n in 11: Path {
viewbox-width: self.width / 1px;
viewbox-height: self.height / 1px;
stroke: Palette.alternate-foreground.darker(200%);
stroke: RogPalette.control-border;
stroke-width: 1px;
MoveTo {
x: scale_x_to_graph(n * 10px) / 1px;
@@ -60,7 +61,7 @@ export component Graph inherits Rectangle {
}
for n in 11: Text {
color: Palette.accent-background;
color: RogPalette.text-secondary;
font-size <=> root.axis_font_size;
text: "\{n * 10}c";
x: scale_x_to_graph(n * 10px) - self.width / 3;
@@ -70,7 +71,7 @@ export component Graph inherits Rectangle {
for n in 11: Path {
viewbox-width: self.width / 1px;
viewbox-height: self.height / 1px;
stroke: Palette.alternate-foreground.darker(200%);
stroke: RogPalette.control-border;
stroke-width: 1px;
MoveTo {
x: 0;
@@ -86,7 +87,7 @@ export component Graph inherits Rectangle {
}
for n in 11: Text {
color: Palette.accent-background;
color: RogPalette.text-secondary;
font-size <=> root.axis_font_size;
text: "\{n * 10}%";
x: - self.width;
@@ -97,7 +98,7 @@ export component Graph inherits Rectangle {
if idx + 1 != nodes.length: Path {
viewbox-width: self.width / 1px;
viewbox-height: self.height / 1px;
stroke: Palette.control-foreground;
stroke: RogPalette.accent;
stroke-width: 2px;
MoveTo {
x: scale_x_to_graph(nodes[idx].x) / 1px;
@@ -114,19 +115,19 @@ export component Graph inherits Rectangle {
for n[idx] in nodes: Rectangle {
states [
pressed when touch.pressed: {
point.background: Palette.selection-background;
tip.background: Palette.selection-background;
point.background: RogPalette.accent;
tip.background: RogPalette.accent;
tip.opacity: 1.0;
}
hover when touch.has-hover: {
point.background: Palette.accent-background;
tip.background: Palette.accent-background;
point.background: RogPalette.accent;
tip.background: RogPalette.accent;
tip.opacity: 1.0;
}
]
//
point := Rectangle {
background: Palette.control-foreground;
background: RogPalette.text-primary;
x: scale_x_to_graph(n.x) - self.width / 2;
y: graph.height - scale_y_to_graph(n.y) - self.height / 2;
width: 18px;
@@ -142,10 +143,14 @@ export component Graph inherits Rectangle {
} else if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) < nodes[idx - 1].x {
n.x = nodes[idx - 1].x + pad;
}
// Y-Axis: Monotonic Non-Decreasing
if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) > nodes[idx + 1].y {
n.y = nodes[idx + 1].y - pad;
n.y = nodes[idx + 1].y; // Allow equality
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < nodes[idx - 1].y {
n.y = nodes[idx - 1].y + pad;
n.y = nodes[idx - 1].y; // Allow equality
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < 0.0 {
n.y = 0px;
}
} else if idx == 0 {
if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) < 0.0 {
@@ -153,10 +158,12 @@ export component Graph inherits Rectangle {
} else if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) > nodes[idx + 1].x {
n.x = nodes[idx + 1].x - pad;
}
// Y-Axis: <= Next Point
if n.y - scale_y_to_node(self.mouse-y - self.pressed-y) < 0.0 {
n.y = 1px;
n.y = 0px; // Allow 0 RPM
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) > nodes[idx + 1].y {
n.y = nodes[idx + 1].y - pad;
n.y = nodes[idx + 1].y; // Allow equality
}
} else if idx == nodes.length - 1 {
if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) > scale_x_to_node(graph.width) {
@@ -164,10 +171,14 @@ export component Graph inherits Rectangle {
} else if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) < nodes[idx - 1].x {
n.x = nodes[idx - 1].x + pad;
}
// Y-Axis: >= Previous Point
if n.y - scale_y_to_node(self.mouse-y - self.pressed-y) > scale_y_to_node(graph.height) {
n.y = scale_y_to_node(graph.height - 1px);
n.y = scale_y_to_node(graph.height);
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < nodes[idx - 1].y {
n.y = nodes[idx - 1].y + pad;
n.y = nodes[idx - 1].y; // Allow equality
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < 0.0 {
n.y = 0px;
}
}
}
@@ -189,7 +200,7 @@ export component Graph inherits Rectangle {
}
tip := Rectangle {
background: Palette.control-foreground;
background: RogPalette.control-background;
opacity: 0.3;
x: final_x_pos();
y: final_y_pos();
@@ -224,7 +235,7 @@ export component Graph inherits Rectangle {
}
//
label := Text {
color: Palette.accent-foreground;
color: RogPalette.text-primary;
font-size: 16px;
text: "\{Math.floor(n.x / 1px)}c, \{fan_pct()}%";
}
+30 -12
View File
@@ -1,7 +1,8 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette, HorizontalBox, VerticalBox } from "std-widgets.slint";
import { HorizontalBox, VerticalBox } from "std-widgets.slint";
import { RogPalette } from "../themes/rog_theme.slint";
component SideBarItem inherits Rectangle {
// padding only has effect on layout elements
@@ -28,12 +29,21 @@ component SideBarItem inherits Rectangle {
]
state := Rectangle {
opacity: 0;
border-width: 2px;
border-radius: 10px;
border-color: Palette.accent-background;
background: Palette.alternate-background;
border-width: 0px; // Modern look: no full border, maybe just a left bar?
// Or keep the ROG style border
border-color: RogPalette.accent;
background: root.selected ? RogPalette.control-background : RogPalette.alternate-background;
// Add a red indicator line on the left for selected items
Rectangle {
x: 0;
width: 4px;
height: 100%;
background: root.selected ? RogPalette.accent : Colors.transparent;
}
animate opacity { duration: 150ms; }
animate border-width { duration: 150ms; }
// animate border-width { duration: 150ms; }
height: l.preferred-height;
}
@@ -41,9 +51,10 @@ component SideBarItem inherits Rectangle {
y: (parent.height - self.height) / 2;
spacing: 0px;
label := Text {
color: Palette.foreground;
color: root.selected ? RogPalette.accent : RogPalette.text-primary;
vertical-alignment: center;
font-size: 14px;
font-weight: root.selected ? 700 : 400;
}
}
@@ -66,10 +77,10 @@ export component SideBar inherits Rectangle {
accessible-role: tab;
accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item;
Rectangle {
border-width: 2px;
border-color: Palette.accent-background;
border-width: 0px;
// border-color: RogPalette.accent;
border-radius: 0px;
background: Palette.background.darker(0.2);
background: RogPalette.alternate-background; // Darker sidebar
fs := FocusScope {
key-pressed(event) => {
if (event.text == "\n") {
@@ -104,12 +115,19 @@ export component SideBar inherits Rectangle {
spacing: 4px;
alignment: start;
label := Text {
font-size: 16px;
font-size: 24px; // Larger brand text
font-weight: 800;
horizontal-alignment: center;
color: RogPalette.accent; // ROG Red brand text
}
// Spacer after brand text
Rectangle {
height: 20px;
}
navigation := VerticalLayout {
spacing: -6px;
spacing: 4px; // Spacing between items
alignment: start;
vertical-stretch: 0;
for item[index] in root.model: SideBarItem {
@@ -0,0 +1,58 @@
import { RogPalette } from "../themes/rog_theme.slint";
export global SystemStatus {
in property <int> cpu_temp: 0;
in property <int> gpu_temp: 0;
in property <int> cpu_fan: 0;
in property <int> gpu_fan: 0;
in property <string> power_w: "--";
in property <string> power_avg_w: "--";
}
component StatusItem inherits Rectangle {
in property <string> label;
in property <string> value;
in property <string> unit;
HorizontalLayout {
spacing: 5px;
Text { text: label; color: RogPalette.text-secondary; font-weight: 700; vertical-alignment: center; }
Text { text: value; color: RogPalette.text-primary; vertical-alignment: center; }
Text { text: unit; color: RogPalette.text-secondary; font-size: 12px; vertical-alignment: center; }
}
}
export component StatusBar inherits Rectangle {
background: RogPalette.control-background;
height: 30px;
// Simulated top border
Rectangle {
y: 0px;
x: 0px;
width: parent.width;
height: 1px;
background: RogPalette.control-border;
}
HorizontalLayout {
padding-left: 20px;
padding-right: 20px;
spacing: 20px;
alignment: space-between;
HorizontalLayout {
spacing: 20px;
StatusItem { label: "CPU"; value: SystemStatus.cpu_temp; unit: "°C"; }
StatusItem { label: "GPU"; value: SystemStatus.gpu_temp; unit: "°C"; }
}
HorizontalLayout {
spacing: 20px;
StatusItem { label: "PWR"; value: SystemStatus.power_w; unit: "W"; }
StatusItem { label: "AVG"; value: SystemStatus.power_avg_w; unit: "W"; }
StatusItem { label: "CPU Fan"; value: SystemStatus.cpu_fan; unit: "RPM"; }
StatusItem { label: "GPU Fan"; value: SystemStatus.gpu_fan; unit: "RPM"; }
}
}
}
@@ -0,0 +1,76 @@
import { RogPalette } from "../themes/rog_theme.slint";
import { SystemStatus } from "../widgets/status_bar.slint";
component StatusItem inherits Rectangle {
in property <string> label;
in property <string> value;
in property <string> unit;
HorizontalLayout {
spacing: 8px;
Text {
text: label;
color: RogPalette.text-secondary;
font-weight: 700;
vertical-alignment: center;
font-size: 13px;
}
Text {
text: value;
color: RogPalette.text-primary;
vertical-alignment: center;
font-size: 14px;
}
Text {
text: unit;
color: RogPalette.text-secondary;
font-size: 11px;
vertical-alignment: center;
}
}
}
export component TrayTooltip inherits Window {
always-on-top: true;
no-frame: true;
background: transparent;
width: 280px;
height: 160px;
Rectangle {
background: RogPalette.control-background;
border-radius: 8px;
border-width: 1px;
border-color: RogPalette.control-border;
drop-shadow-blur: 10px;
drop-shadow-color: rgba(0,0,0,0.5);
VerticalLayout {
padding: 15px;
spacing: 12px;
Text {
text: "System Statistics";
color: RogPalette.accent;
font-size: 16px;
font-weight: 800;
}
GridLayout {
spacing: 15px;
Row {
StatusItem { label: "CPU"; value: SystemStatus.cpu_temp; unit: "°C"; }
StatusItem { label: "GPU"; value: SystemStatus.gpu_temp; unit: "°C"; }
}
Row {
StatusItem { label: "FAN"; value: SystemStatus.cpu_fan; unit: "RPM"; }
StatusItem { label: "GPU"; value: SystemStatus.gpu_fan; unit: "RPM"; }
}
Row {
StatusItem { label: "PWR"; value: SystemStatus.power_w; unit: "W"; }
StatusItem { label: "AVG"; value: SystemStatus.power_avg_w; unit: "W"; }
}
}
}
}
}