yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
adaptive_sheet_layout.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GUI_LAYOUT_ADAPTIVE_SHEET_LAYOUT_H_
2#define YAZE_APP_GUI_LAYOUT_ADAPTIVE_SHEET_LAYOUT_H_
3
4#include <algorithm>
5#include <cmath>
6#include <string_view>
7
8namespace yaze::gui {
9
11 kFit,
12 k1x,
13 k2x,
14 k4x,
15};
16
17inline std::string_view AdaptiveSheetScaleModeLabel(
19 switch (mode) {
21 return "1x";
23 return "2x";
25 return "4x";
27 default:
28 return "Fit";
29 }
30}
31
33 switch (mode) {
35 return 1.0f;
37 return 2.0f;
39 return 4.0f;
41 default:
42 return 0.0f;
43 }
44}
45
47 float display_scale = 1.0f;
48 float displayed_width = 0.0f;
49 float displayed_height = 0.0f;
50 float usable_width = 0.0f;
51};
52
54 float available_width, int source_width, int source_height,
56 float min_scale = 0.35f, float max_scale = 4.0f,
57 float horizontal_chrome = 24.0f) {
58 min_scale = std::max(0.01f, min_scale);
59 max_scale = std::max(min_scale, max_scale);
60 const float usable_width =
61 std::max(1.0f, available_width - std::max(0.0f, horizontal_chrome));
62
63 float scale = AdaptiveSheetFixedScale(mode);
64 if (mode == AdaptiveSheetScaleMode::kFit) {
65 scale = source_width > 0 ? usable_width / static_cast<float>(source_width)
66 : min_scale;
67 }
68 scale = std::clamp(scale, min_scale, max_scale);
69
70 return {
71 .display_scale = scale,
72 .displayed_width =
73 source_width > 0 ? static_cast<float>(source_width) * scale : 0.0f,
74 .displayed_height =
75 source_height > 0 ? static_cast<float>(source_height) * scale : 0.0f,
76 .usable_width = usable_width,
77 };
78}
79
81 float display_scale = 1.0f;
82 int columns = 1;
83 int rows = 0;
84 float item_width = 0.0f;
85 float item_height = 0.0f;
86 float content_width = 0.0f;
87 float content_height = 0.0f;
88};
89
91 float available_width, int source_item_width, int source_item_height,
92 int item_count, int preferred_columns = 2,
94 float min_scale = 0.35f, float max_scale = 4.0f, float gap = 4.0f,
95 float horizontal_chrome = 24.0f) {
96 if (source_item_width <= 0 || source_item_height <= 0 || item_count <= 0) {
97 return {};
98 }
99
100 min_scale = std::max(0.01f, min_scale);
101 max_scale = std::max(min_scale, max_scale);
102 gap = std::max(0.0f, gap);
103 const float usable =
104 std::max(1.0f, available_width - std::max(0.0f, horizontal_chrome));
105 int columns = std::clamp(preferred_columns, 1, item_count);
106
107 auto fit_scale = [&](int candidate_columns) {
108 const float gaps = gap * static_cast<float>(candidate_columns - 1);
109 return std::max(0.01f,
110 (usable - gaps) / (static_cast<float>(source_item_width) *
111 static_cast<float>(candidate_columns)));
112 };
113
114 float scale = AdaptiveSheetFixedScale(mode);
115 if (mode == AdaptiveSheetScaleMode::kFit) {
116 while (columns > 1 && fit_scale(columns) < min_scale) {
117 --columns;
118 }
119 while (columns < item_count) {
120 const int next_columns = columns + 1;
121 const float next_width =
122 static_cast<float>(next_columns * source_item_width) * max_scale +
123 gap * static_cast<float>(next_columns - 1);
124 if (next_width > usable) {
125 break;
126 }
127 columns = next_columns;
128 }
129 scale = std::clamp(fit_scale(columns), min_scale, max_scale);
130 } else {
131 scale = std::clamp(scale, min_scale, max_scale);
132 columns = std::clamp(
133 static_cast<int>(
134 std::floor((usable + gap) / (source_item_width * scale + gap))),
135 1, item_count);
136 }
137
138 const int rows = (item_count + columns - 1) / columns;
139 const float item_width = source_item_width * scale;
140 const float item_height = source_item_height * scale;
141 return {
142 .display_scale = scale,
143 .columns = columns,
144 .rows = rows,
145 .item_width = item_width,
146 .item_height = item_height,
147 .content_width =
148 item_width * columns + gap * static_cast<float>(columns - 1),
149 .content_height =
150 item_height * rows + gap * static_cast<float>(std::max(0, rows - 1)),
151 };
152}
153
154} // namespace yaze::gui
155
156#endif // YAZE_APP_GUI_LAYOUT_ADAPTIVE_SHEET_LAYOUT_H_
Graphical User Interface (GUI) components for the application.
AdaptiveSheetLayout ResolveAdaptiveSheetLayout(float available_width, int source_width, int source_height, AdaptiveSheetScaleMode mode=AdaptiveSheetScaleMode::kFit, float min_scale=0.35f, float max_scale=4.0f, float horizontal_chrome=24.0f)
float AdaptiveSheetFixedScale(AdaptiveSheetScaleMode mode)
std::string_view AdaptiveSheetScaleModeLabel(AdaptiveSheetScaleMode mode)
AdaptiveSheetGridLayout ResolveAdaptiveSheetGridLayout(float available_width, int source_item_width, int source_item_height, int item_count, int preferred_columns=2, AdaptiveSheetScaleMode mode=AdaptiveSheetScaleMode::kFit, float min_scale=0.35f, float max_scale=4.0f, float gap=4.0f, float horizontal_chrome=24.0f)