Changeset - r26695:8bfe7e010e4f
[Not reviewed]
master
0 1 0
PeterN - 22 months ago 2022-12-26 18:26:01
peter1138@openttd.org
Fix: Local authority window rating list height ignored icon sizes. (#10285)

Only font height was taken into account, so the list was broken if icon
sizes were taller than font height.
1 file changed with 23 insertions and 18 deletions:
0 comments (0 inline, 0 general)
src/town_gui.cpp
Show inline comments
 
@@ -64,24 +64,27 @@ static const NWidgetPart _nested_town_au
 
	EndContainer()
 
};
 

	
 
/** Town authority window. */
 
struct TownAuthorityWindow : Window {
 
private:
 
	Town *town;    ///< Town being displayed.
 
	int sel_index; ///< Currently selected town action, \c 0 to \c TACT_COUNT-1, \c -1 means no action selected.
 
	uint displayed_actions_on_previous_painting; ///< Actions that were available on the previous call to OnPaint()
 
	TownActions enabled_actions; ///< Actions that are enabled in settings.
 
	TownActions available_actions; ///< Actions that are available to execute for the current company.
 

	
 
	Dimension icon_size;      ///< Dimensions of company icon
 
	Dimension exclusive_size; ///< Dimensions of exlusive icon
 

	
 
	/**
 
	 * Get the position of the Nth set bit.
 
	 *
 
	 * If there is no Nth bit set return -1
 
	 *
 
	 * @param n The Nth set bit from which we want to know the position
 
	 * @return The position of the Nth set bit, or -1 if no Nth bit set.
 
	 */
 
	int GetNthSetBit(int n)
 
	{
 
		if (n >= 0) {
 
			for (uint i : SetBitIterator(this->enabled_actions)) {
 
@@ -108,87 +111,89 @@ private:
 

	
 
		return enabled;
 
	}
 

	
 
public:
 
	TownAuthorityWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), sel_index(-1), displayed_actions_on_previous_painting(0), available_actions(TACT_NONE)
 
	{
 
		this->town = Town::Get(window_number);
 
		this->enabled_actions = GetEnabledActions();
 
		this->InitNested(window_number);
 
	}
 

	
 
	void OnInit() override
 
	{
 
		this->icon_size      = GetSpriteSize(SPR_COMPANY_ICON);
 
		this->exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT);
 
	}
 

	
 
	void OnPaint() override
 
	{
 
		this->available_actions = GetMaskOfTownActions(_local_company, this->town);
 
		if (this->available_actions != displayed_actions_on_previous_painting) this->SetDirty();
 
		displayed_actions_on_previous_painting = this->available_actions;
 

	
 
		this->SetWidgetLoweredState(WID_TA_ZONE_BUTTON, this->town->show_zone);
 
		this->SetWidgetDisabledState(WID_TA_EXECUTE, (this->sel_index == -1) || !HasBit(this->available_actions, this->sel_index));
 

	
 
		this->DrawWidgets();
 
		if (!this->IsShaded())
 
		{
 
			this->DrawRatings();
 
			this->DrawActions();
 
		}
 
	}
 

	
 
	/** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */
 
	void DrawRatings()
 
	{
 
		Rect r = this->GetWidget<NWidgetBase>(WID_TA_RATING_INFO)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
 

	
 
		DrawString(r, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
 
		r.top += FONT_HEIGHT_NORMAL;
 
		int text_y_offset      = (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2;
 
		int icon_y_offset      = (this->resize.step_height - this->icon_size.height) / 2;
 
		int exclusive_y_offset = (this->resize.step_height - this->exclusive_size.height) / 2;
 

	
 
		Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON);
 
		int icon_width      = icon_size.width;
 
		int icon_y_offset   = (FONT_HEIGHT_NORMAL - icon_size.height) / 2;
 

	
 
		Dimension exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT);
 
		int exclusive_width      = exclusive_size.width;
 
		int exclusive_y_offset   = (FONT_HEIGHT_NORMAL - exclusive_size.height) / 2;
 
		DrawString(r.left, r.right, r.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
 
		r.top += this->resize.step_height;
 

	
 
		bool rtl = _current_text_dir == TD_RTL;
 
		Rect text = r.Indent(icon_width + WidgetDimensions::scaled.hsep_normal + exclusive_width + WidgetDimensions::scaled.hsep_normal, rtl);
 
		uint icon_left = r.WithWidth(icon_width, rtl).left;
 
		uint exclusive_left = r.Indent(icon_width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(exclusive_width, rtl).left;
 
		Rect icon      = r.WithWidth(this->icon_size.width, rtl);
 
		Rect exclusive = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(this->exclusive_size.width, rtl);
 
		Rect text      = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal + this->exclusive_size.width + WidgetDimensions::scaled.hsep_normal, rtl);
 

	
 
		/* Draw list of companies */
 
		for (const Company *c : Company::Iterate()) {
 
			if ((HasBit(this->town->have_ratings, c->index) || this->town->exclusivity == c->index)) {
 
				DrawCompanyIcon(c->index, icon_left, text.top + icon_y_offset);
 
				DrawCompanyIcon(c->index, icon.left, text.top + icon_y_offset);
 

	
 
				SetDParam(0, c->index);
 
				SetDParam(1, c->index);
 

	
 
				int rating = this->town->ratings[c->index];
 
				StringID str = STR_CARGO_RATING_APPALLING;
 
				if (rating > RATING_APPALLING) str++;
 
				if (rating > RATING_VERYPOOR)  str++;
 
				if (rating > RATING_POOR)      str++;
 
				if (rating > RATING_MEDIOCRE)  str++;
 
				if (rating > RATING_GOOD)      str++;
 
				if (rating > RATING_VERYGOOD)  str++;
 
				if (rating > RATING_EXCELLENT) str++;
 

	
 
				SetDParam(2, str);
 
				if (this->town->exclusivity == c->index) {
 
					DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive_left, r.top + exclusive_y_offset);
 
					DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive.left, text.top + exclusive_y_offset);
 
				}
 

	
 
				DrawString(text, STR_LOCAL_AUTHORITY_COMPANY_RATING);
 
				text.top += FONT_HEIGHT_NORMAL;
 
				DrawString(text.left, text.right, text.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATING);
 
				text.top += this->resize.step_height;
 
			}
 
		}
 

	
 
		text.bottom = text.top - 1;
 
		if (text.bottom > r.bottom) {
 
			/* If the company list is too big to fit, mark ourself dirty and draw again. */
 
			ResizeWindow(this, 0, text.bottom - r.bottom, false);
 
		}
 
	}
 

	
 
	/** Draws the contents of the actions panel. May re-initialise window to resize panel, if the list does not fit. */
 
	void DrawActions()
 
@@ -252,26 +257,26 @@ public:
 
			}
 

	
 
			case WID_TA_COMMAND_LIST:
 
				size->height = (TACT_COUNT + 1) * FONT_HEIGHT_NORMAL + padding.height;
 
				size->width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width;
 
				for (uint i = 0; i < TACT_COUNT; i++ ) {
 
					size->width = std::max(size->width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i).width);
 
				}
 
				size->width += padding.width;
 
				break;
 

	
 
			case WID_TA_RATING_INFO:
 
				resize->height = FONT_HEIGHT_NORMAL;
 
				size->height = 9 * FONT_HEIGHT_NORMAL + padding.height;
 
				resize->height = std::max({this->icon_size.height + WidgetDimensions::scaled.vsep_normal, this->exclusive_size.height + WidgetDimensions::scaled.vsep_normal, (uint)FONT_HEIGHT_NORMAL});
 
				size->height = 9 * resize->height + padding.height;
 
				break;
 
		}
 
	}
 

	
 
	void OnClick(Point pt, int widget, int click_count) override
 
	{
 
		switch (widget) {
 
			case WID_TA_ZONE_BUTTON: {
 
				bool new_show_state = !this->town->show_zone;
 
				TownID index = this->town->index;
 

	
 
				new_show_state ? _town_local_authority_kdtree.Insert(index) : _town_local_authority_kdtree.Remove(index);
0 comments (0 inline, 0 general)