1package component
2
3import (
4 "github.com/bnema/dumber/internal/ui/layout"
5 "github.com/jwijenbergh/puregotk/v4/gtk"
6)
7
8// ModalSizeConfig holds configuration for modal sizing calculations.
9type ModalSizeConfig struct {
10 WidthPct float64 // Percentage of parent width (e.g., 0.6)
11 MaxWidth int // Maximum width in pixels
12 TopMarginPct float64 // Top margin as percentage of parent height
13 FallbackWidth int // Fallback when parent not allocated
14 FallbackHeight int // Fallback height
15}
16
17// RowHeightDefaults holds default (unscaled) row heights for list-based modals.
18// These are base pixel values that should be multiplied by UI scale.
19type RowHeightDefaults struct {
20 Standard int // Standard list row (e.g., session row, history row)
21 Compact int // Compact row (e.g., tree row, sub-item)
22 Divider int // Divider/separator row
23}
24
25// ListDisplayDefaults holds display limits for list-based modals.
26type ListDisplayDefaults struct {
27 MaxVisibleRows int // Maximum rows visible before scrolling
28 MaxResults int // Maximum results to fetch/display
29}
30
31// Package-level defaults for row heights.
32var DefaultRowHeights = RowHeightDefaults{
33 Standard: 50,
34 Compact: 28,
35 Divider: 30,
36}
37
38// OmniboxSizeDefaults provides default sizing for omnibox modal.
39var OmniboxSizeDefaults = ModalSizeConfig{
40 WidthPct: 0.8,
41 MaxWidth: 800,
42 TopMarginPct: 0.2,
43 FallbackWidth: 800,
44 FallbackHeight: 600,
45}
46
47// OmniboxListDefaults provides display limits for omnibox modal.
48var OmniboxListDefaults = ListDisplayDefaults{
49 MaxVisibleRows: 10,
50 MaxResults: 10,
51}
52
53// SessionManagerSizeDefaults provides default sizing for session manager modal.
54var SessionManagerSizeDefaults = ModalSizeConfig{
55 WidthPct: 0.6,
56 MaxWidth: 600,
57 TopMarginPct: 0.15,
58 FallbackWidth: 600,
59 FallbackHeight: 600,
60}
61
62// SessionManagerListDefaults provides display limits for session manager modal.
63var SessionManagerListDefaults = ListDisplayDefaults{
64 MaxVisibleRows: 6,
65 MaxResults: 50,
66}
67
68// CalculateModalDimensions computes width and top margin based on parent overlay.
69// Returns calculated width and top margin in pixels.
70func CalculateModalDimensions(parent layout.OverlayWidget, cfg ModalSizeConfig) (width, marginTop int) {
71 var parentWidth, parentHeight int
72
73 if parent != nil {
74 parentWidth = parent.GetAllocatedWidth()
75 parentHeight = parent.GetAllocatedHeight()
76 }
77
78 if parentWidth <= 0 {
79 parentWidth = cfg.FallbackWidth
80 }
81 if parentHeight <= 0 {
82 parentHeight = cfg.FallbackHeight
83 }
84
85 width = int(float64(parentWidth) * cfg.WidthPct)
86 if width > cfg.MaxWidth {
87 width = cfg.MaxWidth
88 }
89
90 marginTop = int(float64(parentHeight) * cfg.TopMarginPct)
91 return width, marginTop
92}
93
94// SetScrolledWindowHeight safely sets min/max content height on a ScrolledWindow.
95// Resets min to -1 first to avoid GTK assertion (min <= max) when shrinking.
96func SetScrolledWindowHeight(sw *gtk.ScrolledWindow, height int) {
97 if sw == nil {
98 return
99 }
100 sw.SetMinContentHeight(-1)
101 sw.SetMaxContentHeight(height)
102 sw.SetMinContentHeight(height)
103}
104
105// MeasureWidgetHeight returns the natural height of a widget for a given width.
106// Returns 0 if widget is nil or measurement fails.
107func MeasureWidgetHeight(widget *gtk.Widget, forWidth int) int {
108 if widget == nil {
109 return 0
110 }
111 var minH, natH int
112 widget.Measure(gtk.OrientationVerticalValue, forWidth, &minH, &natH, nil, nil)
113 return natH
114}
115
116// ScaleValue scales a base pixel value by UI scale factor.
117// Returns the base value if scale is <= 0.
118func ScaleValue(base int, uiScale float64) int {
119 if uiScale <= 0 {
120 uiScale = 1.0
121 }
122 return int(float64(base) * uiScale)
123}