From 73bb77fe46aa5a1a7b09ee13d8ee0bdc327f7647 Mon Sep 17 00:00:00 2001 From: Benexl Date: Tue, 12 Aug 2025 16:50:21 +0300 Subject: [PATCH] feat(rofi-theme-defaults): enhance ui and ux --- .../assets/defaults/rofi-themes/confirm.rasi | 118 +++++++++--- .../assets/defaults/rofi-themes/input.rasi | 103 ++++++---- .../assets/defaults/rofi-themes/main.rasi | 124 +++++++----- .../assets/defaults/rofi-themes/preview.rasi | 177 ++++++++---------- fastanime/libs/selectors/rofi/selector.py | 22 ++- 5 files changed, 330 insertions(+), 214 deletions(-) diff --git a/fastanime/assets/defaults/rofi-themes/confirm.rasi b/fastanime/assets/defaults/rofi-themes/confirm.rasi index 80107b7..7fb718e 100644 --- a/fastanime/assets/defaults/rofi-themes/confirm.rasi +++ b/fastanime/assets/defaults/rofi-themes/confirm.rasi @@ -1,55 +1,113 @@ +/** + * Rofi Theme: FastAnime "Tokyo Night" Confirmation + * Author: Gemini ft Benexl + * Description: A compact and clear modal dialog for Yes/No confirmations that displays a prompt. + */ + +/*****----- Configuration -----*****/ configuration { - font: "Sans 12"; + font: "JetBrains Mono Nerd Font 12"; } +/*****----- Global Properties -----*****/ * { - background-color: rgba(0, 0, 0, 0.7); - text-color: #FFFFFF; + /* Tokyo Night Color Palette */ + bg-col: #1a1b26; + bg-alt: #24283b; + fg-col: #c0caf5; + + blue: #7aa2f7; + green: #9ece6a; /* For 'Yes' */ + red: #f7768e; /* For 'No' */ + + background-color: transparent; + text-color: @fg-col; } +/*****----- Main Window -----*****/ window { - fullscreen: true; - transparency: "real"; - background-color: transparent; + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 350px; + + border: 2px; + border-color: @blue; + border-radius: 12px; + padding: 20px; + background-color: @bg-col; } +/*****----- Main Box -----*****/ mainbox { - children: [ message, listview, inputbar ]; - padding: 40% 30%; + children: [ inputbar, message, listview ]; + spacing: 15px; background-color: transparent; } -message { - border: 0; - padding: 10px; - border-radius:20px; - margin: 0 0 20px 0; - font: "Sans Bold 24"; /* Increased font size and made it bold */ -} - +/*****----- Inputbar (Displays the -p 'prompt') -----*****/ inputbar { - children: [ prompt, entry ]; - background-color: rgba(255, 255, 255, 0.1); - padding: 8px; - border-radius: 4px; + background-color: transparent; + text-color: @blue; + children: [ prompt ]; } prompt { - padding: 8px; -} - -entry { - padding: 8px; + font: "JetBrains Mono Nerd Font Bold 14"; + horizontal-align: 0.5; /* Center the title */ background-color: transparent; + text-color: inherit; } -listview { - lines: 0; + +/*****----- Message (Displays the -mesg 'Are you Sure?') -----*****/ +message { + padding: 10px; + margin: 5px 0px; + border-radius: 8px; + background-color: @bg-alt; + text-color: @fg-col; } -/* Style for the message text specifically */ textbox { - horizontal-align: 0.5; /* Center the text */ - font: "Sans Bold 24"; /* Match message font */ + font: "JetBrains Mono Nerd Font 12"; + horizontal-align: 0.5; + background-color: transparent; + text-color: inherit; +} + +/*****----- Listview (The Buttons) -----*****/ +listview { + columns: 2; + lines: 1; + spacing: 15px; + layout: vertical; background-color: transparent; } + +/*****----- Elements (Yes/No Buttons) -----*****/ +element { + padding: 12px; + border-radius: 8px; + background-color: @bg-alt; + text-color: @fg-col; + cursor: pointer; +} + +element-text { + font: "JetBrains Mono Nerd Font Bold 12"; + horizontal-align: 0.5; + background-color: transparent; + text-color: inherit; +} + +element normal.normal { + background-color: @bg-alt; + text-color: @fg-col; +} + +element selected.normal { + background-color: @blue; + text-color: @bg-col; +} diff --git a/fastanime/assets/defaults/rofi-themes/input.rasi b/fastanime/assets/defaults/rofi-themes/input.rasi index 80107b7..60917be 100644 --- a/fastanime/assets/defaults/rofi-themes/input.rasi +++ b/fastanime/assets/defaults/rofi-themes/input.rasi @@ -1,55 +1,86 @@ +/** + * Rofi Theme: FastAnime "Tokyo Night" Input + * Author: Gemini ft Benexl + * Description: A compact, modern modal dialog for text input that correctly displays the prompt. + */ + +/*****----- Configuration -----*****/ configuration { - font: "Sans 12"; + font: "JetBrains Mono Nerd Font 14"; } +/*****----- Global Properties -----*****/ * { - background-color: rgba(0, 0, 0, 0.7); - text-color: #FFFFFF; + /* Tokyo Night Color Palette */ + bg-col: #1a1b26ff; + bg-alt: #24283bff; + fg-col: #c0caf5ff; + fg-alt: #a9b1d6ff; + accent: #bb9af7ff; + blue: #7aa2f7ff; + + background-color: transparent; + text-color: @fg-col; } +/*****----- Main Window -----*****/ window { - fullscreen: true; - transparency: "real"; - background-color: transparent; + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 500px; + + border: 2px; + border-color: @blue; + border-radius: 8px; + padding: 20px; + background-color: @bg-col; } +/*****----- Main Box -----*****/ mainbox { - children: [ message, listview, inputbar ]; - padding: 40% 30%; + children: [ message, inputbar ]; + spacing: 20px; background-color: transparent; } +/*****----- Message (The Main Question, uses -mesg) -----*****/ message { - border: 0; - padding: 10px; - border-radius:20px; - margin: 0 0 20px 0; - font: "Sans Bold 24"; /* Increased font size and made it bold */ + padding: 10px; + border-radius: 8px; + background-color: @bg-alt; + text-color: @fg-col; } -inputbar { - children: [ prompt, entry ]; - background-color: rgba(255, 255, 255, 0.1); - padding: 8px; - border-radius: 4px; -} - -prompt { - padding: 8px; -} - -entry { - padding: 8px; - background-color: transparent; -} - -listview { - lines: 0; -} - -/* Style for the message text specifically */ textbox { - horizontal-align: 0.5; /* Center the text */ - font: "Sans Bold 24"; /* Match message font */ + font: "JetBrains Mono Nerd Font Bold 14"; + horizontal-align: 0.5; /* Center the prompt text */ background-color: transparent; + text-color: inherit; +} + +/*****----- Inputbar (Contains the title and entry field) -----*****/ +inputbar { + padding: 8px 12px; + border: 1px; + border-radius: 6px; + border-color: @accent; + background-color: @bg-alt; + spacing: 10px; + children: [ prompt, entry ]; +} + +/* This is the title from the -p flag */ +prompt { + background-color: transparent; + text-color: @accent; +} + +/* This is where the user types */ +entry { + background-color: transparent; + text-color: @fg-col; + placeholder: "Type here..."; + placeholder-color: @fg-alt; } diff --git a/fastanime/assets/defaults/rofi-themes/main.rasi b/fastanime/assets/defaults/rofi-themes/main.rasi index 9027343..07c3470 100644 --- a/fastanime/assets/defaults/rofi-themes/main.rasi +++ b/fastanime/assets/defaults/rofi-themes/main.rasi @@ -1,80 +1,104 @@ +/** + * Rofi Theme: FastAnime "Tokyo Night" Main + * Author: Gemini ft Benexl + * Description: A sharp, modern, and ultra-compact theme with a Tokyo Night palette. + */ + +/*****----- Configuration -----*****/ configuration { - font: "Sans 12"; - line-margin: 10; - display-drun: ""; + font: "JetBrains Mono Nerd Font 14"; + show-icons: false; + location: 0; /* 0 = center */ + width: 50; + yoffset: -50; + lines: 3; } +/*****----- Global Properties -----*****/ * { - background: #000000; /* Black background for everything */ - background-alt: #000000; /* Ensures no alternation */ - foreground: #CCCCCC; - selected: #3584E4; - active: #2E7D32; - urgent: #C62828; + /* Tokyo Night Color Palette */ + bg-col: #1a1b26ff; /* Main Background */ + bg-alt: #24283bff; /* Lighter Background for elements */ + fg-col: #c0caf5ff; /* Main Foreground */ + fg-alt: #a9b1d6ff; /* Dimmer Foreground for placeholders */ + accent: #bb9af7ff; /* Magenta/Purple for accents */ + selected: #7aa2f7ff; /* Blue for selection highlight */ + + background-color: transparent; + text-color: @fg-col; } +/*****----- Main Window -----*****/ window { - fullscreen: false; - background-color: rgba(0, 0, 0, 0.8); /* Solid black transparent background */ - border-radius: 50px; + transparency: "real"; + background-color: @bg-col; + border: 2px; + border-color: @selected; /* Using blue for the main border */ + border-radius: 8px; + padding: 12px; } +/*****----- Main Box -----*****/ mainbox { - padding: 50px 50px; - background-color: transparent; /* Ensures black background fills entire main area */ - children: [inputbar, listview]; - spacing: 20px; + children: [ inputbar, listview ]; + spacing: 10px; + background-color: transparent; } +/*****----- Inputbar -----*****/ inputbar { - background-color: #333333; /* Dark gray background for input bar */ - padding: 8px; - border-radius: 8px; - children: [prompt, entry]; + background-color: @bg-alt; + border: 1px; + border-color: @accent; /* Using magenta for the input border */ + border-radius: 6px; + padding: 6px 12px; + spacing: 12px; + children: [ prompt, entry ]; } prompt { - enabled: true; - padding: 8px; - background-color: @selected; - text-color: #000000; - border-radius: 4px; + background-color: transparent; + text-color: @accent; } entry { - padding: 8px; - background-color: transparent; /* Slightly lighter gray for visibility */ - text-color: #FFFFFF; /* White text to make typing visible */ - placeholder: "Search..."; - placeholder-color: rgba(255, 255, 255, 0.5); - border-radius: 6px; + background-color: transparent; + text-color: @fg-col; + placeholder: "Search..."; + placeholder-color: @fg-alt; } +/*****----- List of items -----*****/ listview { - layout: vertical; - spacing: 8px; - lines: 9; - background-color: transparent; /* Consistent black background for list items */ + scrollbar: false; + spacing: 4px; + padding: 4px 0px; + layout: vertical; + background-color: transparent; } +/*****----- Elements -----*****/ element { - padding: 12px; - border-radius: 4px; - background-color: transparent; /* Uniform color for each list item */ - text-color: @foreground; -} - -element normal.normal { - background-color: transparent; /* Ensures no alternating color */ -} - -element selected.normal { - background-color: @selected; - text-color: #FFFFFF; + padding: 6px 12px; + border-radius: 6px; + spacing: 15px; + background-color: transparent; } element-text { + vertical-align: 0.5; background-color: transparent; - text-color: inherit; - vertical-align: 0.5; + text-color: inherit; +} + +/* Default state of elements */ +element normal.normal { + background-color: transparent; + text-color: @fg-col; +} + +/* Selected entry in the list */ +element selected.normal { + background-color: @selected; /* Blue highlight */ + text-color: @bg-col; /* Dark text for high contrast */ } diff --git a/fastanime/assets/defaults/rofi-themes/preview.rasi b/fastanime/assets/defaults/rofi-themes/preview.rasi index f381f79..feac9cf 100644 --- a/fastanime/assets/defaults/rofi-themes/preview.rasi +++ b/fastanime/assets/defaults/rofi-themes/preview.rasi @@ -1,120 +1,109 @@ -// Colours -* { - background-color: transparent; /* Transparent background for the global UI */ - background: #000000; /* Solid black background */ - background-transparent: #1D2330A0; /* Semi-transparent background */ - text-color: #BBBBBB; /* Default text color (light gray) */ - text-color-selected: #FFFFFF; /* Text color when selected (white) */ - primary: rgba(53, 132, 228, 0.75); /* Blusish primary color */ - important: rgba(53, 132, 228, 0.75); /* Bluish primary color */ -} +/** + * Rofi Theme: FastAnime "Tokyo Night" Horizontal Strip + * Author: Gemini ft Benexl + * Description: A fullscreen, horizontal, icon-centric theme for previews. + */ +/*****----- Configuration -----*****/ configuration { - font: "Roboto 14"; /* Sets the global font to Roboto, size 14 */ - show-icons: true; /* Option to display icons in the UI */ + font: "JetBrains Mono Nerd Font 12"; + show-icons: true; } +/*****----- Global Properties -----*****/ +* { + /* Tokyo Night Color Palette */ + bg-col: #1a1b26; + bg-alt: #24283b; /* Slightly lighter for elements */ + fg-col: #c0caf5; + fg-alt: #a9b1d6; + + blue: #7aa2f7; + cyan: #7dcfff; + magenta: #bb9af7; + + background-color: transparent; + text-color: @fg-col; +} + +/*****----- Main Window -----*****/ window { - fullscreen: true; /* The window will open in fullscreen */ - height: 100%; /* Full window height */ - width: 100%; /* Full window width */ - transparency: "real"; /* Real transparency effect */ - background-color: @background-transparent; /* Transparent background */ - border: 0px; /* No border around the window */ - border-color: @primary; /* Border color set to the primary color */ + transparency: "real"; + background-color: @bg-col; + fullscreen: true; + padding: 2%; } +/*****----- Main Box -----*****/ mainbox { - children: [prompt, inputbar-box, listview]; /* Main box contains prompt, input bar, and list view */ - padding: 0px; /* No padding around the main box */ + children: [ inputbar, listview ]; + spacing: 3%; + background-color: transparent; +} + +/*****----- Inputbar -----*****/ +inputbar { + spacing: 15px; + padding: 12px 16px; + border-radius: 10px; + background-color: @bg-alt; + text-color: @fg-col; + margin: 0% 20%; /* Center the input bar */ + children: [ prompt, entry ]; } prompt { - width: 100%; /* Prompt takes full width */ - margin: 10px 0px 0px 30px; /* Margin around the prompt */ - text-color: @important; /* Text color for prompt (important color) */ - font: "Roboto Bold 27"; /* Bold Roboto font, size 27 */ -} - -listview { - layout: vertical; /* Vertical layout for list items */ - padding: 10px; /* Padding inside the list view */ - spacing: 20px; /* Space between items in the list */ - columns: 8; /* Maximum 8 items per row */ - dynamic: true; /* Allows the list to dynamically adjust */ - orientation: horizontal; /* Horizontal orientation for list items */ -} - -inputbar-box { - children: [dummy, inputbar, dummy]; /* Input bar is centered with dummy placeholders */ - orientation: horizontal; /* Horizontal layout for input bar */ - expand: false; /* Does not expand to fill the space */ -} - -inputbar { - children: [textbox-prompt, entry]; /* Contains a prompt and an entry field */ - margin: 0px; /* No margin around the input bar */ - background-color: @primary; /* Background color set to the primary color */ - border: 4px; /* Border thickness around the input bar */ - border-color: @primary; /* Border color matches the primary color */ - border-radius: 8px; /* Rounded corners for the input bar */ -} - -textbox-prompt { - text-color: @background; /* Text color inside prompt matches the background color */ - horizontal-align: 0.5; /* Horizontally centered */ - vertical-align: 0.5; /* Vertically centered */ - expand: false; /* Does not expand to fill available space */ + text-color: @magenta; + background-color: transparent; } entry { - expand: false; /* Entry field does not expand */ - padding: 8px; /* Padding inside the entry field */ - margin: -6px; /* Negative margin to position entry properly */ - horizontal-align: 0; /* Left-aligned text inside the entry field */ - width: 300; /* Fixed width for the entry field */ - background-color: @background; /* Entry background color matches the global background */ - border: 6px; /* Border thickness around the entry field */ - border-color: @primary; /* Border color matches the primary color */ - border-radius: 8px; /* Rounded corners for the entry field */ - cursor: text; /* Cursor changes to text input cursor inside the entry field */ + background-color: transparent; + placeholder: "Select an option..."; + placeholder-color: @fg-alt; } +/*****----- List of items -----*****/ +listview { + layout: horizontal; + columns: 5; + spacing: 20px; + fixed-height: true; + background-color: transparent; +} + +/*****----- Elements -----*****/ element { - children: [dummy, element-box, dummy]; /* Contains an element box with dummy placeholders */ - padding: 5px; /* Padding around the element */ - orientation: vertical; /* Vertical layout for element content */ - border: 0px; /* No border around the element */ - border-radius: 16px; /* Rounded corners for the element */ - background-color: transparent; /* Transparent background */ - width: 100px; /* Width of each element */ - height: 50px; /* Height of each element */ -} - -element selected { - background-color: @primary; /* Background color of the element when selected */ -} - -element-box { - children: [element-icon, element-text]; /* Element box contains an icon and text */ - orientation: vertical; /* Vertical layout for icon and text */ - expand: false; /* Does not expand to fill available space */ - cursor: pointer; /* Cursor changes to a pointer when hovering over the element */ + orientation: vertical; + padding: 30px 20px; + border-radius: 12px; + spacing: 20px; + background-color: @bg-alt; + cursor: pointer; + width: 200px; /* Width of each element */ + height: 50px; /* Height of each element */ } element-icon { - padding: 10px; /* Padding inside the icon */ - cursor: inherit; /* Inherits cursor style from the parent */ - size: 33%; /* Icon size is set to 33% of the parent element */ - margin: 10px; /* Margin around the icon */ + size: 33%; + horizontal-align: 0.5; + background-color: transparent; } element-text { - horizontal-align: 0.5; /* Horizontally center-aligns the text */ - cursor: inherit; /* Inherits cursor style from the parent */ - text-color: @text-color; /* Text color for element text */ + horizontal-align: 0.5; + background-color: transparent; + text-color: inherit; } -element-text selected { - text-color: @text-color-selected; /* Text color when the element is selected */ +/* Default state of elements */ +element normal.normal { + background-color: @bg-alt; + text-color: @fg-col; +} + +/* Selected entry in the list */ +element selected.normal { + background-color: @blue; + text-color: @bg-col; /* Invert text color for contrast */ } diff --git a/fastanime/libs/selectors/rofi/selector.py b/fastanime/libs/selectors/rofi/selector.py index c19098c..6c43b4a 100644 --- a/fastanime/libs/selectors/rofi/selector.py +++ b/fastanime/libs/selectors/rofi/selector.py @@ -1,5 +1,6 @@ import shutil import subprocess +import textwrap from ....core.config import RofiConfig from ....core.utils import detect @@ -18,11 +19,14 @@ class RofiSelector(BaseSelector): preview = None rofi_input = preview if preview else "\n".join(choices) + theme = self.config.theme_preview if preview else self.config.theme_main + theme = theme if choices else self.config.theme_input + theme = self.config.theme_confirm if "Yes" in choices else theme args = [ self.executable, "-no-config", "-theme", - self.config.theme_preview if preview else self.config.theme_main, + theme, "-p", prompt, "-i", @@ -40,15 +44,23 @@ class RofiSelector(BaseSelector): if result: choice = result.stdout.strip() return choice + else: + # HACK: force exit if no input + exit(1) def confirm(self, prompt, *, default=False): choices = ["Yes", "No"] default_choice = "Yes" if default else "No" - result = self.choose(prompt, choices, header=f"Default: {default_choice}") + + result = self.choose( + "\n".join(textwrap.wrap(prompt, width=30)), + choices, + header=f"Default: {default_choice}", + ) return result == "Yes" def ask(self, prompt, *, default=None): - return self.choose(prompt, []) + return self.choose("\n".join(textwrap.wrap(prompt, width=30)), []) def choose_multiple( self, prompt: str, choices: list[str], preview: str | None = None @@ -75,7 +87,9 @@ class RofiSelector(BaseSelector): if result: choice = result.stdout.strip() return choice.split() - return [] + + # HACK: force exit if no input + exit(1) if __name__ == "__main__":