norcal 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/norcal +175 -201
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 01d60640ac4be6724791dd1a510ca21f17748c5cebb705c2acc33864353ee3f2
4
- data.tar.gz: 6f393645e5b43e5671d71acbfdb132a32aa9add25524e725ae8f25a878879b7d
3
+ metadata.gz: 628317b98eb4536e13c1199961ce51f89f246add68275897845fa08654060de1
4
+ data.tar.gz: 23ef85bb70d9342b372fb443b6ab26a3664c7b39b69ec479bbc54fe7a10c6423
5
5
  SHA512:
6
- metadata.gz: c181d09cbb95b52c24e220c9dc3293fe738d2614cff48d1e65766b4ef18aa2a48e33c8998fb1a420a4d2b12633fd1f2abb881b6501cb597beca45c5ff3ac7cfb
7
- data.tar.gz: 331b2f5093a691edb71a32b36c906b0c76471baf0cfc38555bc540935ede4d8c88bb73381f815110f59bb7f31bb9bd29e119097c998c41d1de62de8a3ef8898b
6
+ metadata.gz: a23ac49843b37ed383b08d6215a5a9f4f24416471539654053abd2574c4d4f5aa46e714d56d6f78a50a14a9e43d17652d08173d2cb08ddb6a584e8d2a6515432
7
+ data.tar.gz: d4392d35c14eda23aebf58669e627c908c754cda781cdba6d61f72e4dc1a9b135ed56c8ff387683bf4f3e2c919c512ed44c839aae7d2c6901f773f611e5281f7
data/README.md CHANGED
@@ -31,7 +31,7 @@ gem install norcal
31
31
  git clone https://github.com/baosen/norcal.git
32
32
  cd norcal
33
33
  gem build norcal.gemspec
34
- gem install norcal-1.1.0.gem
34
+ gem install norcal-1.2.0.gem
35
35
  ```
36
36
 
37
37
  ## Usage
data/bin/norcal CHANGED
@@ -170,56 +170,86 @@ def make_fonts
170
170
  }
171
171
  end
172
172
 
173
- root = TkRoot.new do
173
+ $root = TkRoot.new do
174
174
  title "norcal"
175
175
  end
176
176
 
177
- # -- Calendar content ----------------------------------------------------------
177
+ # -- Widget tracking for in-place updates --------------------------------------
178
178
 
179
- def render_month(parent, year, month, holidays, f)
179
+ # All trackable widgets, grouped by update type.
180
+ # Labels store {w: widget, fg: theme_key, bg: theme_key, font: font_key}.
181
+ # Buttons store {w: widget, fg: theme_key, text_key: theme_key or nil, text: static}.
182
+ $w = { bg: [], border: [], sep: [], labels: [], texts: [], buttons: [] }
183
+
184
+ # Apply current theme + zoom to all tracked widgets (no widget recreation).
185
+ def restyle
180
186
  t = theme
187
+ f = make_fonts
188
+
189
+ $root.configure(background: t[:bg])
190
+ $canvas.configure(background: t[:bg])
191
+ $scrollbar.configure(background: t[:bg], troughcolor: t[:bg])
192
+ $root.title = "Kalender #{$year}"
193
+
194
+ $w[:bg].each { |w| w.configure(background: t[:bg]) }
195
+ $w[:border].each { |w| w.configure(background: t[:bg], highlightbackground: t[:border]) }
196
+ $w[:sep].each { |w| w.configure(background: t[:sep]) }
197
+
198
+ $w[:labels].each do |e|
199
+ e[:w].configure(foreground: t[e[:fg]], background: t[e[:bg]], font: f[e[:font]])
200
+ end
181
201
 
202
+ $w[:texts].each do |tw|
203
+ tab = [65 + $zoom * 4, 40].max
204
+ tw.configure(background: t[:bg], font: f[:note], tabs: tab.to_s)
205
+ tw.tag_configure('dt', foreground: t[:fg], font: f[:note_b])
206
+ tw.tag_configure('dtr', foreground: t[:red], font: f[:note_b])
207
+ tw.tag_configure('desc', foreground: t[:desc_fg], font: f[:note_d])
208
+ end
209
+
210
+ $w[:buttons].each do |e|
211
+ text = e[:text_key] ? t[e[:text_key]] : e[:text]
212
+ e[:w].configure(text: text, font: f[:btn], foreground: t[e[:fg]],
213
+ background: t[:bg], activebackground: t[:bg], activeforeground: t[:fg])
214
+ end
215
+ end
216
+
217
+ # -- Build calendar (one-time per year) ----------------------------------------
218
+
219
+ def build_month(parent, year, month, holidays)
182
220
  first = Date.new(year, month, 1)
183
221
  last_day = Date.new(year, month, -1)
184
222
  monday = first - (first.cwday - 1)
185
223
  today = Date.today
186
224
 
187
- outer = TkFrame.new(parent) {
188
- borderwidth 1; relief 'solid'; background t[:bg]
189
- highlightbackground t[:border]; highlightthickness 0
190
- }
225
+ outer = TkFrame.new(parent) { borderwidth 1; relief 'solid'; highlightthickness 0 }
226
+ $w[:border] << outer
191
227
 
192
- grid = TkFrame.new(outer) { background t[:bg]; padx 6; pady 4 }
228
+ grid = TkFrame.new(outer) { padx 6; pady 4 }
229
+ $w[:bg] << grid
193
230
  grid.pack
194
231
 
195
- # Month name header
196
- TkLabel.new(grid) {
197
- text MONTHS_NO[month - 1]; font f[:mheader]; foreground t[:fg]; background t[:bg]
198
- }.grid(row: 0, column: 0, columnspan: 8, pady: [0, 2])
232
+ hdr = TkLabel.new(grid) { text MONTHS_NO[month - 1] }
233
+ $w[:labels] << { w: hdr, fg: :fg, bg: :bg, font: :mheader }
234
+ hdr.grid(row: 0, column: 0, columnspan: 8, pady: [0, 2])
199
235
 
200
- # Day-name headers
201
- TkLabel.new(grid) {
202
- text 'Uke'; font f[:cal]; foreground t[:dkgray]; background t[:bg]
203
- }.grid(row: 1, column: 0, sticky: 'e', padx: [0, 4])
236
+ uke = TkLabel.new(grid) { text 'Uke' }
237
+ $w[:labels] << { w: uke, fg: :dkgray, bg: :bg, font: :cal }
238
+ uke.grid(row: 1, column: 0, sticky: 'e', padx: [0, 4])
204
239
 
205
240
  DAYS_NO.each_with_index do |d, i|
206
- fg = case i
207
- when 5 then t[:gray]
208
- when 6 then t[:red]
209
- else t[:fg]
210
- end
211
- TkLabel.new(grid) {
212
- text d; font f[:cal_bold]; foreground fg; background t[:bg]
213
- }.grid(row: 1, column: i + 1, sticky: 'e')
241
+ fg_key = case i when 5 then :gray when 6 then :red else :fg end
242
+ lbl = TkLabel.new(grid) { text d }
243
+ $w[:labels] << { w: lbl, fg: fg_key, bg: :bg, font: :cal_bold }
244
+ lbl.grid(row: 1, column: i + 1, sticky: 'e')
214
245
  end
215
246
 
216
- # Week rows
217
247
  row = 2
218
248
  cur = monday
219
249
  while cur <= last_day
220
- TkLabel.new(grid) {
221
- text cur.cweek.to_s; font f[:cal]; foreground t[:dkgray]; background t[:bg]
222
- }.grid(row: row, column: 0, sticky: 'e', padx: [0, 4])
250
+ wk = TkLabel.new(grid) { text cur.cweek.to_s }
251
+ $w[:labels] << { w: wk, fg: :dkgray, bg: :bg, font: :cal }
252
+ wk.grid(row: row, column: 0, sticky: 'e', padx: [0, 4])
223
253
 
224
254
  7.times do |i|
225
255
  day = cur + i
@@ -227,263 +257,207 @@ def render_month(parent, year, month, holidays, f)
227
257
  is_red = day.cwday == 7 || holidays.key?(day)
228
258
  is_sat = day.cwday == 6 && !holidays.key?(day)
229
259
  is_today = day == today
230
- fg = if is_red then t[:red]
231
- elsif is_sat then t[:gray]
232
- else t[:fg]
233
- end
234
- TkLabel.new(grid) {
235
- text day.day.to_s
236
- font(is_today ? f[:cal_bold] : f[:cal])
237
- foreground fg
238
- background(is_today ? t[:today_bg] : t[:bg])
239
- }.grid(row: row, column: i + 1, sticky: 'e')
260
+ fg_key = is_red ? :red : (is_sat ? :gray : :fg)
261
+ bg_key = is_today ? :today_bg : :bg
262
+ font_key = is_today ? :cal_bold : :cal
263
+
264
+ lbl = TkLabel.new(grid) { text day.day.to_s }
265
+ $w[:labels] << { w: lbl, fg: fg_key, bg: bg_key, font: font_key }
266
+ lbl.grid(row: row, column: i + 1, sticky: 'e')
240
267
  end
241
268
  end
242
269
  row += 1
243
270
  cur += 7
244
271
  end
245
272
 
246
- # Pad empty rows so all months have the same height (max 6 week rows)
247
273
  while row < 8
248
- TkLabel.new(grid) { text ' '; font f[:cal]; background t[:bg] }
249
- .grid(row: row, column: 0)
274
+ pad = TkLabel.new(grid) { text ' ' }
275
+ $w[:labels] << { w: pad, fg: :fg, bg: :bg, font: :cal }
276
+ pad.grid(row: row, column: 0)
250
277
  row += 1
251
278
  end
252
279
 
253
- # Uniform column widths
254
280
  (1..7).each { |c| grid.grid_columnconfigure(c, uniform: 'day', minsize: 22) }
255
-
256
281
  outer
257
282
  end
258
283
 
259
- def render_notable(parent, year, f)
260
- t = theme
284
+ def build_notable(parent, year)
261
285
  dates = notable_dates(year)
262
-
263
- # Split into 3 roughly-equal columns
264
286
  third = (dates.size / 3.0).ceil
265
- cols = dates.each_slice(third).to_a
287
+ cols = dates.each_slice(third).to_a
266
288
 
267
- outer = TkFrame.new(parent) {
268
- borderwidth 1; relief 'solid'; background t[:bg]
269
- highlightbackground t[:border]; highlightthickness 0
270
- }
289
+ outer = TkFrame.new(parent) { borderwidth 1; relief 'solid'; highlightthickness 0 }
290
+ $w[:border] << outer
271
291
 
272
- inner = TkFrame.new(outer) { background t[:bg] }
292
+ inner = TkFrame.new(outer)
293
+ $w[:bg] << inner
273
294
  inner.pack(padx: 5, pady: 5, fill: 'both')
274
295
 
275
296
  cols.each_with_index do |entries, ci|
276
297
  tw = TkText.new(inner) {
277
298
  width 1; height(entries.size + 4)
278
- font f[:note]; borderwidth 0; highlightthickness 0
279
- wrap 'word'; background t[:bg]; padx 3; pady 2
280
- cursor ''; insertwidth 0
281
- tabs '65'
299
+ borderwidth 0; highlightthickness 0
300
+ wrap 'word'; padx 3; pady 2; cursor ''; insertwidth 0
282
301
  }
283
- tw.tag_configure('dt', foreground: t[:fg], font: f[:note_b])
284
- tw.tag_configure('dtr', foreground: t[:red], font: f[:note_b])
285
- tw.tag_configure('desc', foreground: t[:desc_fg], font: f[:note_d])
302
+ $w[:texts] << tw
286
303
 
287
304
  entries.each_with_index do |(date, desc, is_red), i|
288
305
  dtag = is_red ? 'dtr' : 'dt'
289
- date_str = "#{date.day}. #{MABBR_NO[date.month - 1]}"
290
- tw.insert('end', date_str, dtag)
306
+ tw.insert('end', "#{date.day}. #{MABBR_NO[date.month - 1]}", dtag)
291
307
  tw.insert('end', "\t")
292
308
  tw.insert('end', desc, 'desc')
293
309
  tw.insert('end', "\n") unless i == entries.size - 1
294
310
  end
295
-
296
311
  tw.state 'disabled'
297
312
  tw.grid(row: 0, column: ci * 2, sticky: 'nsew', padx: [0, 2])
298
313
  inner.grid_columnconfigure(ci * 2, weight: 1, uniform: 'notecol')
299
314
  inner.grid_rowconfigure(0, weight: 1)
300
315
 
301
- # vertical separator between columns (except after last)
302
316
  if ci < cols.size - 1
303
- sep = TkFrame.new(inner) { background t[:sep]; width 1 }
317
+ sep = TkFrame.new(inner) { width 1 }
318
+ $w[:sep] << sep
304
319
  sep.grid(row: 0, column: ci * 2 + 1, sticky: 'ns', padx: 4)
305
320
  end
306
321
  end
307
-
308
322
  outer
309
323
  end
310
324
 
311
- def build_calendar(parent, year, f)
312
- t = theme
325
+ def build_buttons(parent)
326
+ btn_bar = TkFrame.new(parent)
327
+ $w[:bg] << btn_bar
328
+ btn_bar.grid(row: 5, column: 0, columnspan: 3, pady: [4, 0])
329
+
330
+ b1 = TkButton.new(btn_bar) { relief 'flat'; borderwidth 0; command { $dark = !$dark; restyle } }
331
+ $w[:buttons] << { w: b1, fg: :dkgray, text_key: :toggle_label, text: nil }
332
+ b1.pack(side: 'left', padx: 4)
333
+
334
+ b2 = TkButton.new(btn_bar) { relief 'flat'; borderwidth 0; command { $zoom += 1; restyle } }
335
+ $w[:buttons] << { w: b2, fg: :dkgray, text_key: nil, text: '+' }
336
+ b2.pack(side: 'left', padx: 2)
337
+
338
+ b3 = TkButton.new(btn_bar) { relief 'flat'; borderwidth 0; command { $zoom -= 1 if $zoom > -8; restyle } }
339
+ $w[:buttons] << { w: b3, fg: :dkgray, text_key: nil, text: "\u2013" }
340
+ b3.pack(side: 'left', padx: 2)
341
+
342
+ b4 = TkButton.new(btn_bar) { relief 'flat'; borderwidth 0; command { $fit.call(false) } }
343
+ $w[:buttons] << { w: b4, fg: :dkgray, text_key: nil, text: 'fit' }
344
+ b4.pack(side: 'left', padx: 2)
345
+ end
346
+
347
+ def build_all(year)
348
+ $w.each_value(&:clear)
349
+ $inner_frame&.destroy
350
+
313
351
  holidays = red_days(year)
314
352
 
315
- frame = TkFrame.new(parent) { background t[:bg] }
353
+ $inner_frame = TkFrame.new($canvas)
354
+ $w[:bg] << $inner_frame
355
+
356
+ title = TkLabel.new($inner_frame) { text year.to_s }
357
+ $w[:labels] << { w: title, fg: :title_fg, bg: :bg, font: :title }
358
+ title.pack(pady: [8, 2])
359
+
360
+ frame = TkFrame.new($inner_frame)
361
+ $w[:bg] << frame
362
+ frame.pack(padx: 10, pady: [2, 8])
316
363
 
317
- # Single grid for months and notable dates
318
- grid_f = TkFrame.new(frame) { background t[:bg] }
319
- grid_f.pack(padx: 10, pady: [2, 8])
364
+ grid_f = TkFrame.new(frame)
365
+ $w[:bg] << grid_f
366
+ grid_f.pack
320
367
 
321
368
  12.times do |idx|
322
- m_frame = render_month(grid_f, year, idx + 1, holidays, f)
323
- m_frame.grid(row: idx / 3, column: idx % 3, padx: 3, pady: 3, sticky: 'nsew')
369
+ build_month(grid_f, year, idx + 1, holidays)
370
+ .grid(row: idx / 3, column: idx % 3, padx: 3, pady: 3, sticky: 'nsew')
324
371
  end
325
372
 
326
- # Notable dates in row 4, spanning all 3 month columns
327
- note_f = render_notable(grid_f, year, f)
328
- note_f.grid(row: 4, column: 0, columnspan: 3, padx: 3, pady: [4, 0], sticky: 'ew')
373
+ build_notable(grid_f, year)
374
+ .grid(row: 4, column: 0, columnspan: 3, padx: 3, pady: [4, 0], sticky: 'ew')
329
375
 
330
- # Button bar: toggle + zoom
331
- btn_bar = TkFrame.new(grid_f) { background t[:bg] }
332
- btn_bar.grid(row: 5, column: 0, columnspan: 3, pady: [4, 0])
376
+ build_buttons(grid_f)
377
+ 3.times { |c| grid_f.grid_columnconfigure(c, weight: 1) }
333
378
 
334
- TkButton.new(btn_bar) {
335
- text t[:toggle_label]; font f[:btn]
336
- relief 'flat'; borderwidth 0
337
- foreground t[:dkgray]; background t[:bg]
338
- activebackground t[:bg]; activeforeground t[:fg]
339
- command { $dark = !$dark; $rebuild&.call }
340
- }.pack(side: 'left', padx: 4)
341
-
342
- TkButton.new(btn_bar) {
343
- text '+'; font f[:btn]
344
- relief 'flat'; borderwidth 0
345
- foreground t[:dkgray]; background t[:bg]
346
- activebackground t[:bg]; activeforeground t[:fg]
347
- command { $zoom += 1; $rebuild&.call }
348
- }.pack(side: 'left', padx: 2)
349
-
350
- TkButton.new(btn_bar) {
351
- text "\u2013"; font f[:btn] # en-dash for minus
352
- relief 'flat'; borderwidth 0
353
- foreground t[:dkgray]; background t[:bg]
354
- activebackground t[:bg]; activeforeground t[:fg]
355
- command { $zoom -= 1 if $zoom > -8; $rebuild&.call }
356
- }.pack(side: 'left', padx: 2)
357
-
358
- TkButton.new(btn_bar) {
359
- text 'fit'; font f[:btn]
360
- relief 'flat'; borderwidth 0
361
- foreground t[:dkgray]; background t[:bg]
362
- activebackground t[:bg]; activeforeground t[:fg]
363
- command { $fit&.call }
364
- }.pack(side: 'left', padx: 2)
379
+ # Embed in canvas
380
+ $canvas.delete('all')
381
+ $canvas_win = $canvas.create(:window, 0, 0, window: $inner_frame, anchor: 'nw')
365
382
 
366
- 3.times { |c| grid_f.grid_columnconfigure(c, weight: 1) }
383
+ center = proc {
384
+ cw = $canvas.winfo_width; ch = $canvas.winfo_height
385
+ fw = $inner_frame.winfo_reqwidth; fh = $inner_frame.winfo_reqheight
386
+ $canvas.coords($canvas_win, [(cw - fw) / 2, 0].max, [(ch - fh) / 2, 0].max)
387
+ $canvas.configure(scrollregion: "0 0 #{[cw, fw].max} #{[ch, fh].max}")
388
+ }
389
+ $inner_frame.bind('Configure', center)
390
+ $canvas.bind('Configure', center)
367
391
 
368
- frame
392
+ restyle
369
393
  end
370
394
 
371
395
  # -- Scrollable wrapper --------------------------------------------------------
372
396
 
373
- $scrollbar = TkScrollbar.new(root)
374
- $canvas = TkCanvas.new(root) {
375
- highlightthickness 0; borderwidth 0
376
- }
397
+ $scrollbar = TkScrollbar.new($root)
398
+ $canvas = TkCanvas.new($root) { highlightthickness 0; borderwidth 0 }
377
399
  $canvas.configure(yscrollcommand: proc { |*a| $scrollbar.set(*a) })
378
400
  $scrollbar.command(proc { |*a| $canvas.yview(*a) })
379
-
380
401
  $scrollbar.pack(side: 'right', fill: 'y')
381
402
  $canvas.pack(side: 'left', fill: 'both', expand: true)
382
403
 
383
- # Mouse wheel scrolling
384
- root.bind('MouseWheel') { |e| $canvas.yview_scroll(-e.delta / 120, 'units') }
385
- root.bind('Button-4') { $canvas.yview_scroll(-3, 'units') }
386
- root.bind('Button-5') { $canvas.yview_scroll(3, 'units') }
404
+ # Scrolling
405
+ $root.bind('MouseWheel') { |e| $canvas.yview_scroll(-e.delta / 120, 'units') }
406
+ $root.bind('Button-4') { $canvas.yview_scroll(-3, 'units') }
407
+ $root.bind('Button-5') { $canvas.yview_scroll(3, 'units') }
387
408
 
388
- # Keyboard zoom: Ctrl++ and Ctrl+-
389
- root.bind('Control-plus') { $zoom += 1; $rebuild&.call }
390
- root.bind('Control-equal') { $zoom += 1; $rebuild&.call } # Ctrl+= (unshifted +)
391
- root.bind('Control-minus') { $zoom -= 1 if $zoom > -8; $rebuild&.call }
409
+ # Keyboard zoom
410
+ $root.bind('Control-plus') { $zoom += 1; restyle }
411
+ $root.bind('Control-equal') { $zoom += 1; restyle }
412
+ $root.bind('Control-minus') { $zoom -= 1 if $zoom > -8; restyle }
392
413
 
393
414
  # Ctrl+mouse wheel zoom
394
- root.bind('Control-MouseWheel') { |e|
415
+ $root.bind('Control-MouseWheel') { |e|
395
416
  if e.delta > 0 then $zoom += 1 else $zoom -= 1 if $zoom > -8 end
396
- $rebuild&.call
417
+ restyle
397
418
  }
398
- root.bind('Control-Button-4') { $zoom += 1; $rebuild&.call }
399
- root.bind('Control-Button-5') { $zoom -= 1 if $zoom > -8; $rebuild&.call }
400
-
401
- # -- Build & rebuild -----------------------------------------------------------
402
-
403
- $inner_frame = nil
404
- $rebuild = nil
405
-
406
- $rebuild = proc {
407
- t = theme
408
- f = make_fonts
409
-
410
- $inner_frame&.destroy
411
- root.configure(background: t[:bg])
412
- $canvas.configure(background: t[:bg])
413
- $scrollbar.configure(background: t[:bg], troughcolor: t[:bg])
414
- root.title = "norcal - #{$year}"
415
-
416
- $inner_frame = TkFrame.new($canvas) { background t[:bg] }
417
-
418
- # Title
419
- TkLabel.new($inner_frame) {
420
- text $year.to_s; font f[:title]; foreground t[:title_fg]; background t[:bg]
421
- }.pack(pady: [8, 2])
422
-
423
- # Calendar content
424
- build_calendar($inner_frame, $year, f).pack(fill: 'both', expand: true)
419
+ $root.bind('Control-Button-4') { $zoom += 1; restyle }
420
+ $root.bind('Control-Button-5') { $zoom -= 1 if $zoom > -8; restyle }
425
421
 
426
- # Embed frame in canvas, centered
427
- $canvas.delete('all')
428
- $canvas_win = $canvas.create(:window, 0, 0, window: $inner_frame, anchor: 'nw')
429
-
430
- # Center content and update scroll region on resize
431
- center_content = proc {
432
- cw = $canvas.winfo_width
433
- ch = $canvas.winfo_height
434
- fw = $inner_frame.winfo_reqwidth
435
- fh = $inner_frame.winfo_reqheight
436
- x = [(cw - fw) / 2, 0].max
437
- y = [(ch - fh) / 2, 0].max
438
- $canvas.coords($canvas_win, x, y)
439
- $canvas.configure(scrollregion: "#{0} #{0} #{[cw, fw].max} #{[ch, fh].max}")
440
- }
422
+ # -- Fit to window -------------------------------------------------------------
441
423
 
442
- $inner_frame.bind('Configure', center_content)
443
- $canvas.bind('Configure', center_content)
444
- }
445
-
446
- # Fit-to-window: zoom so content fills available height, then resize window
447
- $fit = proc {
448
- # Measure current content height and extrapolate target zoom
424
+ $fit = proc { |resize_window|
425
+ target_h = resize_window ? $root.winfo_screenheight - 80 : $root.winfo_height
449
426
  cur_h = $inner_frame.winfo_reqheight.to_f
450
- screen_h = root.winfo_screenheight - 80
451
- base_avg = 13.0 # average base font size at zoom 0
427
+ base_avg = 13.0
452
428
 
453
- if cur_h > 0 && screen_h > 0
454
- # Current effective font size, and what it needs to be
455
- cur_font = base_avg + $zoom
456
- target_font = cur_font * (screen_h / cur_h)
429
+ if cur_h > 0 && target_h > 0
430
+ cur_font = base_avg + $zoom
431
+ target_font = cur_font * (target_h / cur_h)
457
432
  $zoom = (target_font - base_avg).floor
458
433
  $zoom = [$zoom, -8].max
459
434
  end
460
435
 
461
- $rebuild.call
436
+ restyle
462
437
  Tk.update_idletasks
463
438
 
464
- # If overshot, back off by one
465
- if $inner_frame.winfo_reqheight > screen_h
439
+ if $inner_frame.winfo_reqheight > target_h
466
440
  $zoom -= 1
467
- $rebuild.call
441
+ restyle
468
442
  Tk.update_idletasks
469
443
  end
470
444
 
471
- # Size window to actual content, capped at screen
472
- content_w = $inner_frame.winfo_reqwidth + 20
473
- content_h = $inner_frame.winfo_reqheight
474
- screen_w = root.winfo_screenwidth
475
- max_h = root.winfo_screenheight - 50
476
- w = [content_w, screen_w].min
477
- h = [content_h, max_h].min
478
- x = (screen_w - w) / 2
479
- root.geometry("#{w}x#{h}+#{x}+0")
445
+ if resize_window
446
+ cw = $inner_frame.winfo_reqwidth + 20
447
+ ch = $inner_frame.winfo_reqheight
448
+ sw = $root.winfo_screenwidth
449
+ mh = $root.winfo_screenheight - 50
450
+ w = [cw, sw].min; h = [ch, mh].min
451
+ $root.geometry("#{w}x#{h}+#{(sw - w) / 2}+0")
452
+ end
480
453
  }
481
454
 
482
- # Initial build, then fit to window (withdraw during startup to avoid flicker)
483
- root.withdraw
484
- $rebuild.call
455
+ # -- Startup -------------------------------------------------------------------
456
+
457
+ $root.withdraw
458
+ build_all($year)
485
459
  Tk.update_idletasks
486
- $fit.call
487
- root.deiconify
460
+ $fit.call(true)
461
+ $root.deiconify
488
462
 
489
463
  Tk.mainloop
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: norcal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - baosen