From eaf1e33bd7fde28bab48c3a243aa13bb6df4e1a7 Mon Sep 17 00:00:00 2001 From: PeterN Date: Mon, 28 Nov 2022 00:27:57 +0000 Subject: [PATCH] Fix #10021: Object GUI resized when switching between different objects. (#10196) * Fix: Scale object gui margin by interface scale. * Fix: Improve padding on object info text. * Fix #10021: Resizing for 1/2/4 object views didn't account for interface scale. As halving and doubling padding is problematic due to rounding, it is now added on lower view counts instead of removing on higher view counts. --- src/object_gui.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 58fd1771c3..31b7df2d25 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -48,8 +48,8 @@ class BuildObjectWindow : public Window { typedef GUIList GUIObjectClassList; ///< Type definition for the list to hold available object classes. static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box. - static const int OBJECT_MARGIN = 4; ///< The margin (in pixels) around an object. + int object_margin; ///< The margin (in pixels) around an object. int line_height; ///< The height of a single line. int info_height; ///< The height of the info box. Scrollbar *vscroll; ///< The scrollbar. @@ -229,6 +229,11 @@ public: } } + void OnInit() override + { + this->object_margin = ScaleGUITrad(4); + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { @@ -266,7 +271,7 @@ public: case WID_BO_OBJECT_SPRITE: { bool two_wide = false; // Whether there will be two widgets next to each other in the matrix or not. - int height[2] = {0, 0}; // The height for the different views; in this case views 1/2 and 4. + uint height[2] = {0, 0}; // The height for the different views; in this case views 1/2 and 4. /* Get the height and view information. */ for (int i = 0; i < NUM_OBJECTS; i++) { @@ -279,26 +284,28 @@ public: /* Determine the pixel heights. */ for (size_t i = 0; i < lengthof(height); i++) { height[i] *= ScaleGUITrad(TILE_HEIGHT); - height[i] += ScaleGUITrad(TILE_PIXELS) + 2 * OBJECT_MARGIN; + height[i] += ScaleGUITrad(TILE_PIXELS) + 2 * this->object_margin; } /* Now determine the size of the minimum widgets. When there are two columns, then * we want these columns to be slightly less wide. When there are two rows, then * determine the size of the widgets based on the maximum size for a single row * of widgets, or just the twice the widget height of the two row ones. */ - size->height = std::max(height[0], height[1] * 2 + 2); + size->height = std::max(height[0], height[1] * 2); if (two_wide) { - size->width = (3 * ScaleGUITrad(TILE_PIXELS) + 2 * OBJECT_MARGIN) * 2 + 2; + size->width = (3 * ScaleGUITrad(TILE_PIXELS) + 2 * this->object_margin) * 2; } else { - size->width = 4 * ScaleGUITrad(TILE_PIXELS) + 2 * OBJECT_MARGIN; + size->width = 4 * ScaleGUITrad(TILE_PIXELS) + 2 * this->object_margin; } /* Get the right size for the single widget based on the current spec. */ ObjectClass *objclass = ObjectClass::Get(_selected_object_class); const ObjectSpec *spec = objclass->GetSpec(_selected_object_index); if (spec != nullptr) { - if (spec->views >= 2) size->width = size->width / 2 - 1; - if (spec->views >= 4) size->height = size->height / 2 - 1; + if (spec->views <= 1) size->width += WidgetDimensions::scaled.hsep_normal; + if (spec->views <= 2) size->height += WidgetDimensions::scaled.vsep_normal; + if (spec->views >= 2) size->width /= 2; + if (spec->views >= 4) size->height /= 2; } break; } @@ -360,9 +367,9 @@ public: if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; - DrawOrigTileSeqInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleSpriteTrad(TILE_PIXELS), dts, PAL_NONE); + DrawOrigTileSeqInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), dts, PAL_NONE); } else { - DrawNewObjectTileInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleSpriteTrad(TILE_PIXELS), spec, GB(widget, 16, 16)); + DrawNewObjectTileInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), spec, GB(widget, 16, 16)); } _cur_dpi = old_dpi; } @@ -387,9 +394,9 @@ public: if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; - DrawOrigTileSeqInGUI(r.Width() / 2 - 1, r.Height() - OBJECT_MARGIN - ScaleSpriteTrad(TILE_PIXELS), dts, PAL_NONE); + DrawOrigTileSeqInGUI(r.Width() / 2 - 1, r.Height() - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), dts, PAL_NONE); } else { - DrawNewObjectTileInGUI(r.Width() / 2 - 1, r.Height() - OBJECT_MARGIN - ScaleSpriteTrad(TILE_PIXELS), spec, + DrawNewObjectTileInGUI(r.Width() / 2 - 1, r.Height() - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), spec, std::min(_selected_object_view, spec->views - 1)); } _cur_dpi = old_dpi; @@ -415,11 +422,11 @@ public: /* Use all the available space left from where we stand up to the * end of the window. We ALSO enlarge the window if needed, so we * can 'go' wild with the bottom of the window. */ - int y = DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, message, TC_ORANGE) - r.top; + int y = DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, message, TC_ORANGE) - r.top - 1; StopTextRefStackUsage(); if (y > this->info_height) { BuildObjectWindow *bow = const_cast(this); - bow->info_height = y + 2; + bow->info_height = y; bow->ReInit(); } } @@ -724,7 +731,7 @@ static const NWidgetPart _nested_build_object_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BO_INFO), SetPadding(0, 5, 0, 1), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BO_INFO), SetPadding(0, 5, 2, 2), SetFill(1, 0), SetResize(1, 0), NWidget(NWID_VERTICAL), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(), NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN),