Compare commits
6 Commits
1c9598c00a
...
0.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
30f3ab4ca5
|
|||
|
c26ca6ec02
|
|||
|
99d6d2a578
|
|||
|
603af4f378
|
|||
|
66e7ca4fc7
|
|||
|
a015908d44
|
@@ -0,0 +1,10 @@
|
||||
---
|
||||
inclusion: always
|
||||
---
|
||||
<!------------------------------------------------------------------------------------
|
||||
Add rules to this file or a short description and have Kiro refine them for you.
|
||||
|
||||
Learn about inclusion modes: https://kiro.dev/docs/steering/#inclusion-modes
|
||||
------------------------------------------------------------------------------------->
|
||||
|
||||
This project has a GUI and a TUI when fixing or implmenting features access and make changes to both.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 358 KiB |
@@ -0,0 +1,179 @@
|
||||
# Steam Collections Page Design Update Summary
|
||||
|
||||
## Overview
|
||||
Updated all UI screens (except mod manager) to match Steam Collections page design with modern dark blue theme, improved typography, and Steam-inspired visual elements.
|
||||
|
||||
## Color Scheme Changes
|
||||
|
||||
### New Steam Collections Inspired Colors
|
||||
```python
|
||||
COLORS = {
|
||||
'bg_primary': '#1b2838', # Steam dark blue background
|
||||
'bg_secondary': '#2a475e', # Steam medium blue background
|
||||
'bg_tertiary': '#1e2328', # Steam darker background for cards
|
||||
'bg_card': '#16202d', # Steam card background
|
||||
'bg_hover': '#2a475e', # Steam hover state
|
||||
'text_primary': '#c7d5e0', # Steam primary text (light blue-gray)
|
||||
'text_highlight': '#66c0f4', # Steam blue highlight color
|
||||
'text_body': '#8f98a0', # Steam body text (muted blue-gray)
|
||||
'text_secondary': '#acb2b8', # Steam secondary text
|
||||
'text_muted': '#67707b', # Steam muted text
|
||||
'accent_green': '#5ba32b', # Steam success green
|
||||
'accent_red': '#cd5c5c', # Steam error red
|
||||
'accent_yellow': '#ffa500', # Steam warning orange
|
||||
'accent_blue': '#66c0f4', # Steam signature blue
|
||||
'border_light': '#3c4043', # Steam light border
|
||||
'border_dark': '#0e141b', # Steam dark border
|
||||
}
|
||||
```
|
||||
|
||||
### Previous Colors (Replaced)
|
||||
- Old yellow-green highlights (#f5f5b5) → Steam blue (#66c0f4)
|
||||
- Old gray backgrounds (#424041) → Steam dark blue (#1b2838)
|
||||
- Old bright colors → Muted Steam palette
|
||||
|
||||
## GUI Changes (steam_workshop_gui.py)
|
||||
|
||||
### 1. Main Application Window
|
||||
- **Background**: Updated to Steam dark blue (#1b2838)
|
||||
- **Card System**: Implemented Steam-style cards with rounded corners (12px radius)
|
||||
- **Typography**: Enhanced with Steam blue highlights for titles
|
||||
- **Padding**: Increased from 10px to 15px for better spacing
|
||||
|
||||
### 2. Input Section Redesign
|
||||
- **Card-based Layout**: Each section now uses Steam-style cards
|
||||
- RimWorld Installation card
|
||||
- Workshop Content card
|
||||
- Advanced Configuration card
|
||||
- Steam Workshop Collections card
|
||||
- **Input Fields**:
|
||||
- Dark backgrounds (#1e2328)
|
||||
- Steam blue focus borders (#66c0f4)
|
||||
- Improved padding and spacing
|
||||
- **Buttons**:
|
||||
- Primary button: Steam blue (#66c0f4) with dark text
|
||||
- Secondary button: Steam green (#5ba32b)
|
||||
- Disabled state: Muted colors
|
||||
|
||||
### 3. Output Section (Logs)
|
||||
- **Card Container**: Logs now in Steam-style card
|
||||
- **Color-coded Messages**:
|
||||
- Success: Steam green
|
||||
- Error: Steam red
|
||||
- Warning: Steam orange
|
||||
- Info: Steam blue
|
||||
- **Timestamps**: Added with muted color
|
||||
- **Background**: Dark Steam theme (#1e2328)
|
||||
|
||||
### 4. Loading Screen Updates
|
||||
- **Card Backgrounds**: Updated to Steam styling with subtle borders
|
||||
- **Corner Radius**: Reduced from 20px to 12px for modern look
|
||||
- **Colors**: All text and UI elements use Steam palette
|
||||
- **Error Cards**: Steam red accents for error states
|
||||
|
||||
### 5. Button Styling
|
||||
- **Enable State**: Steam blue primary, Steam green secondary
|
||||
- **Disable State**: Muted Steam colors
|
||||
- **Hover Effects**: Lighter Steam blue on hover
|
||||
- **Cursor**: Hand cursor for better UX
|
||||
|
||||
## TUI Changes (progression_tui.py)
|
||||
|
||||
### 1. Color Scheme
|
||||
- Updated all TUI_COLORS to match GUI Steam palette
|
||||
- Consistent blue theme throughout terminal interface
|
||||
|
||||
### 2. Header Styling
|
||||
- **Border**: Steam blue double border
|
||||
- **Title**: Added "PROGRESSION LOADER" title to panel
|
||||
- **ASCII Art**: Highlighted with Steam blue
|
||||
|
||||
### 3. Menu System
|
||||
- **Table Styling**: Rounded borders with Steam blue accents
|
||||
- **Status Indicators**:
|
||||
- Valid: ✓ with Steam green
|
||||
- Invalid: ⚠ with Steam yellow
|
||||
- Ready: ✓ Ready with Steam green
|
||||
- Disabled: ⚠ Disabled with muted colors
|
||||
|
||||
### 4. Configuration Display
|
||||
- **Path Display**: Added icons and Steam blue labels
|
||||
- **Panel Styling**: Rounded borders with Steam theme
|
||||
- **Status Colors**: Consistent with GUI
|
||||
|
||||
## Font and Styling (font_and_colors_update.py)
|
||||
|
||||
### 1. New Utility Functions
|
||||
- `apply_steam_styling()`: Returns Steam-inspired style dictionaries
|
||||
- `get_steam_button_colors()`: Provides button color schemes by type
|
||||
- Updated color constants to match Steam theme
|
||||
|
||||
### 2. Button Color Schemes
|
||||
- **Default**: Steam secondary background
|
||||
- **Primary**: Steam blue with dark text
|
||||
- **Success**: Steam green
|
||||
- **Warning**: Steam orange
|
||||
- **Danger**: Steam red
|
||||
|
||||
## Visual Improvements
|
||||
|
||||
### 1. Card System
|
||||
- **Rounded Corners**: 12px radius for modern look
|
||||
- **Subtle Borders**: Light Steam borders (#3c4043)
|
||||
- **Inner Highlights**: Very subtle Steam blue inner glow
|
||||
- **Proper Spacing**: Consistent 10-15px padding
|
||||
|
||||
### 2. Typography Hierarchy
|
||||
- **Titles**: Steam blue (#66c0f4) with bold weight
|
||||
- **Labels**: Steam secondary text (#acb2b8)
|
||||
- **Body Text**: Steam body color (#8f98a0)
|
||||
- **Muted Text**: Steam muted (#67707b)
|
||||
|
||||
### 3. Interactive Elements
|
||||
- **Focus States**: Steam blue borders on input fields
|
||||
- **Hover Effects**: Lighter Steam blue on buttons
|
||||
- **Status Indicators**: Color-coded with Steam palette
|
||||
- **Blinking Animation**: Steam blue/muted for invalid states
|
||||
|
||||
## Consistency Improvements
|
||||
|
||||
### 1. Cross-Platform
|
||||
- GUI and TUI now use matching color schemes
|
||||
- Consistent terminology and styling
|
||||
- Same visual hierarchy in both interfaces
|
||||
|
||||
### 2. Error Handling
|
||||
- Consistent error colors (Steam red)
|
||||
- Warning colors (Steam orange)
|
||||
- Success colors (Steam green)
|
||||
- Info colors (Steam blue)
|
||||
|
||||
### 3. Accessibility
|
||||
- Better contrast ratios with Steam's tested palette
|
||||
- Consistent focus indicators
|
||||
- Clear visual hierarchy
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. **steam_workshop_gui.py** - Main GUI application
|
||||
2. **progression_tui.py** - Terminal user interface
|
||||
3. **font_and_colors_update.py** - Color and styling utilities
|
||||
4. **update_checker.py** - Update dialog styling
|
||||
|
||||
## Testing
|
||||
|
||||
- ✅ Syntax validation passed for all Python files
|
||||
- ✅ Color scheme consistency verified
|
||||
- ✅ Both GUI and TUI updated per requirements
|
||||
- ✅ Steam Collections design patterns implemented
|
||||
|
||||
## Result
|
||||
|
||||
The application now features a cohesive Steam Collections inspired design with:
|
||||
- Modern dark blue theme matching Steam's visual identity
|
||||
- Improved card-based layouts for better organization
|
||||
- Consistent typography and color usage
|
||||
- Enhanced user experience with better visual hierarchy
|
||||
- Professional appearance matching Steam's design standards
|
||||
|
||||
All screens except the mod manager have been updated to match the Steam Collections page design as requested.
|
||||
@@ -0,0 +1,116 @@
|
||||
@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@ @ @@@@@@@@@@
|
||||
@....................@@@ @....................%@@@ @@@...........*@@@ @@@+................@@ @....................@@@ @@......................@@ @@@...................@@ @@@..................@@@ @@.......@@ @@@@...........@@@ @..@@ @@.......@@
|
||||
@@.......................@@ @*......................@@@ @@..................@@@ @@@....................@@@@@@.......................@@ @@......................@@@@ @@%......................@@@ @@.......................@@@ @@.......@@@@ @@..................@@@ @....@@ @@.......@@@@
|
||||
@@.........................@@@ @@#........................@@@ @@......................@@@ @@.......................@@@@@@.........................@@@ @@@......................@@@@@@@.........................@@@@ @.........................%@@@@@@.......@@@@@ @@......................@@@ @=.....@@ @@.......@@@@@
|
||||
@@..........................@@@@@@*.........................@@@@ @@..........................@@@ @@........................@@@@@@..........................@@@@@@@......................@@@@@@..........................@@@@@@@..........................@@@@@@.......@@@@@@@..........................@@@@@@=......@@@ @@@.......@@@@@
|
||||
@@.......@@@@@@@@@@@........@@@@@@*.......@@@@@@@@@@@........@@@@@@.........#@@@@@@@@..........@@@ @@..........@@@@@@@@@@@@@@@@@@@@@.......@@@@@@@@@@@........@@@@@@@.......@@@@@@@@@@@@@@@@@@@@@.......@@@@@@@@@@@@@@@@@@@@@@@@@........@@@@@@@@@@@@@@@@@@@@@@@@@.......@@@@@@..........@@@@@@@@@.........@@@@@=........@@@@@@.......@@@@@
|
||||
@@.......@@@@@@@@@@@@.......@@@@@@#.......@@@@@@@@@@@........@@@@@........@@@@@@@@@@@@@.........@@@@@.........@@@@@@@@@@@@@@@@@@@@@@@.......@@@@@@@@@@@@.......@@@@@@@.......@@@@@@@@@@@@@@@@@@@@@.......@@@@@@@@@@@@@@@@@@@@@@@@@........@@@@@@@@@@@@@@@@@@@@@@@@@.......@@@@@@........@@@@@@@@@@@@@........@@@@=..........@@@@.......@@@@@
|
||||
@@.......@@@@@@@@@@@@.......@@@@@@#.......@@@@@@@@@@@........@@@@@.......@@@@@@@@@@@@@@@@.......@@@@@.......@@@@@@@@@@@@@@@@@@@@@@@@@.......@@@@@@@@@@@@.......@@@@@@@................@@@@@@@@@@@@..................@@@@@@@@@@@@@@#..................@@@@@@@@@@@@@@.......@@@@@........@@@@@@@@@@@@@@@........@@@+............@@.......@@@@@
|
||||
@@.......@.......:..........@@@@@@#.........................@@@@@........@@@@@@@@@@@@@@@@.......*@@@........@@@@@@@@@@@@@@@@@@.@@@@@@..........................@@@@@@@................@@@@@@@@@@@@@.....................@@@@@@@@@@@......................@@@@@@@@@@.......@@@@@.......@@@@@@@@@@@@@@@@@.......@@@+.....................@@@@@
|
||||
@@.........................@@@@@@@#........................:@@@@@........@@@@@@@ @@@@@........@@@........@@@@@@@@ @@@.....@@@@@@.........................@@@@@@@@................@@@@@ @@@@......................@@@@ @@@@@......................@@@ @@@.......@@@@@.......@@@@@@@@ @@@@@.......@@@+.....................@@@@@
|
||||
@@........................@@@@@@@@#.......................@@@@@@@@.......@@@@@@ @@@.......@@@@*.......@@@@@@ @........@@@@@@........................@@@@@@@@@................@@@@@ @@@@@@@....................@@@@ @@@@@@@.....................@@@@@@@.......@@@@@.......@@@@@@ @@@........@@@+.......@.............@@@@@
|
||||
@@......................@@@@@@@@@@#.....................@@@@@@@@@@........@@@@ @@........@@@@@........@@@@ @........@@@@@@.....................@@@@@@@@@@@@.......@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@........@@@@@@@@@@@@@@@@@@@@@@@@........@@@@@@@.......@@@@@........@@@@@ @@.......@@@@*.......@@............@@@@@
|
||||
@@.......@*********@@@@@@@@@@@@@@@#.......@****@........@@@@@@@@@@@........@@@@ @@@........@@@@@@.........@@@@ @@........@@@@@@.......@****%.........@@@@@@@@@@@.......@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@.......@@@@@ @@@@@@@@@@@@@@@@@@@........@@@@@@.......@@@@@@........@@@@ @@.........@@@@*.......@@@@..........@@@@@
|
||||
@@.......@@@@@@@@@@@@@@@@@@@@@@@@@%.......@@@@@@@........@@@@@@@@@@...........@@@@@@..........@@@@@@@@............@@@@@........@@@@@@.......@@@@@@@.........@@@@@@@@@@.......@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@........@@@@@@@@@@@@@@@@@@@@@@@@........@@@@@@@.......@@@@@@@..........@@@@@@...........@@@@@*.......@@@@@@........@@@@@
|
||||
@@.......@@@@@@@@@@@@@@@@@@@@ @@#.......@@@@@@@@........@@@@@@@@@@@........................@@@@@@@@@@@.......................@@@@@@.......@@@@@@@@=........@@@@ @@@......................@@@ @@.........................@@@@@@@..........................@@@@@@@.......@@@@@@@@........................@@@@@@@*.......@@@@@@@@......@@@@@
|
||||
@@.......@@@@@@@@@@@@@@@@@ @@@.......@@@@@@@@@........@@@@@@@@@@@@....................@@@@@@@@@@@@@@-.....................@@@@@@.......@@@@@@@@@@........@@@@ @@@......................@@@@@@........................@@@@@@@@.........................@@@@@@@@.......@@@@@@@@@@.....................@@@@@@@@@.......@@@@@@@@@@....@@@@@
|
||||
@@@......@@@@@@@@@@@@ @@@*......@@@@@@@@@@.........@@@@@@@@@@@@...............-@@@@@@@@@@@@@@@@@@@...................@@@@@@@......@@@@@@@@@@@........@@@@@@@@.....................@@@@@@@.....................@@@@@@@@@@@:.....................@@@@@@@@@@@......@@@@@@@@@@@@@...............@@@@@@@@@@@@@......@@@@@@@@@@@@..@@@@@
|
||||
@@@@@@@.+@@@@@@ @@@@@@@-.@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@@@@@@#..@@@@@@@@@@@@@@@@ @@@@@@@@@@@@-...........-@@@@@@@@@@@.+@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@#................*@@@@@@@@@@+............@@@@@@@@@@@@@@@@@@@@............%@@@@@@@@@@@@@@@@@@@*.@@@@@@@@@@@@@@@@@@@@:.*@@@@@@@@@@@@@@@@@@@@@@#.@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@@@@@@
|
||||
@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@
|
||||
@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@
|
||||
|
||||
@@@@@@@@%@@@@@@@@
|
||||
@@@....@@@@.....@@@@@@
|
||||
%@@.....@@@@..........@@@@
|
||||
%@@......@@@@.............@@@%
|
||||
:@@.......@@@@...............@@@-
|
||||
@@@.......@@@@.................@@@
|
||||
@@@........@@@@..................@@@
|
||||
@@@.....@@@@@@@@@@@.................@@+
|
||||
@@@......@@-. .+@@@@:..............@@-
|
||||
@@@.......@@ @@@@.............@@
|
||||
+@@........@@@@@@@@@@@ @@@............@@%
|
||||
-@@.........@@-......@@@@ =@@............@@
|
||||
@@:.........@@.........=@@. @@@...........@@@
|
||||
@@@..........@@..........:@@ .@@...........#@@
|
||||
@@@...........@@...........@@ @@............@@
|
||||
@@@............@@...........@@ @@...........=@@
|
||||
#@@.............@@..........@@@ :@@...........@@@
|
||||
*@@..............@@.........@@@ @@:...........@@=
|
||||
:@@...............@@@@....@@@@: @@@............@@
|
||||
@@:...............@@#@@@@@@+ #@@%............@@*
|
||||
@@@................@@ .@@@@.............@@%
|
||||
@@@.............@@@@@@@@@@@@@@@@@@..............@@@
|
||||
@@@..............@@ @@.-@@@@...................@@@
|
||||
@@@...............@@ @@........................@@@
|
||||
=@@................@@ @@......................@@@.
|
||||
@@.................@@ @@....................@@@#
|
||||
@@@.................@@ @@..................@@@%
|
||||
@@-..................@@ @@..............@@@@@
|
||||
-@@@@@@@@@@@@@@@@@@@@@@@ @@.......*@@@@@@@*
|
||||
+@@@@@@@@@@@@@@@@@@@@@ %@@@@@@@@@@%=
|
||||
|
||||
█████████████████
|
||||
███░░░░████░░░░░██████
|
||||
███░░░░░████░░░░░░░░░░████
|
||||
███░░░░░░████░░░░░░░░░░░░░████
|
||||
▒██░░░░░░░████░░░░░░░░░░░░░░░███▒
|
||||
███░░░░░░░████░░░░░░░░░░░░░░░░░███
|
||||
███░░░░░░░░████░░░░░░░░░░░░░░░░░░███
|
||||
███░░░░░███████████░░░░░░░░░░░░░░░░░██▓
|
||||
███░░░░░░██▒░ ░▓████▒░░░░░░░░░░░░░░██▒
|
||||
███░░░░░░░██ ████░░░░░░░░░░░░░██
|
||||
▓██░░░░░░░░███████████ ███░░░░░░░░░░░░███
|
||||
▒██░░░░░░░░░██▒░░░░░░████ ▓██░░░░░░░░░░░░██
|
||||
██▒░░░░░░░░░██░░░░░░░░░▒██░ ███░░░░░░░░░░░███
|
||||
███░░░░░░░░░░██░░░░░░░░░░▒██ ░██░░░░░░░░░░░▓██
|
||||
███░░░░░░░░░░░██░░░░░░░░░░░██ ██░░░░░░░░░░░░██
|
||||
███░░░░░░░░░░░░██░░░░░░░░░░░██ ██░░░░░░░░░░░▓██
|
||||
███░░░░░░░░░░░░░██░░░░░░░░░░███ ▒██░░░░░░░░░░░███
|
||||
▓██░░░░░░░░░░░░░░██░░░░░░░░░███ ██▒░░░░░░░░░░░██▓
|
||||
▒██░░░░░░░░░░░░░░░████░░░░████▒ ███░░░░░░░░░░░░██
|
||||
██▒░░░░░░░░░░░░░░░█████████▓ ████░░░░░░░░░░░░██▓
|
||||
███░░░░░░░░░░░░░░░░██ ░████░░░░░░░░░░░░░███
|
||||
███░░░░░░░░░░░░░██████████████████░░░░░░░░░░░░░░███
|
||||
███░░░░░░░░░░░░░░██ ██░▒████░░░░░░░░░░░░░░░░░░░███
|
||||
███░░░░░░░░░░░░░░░██ ██░░░░░░░░░░░░░░░░░░░░░░░░███
|
||||
▒██░░░░░░░░░░░░░░░░██ ██░░░░░░░░░░░░░░░░░░░░░░███░
|
||||
██░░░░░░░░░░░░░░░░░██ ██░░░░░░░░░░░░░░░░░░░░████
|
||||
███░░░░░░░░░░░░░░░░░██ ██░░░░░░░░░░░░░░░░░░████
|
||||
██▒░░░░░░░░░░░░░░░░░░██ ██░░░░░░░░░░░░░░█████
|
||||
▒███████████████████████ ██░░░░░░░▓███████▓
|
||||
▓█████████████████████ ████████████▒
|
||||
|
||||
``````` ````````````````````````````````````````´
|
||||
``````` ``````````````````````````````````````````
|
||||
``````´ ´``````````````````````````````````````````
|
||||
``````` ``````````````````````````````````````````´
|
||||
``````` ````````
|
||||
``````` ``````
|
||||
``````` ´`````´
|
||||
``````` ´``````
|
||||
``````` ``````´
|
||||
``````` ´```````
|
||||
``````´````````````````````````` ```````````````````````````````
|
||||
`````````````````````````````````` ´```````````````````````````
|
||||
```````````````````````````````````` ´``````````````````````´
|
||||
`````````````````````````````````````` ```````````````````
|
||||
``````` `````` `````````´
|
||||
``````` `````` ``````````
|
||||
``````` `````` `````````
|
||||
``````` `````` ``````````
|
||||
``````` `````` ``````````
|
||||
``````` `````` ``````````
|
||||
``````` `````` ``````````
|
||||
``````` `````` `````````´
|
||||
``````` `````` `````````
|
||||
``````` `````` ´`````````
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,187 @@
|
||||
# Updated font loading and color scheme for Progression Loader
|
||||
# Steam Collections page inspired design:
|
||||
# - Dark blue theme matching Steam's signature colors
|
||||
# - Steam blue (#66c0f4) for highlights and accents
|
||||
# - Dark blue backgrounds (#1b2838, #2a475e) for depth
|
||||
# - Light blue-gray text (#c7d5e0) for readability
|
||||
# - Card-based layouts with rounded corners
|
||||
# - Subtle shadows and glows for depth
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def get_resource_path(relative_path):
|
||||
"""Get absolute path to resource, works for dev and for PyInstaller"""
|
||||
try:
|
||||
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
||||
base_path = sys._MEIPASS
|
||||
except Exception:
|
||||
base_path = os.path.abspath(".")
|
||||
|
||||
return os.path.join(base_path, relative_path)
|
||||
|
||||
# Steam Collections inspired color constants
|
||||
COLORS = {
|
||||
'bg_primary': '#1b2838', # Steam dark blue background
|
||||
'bg_secondary': '#2a475e', # Steam medium blue background
|
||||
'bg_tertiary': '#1e2328', # Steam darker background for cards
|
||||
'bg_card': '#16202d', # Steam card background
|
||||
'bg_hover': '#2a475e', # Steam hover state
|
||||
'text_primary': '#c7d5e0', # Steam primary text (light blue-gray)
|
||||
'text_highlight': '#66c0f4', # Steam blue highlight color
|
||||
'text_body': '#8f98a0', # Steam body text (muted blue-gray)
|
||||
'text_secondary': '#acb2b8', # Steam secondary text
|
||||
'text_muted': '#67707b', # Steam muted text
|
||||
'accent_green': '#5ba32b', # Steam success green
|
||||
'accent_red': '#cd5c5c', # Steam error red
|
||||
'accent_yellow': '#ffa500', # Steam warning orange
|
||||
'accent_blue': '#66c0f4', # Steam signature blue
|
||||
'border_light': '#3c4043', # Steam light border
|
||||
'border_dark': '#0e141b', # Steam dark border
|
||||
}
|
||||
|
||||
def load_all_georgia_fonts():
|
||||
"""Load all Georgia font variants using Windows AddFontResourceEx with private flag"""
|
||||
custom_font_available = False
|
||||
custom_font_family = None
|
||||
|
||||
# List of Georgia font files to load
|
||||
georgia_fonts = [
|
||||
"georgia.ttf", # Regular
|
||||
"georgiab.ttf", # Bold
|
||||
"georgiai.ttf", # Italic
|
||||
"georgiaz.ttf" # Bold Italic
|
||||
]
|
||||
|
||||
fonts_loaded = 0
|
||||
|
||||
try:
|
||||
for font_file in georgia_fonts:
|
||||
font_path = get_resource_path(os.path.join("art", font_file))
|
||||
if os.path.exists(font_path):
|
||||
abs_font_path = os.path.abspath(font_path)
|
||||
|
||||
# Use the Stack Overflow method with AddFontResourceEx
|
||||
success = _load_font_private(abs_font_path)
|
||||
|
||||
if success:
|
||||
fonts_loaded += 1
|
||||
print(f"Successfully loaded font: {font_file}")
|
||||
else:
|
||||
print(f"Failed to load font: {font_file}")
|
||||
else:
|
||||
print(f"Font file not found: {font_path}")
|
||||
|
||||
if fonts_loaded > 0:
|
||||
custom_font_available = True
|
||||
custom_font_family = "Georgia"
|
||||
print(f"Successfully loaded {fonts_loaded} Georgia font variants")
|
||||
else:
|
||||
print("No Georgia fonts could be loaded, using system fallback")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error loading fonts: {e}")
|
||||
custom_font_available = False
|
||||
custom_font_family = None
|
||||
|
||||
return custom_font_available, custom_font_family
|
||||
|
||||
def _load_font_private(fontpath):
|
||||
"""
|
||||
Load font privately using AddFontResourceEx
|
||||
Based on Stack Overflow solution by Felipe
|
||||
"""
|
||||
try:
|
||||
from ctypes import windll, byref, create_unicode_buffer
|
||||
|
||||
# Constants for AddFontResourceEx
|
||||
FR_PRIVATE = 0x10 # Font is private to this process
|
||||
FR_NOT_ENUM = 0x20 # Font won't appear in font enumeration
|
||||
|
||||
# Create unicode buffer for the font path
|
||||
pathbuf = create_unicode_buffer(fontpath)
|
||||
|
||||
# Use AddFontResourceExW for Unicode strings
|
||||
AddFontResourceEx = windll.gdi32.AddFontResourceExW
|
||||
|
||||
# Set flags: private (unloaded when process dies) and not enumerable
|
||||
flags = FR_PRIVATE | FR_NOT_ENUM
|
||||
|
||||
# Add the font resource
|
||||
numFontsAdded = AddFontResourceEx(byref(pathbuf), flags, 0)
|
||||
|
||||
return numFontsAdded > 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error in _load_font_private: {e}")
|
||||
return False
|
||||
|
||||
def apply_steam_styling():
|
||||
"""Apply Steam Collections page inspired styling to UI components"""
|
||||
return {
|
||||
'button_style': {
|
||||
'relief': 'flat',
|
||||
'borderwidth': 0,
|
||||
'highlightthickness': 0,
|
||||
'font': ('Georgia', 10, 'bold'),
|
||||
'cursor': 'hand2'
|
||||
},
|
||||
'entry_style': {
|
||||
'relief': 'flat',
|
||||
'borderwidth': 2,
|
||||
'highlightthickness': 0,
|
||||
'font': ('Georgia', 9),
|
||||
'insertbackground': COLORS['text_primary']
|
||||
},
|
||||
'label_style': {
|
||||
'font': ('Georgia', 9),
|
||||
'anchor': 'w'
|
||||
},
|
||||
'title_style': {
|
||||
'font': ('Georgia', 14, 'bold'),
|
||||
'anchor': 'center'
|
||||
},
|
||||
'card_style': {
|
||||
'relief': 'flat',
|
||||
'borderwidth': 1,
|
||||
'highlightthickness': 0
|
||||
}
|
||||
}
|
||||
|
||||
def get_steam_button_colors(button_type='default'):
|
||||
"""Get Steam-inspired button color schemes"""
|
||||
button_colors = {
|
||||
'default': {
|
||||
'bg': COLORS['bg_secondary'],
|
||||
'fg': COLORS['text_primary'],
|
||||
'activebackground': COLORS['bg_hover'],
|
||||
'activeforeground': COLORS['text_highlight']
|
||||
},
|
||||
'primary': {
|
||||
'bg': COLORS['accent_blue'],
|
||||
'fg': COLORS['bg_primary'],
|
||||
'activebackground': COLORS['text_highlight'],
|
||||
'activeforeground': COLORS['bg_primary']
|
||||
},
|
||||
'success': {
|
||||
'bg': COLORS['accent_green'],
|
||||
'fg': COLORS['text_primary'],
|
||||
'activebackground': '#6bb33f',
|
||||
'activeforeground': COLORS['text_primary']
|
||||
},
|
||||
'warning': {
|
||||
'bg': COLORS['accent_yellow'],
|
||||
'fg': COLORS['bg_primary'],
|
||||
'activebackground': '#ffb733',
|
||||
'activeforeground': COLORS['bg_primary']
|
||||
},
|
||||
'danger': {
|
||||
'bg': COLORS['accent_red'],
|
||||
'fg': COLORS['text_primary'],
|
||||
'activebackground': '#d66f6f',
|
||||
'activeforeground': COLORS['text_primary']
|
||||
}
|
||||
}
|
||||
|
||||
return button_colors.get(button_type, button_colors['default'])
|
||||
+1160
File diff suppressed because it is too large
Load Diff
@@ -4,3 +4,4 @@ pyglet>=1.5.0
|
||||
Pillow>=8.0.0
|
||||
packaging>=21.0
|
||||
customtkinter>=5.0.0
|
||||
rich>=13.0.0
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 962 KiB |
+1474
-716
File diff suppressed because it is too large
Load Diff
+258
@@ -0,0 +1,258 @@
|
||||
from functools import lru_cache
|
||||
|
||||
from PIL import Image, ImageColor, ImageDraw
|
||||
|
||||
|
||||
FONT_FAMILY = "Georgia"
|
||||
|
||||
COLORS = {
|
||||
"bg_primary": "#151515",
|
||||
"bg_secondary": "#1d1d1d",
|
||||
"bg_tertiary": "#212121",
|
||||
"bg_card": "#2b2b2b",
|
||||
"bg_hover": "#36312c",
|
||||
"bg_error": "#2f2926",
|
||||
"text_primary": "#f5f2ec",
|
||||
"text_highlight": "#f0a621",
|
||||
"text_body": "#c8c8c8",
|
||||
"text_secondary": "#ffffff",
|
||||
"text_muted": "#979797",
|
||||
"accent_green": "#3a8e35",
|
||||
"accent_red": "#ff4a46",
|
||||
"accent_yellow": "#f0a621",
|
||||
"accent_blue": "#d7b56a",
|
||||
"border_light": "#4d453b",
|
||||
"border_dark": "#0f0f0f",
|
||||
"stripe": "#1d1d1d",
|
||||
"stripe_soft": "#232323",
|
||||
}
|
||||
|
||||
|
||||
@lru_cache(maxsize=4)
|
||||
def _load_rgba_source(image_path):
|
||||
"""Load and cache a source image in RGBA form for repeated resizes."""
|
||||
return Image.open(image_path).convert("RGBA")
|
||||
|
||||
|
||||
def _rgba(color, alpha=255):
|
||||
red, green, blue = ImageColor.getrgb(color)
|
||||
return red, green, blue, alpha
|
||||
|
||||
|
||||
def create_striped_texture(
|
||||
width,
|
||||
height,
|
||||
*,
|
||||
base_color=None,
|
||||
stripe_color=None,
|
||||
stripe_width=16,
|
||||
stripe_gap=18,
|
||||
stripe_alpha=110,
|
||||
corner_radius=0,
|
||||
border_color=None,
|
||||
border_width=0,
|
||||
border_alpha=255,
|
||||
):
|
||||
"""Create a dark diagonal striped texture matching the pack UI style."""
|
||||
width = max(1, int(width))
|
||||
height = max(1, int(height))
|
||||
|
||||
base = Image.new(
|
||||
"RGBA",
|
||||
(width, height),
|
||||
_rgba(base_color or COLORS["bg_card"]),
|
||||
)
|
||||
|
||||
stripes = Image.new("RGBA", (width, height), (0, 0, 0, 0))
|
||||
stripe_draw = ImageDraw.Draw(stripes)
|
||||
span = width + height
|
||||
step = max(1, stripe_width + stripe_gap)
|
||||
|
||||
for offset in range(-height, span + height, step):
|
||||
stripe_draw.line(
|
||||
(offset, 0, offset + height, height),
|
||||
fill=_rgba(stripe_color or COLORS["stripe"], stripe_alpha),
|
||||
width=max(1, stripe_width),
|
||||
)
|
||||
|
||||
image = Image.alpha_composite(base, stripes)
|
||||
|
||||
if border_color and border_width > 0:
|
||||
border_draw = ImageDraw.Draw(image)
|
||||
inset = max(1, border_width // 2)
|
||||
bounds = (inset, inset, width - inset - 1, height - inset - 1)
|
||||
if corner_radius > 0:
|
||||
border_draw.rounded_rectangle(
|
||||
bounds,
|
||||
radius=max(1, corner_radius - inset),
|
||||
outline=_rgba(border_color, border_alpha),
|
||||
width=border_width,
|
||||
)
|
||||
else:
|
||||
border_draw.rectangle(
|
||||
bounds,
|
||||
outline=_rgba(border_color, border_alpha),
|
||||
width=border_width,
|
||||
)
|
||||
|
||||
if corner_radius > 0:
|
||||
mask = Image.new("L", (width, height), 0)
|
||||
mask_draw = ImageDraw.Draw(mask)
|
||||
mask_draw.rounded_rectangle(
|
||||
(0, 0, width - 1, height - 1),
|
||||
radius=corner_radius,
|
||||
fill=255,
|
||||
)
|
||||
clipped = Image.new("RGBA", (width, height), (0, 0, 0, 0))
|
||||
clipped.paste(image, (0, 0), mask)
|
||||
image = clipped
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def create_striped_panel(
|
||||
width,
|
||||
height,
|
||||
*,
|
||||
panel_color=None,
|
||||
stripe_color=None,
|
||||
stripe_width=18,
|
||||
stripe_gap=18,
|
||||
stripe_alpha=110,
|
||||
halo_padding=22,
|
||||
halo_alpha=135,
|
||||
panel_alpha=240,
|
||||
corner_radius=18,
|
||||
border_color=None,
|
||||
border_width=1,
|
||||
border_alpha=255,
|
||||
):
|
||||
"""Create a mostly solid panel with stripes that extend just beyond its edges."""
|
||||
width = max(1, int(width))
|
||||
height = max(1, int(height))
|
||||
halo_padding = max(0, int(halo_padding))
|
||||
total_width = width + (halo_padding * 2)
|
||||
total_height = height + (halo_padding * 2)
|
||||
|
||||
image = Image.new("RGBA", (total_width, total_height), (0, 0, 0, 0))
|
||||
|
||||
stripes = Image.new("RGBA", (total_width, total_height), (0, 0, 0, 0))
|
||||
stripe_draw = ImageDraw.Draw(stripes)
|
||||
span = total_width + total_height
|
||||
step = max(1, stripe_width + stripe_gap)
|
||||
|
||||
for offset in range(-total_height, span + total_height, step):
|
||||
stripe_draw.line(
|
||||
(offset, 0, offset + total_height, total_height),
|
||||
fill=_rgba(stripe_color or COLORS["stripe"], halo_alpha),
|
||||
width=max(1, stripe_width),
|
||||
)
|
||||
|
||||
halo_mask = Image.new("L", (total_width, total_height), 0)
|
||||
halo_draw = ImageDraw.Draw(halo_mask)
|
||||
halo_draw.rounded_rectangle(
|
||||
(0, 0, total_width - 1, total_height - 1),
|
||||
radius=max(1, corner_radius + halo_padding),
|
||||
fill=255,
|
||||
)
|
||||
halo_image = Image.new("RGBA", (total_width, total_height), (0, 0, 0, 0))
|
||||
halo_image.paste(stripes, (0, 0), halo_mask)
|
||||
image = Image.alpha_composite(image, halo_image)
|
||||
|
||||
panel_left = halo_padding
|
||||
panel_top = halo_padding
|
||||
panel_right = panel_left + width - 1
|
||||
panel_bottom = panel_top + height - 1
|
||||
|
||||
panel = Image.new("RGBA", (total_width, total_height), (0, 0, 0, 0))
|
||||
panel_draw = ImageDraw.Draw(panel)
|
||||
panel_draw.rounded_rectangle(
|
||||
(panel_left, panel_top, panel_right, panel_bottom),
|
||||
radius=corner_radius,
|
||||
fill=_rgba(panel_color or COLORS["bg_card"], panel_alpha),
|
||||
)
|
||||
|
||||
if border_color and border_width > 0:
|
||||
inset = max(1, border_width // 2)
|
||||
panel_draw.rounded_rectangle(
|
||||
(
|
||||
panel_left + inset,
|
||||
panel_top + inset,
|
||||
panel_right - inset,
|
||||
panel_bottom - inset,
|
||||
),
|
||||
radius=max(1, corner_radius - inset),
|
||||
outline=_rgba(border_color, border_alpha),
|
||||
width=border_width,
|
||||
)
|
||||
|
||||
image = Image.alpha_composite(image, panel)
|
||||
return image
|
||||
|
||||
|
||||
def load_cover_background(image_path, width, height, *, overlay_color=None, overlay_alpha=125):
|
||||
"""Load an image, scale it to cover, and apply a dark overlay for readability."""
|
||||
width = max(1, int(width))
|
||||
height = max(1, int(height))
|
||||
|
||||
image = _load_rgba_source(image_path)
|
||||
source_ratio = image.width / image.height
|
||||
target_ratio = width / height
|
||||
|
||||
if source_ratio > target_ratio:
|
||||
new_height = height
|
||||
new_width = int(height * source_ratio)
|
||||
else:
|
||||
new_width = width
|
||||
new_height = int(width / source_ratio)
|
||||
|
||||
image = image.resize((new_width, new_height), Image.Resampling.BICUBIC)
|
||||
left = (new_width - width) // 2
|
||||
top = (new_height - height) // 2
|
||||
image = image.crop((left, top, left + width, top + height))
|
||||
|
||||
overlay = Image.new(
|
||||
"RGBA",
|
||||
(width, height),
|
||||
_rgba(overlay_color or COLORS["bg_primary"], overlay_alpha),
|
||||
)
|
||||
return Image.alpha_composite(image, overlay)
|
||||
|
||||
|
||||
def style_text_button(
|
||||
button,
|
||||
foreground,
|
||||
background,
|
||||
*,
|
||||
hover_foreground=None,
|
||||
disabled_foreground=None,
|
||||
):
|
||||
"""Style a tkinter Button to look like a color-coded text action."""
|
||||
button.configure(
|
||||
bg=background,
|
||||
fg=foreground,
|
||||
activebackground=background,
|
||||
activeforeground=hover_foreground or COLORS["text_primary"],
|
||||
relief="flat",
|
||||
bd=0,
|
||||
borderwidth=0,
|
||||
highlightthickness=0,
|
||||
disabledforeground=disabled_foreground or COLORS["text_muted"],
|
||||
cursor="hand2",
|
||||
)
|
||||
|
||||
|
||||
def center_window(window, width, height, parent=None):
|
||||
"""Center a window either on its parent or the current screen."""
|
||||
width = int(width)
|
||||
height = int(height)
|
||||
window.update_idletasks()
|
||||
|
||||
if parent is not None and parent.winfo_exists():
|
||||
x = parent.winfo_rootx() + (parent.winfo_width() // 2) - (width // 2)
|
||||
y = parent.winfo_rooty() + (parent.winfo_height() // 2) - (height // 2)
|
||||
else:
|
||||
x = (window.winfo_screenwidth() // 2) - (width // 2)
|
||||
y = (window.winfo_screenheight() // 2) - (height // 2)
|
||||
|
||||
window.geometry(f"{width}x{height}+{max(0, x)}+{max(0, y)}")
|
||||
+152
-62
@@ -16,6 +16,7 @@ from datetime import datetime, timedelta
|
||||
import os
|
||||
from pathlib import Path
|
||||
from update_config import get_update_config
|
||||
from ui_theme import COLORS, FONT_FAMILY, style_text_button, center_window
|
||||
|
||||
class UpdateChecker:
|
||||
def __init__(self, current_version=None):
|
||||
@@ -171,6 +172,57 @@ class UpdateChecker:
|
||||
|
||||
return latest_release, None
|
||||
|
||||
def _show_notice_dialog(self, parent_window, title, message, accent_color):
|
||||
"""Show a small themed notice dialog."""
|
||||
dialog = tk.Toplevel(parent_window)
|
||||
dialog.title(title)
|
||||
dialog.configure(bg=COLORS['bg_primary'])
|
||||
dialog.resizable(False, False)
|
||||
dialog.attributes('-topmost', True)
|
||||
|
||||
panel = tk.Frame(
|
||||
dialog,
|
||||
bg=COLORS['bg_card'],
|
||||
highlightbackground=COLORS['border_light'],
|
||||
highlightcolor=COLORS['border_light'],
|
||||
highlightthickness=1,
|
||||
)
|
||||
panel.pack(fill='both', expand=True, padx=16, pady=16)
|
||||
|
||||
tk.Label(
|
||||
panel,
|
||||
text=title,
|
||||
fg=accent_color,
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 18, 'bold italic'),
|
||||
).pack(pady=(18, 10))
|
||||
|
||||
tk.Label(
|
||||
panel,
|
||||
text=message,
|
||||
fg=COLORS['text_body'],
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 11),
|
||||
justify='center',
|
||||
wraplength=340,
|
||||
).pack(padx=24, pady=(0, 18))
|
||||
|
||||
close_btn = tk.Button(
|
||||
panel,
|
||||
text="Close",
|
||||
command=dialog.destroy,
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'),
|
||||
padx=0,
|
||||
pady=6,
|
||||
)
|
||||
style_text_button(close_btn, COLORS['accent_green'], COLORS['bg_card'])
|
||||
close_btn.pack(pady=(0, 18))
|
||||
|
||||
center_window(dialog, 420, 220, parent_window)
|
||||
dialog.protocol("WM_DELETE_WINDOW", dialog.destroy)
|
||||
return dialog
|
||||
|
||||
def show_update_dialog(self, parent_window, release_info):
|
||||
"""Show an update notification dialog"""
|
||||
if not release_info:
|
||||
@@ -184,7 +236,7 @@ class UpdateChecker:
|
||||
# Create update dialog
|
||||
dialog = tk.Toplevel(parent_window)
|
||||
dialog.title("Update Available - Progression Loader")
|
||||
dialog.configure(bg='#2b2b2b')
|
||||
dialog.configure(bg=COLORS['bg_primary'])
|
||||
dialog.resizable(False, False)
|
||||
dialog.attributes('-topmost', True)
|
||||
|
||||
@@ -195,58 +247,74 @@ class UpdateChecker:
|
||||
except:
|
||||
pass
|
||||
|
||||
# Calculate dialog size
|
||||
dialog_width = 500
|
||||
dialog_height = 400
|
||||
dialog_height = 430
|
||||
center_window(dialog, dialog_width, dialog_height, parent_window)
|
||||
|
||||
# Center the dialog
|
||||
x = parent_window.winfo_x() + (parent_window.winfo_width() // 2) - (dialog_width // 2)
|
||||
y = parent_window.winfo_y() + (parent_window.winfo_height() // 2) - (dialog_height // 2)
|
||||
dialog.geometry(f"{dialog_width}x{dialog_height}+{x}+{y}")
|
||||
panel = tk.Frame(
|
||||
dialog,
|
||||
bg=COLORS['bg_card'],
|
||||
highlightbackground=COLORS['border_light'],
|
||||
highlightcolor=COLORS['border_light'],
|
||||
highlightthickness=1,
|
||||
)
|
||||
panel.pack(fill='both', expand=True, padx=16, pady=16)
|
||||
|
||||
# Title
|
||||
title_label = tk.Label(dialog,
|
||||
text="🔄 Update Available!",
|
||||
fg='#00ff00', bg='#2b2b2b',
|
||||
font=('Arial', 16, 'bold'))
|
||||
title_label = tk.Label(
|
||||
panel,
|
||||
text="Update Available",
|
||||
fg=COLORS['text_highlight'],
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 18, 'bold italic'),
|
||||
)
|
||||
title_label.pack(pady=20)
|
||||
|
||||
# Version info
|
||||
version_frame = tk.Frame(dialog, bg='#2b2b2b')
|
||||
version_frame = tk.Frame(panel, bg=COLORS['bg_card'])
|
||||
version_frame.pack(pady=10)
|
||||
|
||||
current_label = tk.Label(version_frame,
|
||||
text=f"Current Version: {self.current_version}",
|
||||
fg='#cccccc', bg='#2b2b2b',
|
||||
font=('Arial', 12))
|
||||
fg=COLORS['text_body'], bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12))
|
||||
current_label.pack()
|
||||
|
||||
latest_label = tk.Label(version_frame,
|
||||
text=f"Latest Version: {latest_version}",
|
||||
fg='#00ff00', bg='#2b2b2b',
|
||||
font=('Arial', 12, 'bold'))
|
||||
fg=COLORS['accent_green'], bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold'))
|
||||
latest_label.pack()
|
||||
|
||||
# Release notes
|
||||
if release_info.get('body'):
|
||||
notes_label = tk.Label(dialog,
|
||||
notes_label = tk.Label(panel,
|
||||
text="Release Notes:",
|
||||
fg='#cccccc', bg='#2b2b2b',
|
||||
font=('Arial', 12, 'bold'))
|
||||
fg=COLORS['text_primary'], bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'))
|
||||
notes_label.pack(pady=(20, 5))
|
||||
|
||||
# Create scrollable text widget for release notes
|
||||
notes_frame = tk.Frame(dialog, bg='#2b2b2b')
|
||||
notes_frame = tk.Frame(panel, bg=COLORS['bg_card'])
|
||||
notes_frame.pack(fill='both', expand=True, padx=20, pady=(0, 20))
|
||||
|
||||
notes_text = tk.Text(notes_frame,
|
||||
height=8,
|
||||
bg='#404040', fg='#ffffff',
|
||||
font=('Arial', 10),
|
||||
bg=COLORS['bg_tertiary'], fg=COLORS['text_body'],
|
||||
font=(FONT_FAMILY, 10),
|
||||
wrap=tk.WORD,
|
||||
state='disabled')
|
||||
state='disabled',
|
||||
relief='flat',
|
||||
bd=0,
|
||||
insertbackground=COLORS['text_primary'],
|
||||
highlightthickness=1,
|
||||
highlightbackground=COLORS['border_light'])
|
||||
|
||||
scrollbar = tk.Scrollbar(notes_frame)
|
||||
scrollbar = tk.Scrollbar(
|
||||
notes_frame,
|
||||
bg=COLORS['bg_tertiary'],
|
||||
troughcolor=COLORS['bg_secondary'],
|
||||
activebackground=COLORS['bg_hover'],
|
||||
)
|
||||
scrollbar.pack(side='right', fill='y')
|
||||
|
||||
notes_text.pack(side='left', fill='both', expand=True)
|
||||
@@ -259,7 +327,7 @@ class UpdateChecker:
|
||||
notes_text.config(state='disabled')
|
||||
|
||||
# Buttons
|
||||
button_frame = tk.Frame(dialog, bg='#2b2b2b')
|
||||
button_frame = tk.Frame(panel, bg=COLORS['bg_card'])
|
||||
button_frame.pack(pady=20)
|
||||
|
||||
def download_update():
|
||||
@@ -302,9 +370,10 @@ class UpdateChecker:
|
||||
download_btn = tk.Button(button_frame,
|
||||
text="Download Update",
|
||||
command=download_update,
|
||||
bg='#00aa00', fg='white',
|
||||
font=('Arial', 12, 'bold'),
|
||||
padx=20, pady=5)
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'),
|
||||
padx=0, pady=6)
|
||||
style_text_button(download_btn, COLORS['accent_green'], COLORS['bg_card'])
|
||||
download_btn.pack(side='left', padx=5)
|
||||
|
||||
# Only show remind/skip buttons if persistence is enabled
|
||||
@@ -312,25 +381,28 @@ class UpdateChecker:
|
||||
later_btn = tk.Button(button_frame,
|
||||
text="Remind Later",
|
||||
command=remind_later,
|
||||
bg='#0078d4', fg='white',
|
||||
font=('Arial', 12),
|
||||
padx=20, pady=5)
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'),
|
||||
padx=0, pady=6)
|
||||
style_text_button(later_btn, COLORS['accent_yellow'], COLORS['bg_card'])
|
||||
later_btn.pack(side='left', padx=5)
|
||||
|
||||
skip_btn = tk.Button(button_frame,
|
||||
text="Skip Version",
|
||||
command=skip_version,
|
||||
bg='#666666', fg='white',
|
||||
font=('Arial', 12),
|
||||
padx=20, pady=5)
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'),
|
||||
padx=0, pady=6)
|
||||
style_text_button(skip_btn, COLORS['accent_red'], COLORS['bg_card'])
|
||||
skip_btn.pack(side='left', padx=5)
|
||||
else:
|
||||
close_btn = tk.Button(button_frame,
|
||||
text="Close",
|
||||
command=dialog.destroy,
|
||||
bg='#666666', fg='white',
|
||||
font=('Arial', 12),
|
||||
padx=20, pady=5)
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'),
|
||||
padx=0, pady=6)
|
||||
style_text_button(close_btn, COLORS['accent_red'], COLORS['bg_card'])
|
||||
close_btn.pack(side='left', padx=5)
|
||||
|
||||
# Handle window close
|
||||
@@ -355,15 +427,21 @@ class UpdateChecker:
|
||||
"""Manually check for updates and show result"""
|
||||
def check_complete(release_info, error):
|
||||
if error:
|
||||
messagebox.showerror("Update Check Failed",
|
||||
f"Could not check for updates:\n{error}",
|
||||
parent=parent_window)
|
||||
self._show_notice_dialog(
|
||||
parent_window,
|
||||
"Update Check Failed",
|
||||
f"Could not check for updates:\n{error}",
|
||||
COLORS['accent_red'],
|
||||
)
|
||||
return
|
||||
|
||||
if not release_info:
|
||||
messagebox.showinfo("No Updates",
|
||||
"Could not retrieve release information.",
|
||||
parent=parent_window)
|
||||
self._show_notice_dialog(
|
||||
parent_window,
|
||||
"No Updates",
|
||||
"Could not retrieve release information.",
|
||||
COLORS['accent_yellow'],
|
||||
)
|
||||
return
|
||||
|
||||
latest_version = release_info['version']
|
||||
@@ -371,33 +449,44 @@ class UpdateChecker:
|
||||
if self.is_newer_version(latest_version) and not self.should_skip_version(latest_version):
|
||||
self.show_update_dialog(parent_window, release_info)
|
||||
else:
|
||||
messagebox.showinfo("Up to Date",
|
||||
f"You are running the latest version ({self.current_version}).",
|
||||
parent=parent_window)
|
||||
self._show_notice_dialog(
|
||||
parent_window,
|
||||
"Up To Date",
|
||||
f"You are running the latest version ({self.current_version}).",
|
||||
COLORS['accent_green'],
|
||||
)
|
||||
|
||||
# Show checking message
|
||||
checking_dialog = tk.Toplevel(parent_window)
|
||||
checking_dialog.title("Checking for Updates")
|
||||
checking_dialog.configure(bg='#2b2b2b')
|
||||
checking_dialog.configure(bg=COLORS['bg_primary'])
|
||||
checking_dialog.resizable(False, False)
|
||||
checking_dialog.attributes('-topmost', True)
|
||||
|
||||
# Center the dialog
|
||||
checking_dialog.geometry("300x100")
|
||||
x = parent_window.winfo_x() + (parent_window.winfo_width() // 2) - 150
|
||||
y = parent_window.winfo_y() + (parent_window.winfo_height() // 2) - 50
|
||||
checking_dialog.geometry(f"300x100+{x}+{y}")
|
||||
panel = tk.Frame(
|
||||
checking_dialog,
|
||||
bg=COLORS['bg_card'],
|
||||
highlightbackground=COLORS['border_light'],
|
||||
highlightcolor=COLORS['border_light'],
|
||||
highlightthickness=1,
|
||||
)
|
||||
panel.pack(fill='both', expand=True, padx=14, pady=14)
|
||||
|
||||
label = tk.Label(checking_dialog,
|
||||
text="Checking for updates...",
|
||||
fg='white', bg='#2b2b2b',
|
||||
font=('Arial', 12))
|
||||
label = tk.Label(
|
||||
panel,
|
||||
text="Checking for updates...",
|
||||
fg=COLORS['text_primary'],
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 12, 'bold italic'),
|
||||
)
|
||||
label.pack(expand=True)
|
||||
|
||||
center_window(checking_dialog, 320, 120, parent_window)
|
||||
|
||||
def check_and_close():
|
||||
release_info, error = self.check_for_updates_sync()
|
||||
checking_dialog.destroy()
|
||||
check_complete(release_info, error)
|
||||
parent_window.after(0, lambda: checking_dialog.destroy())
|
||||
parent_window.after(0, lambda: check_complete(release_info, error))
|
||||
|
||||
# Start check in background
|
||||
threading.Thread(target=check_and_close, daemon=True).start()
|
||||
@@ -452,9 +541,10 @@ def integrate_update_checker_with_gui(gui_class):
|
||||
update_btn = tk.Button(parent_frame,
|
||||
text="Check Updates",
|
||||
command=self.manual_update_check,
|
||||
bg='#404040', fg='white',
|
||||
font=('Arial', 10),
|
||||
padx=10, pady=2)
|
||||
bg=COLORS['bg_card'],
|
||||
font=(FONT_FAMILY, 10, 'bold italic'),
|
||||
padx=8, pady=3)
|
||||
style_text_button(update_btn, COLORS['accent_yellow'], COLORS['bg_card'])
|
||||
update_btn.pack(side='right', padx=5, pady=5)
|
||||
except Exception as e:
|
||||
print(f"Could not add update button: {e}")
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ Configuration settings for the update checker
|
||||
# Update checker configuration
|
||||
UPDATE_CONFIG = {
|
||||
# Current version of the application
|
||||
"current_version": "0.1.1",
|
||||
"current_version": "0.2.1",
|
||||
|
||||
# Repository information
|
||||
"repo_owner": "HRiggs",
|
||||
|
||||
Reference in New Issue
Block a user