From: Dustin Walde Date: Tue, 2 May 2023 15:32:36 +0000 (-0700) Subject: Improve UI X-Git-Url: https://git.walde.dev/?a=commitdiff_plain;h=735ed76c8dfebd02bb3c956f7d91d12b38e84172;p=punch Improve UI - Slightly round icon - Improve menu text --- diff --git a/src/image_generator.py b/src/image_generator.py index 533ae6e..280c094 100644 --- a/src/image_generator.py +++ b/src/image_generator.py @@ -44,16 +44,28 @@ def day(sheet: TimeSheet, date: datetime.date) -> Image.Image: for i in range(IMAGE_SIZE-2): img.putpixel((i+1,0), color) img.putpixel((i+1,IMAGE_SIZE-1), color) - _day(sheet, img, date, (2, IMAGE_SIZE-2), (2, IMAGE_SIZE-2), TARGET_HOURS, 255) + tt = _day(sheet, img, date, (2, IMAGE_SIZE-2), (2, IMAGE_SIZE-2), TARGET_HOURS, 255) + hr_ratio = floor(min(1, tt.total_seconds()/(TARGET_HOURS*60*60))*128) + grad_size = IMAGE_SIZE-2 + for i in range(IMAGE_SIZE-2): + img.putpixel((1,1+i), (255,255,255, floor(hr_ratio*(grad_size-i)/grad_size))) + img.putpixel((IMAGE_SIZE-2,1+i), (255,255,255, floor(hr_ratio*(grad_size-i)/grad_size))) + for i in range(IMAGE_SIZE-4): + img.putpixel((2+i,1), (255,255,255, hr_ratio)) else: _day(sheet, img, date, (0, IMAGE_SIZE), (0, IMAGE_SIZE), TARGET_HOURS, 255) + corner_alpha = 64 + for px in (0, IMAGE_SIZE-1): + for py in (0, IMAGE_SIZE-1): + pxl = img.getpixel((px,py)) + img.putpixel((px,py), pxl[:3] + (floor(corner_alpha*pxl[3]/255),)) img = img.resize((32,32), Image.NEAREST) return img def _day(sheet: TimeSheet, image: Image.Image, date: datetime.date, x_range: Tuple[int,int], y_range: Tuple[int,int], - target_hours: int = 0, alpha: int = 255) -> None: + target_hours: int = 0, alpha: int = 255) -> datetime.timedelta: dt = datetime.datetime.combine(date, datetime.time(), datetime.datetime.now().astimezone().tzinfo) de = dt + datetime.timedelta(days=1) tt = datetime.timedelta(0) @@ -62,12 +74,20 @@ def _day(sheet: TimeSheet, image: Image.Image, date: datetime.date, segments = x_range[1] - x_range[0] hours = y_range[1] - y_range[0] + size = max(floor(hours/target_hours), 1) + hours = floor(hours/size) + segments = floor(segments/size) + seg_time = _time_per_segment(segments) # pre-fill taget range for i in range(min(target_hours, hours)): for j in range(segments): - image.putpixel((x_range[0]+j, y_range[1]-1-i), (255,255,255,32)) + for sx in range(size): + for sy in range(size): + image.putpixel((x_range[0]+j*size+sx, + y_range[1]-1-i*size-sy), + (255,255,255,32)) for entry in sheet.entries: if entry is None: @@ -85,10 +105,14 @@ def _day(sheet: TimeSheet, image: Image.Image, date: datetime.date, time = entry.t_out - max(dt, entry.t_in) # type: ignore tt += time while ct < hours * segments and tt > datetime.timedelta(0): - image.putpixel((x_range[0]+ct%segments, y_range[1]-1-floor(ct/segments)), color) + for sx in range(size): + for sy in range(size): + image.putpixel((x_range[0]+size*(ct%segments)+sx, y_range[1]-1-size*floor(ct/segments)-sy), color) tt -= seg_time ct += 1 + return ct*seg_time + tt + def _time_per_segment(segments: int) -> datetime.timedelta: seg_minutes = floor(60/segments) diff --git a/src/service.py b/src/service.py index fa5fcd6..e95b434 100644 --- a/src/service.py +++ b/src/service.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import datetime +from math import floor import pystray from threading import Condition, Thread from time import sleep @@ -55,14 +56,20 @@ class Service: def _generate_menu_items(self): active = self.sheet.get_open_entries() + in_text = "" + if len(active) == 1: + in_text = " " + self.sheet.categories[active[0].category].name punch_in_menu = pystray.Menu(*self._generate_punch_in_items()) + today_times = self._generate_todays_times() return [ pystray.MenuItem("Punch in", punch_in_menu), - pystray.MenuItem("Punch out", + pystray.MenuItem("Punch out" + in_text, lambda: self.sheet.punch_out(), enabled=len(active)==1, default=True), pystray.Menu.SEPARATOR, + pystray.MenuItem(today_times, None), + pystray.Menu.SEPARATOR, pystray.MenuItem("Pop", lambda: self._pop_last()), ] @@ -77,9 +84,37 @@ class Service: if i >= 5: break punch_in_items.append( - pystray.MenuItem(entry.category, + pystray.MenuItem(self.sheet.categories[entry.category].name + " (" + entry.category + ")", lambda _icon, item: self._punch_in(item))) - return tuple(punch_in_items) + return punch_in_items + + + def _generate_todays_times(self) -> str: + today_times = "" + td = datetime.datetime.combine(datetime.date.today(), datetime.time(), tzinfo=datetime.datetime.now().astimezone().tzinfo) + for cat, times in self.sheet.cat_entries.items(): + tt = datetime.timedelta(0) + for entry_i in reversed(times): + entry = self.sheet.entries[entry_i] + if entry is None: + break + if not entry.is_complete: + tt += datetime.datetime.now().astimezone() - max(td, entry.t_in) + elif entry.t_in < td and entry.t_out < td: # type: ignore + break + elif entry.t_in < td: + tt += entry.t_out - td # type: ignore + break + else: + tt += entry.duration # type: ignore + + if tt > datetime.timedelta(0): + seconds = tt.total_seconds() + minutes = floor(seconds/60) + hours = floor(minutes/60) + today_times += f"{cat} {hours:02}:{minutes:02}\n" + + return today_times.strip() def _punch_in(self, item: pystray.MenuItem): @@ -88,7 +123,7 @@ class Service: return if len(active) == 1: self.sheet.punch_out() - self.sheet.punch_in(item.text) + self.sheet.punch_in(item.text[item.text.find("(")+1:-1]) def _pop_last(self):