diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 552a5e5b..7660c4b0 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -88,7 +88,7 @@ class AppWindow: else: from PIL import Image, ImageTk self.w.tk.call('wm', 'iconphoto', self.w, '-default', ImageTk.PhotoImage(Image.open("EDMarketConnector.png"))) - self.theme_icon = tk.PhotoImage(data = 'R0lGODlhFAAQAMZVAAAAAAEAAAIBAAMBAAQCAAYDAAcDAAkEAAoEAAwGAQ8IARAIAREJARYKABkLARsMASMQASgSAiUUAy0UAjAVAioXBDIWAy4YBC4ZBS8ZBTkZA0EdBDsgBkUfA0MkB00iA1AjA1IlBFQmBE4qCFgoBVkoBFArCF0qBVQtCGUrBGMtBWYtBWA0Cm8xBW8xBm8yBXMzBXU1Bms5C3s1BXs2BXw2BX02BXw4B4A5B3Q/DIJGDYNGDYJHDoNHDYdJDppGCItLD4xLDo5MDo5MD5hSD59VEKdaEbJgErtlE7tlFLxlE8BpFMJpFMNpFMZrFdFxFtl1F995GOB6GOF6GP+LG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAUABAAAAejgACCgiODhoeGBABPPgACj48DA4gAk00cSRUYGZycEogBAE4LCUM8Oj2pOzlQBAKHSBeKlABKBq+DHkS0g0wJiCZFvABHJBuHBSxADFRTUs/PUUsiKhaIKEZBKTM13TU0Nj8IIRqThjJCK8MnFIgKMMMAJRGGAQUvvAIPLocBAjgdPggcKMLAgRi0GjxYyNBBCwjwQoEKQLEiABA3HMU7NOFQIAA7') + self.theme_icon = tk.PhotoImage(data = 'R0lGODlhFAAQAMZQAAoKCQoKCgsKCQwKCQsLCgwLCg4LCQ4LCg0MCg8MCRAMCRANChINCREOChIOChQPChgQChgRCxwTCyYVCSoXCS0YCTkdCTseCT0fCTsjDU0jB0EnDU8lB1ElB1MnCFIoCFMoCEkrDlkqCFwrCGEuCWIuCGQvCFs0D1w1D2wyCG0yCF82D182EHE0CHM0CHQ1CGQ5EHU2CHc3CHs4CH45CIA6CIE7CJdECIdLEolMEohQE5BQE41SFJBTE5lUE5pVE5RXFKNaFKVbFLVjFbZkFrxnFr9oFsNqFsVrF8RsFshtF89xF9NzGNh1GNl2GP+KG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAUABAAAAeegAGCgiGDhoeIRDiIjIZGKzmNiAQBQxkRTU6am0tPCJSGShuSAUcLoIIbRYMFra4FAUgQAQCGJz6CDQ67vAFJJBi0hjBBD0w9PMnJOkAiJhaIKEI7HRoc19ceNAolwbWDLD8uAQnl5ga1I9CHEjEBAvDxAoMtFIYCBy+kFDKHAgM3ZtgYSLAGgwkp3pEyBOJCC2ELB31QATGioAoVAwEAOw==') self.theme_minimize = tk.BitmapImage(data = '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f,\n 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\n') self.theme_close = tk.BitmapImage(data = '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x1c, 0x38, 0x38, 0x1c, 0x70, 0x0e,\n 0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0x70, 0x0e, 0x38, 0x1c,\n 0x1c, 0x38, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00 };\n') @@ -133,7 +133,7 @@ class AppWindow: row = frame.grid_size()[1] self.button.grid(row=row, columnspan=2, sticky=tk.NSEW) self.theme_button.grid(row=row, columnspan=2, sticky=tk.NSEW) - theme.register_alternate((self.button, self.theme_button), {'row':row, 'columnspan':2, 'sticky':tk.NSEW}) + theme.register_alternate((self.button, self.theme_button, self.theme_button), {'row':row, 'columnspan':2, 'sticky':tk.NSEW}) self.status.grid(columnspan=2, sticky=tk.EW) self.button.bind('', self.getandsend) theme.button_bind(self.theme_button, self.getandsend) @@ -234,7 +234,10 @@ class AppWindow: theme.register_highlight(theme_titlebar) theme.register(self.theme_minimize) # images aren't automatically registered theme.register(self.theme_close) - theme.register_alternate((self.menubar, self.theme_menubar), {'row':0, 'columnspan':2, 'sticky':tk.NSEW}) + self.blank_menubar = tk.Frame(frame) + tk.Label(self.blank_menubar).grid() + tk.Label(self.blank_menubar).grid() + theme.register_alternate((self.menubar, self.theme_menubar, self.blank_menubar), {'row':0, 'columnspan':2, 'sticky':tk.NSEW}) self.set_labels() @@ -264,7 +267,11 @@ class AppWindow: theme.register_highlight(self.station) theme.apply(self.w) - self.w.bind("", self.onmap) # Special handling for overrideredict + self.w.bind('', self.onmap) # Special handling for overrideredict + self.w.bind('', self.onenter) # Special handling for transparency + self.w.bind('', self.onenter) # " + self.w.bind('', self.onleave) # " + self.w.bind('', self.onleave) # " self.w.bind('', self.getandsend) self.w.bind('', self.getandsend) self.w.bind_all('<>', self.getandsend) # Hotkey monitoring @@ -817,6 +824,17 @@ class AppWindow: if event.widget == self.w: theme.apply(self.w) + def onenter(self, event=None): + if config.getint('theme') > 1: + self.w.attributes("-transparentcolor", '') + self.blank_menubar.grid_remove() + self.theme_menubar.grid(row=0, columnspan=2, sticky=tk.NSEW) + + def onleave(self, event=None): + if config.getint('theme') > 1 and event.widget==self.w: + self.w.attributes("-transparentcolor", 'grey4') + self.theme_menubar.grid_remove() + self.blank_menubar.grid(row=0, columnspan=2, sticky=tk.NSEW) # Run the app if __name__ == "__main__": diff --git a/L10n/cs.strings b/L10n/cs.strings index a1826697..85708a16 100644 --- a/L10n/cs.strings +++ b/L10n/cs.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Průhledná"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/de.strings b/L10n/de.strings index b0840e95..bc588002 100644 --- a/L10n/de.strings +++ b/L10n/de.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Wegebner"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Transparent"; + /* Trade rank. [stats.py] */ "Tycoon" = "Magnat"; diff --git a/L10n/en.template b/L10n/en.template index b6f505f4..e4095422 100644 --- a/L10n/en.template +++ b/L10n/en.template @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Transparent"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/es.strings b/L10n/es.strings index b704eb9d..faeedfae 100644 --- a/L10n/es.strings +++ b/L10n/es.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Rastreador"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Transparente"; + /* Trade rank. [stats.py] */ "Tycoon" = "Magnate"; diff --git a/L10n/fr.strings b/L10n/fr.strings index 27a53076..ebbe3d7c 100644 --- a/L10n/fr.strings +++ b/L10n/fr.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Prospecteur"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Transparent"; + /* Trade rank. [stats.py] */ "Tycoon" = "Magnat"; diff --git a/L10n/it.strings b/L10n/it.strings index 01fab8ad..f3e01cda 100644 --- a/L10n/it.strings +++ b/L10n/it.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Trasparente"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/ja.strings b/L10n/ja.strings index dabf7e46..acf4865c 100644 --- a/L10n/ja.strings +++ b/L10n/ja.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "透明"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/lv.strings b/L10n/lv.strings index fb57f58a..1044a954 100644 --- a/L10n/lv.strings +++ b/L10n/lv.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Caurspīdīga"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/nl.strings b/L10n/nl.strings index 5f5c37ef..cc3aec70 100644 --- a/L10n/nl.strings +++ b/L10n/nl.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Transparent"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/pl.strings b/L10n/pl.strings index fc24c376..3a7a9768 100644 --- a/L10n/pl.strings +++ b/L10n/pl.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Przezroczyste"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/ru.strings b/L10n/ru.strings index 4c1180d2..dbeefbc0 100644 --- a/L10n/ru.strings +++ b/L10n/ru.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Путешественние"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Прозрачный"; + /* Trade rank. [stats.py] */ "Tycoon" = "Магнат"; diff --git a/L10n/sl.strings b/L10n/sl.strings index a17bc818..7521816c 100644 --- a/L10n/sl.strings +++ b/L10n/sl.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Trailblazer"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Prosojno"; + /* Trade rank. [stats.py] */ "Tycoon" = "Tycoon"; diff --git a/L10n/uk.strings b/L10n/uk.strings index 8bbe6b6b..dd88767c 100644 --- a/L10n/uk.strings +++ b/L10n/uk.strings @@ -448,6 +448,9 @@ /* Explorer rank. [stats.py] */ "Trailblazer" = "Новатор"; +/* Appearance theme setting. [prefs.py] */ +"Transparent" = "Прозора"; + /* Trade rank. [stats.py] */ "Tycoon" = "Магнат"; diff --git a/README.md b/README.md index 48766df8..ccfce593 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Click on the station name to go to its [Elite: Dangerous Database](http://eddb.i ![Windows screenshot](img/win_dark.png)   ![Mac screenshot](img/mac_dark.png) +![Windows screenshot](img/win_transparent.png) Installation -------- diff --git a/img/win_transparent.png b/img/win_transparent.png new file mode 100644 index 00000000..b4ff49d9 Binary files /dev/null and b/img/win_transparent.png differ diff --git a/prefs.py b/prefs.py index 51db8c16..bf7b0609 100644 --- a/prefs.py +++ b/prefs.py @@ -259,7 +259,7 @@ class PreferencesDialog(tk.Toplevel): self.languages = Translations().available_names() self.lang = tk.StringVar(value = self.languages.get(config.get('language'), _('Default'))) # Appearance theme and language setting self.always_ontop = tk.BooleanVar(value = config.getint('always_ontop')) - self.theme = tk.IntVar(value = config.getint('theme') and 1 or 0) + self.theme = tk.IntVar(value = config.getint('theme')) self.theme_colors = [config.get('dark_text'), config.get('dark_highlight')] self.theme_prompts = [ _('Normal text'), # Dark theme color setting @@ -274,6 +274,8 @@ class PreferencesDialog(tk.Toplevel): nb.Label(themeframe, text=_('Theme')).grid(columnspan=3, padx=PADX, sticky=tk.W) # Appearance setting nb.Radiobutton(themeframe, text=_('Default'), variable=self.theme, value=0, command=self.themevarchanged).grid(columnspan=3, padx=BUTTONX, sticky=tk.W) # Appearance theme and language setting nb.Radiobutton(themeframe, text=_('Dark'), variable=self.theme, value=1, command=self.themevarchanged).grid(columnspan=3, padx=BUTTONX, sticky=tk.W) # Appearance theme setting + if platform == 'win32': + nb.Radiobutton(themeframe, text=_('Transparent'), variable=self.theme, value=2, command=self.themevarchanged).grid(columnspan=3, padx=BUTTONX, sticky=tk.W) # Appearance theme setting self.theme_label_0 = nb.Label(themeframe, text=self.theme_prompts[0]) self.theme_label_0.grid(row=20, padx=PADX, sticky=tk.W) self.theme_button_0 = nb.ColoredButton(themeframe, text=_('Station'), background='grey4', command=lambda:self.themecolorbrowse(0)) # Main window diff --git a/theme.py b/theme.py index ff8c5d49..687fa61b 100644 --- a/theme.py +++ b/theme.py @@ -151,19 +151,16 @@ class _Theme: background = self.current['background']) for pair, gridopts in self.widgets_pair: - (default, dark) = pair - if isinstance(default, tk.Menu): + for widget in pair: + widget.grid_remove() + if isinstance(pair[0], tk.Menu): if theme: root['menu'] = '' - dark.grid(**gridopts) + pair[theme].grid(**gridopts) else: - root['menu'] = default - dark.grid_remove() + root['menu'] = pair[0] else: - old = theme and default or dark - current = theme and dark or default - old.grid_remove() - current.grid(**gridopts) + pair[theme].grid(**gridopts) if self.active == theme: return # Don't need to mess with the window manager @@ -188,17 +185,16 @@ class _Theme: elif platform == 'win32': # tk8.5.9/win/tkWinWm.c:342 import ctypes - GWL_STYLE = -16 - WS_BORDER = 0x00800000 - WS_OVERLAPPEDWINDOW =0x00CF0000 GWL_EXSTYLE = -20 - WS_EX_WINDOWEDGE = 0x00000100 WS_EX_APPWINDOW = 0x00040000 - root.overrideredirect(theme and 1 or 0) # Destroys any top-level window + WS_EX_LAYERED = 0x00080000 + + root.overrideredirect(theme and 1 or 0) + root.attributes("-transparentcolor", theme > 1 and 'grey4' or '') + root.withdraw() root.update_idletasks() # Size and windows styles get recalculated here hwnd = ctypes.windll.user32.GetParent(root.winfo_id()) - ctypes.windll.user32.SetWindowLongW(hwnd, GWL_STYLE, theme and WS_BORDER or WS_OVERLAPPEDWINDOW) - ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, theme and WS_EX_APPWINDOW or WS_EX_WINDOWEDGE) + ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, theme > 1 and WS_EX_APPWINDOW|WS_EX_LAYERED or WS_EX_APPWINDOW) # Add to taskbar root.deiconify() root.wait_visibility() # need main window to be displayed before returning