MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / UpdateSizeAndPosition

Method UpdateSizeAndPosition

src/dropdown.cpp:170–215  ·  view source on GitHub ↗

* Update size and position of window to fit dropdown list into available space. */

Source from the content-addressed store, hash-verified

168 * Update size and position of window to fit dropdown list into available space.
169 */
170 void UpdateSizeAndPosition()
171 {
172 Rect button_rect = this->wi_rect.Translate(this->parent->left, this->parent->top);
173
174 /* Get the dimensions required for the list. */
175 Dimension list_dim = GetDropDownListDimension(this->list);
176
177 /* Set up dimensions for the items widget. */
178 Dimension widget_dim = list_dim;
179 widget_dim.width += WidgetDimensions::scaled.dropdownlist.Horizontal();
180 widget_dim.height += WidgetDimensions::scaled.dropdownlist.Vertical();
181
182 /* Width should match at least the width of the parent widget. */
183 widget_dim.width = std::max<uint>(widget_dim.width, button_rect.Width());
184
185 /* Available height below (or above, if the dropdown is placed above the widget). */
186 uint available_height_below = std::max(GetMainViewBottom() - button_rect.bottom - 1, 0);
187 uint available_height_above = std::max(button_rect.top - 1 - GetMainViewTop(), 0);
188
189 /* Is it better to place the dropdown above the widget? */
190 if (widget_dim.height > available_height_below && available_height_above > available_height_below) {
191 FitAvailableHeight(widget_dim, list_dim, available_height_above);
192 this->position.y = button_rect.top - widget_dim.height;
193 } else {
194 FitAvailableHeight(widget_dim, list_dim, available_height_below);
195 this->position.y = button_rect.bottom + 1;
196 }
197
198 if (_current_text_dir == TD_RTL) {
199 /* In case the list is wider than the parent button, the list should be right aligned to the button and overflow to the left. */
200 this->position.x = button_rect.right + 1 - (int)(widget_dim.width + (list_dim.height > widget_dim.height ? NWidgetScrollbar::GetVerticalDimension().width : 0));
201 } else {
202 this->position.x = button_rect.left;
203 }
204
205 this->items_dim = widget_dim;
206 this->GetWidget<NWidgetStacked>(WID_DM_SHOW_SCROLL)->SetDisplayedPlane(list_dim.height > widget_dim.height ? 0 : SZSP_NONE);
207
208 /* Capacity is the average number of items visible */
209 this->vscroll->SetCapacity(widget_dim.height - WidgetDimensions::scaled.dropdownlist.Vertical());
210 this->vscroll->SetStepSize(list_dim.height / this->list.size());
211 this->vscroll->SetCount(list_dim.height);
212
213 /* If the dropdown is positioned above the parent widget, start selection at the bottom. */
214 if (this->position.y < button_rect.top && list_dim.height > widget_dim.height) this->vscroll->UpdatePosition(INT_MAX);
215 }
216
217 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
218 {

Callers 2

DropdownWindowMethod · 0.95
ReplaceListMethod · 0.95

Calls 13

GetDropDownListDimensionFunction · 0.85
GetMainViewBottomFunction · 0.85
GetMainViewTopFunction · 0.85
TranslateMethod · 0.80
HorizontalMethod · 0.80
VerticalMethod · 0.80
SetDisplayedPlaneMethod · 0.80
SetCapacityMethod · 0.80
SetStepSizeMethod · 0.80
WidthMethod · 0.45
sizeMethod · 0.45
SetCountMethod · 0.45

Tested by

no test coverage detected