Skip to content

Commit c576bd0

Browse files
authored
Merge pull request #186 from mathoudebine/feature/allow-drawing-over-theme-editor
Allow drawing zones and click to get coordinates for the theme
2 parents bdf543e + c397f38 commit c576bd0

File tree

1 file changed

+110
-5
lines changed

1 file changed

+110
-5
lines changed

theme-editor.py

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from PIL import ImageTk
5353

5454
import library.log
55+
5556
library.log.logger.setLevel(logging.NOTSET) # Disable system monitor logging for the editor
5657

5758
# Create a logger for the editor
@@ -60,12 +61,15 @@
6061

6162
# Hardcode specific configuration for theme editor
6263
from library import config
64+
6365
config.CONFIG_DATA["display"]["REVISION"] = "SIMU" # For theme editor, always use simulated LCD
6466
config.CONFIG_DATA["config"]["HW_SENSORS"] = "STATIC" # For theme editor always use stub data
6567
config.CONFIG_DATA["config"]["THEME"] = sys.argv[1] # Theme is given as argument
6668

6769
from library.display import display # Only import display after hardcoded config is set
6870

71+
RGB_LED_MARGIN = 12
72+
6973

7074
def refresh_theme():
7175
config.load_theme()
@@ -92,6 +96,20 @@ def refresh_theme():
9296
stats.Date.stats()
9397

9498

99+
def get_width(self) -> int:
100+
if config.THEME_DATA["display"]["DISPLAY_ORIENTATION"] == 'portrait':
101+
return config.CONFIG_DATA["display"]["DISPLAY_WIDTH"]
102+
else:
103+
return config.CONFIG_DATA["display"]["DISPLAY_HEIGHT"]
104+
105+
106+
def get_height(self) -> int:
107+
if config.THEME_DATA["display"]["DISPLAY_ORIENTATION"] == 'portrait':
108+
return config.CONFIG_DATA["display"]["DISPLAY_HEIGHT"]
109+
else:
110+
return config.CONFIG_DATA["display"]["DISPLAY_WIDTH"]
111+
112+
95113
if __name__ == "__main__":
96114
def on_closing():
97115
logger.debug("Exit Theme Editor...")
@@ -101,6 +119,78 @@ def on_closing():
101119
os._exit(0)
102120

103121

122+
x0 = 0
123+
y0 = 0
124+
125+
126+
def draw_zone(x0, y0, x1, y1):
127+
x = min(x0, x1)
128+
y = min(y0, y1)
129+
width = max(x0, x1) - min(x0, x1)
130+
height = max(y0, y1) - min(y0, y1)
131+
if width > 0 and height > 0:
132+
label_zone.place(x=x + RGB_LED_MARGIN, y=y + RGB_LED_MARGIN, width=width, height=height)
133+
else:
134+
label_zone.place_forget()
135+
136+
137+
def on_button1_press(event):
138+
global x0, y0
139+
x0, y0 = event.x, event.y
140+
label_zone.place_forget()
141+
142+
143+
def on_button1_press_and_drag(event):
144+
global x0, y0
145+
x1, y1 = event.x, event.y
146+
147+
# Do not draw zone outside of theme preview
148+
if x1 < 0:
149+
x1 = 0
150+
elif x1 >= display.lcd.get_width():
151+
x1 = display.lcd.get_width() - 1
152+
if y1 < 0:
153+
y1 = 0
154+
elif y1 >= display.lcd.get_height():
155+
y1 = display.lcd.get_height() - 1
156+
157+
label_coord.config(text='Drawing zone from [{},{}] to [{},{}]'.format(x0, y0, x1, y1))
158+
draw_zone(x0, y0, x1, y1)
159+
160+
161+
def on_button1_release(event):
162+
global x0, y0
163+
x1, y1 = event.x, event.y
164+
if x1 != x0 or y1 != y0:
165+
# Do not draw zone outside of theme preview
166+
if x1 < 0:
167+
x1 = 0
168+
elif x1 >= display.lcd.get_width():
169+
x1 = display.lcd.get_width() - 1
170+
if y1 < 0:
171+
y1 = 0
172+
elif y1 >= display.lcd.get_height():
173+
y1 = display.lcd.get_height() - 1
174+
175+
# Display drawn zone and coordinates
176+
draw_zone(x0, y0, x1, y1)
177+
178+
# Display relative zone coordinates, to set in theme
179+
x = min(x0, x1)
180+
y = min(y0, y1)
181+
width = max(x0, x1) - min(x0, x1)
182+
height = max(y0, y1) - min(y0, y1)
183+
label_coord.config(text='Zone: X={}, Y={}, width={} height={}'.format(x, y, width, height))
184+
else:
185+
# Display click coordinates
186+
label_coord.config(
187+
text='X={}, Y={} (click and drag to draw a zone)'.format(x0, y0, abs(x1 - x0), abs(y1 - y0)))
188+
189+
190+
def on_zone_click(event):
191+
label_zone.place_forget()
192+
193+
104194
# Apply system locale to this program
105195
locale.setlocale(locale.LC_ALL, '')
106196

@@ -129,9 +219,11 @@ def on_closing():
129219
viewer = tkinter.Tk()
130220
viewer.title("Turing SysMon Theme Editor")
131221
viewer.iconphoto(True, tkinter.PhotoImage(file="res/icons/monitor-icon-17865/64.png"))
132-
viewer.geometry(str(display.lcd.get_width() + 24) + "x" + str(display.lcd.get_height() + 44))
222+
viewer.geometry(str(display.lcd.get_width() + 2 * RGB_LED_MARGIN) + "x" + str(
223+
display.lcd.get_height() + 2 * RGB_LED_MARGIN + 40))
133224
viewer.protocol("WM_DELETE_WINDOW", on_closing)
134225
viewer.call('wm', 'attributes', '.', '-topmost', '1') # Preview window always on top
226+
viewer.config(cursor="cross")
135227

136228
# Display RGB backplate LEDs color as background color
137229
led_color = config.THEME_DATA['display'].get("DISPLAY_RGB_LED", (255, 255, 255))
@@ -141,12 +233,24 @@ def on_closing():
141233

142234
# Display preview in the window
143235
display_image = ImageTk.PhotoImage(display.lcd.screen_image)
144-
viewer_picture = tkinter.Label(viewer, image=display_image)
145-
viewer_picture.place(x=10, y=10)
236+
viewer_picture = tkinter.Label(viewer, image=display_image, borderwidth=0)
237+
viewer_picture.place(x=RGB_LED_MARGIN, y=RGB_LED_MARGIN)
238+
239+
# Allow to click on preview to show coordinates and draw zones
240+
viewer_picture.bind("<ButtonPress-1>", on_button1_press)
241+
viewer_picture.bind("<B1-Motion>", on_button1_press_and_drag)
242+
viewer_picture.bind("<ButtonRelease-1>", on_button1_release)
243+
244+
label_coord = tkinter.Label(viewer, text="Click or draw a zone to show coordinates")
245+
label_coord.place(x=0, y=display.lcd.get_height() + 2 * RGB_LED_MARGIN,
246+
width=display.lcd.get_width() + 2 * RGB_LED_MARGIN)
146247

147-
label = tkinter.Label(viewer, text="This preview will reload when theme file is updated")
148-
label.place(x=0, y=display.lcd.get_height() + 24, width=display.lcd.get_width() + 24)
248+
label_info = tkinter.Label(viewer, text="This preview will reload when theme file is updated")
249+
label_info.place(x=0, y=display.lcd.get_height() + 2 * RGB_LED_MARGIN + 20,
250+
width=display.lcd.get_width() + 2 * RGB_LED_MARGIN)
149251

252+
label_zone = tkinter.Label(viewer, bg='#%02x%02x%02x' % tuple(map(lambda x: 255 - x, led_color)))
253+
label_zone.bind("<ButtonRelease-1>", on_zone_click)
150254
viewer.update()
151255

152256
logger.debug("You can now edit the theme file in the editor. When you save your changes, the preview window will "
@@ -170,6 +274,7 @@ def on_closing():
170274
if isinstance(led_color, str):
171275
led_color = tuple(map(int, led_color.split(', ')))
172276
viewer.configure(bg='#%02x%02x%02x' % led_color)
277+
label_zone.configure(bg='#%02x%02x%02x' % tuple(map(lambda x: 255 - x, led_color)))
173278

174279
# Regularly update the viewer window even if content unchanged
175280
viewer.update()

0 commit comments

Comments
 (0)