File size: 16,321 Bytes
457b8fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
#splah_utils.py
import time
import atexit

class SplashManager:
    """Simple splash screen manager that works with main thread"""
    
    def __init__(self):
        self.splash_window = None
        self._status_text = "Initializing..."
        self.progress_value = 0  # Track actual progress 0-100
        self.canvas_width = 320  # Progress bar dimensions (increased from 300)
        self.canvas_height = 36  # Increased from 30
        self._after_id = None
        
    def start_splash(self):
        """Create splash window on main thread"""
        try:
            import tkinter as tk
            
            print("🎨 Starting splash screen...")
            
            # Create splash window on main thread
            self.splash_window = tk.Tk()
            self.splash_window.title("Loading Glossarion...")
            self.splash_window.geometry("450x350")
            self.splash_window.configure(bg='#2b2b2b')
            self.splash_window.resizable(False, False)
            self.splash_window.overrideredirect(True)
            
            # Center the window
            self.splash_window.update_idletasks()
            x = (self.splash_window.winfo_screenwidth() // 2) - 225
            y = (self.splash_window.winfo_screenheight() // 2) - 175
            self.splash_window.geometry(f"450x350+{x}+{y}")
            
            # Add content
            main_frame = tk.Frame(self.splash_window, bg='#2b2b2b', relief='raised', bd=2)
            main_frame.pack(fill='both', expand=True, padx=2, pady=2)
            
            # Load the actual Halgakos.ico icon
            self._load_icon(main_frame)
            
            # Title
            title_label = tk.Label(main_frame, text="Glossarion v4.8.5", 
                                  bg='#2b2b2b', fg='#4a9eff', font=('Arial', 20, 'bold'))
            title_label.pack(pady=(10, 5))
            
            # Subtitle
            subtitle_label = tk.Label(main_frame, text="Advanced AI Translation Suite", 
                                     bg='#2b2b2b', fg='#cccccc', font=('Arial', 12))
            subtitle_label.pack(pady=(0, 15))
            
            # Status
            self.status_label = tk.Label(main_frame, text=self._status_text, 
                                        bg='#2b2b2b', fg='#ffffff', font=('Arial', 11))
            self.status_label.pack(pady=(10, 10))
            
            # Progress bar container
            progress_frame = tk.Frame(main_frame, bg='#2b2b2b')
            progress_frame.pack(pady=(5, 15))  # Adjusted padding for larger bar
            
            # Progress bar background
            self.progress_bg = tk.Canvas(progress_frame, width=self.canvas_width, height=self.canvas_height, 
                                        bg='#2b2b2b', highlightthickness=0)
            self.progress_bg.pack()
            
            # Create border
            self.progress_bg.create_rectangle(1, 1, self.canvas_width-1, self.canvas_height-1, 
                                            outline='#666666', width=2)
            
            # Create background
            self.progress_bg.create_rectangle(3, 3, self.canvas_width-3, self.canvas_height-3, 
                                            fill='#1a1a1a', outline='')
            
            # Progress bar fill (will be updated)
            self.progress_fill = None
            
            # Progress percentage text - moved up and with better font
            text_x = self.canvas_width // 2  # 160 for 320px width
            text_y = 13.5  # Positioned slightly above center for visual balance
            
            # Use a cleaner, more modern font
            progress_font = ('Montserrat', 12, 'bold')  # Increased size to 12
            
            # Create outline for better readability
            for dx in [-1, 0, 1]:
                for dy in [-1, 0, 1]:
                    if dx != 0 or dy != 0:
                        self.progress_bg.create_text(text_x + dx, text_y + dy, text="0%", 
                                                   fill='#000000', font=progress_font,
                                                   tags="outline", anchor='center')
            
            # Main text on top (white)
            self.progress_text = self.progress_bg.create_text(text_x, text_y, text="0%", 
                                                             fill='#ffffff', font=progress_font,
                                                             anchor='center')
            
            # Version info
            version_label = tk.Label(main_frame, text="Starting up...", 
                                   bg='#2b2b2b', fg='#888888', font=('Arial', 9))
            version_label.pack(side='bottom', pady=(0, 15))
            
            # Start progress animation
            self._animate_progress()
            
            # Update the display
            self.splash_window.update()
            
            # Register cleanup
            atexit.register(self.close_splash)
            return True
            
        except Exception as e:
            print(f"⚠️ Could not start splash: {e}")
            return False
    
    def _load_icon(self, parent):
        """Load the Halgakos.ico icon"""
        try:
            # Get icon path - handle both development and packaged modes
            import os
            import sys
            import tkinter as tk
            
            if getattr(sys, 'frozen', False):
                # Running as .exe
                base_dir = sys._MEIPASS
            else:
                # Running as .py files
                base_dir = os.path.dirname(os.path.abspath(__file__))
            
            ico_path = os.path.join(base_dir, 'Halgakos.ico')
            
            if os.path.isfile(ico_path):
                try:
                    # Try PIL first for better quality
                    from PIL import Image, ImageTk
                    pil_image = Image.open(ico_path)
                    pil_image = pil_image.resize((128, 128), Image.Resampling.LANCZOS)
                    icon_photo = ImageTk.PhotoImage(pil_image, master=self.splash_window)
                    icon_label = tk.Label(parent, image=icon_photo, bg='#2b2b2b')
                    icon_label.image = icon_photo  # Keep reference
                    icon_label.pack(pady=(20, 10))
                    return
                except ImportError:
                    # Fallback to basic tkinter
                    try:
                        icon_image = tk.PhotoImage(file=ico_path)
                        icon_label = tk.Label(parent, image=icon_image, bg='#2b2b2b')
                        icon_label.image = icon_image
                        icon_label.pack(pady=(20, 10))
                        return
                    except tk.TclError:
                        pass
        except Exception:
            pass
        
        # Fallback emoji if icon loading fails
        import tkinter as tk
        icon_frame = tk.Frame(parent, bg='#4a9eff', width=128, height=128)
        icon_frame.pack(pady=(20, 10))
        icon_frame.pack_propagate(False)
        
        icon_label = tk.Label(icon_frame, text="📚", font=('Arial', 64), 
                             bg='#4a9eff', fg='white')
        icon_label.pack(expand=True)

    def _animate_progress(self):
        """Animate progress bar filling up"""
        # Cancel any existing after callback first
        if self._after_id:
            try:
                self.splash_window.after_cancel(self._after_id)
            except:
                pass
            self._after_id = None
            
        if self.splash_window and self.splash_window.winfo_exists():
            try:
                # Auto-increment progress for visual effect during startup
                if self.progress_value < 100:
                    # Increment at different rates for different phases
                    if self.progress_value < 30:
                        self.progress_value += 8  # Fast initial progress
                    elif self.progress_value < 70:
                        self.progress_value += 4  # Medium progress
                    elif self.progress_value < 90:
                        self.progress_value += 2  # Slow progress
                    else:
                        self.progress_value += 1  # Very slow final progress
                    
                    # Cap at 99% until explicitly set to 100%
                    if self.progress_value >= 99:
                        self.progress_value = 99
                
                # Update progress bar fill
                if self.progress_fill:
                    self.progress_bg.delete(self.progress_fill)
                # Also delete old highlight
                self.progress_bg.delete("highlight")
                
                # Calculate fill width (3 to canvas_width-3)
                fill_width = int((self.progress_value / 100) * (self.canvas_width - 6))  # -6 for borders
                if fill_width > 0:
                    # Create gradient effect
                    self.progress_fill = self.progress_bg.create_rectangle(
                        3, 3, 3 + fill_width, self.canvas_height - 3, 
                        fill='#4a9eff', outline=''
                    )
                    
                    # Add a highlight effect (adjusted for new height)
                    if fill_width > 10:
                        self.progress_bg.create_rectangle(
                            3, 3, min(13, 3 + fill_width), 12,
                            fill='#6bb6ff', outline='', tags="highlight"
                        )
                
                # Update percentage text without changing position
                percent_text = f"{self.progress_value}%"
                
                # Update main text
                self.progress_bg.itemconfig(self.progress_text, text=percent_text)
                
                # Update all outline layers
                for item in self.progress_bg.find_withtag("outline"):
                    self.progress_bg.itemconfig(item, text=percent_text)
                
                # Ensure text stays on top of progress fill
                self.progress_bg.tag_raise("outline")
                self.progress_bg.tag_raise(self.progress_text)

                # Store the after ID so we can cancel it later
                self._after_id = self.splash_window.after(100, self._animate_progress)
                
            except Exception:
                self._after_id = None
                pass
    
    def update_status(self, message):
            """Update splash status and progress with enhanced module loading support"""
            self._status_text = message
            try:
                if self.splash_window and hasattr(self, 'status_label'):
                    self.status_label.config(text=message)
                    
                    # Enhanced progress mapping starting module loading at 10%
                    progress_map = {
                        "Loading theme framework...": 5,
                        "Loading UI framework...": 8,
                        
                        # Module loading phase - starts at 10% and goes to 85%
                        "Loading translation modules...": 10,
                        "Initializing module system...": 15,
                        "Loading translation engine...": 20,
                        "Validating translation engine...": 30,
                        "✅ translation engine loaded": 40,
                        "Loading glossary extractor...": 45,
                        "Validating glossary extractor...": 55,
                        "✅ glossary extractor loaded": 65,
                        "Loading EPUB converter...": 70,
                        "✅ EPUB converter loaded": 75,
                        "Loading QA scanner...": 78,
                        "✅ QA scanner loaded": 82,
                        "Finalizing module initialization...": 85,
                        "✅ All modules loaded successfully": 88,
                        
                        "Creating main window...": 92,
                        "Ready!": 100
                    }
                    
                    # Check for exact matches first
                    if message in progress_map:
                        self.set_progress(progress_map[message])
                    else:
                        # Check for partial matches
                        for key, value in progress_map.items():
                            if key in message:
                                self.set_progress(value)
                                break
                    
                    self.splash_window.update()
            except:
                pass
    
    def set_progress(self, value):
        """Manually set progress value (0-100)"""
        self.progress_value = max(0, min(100, value))
    
    def close_splash(self):
            """Close the splash screen with proper text visibility"""
            try:
                # IMPORTANT: Cancel the animation first
                if self._after_id and self.splash_window:
                    try:
                        self.splash_window.after_cancel(self._after_id)
                    except:
                        pass
                    self._after_id = None
                
                if self.splash_window and self.splash_window.winfo_exists():
                    # Set to 100% and ensure text is visible
                    self.progress_value = 100
                    
                    # Update display one last time without scheduling another callback
                    if hasattr(self, 'progress_fill') and self.progress_fill:
                        self.progress_bg.delete(self.progress_fill)
                    self.progress_bg.delete("highlight")
                    
                    # Create the 100% progress bar (but leave space for text)
                    fill_width = int((self.progress_value / 100) * (self.canvas_width - 6))
                    if fill_width > 0:
                        # Create progress fill that doesn't cover the text area
                        self.progress_fill = self.progress_bg.create_rectangle(
                            3, 3, 3 + fill_width, self.canvas_height - 3, 
                            fill='#4a9eff', outline=''
                        )
                        
                        # Add highlight effect
                        if fill_width > 10:
                            self.progress_bg.create_rectangle(
                                3, 3, min(13, 3 + fill_width), 12,
                                fill='#6bb6ff', outline='', tags="highlight"
                            )
                    
                    # CRITICAL: Make sure text stays on top and is visible
                    if hasattr(self, 'progress_text'):
                        self.progress_bg.itemconfig(self.progress_text, text="100%", fill='#ffffff')
                    
                    # Update all outline layers for better visibility
                    for item in self.progress_bg.find_withtag("outline"):
                        self.progress_bg.itemconfig(item, text="100%", fill='#000000')
                    
                    # Ensure text layers are on top of progress fill
                    self.progress_bg.tag_raise("outline")
                    if hasattr(self, 'progress_text'):
                        self.progress_bg.tag_raise(self.progress_text)
                    
                    self.splash_window.update()
                    time.sleep(0.1)
                    
                    self.splash_window.destroy()
                    self.splash_window = None
            except:
                # Ensure cleanup even on error
                self._after_id = None
                self.splash_window = None