Skip to content

Commit

Permalink
Scrolling the overview (almarklein#419)
Browse files Browse the repository at this point in the history
* WIP scrolling the overview

* even better

* put this in another pr
  • Loading branch information
almarklein authored and ouuan committed Nov 9, 2023
1 parent 08011e8 commit a280e14
Showing 1 changed file with 92 additions and 13 deletions.
105 changes: 92 additions & 13 deletions timetagger/app/front.py
Original file line number Diff line number Diff line change
Expand Up @@ -2907,6 +2907,8 @@ def on_init(self):
self._time_at_last_draw = 0
self._time_since_last_draw = 0
self._npixels_each = 0
self._target_scroll_offset = 0
self._scroll_offset = 0
self.tagzmap = {} # public map of tagz -> tagz
self._tag_bars_dict = {} # tagz -> bar-info

Expand Down Expand Up @@ -3059,20 +3061,30 @@ def _draw_stats(self, ctx, x1, y1, x2, y2):

# Calculate available height for all the bars, plus space to show the total
if len(self.selected_tags) > 0:
header_bar_space = 2
header_bar_slots = 2
else:
header_bar_space = 1
avail_height = (y2 - y1) - 4
header_bar_slots = 1
avail_height1 = (y2 - y1) - 8 - 4 # bit extra to prevent FP hiding

# Set _npixels_each (number of pixels per bar)
npixels_each_min_max = 25, 60
npixels_each = avail_height / (len(bars) + header_bar_space)
npixels_each_min_max = 30, 60
npixels_each = avail_height1 / (len(bars) + header_bar_slots)
npixels_each = max(npixels_each, npixels_each_min_max[0])
npixels_each = min(npixels_each, npixels_each_min_max[1])
self._npixels_each = self._slowly_update_value(self._npixels_each, npixels_each)

# Get overview height
overview_height = self._npixels_each * header_bar_space
# Get vertical bounds of the space for the bars
y_top = y1 + self._npixels_each * header_bar_slots
y_bottom = y2 - 8
avail_height2 = y_bottom - y_top

# From that we can derive how many bars we can show, and the max scroll offset
n_bars = int(avail_height2 / self._npixels_each)
max_scroll_offset = max(0, (len(bars) - n_bars) * self._npixels_each)
self._target_scroll_offset = min(max_scroll_offset, self._target_scroll_offset)
self._scroll_offset = self._slowly_update_value(
self._scroll_offset, self._target_scroll_offset
)

# Calculate right base edge. Note that the bars will go beyond it
x3 = x2 - 10 - 2
Expand All @@ -3082,16 +3094,29 @@ def _draw_stats(self, ctx, x1, y1, x2, y2):
self._resolve_target_dimensions(bar, x3 - x1, self._npixels_each)
for bar in bars:
self._resolve_real_dimensions(bar)
y = y1 + overview_height
y = y_top - self._scroll_offset
for bar in bars:
self._resolve_positions(bar, x1, x3, y)
y += bar.height

# Check what bars to not draw, i.e. how many we're missing in view.
n_hidden1 = n_hidden2 = 0
drawn_bars = bars.copy()
height_missing = 20
while len(drawn_bars) > 1 and drawn_bars[0].y1 < y_top:
drawn_bars.pop(0)
n_hidden1 += 1
while len(drawn_bars) > 1 and drawn_bars[-1].y2 > y_bottom:
drawn_bars.pop(-1)
n_hidden2 += 1

# Get statistics
total_time = 0
overview_y2 = y1 + overview_height
if len(bars):
overview_y2 = bars[-1].y2 + 8
overview_y2 = y_top
if len(drawn_bars):
overview_y2 = drawn_bars[-1].y2 + 8
if n_hidden1 > 0 or n_hidden2 > 0:
overview_y2 = max(overview_y2, y2)
for bar in bars:
total_time += bar.t

Expand All @@ -3102,10 +3127,19 @@ def _draw_stats(self, ctx, x1, y1, x2, y2):
window.store.records.tags_from_record(record).join(" ")
)

# Draw all bars
# Draw all visible bars
self._draw_container(ctx, total_time, x1, y1, x3, overview_y2)
for bar in bars:
for bar in drawn_bars:
self._draw_one_bar(ctx, bar)
if n_hidden1 > 0:
self._draw_placeholder_for_hidden_bars(
ctx, x1 + 10, x1 + 50, y_top, y_top + height_missing, n_hidden1
)
if n_hidden2 > 0:
ymiss = overview_y2 - 8
self._draw_placeholder_for_hidden_bars(
ctx, x1 + 10, x1 + 50, ymiss - height_missing, ymiss, n_hidden2
)

# # Determine help text
# if self._maxlevel > 0:
Expand Down Expand Up @@ -3296,6 +3330,44 @@ def _draw_container(self, ctx, total_time, x1, y1, x2, y2):
else:
ctx.fillText("No target", tx, ty)

def _draw_placeholder_for_hidden_bars(self, ctx, x1, x2, y1, y2, n_hidden):
PSCRIPT_OVERLOAD = False # noqa

# Offset the bubble by a bit
x1 -= 2
x2 -= 2
y1 -= 2
y2 -= 2

npixels = self._npixels_each

# Roundness
rn = min(ANALYSIS_ROUNDNESS, npixels / 2)
rnb = min(COLORBAND_ROUNDNESS, npixels / 2)

# Draw front
ctx.lineWidth = 1.2
ctx.strokeStyle = COLORS.record_edge
ctx.fillStyle = COLORS.record_bg
path = window.Path2D()
path.arc(x2 - rn, y1 + rn, rn, 1.5 * PI, 2.0 * PI)
path.arc(x2 - rn, y2 - rn, rn, 0.0 * PI, 0.5 * PI)
path.arc(x1 + rnb, y2 - rnb, rnb, 0.5 * PI, 1.0 * PI)
path.arc(x1 + rnb, y1 + rnb, rnb, 1.0 * PI, 1.5 * PI)
path.closePath()
ctx.fill(path)

# Draw edge
ctx.stroke(path)

ymid = y1 + 0.5 * (y2 - y1)

# Draw number hidden
ctx.font = "14px " + FONT.default
ctx.textAlign = "left"
ctx.fillStyle = COLORS.prim1_clr
ctx.fillText(f"+ {n_hidden}", x1 + 11, ymid)

def _draw_one_bar(self, ctx, bar):
PSCRIPT_OVERLOAD = False # noqa

Expand Down Expand Up @@ -3476,6 +3548,13 @@ def on_pointer(self, ev):
self._canvas.tag_combo_dialog.open(tagz, self.update)
self.update()

def on_wheel(self, ev):
"""Handle wheel event."""
if len(ev.modifiers) == 0 and ev.vscroll != 0:
self._target_scroll_offset = max(0, self._target_scroll_offset + ev.vscroll)
self.update()
return True


if __name__ == "__main__":
import pscript
Expand Down

0 comments on commit a280e14

Please sign in to comment.