Changeset - r20062:497daea68ca2
[Not reviewed]
master
0 2 0
rubidium - 11 years ago 2013-02-17 20:51:55
rubidium@openttd.org
(svn r25020) -Codechange: refactor SmallMapWindow to make adding map types easier and unduplicate some code (fonsinchen)
2 files changed with 123 insertions and 109 deletions:
0 comments (0 inline, 0 general)
src/smallmap_gui.cpp
Show inline comments
 
@@ -996,17 +996,6 @@ SmallMapWindow::SmallMapWindow(const Win
 
	this->SmallMapCenterOnCurrentPos();
 
}
 

	
 
/**
 
 * Compute height given a number of columns.
 
 * @param num_columns Number of columns.
 
 * @return Needed height for displaying the smallmap legends in pixels.
 
 */
 
uint SmallMapWindow::GetLegendHeight(uint num_columns) const
 
{
 
	uint num_rows = max(this->min_number_of_fixed_rows, CeilDiv(max(_smallmap_company_count, _smallmap_industry_count), num_columns));
 
	return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + num_rows * FONT_HEIGHT_SMALL;
 
}
 

	
 
/* virtual */ void SmallMapWindow::SetStringParameters(int widget) const
 
{
 
	switch (widget) {
 
@@ -1091,7 +1080,7 @@ uint SmallMapWindow::GetLegendHeight(uin
 

	
 
		case WID_SM_LEGEND: {
 
			uint columns = this->GetNumberColumnsLegend(r.right - r.left + 1);
 
			uint number_of_rows = max((this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER) ? CeilDiv(max(_smallmap_company_count, _smallmap_industry_count), columns) : 0, this->min_number_of_fixed_rows);
 
			uint number_of_rows = this->GetNumberRowsLegend(columns);
 
			bool rtl = _current_text_dir == TD_RTL;
 
			uint y_org = r.top + WD_FRAMERECT_TOP;
 
			uint x = rtl ? r.right - this->column_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT;
 
@@ -1104,6 +1093,18 @@ uint SmallMapWindow::GetLegendHeight(uin
 
			uint blob_left  = rtl ? this->column_width - 1 - LEGEND_BLOB_WIDTH : 0;
 
			uint blob_right = rtl ? this->column_width - 1 : LEGEND_BLOB_WIDTH;
 

	
 
			StringID string = STR_NULL;
 
			switch (this->map_type) {
 
				case SMT_INDUSTRY:
 
					string = STR_SMALLMAP_INDUSTRY;
 
					break;
 
				case SMT_OWNER:
 
					string = STR_SMALLMAP_COMPANY;
 
					break;
 
				default:
 
					break;
 
			}
 

	
 
			for (const LegendAndColour *tbl = _legend_table[this->map_type]; !tbl->end; ++tbl) {
 
				if (tbl->col_break || ((this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER) && i++ >= number_of_rows)) {
 
					/* Column break needed, continue at top, COLUMN_WIDTH pixels
 
@@ -1115,38 +1116,36 @@ uint SmallMapWindow::GetLegendHeight(uin
 

	
 
				uint8 legend_colour = tbl->colour;
 

	
 
				if (this->map_type == SMT_INDUSTRY) {
 
					/* Industry name must be formatted, since it's not in tiny font in the specs.
 
					 * So, draw with a parameter and use the STR_SMALLMAP_INDUSTRY string, which is tiny font */
 
					SetDParam(0, tbl->legend);
 
					SetDParam(1, Industry::GetIndustryTypeCount(tbl->type));
 
					if (!tbl->show_on_map) {
 
						/* Simply draw the string, not the black border of the legend colour.
 
						 * This will enforce the idea of the disabled item */
 
						DrawString(x + text_left, x + text_right, y, STR_SMALLMAP_INDUSTRY, TC_GREY);
 
					} else {
 
						if (tbl->type == _smallmap_industry_highlight) {
 
				switch (this->map_type) {
 
					case SMT_INDUSTRY:
 
						/* Industry name must be formatted, since it's not in tiny font in the specs.
 
						 * So, draw with a parameter and use the STR_SMALLMAP_INDUSTRY string, which is tiny font */
 
						SetDParam(0, tbl->legend);
 
						SetDParam(1, Industry::GetIndustryTypeCount(tbl->type));
 
						if (tbl->show_on_map && tbl->type == _smallmap_industry_highlight) {
 
							legend_colour = _smallmap_industry_highlight_state ? PC_WHITE : PC_BLACK;
 
						}
 
						DrawString(x + text_left, x + text_right, y, STR_SMALLMAP_INDUSTRY, TC_BLACK);
 
						GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour
 
					}
 
				} else if (this->map_type == SMT_OWNER && tbl->company != INVALID_COMPANY) {
 
					SetDParam(0, tbl->company);
 
					if (!tbl->show_on_map) {
 
						/* Simply draw the string, not the black border of the legend colour.
 
						 * This will enforce the idea of the disabled item */
 
						DrawString(x + text_left, x + text_right, y, STR_SMALLMAP_COMPANY, TC_GREY);
 
					} else {
 
						DrawString(x + text_left, x + text_right, y, STR_SMALLMAP_COMPANY, TC_BLACK);
 
						GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour
 
					}
 
				} else {
 
					if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP);
 

	
 
					/* Anything that is not an industry or a company is using normal process */
 
					GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK);
 
					DrawString(x + text_left, x + text_right, y, tbl->legend);
 
						/* FALL THROUGH */
 
					case SMT_OWNER:
 
						if (this->map_type != SMT_OWNER || tbl->company != INVALID_COMPANY) {
 
							if (this->map_type == SMT_OWNER) SetDParam(0, tbl->company);
 
							if (!tbl->show_on_map) {
 
								/* Simply draw the string, not the black border of the legend colour.
 
								 * This will enforce the idea of the disabled item */
 
								DrawString(x + text_left, x + text_right, y, string, TC_GREY);
 
							} else {
 
								DrawString(x + text_left, x + text_right, y, string, TC_BLACK);
 
								GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour
 
							}
 
							break;
 
						}
 
						/* FALL_THROUGH */
 
					default:
 
						if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP);
 
						/* Anything that is not an industry or a company is using normal process */
 
						GfxFillRect(x + blob_left, y + 1, x + blob_right, y + row_height - 1, PC_BLACK);
 
						DrawString(x + text_left, x + text_right, y, tbl->legend);
 
						break;
 
				}
 
				GfxFillRect(x + blob_left + 1, y + 2, x + blob_right - 1, y + row_height - 2, legend_colour); // Legend colour
 

	
 
@@ -1172,6 +1171,54 @@ void SmallMapWindow::SwitchMapType(Small
 
}
 

	
 
/**
 
 * Get the number of rows in the legend from the number of columns. Those
 
 * are at least min_number_of_fixed_rows and possibly more if there are so
 
 * many cargoes, industry types or companies that they won't fit in the
 
 * available space.
 
 * @param columns Number of columns in the legend.
 
 * @return Number of rows needed for everything to fit in.
 
 */
 
inline uint SmallMapWindow::GetNumberRowsLegend(uint columns) const
 
{
 
	uint num_rows = CeilDiv(max(_smallmap_industry_count,_smallmap_company_count), columns);
 
	return max(this->min_number_of_fixed_rows, num_rows);
 
}
 

	
 
/**
 
 * Select and toggle a legend item. When CTRL is pressed, disable all other
 
 * items in the group defined by begin_legend_item and end_legend_item and
 
 * keep the clicked one enabled even if it was already enabled before. If
 
 * the other items in the group are all disabled already and CTRL is pressed
 
 * enable them instead.
 
 * @param click_pos the index of the item being selected
 
 * @param legend the legend from which we select
 
 * @param end_legend_item index one past the last item in the group to be inverted
 
 * @param begin_legend_item index of the first item in the group to be inverted
 
 */
 
void SmallMapWindow::SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item)
 
{
 
	if (_ctrl_pressed) {
 
		/* Disable all, except the clicked one */
 
		bool changes = false;
 
		for (int i = begin_legend_item; i != end_legend_item; i++) {
 
			bool new_state = (i == click_pos);
 
			if (legend[i].show_on_map != new_state) {
 
				changes = true;
 
				legend[i].show_on_map = new_state;
 
			}
 
		}
 
		if (!changes) {
 
			/* Nothing changed? Then show all (again). */
 
			for (int i = begin_legend_item; i != end_legend_item; i++) {
 
				legend[i].show_on_map = true;
 
			}
 
		}
 
	} else {
 
		legend[click_pos].show_on_map = !legend[click_pos].show_on_map;
 
	}
 
}
 

	
 
/**
 
 * Determines the mouse position on the legend.
 
 * @param pt Mouse position.
 
 * @return Legend item under the mouse.
 
@@ -1181,7 +1228,7 @@ int SmallMapWindow::GetPositionOnLegend(
 
	const NWidgetBase *wi = this->GetWidget<NWidgetBase>(WID_SM_LEGEND);
 
	uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_SMALL;
 
	uint columns = this->GetNumberColumnsLegend(wi->current_x);
 
	uint number_of_rows = max(CeilDiv(max(_smallmap_company_count, _smallmap_industry_count), columns), this->min_number_of_fixed_rows);
 
	uint number_of_rows = this->GetNumberRowsLegend(columns);
 
	if (line >= number_of_rows) return -1;
 

	
 
	bool rtl = _current_text_dir == TD_RTL;
 
@@ -1276,55 +1323,16 @@ int SmallMapWindow::GetPositionOnLegend(
 

	
 
		case WID_SM_LEGEND: // Legend
 
			if (this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER) {
 
				int click_pos = this->GetPositionOnLegend(pt);
 
				/* If industry type small map*/
 
				if (this->map_type == SMT_INDUSTRY) {
 
					/* If click on industries label, find right industry type and enable/disable it. */
 
					int industry_pos = GetPositionOnLegend(pt);
 
					if (industry_pos >= 0 && industry_pos < _smallmap_industry_count) {
 
						if (_ctrl_pressed) {
 
							/* Disable all, except the clicked one. */
 
							bool changes = false;
 
							for (int i = 0; i != _smallmap_industry_count; i++) {
 
								bool new_state = i == industry_pos;
 
								if (_legend_from_industries[i].show_on_map != new_state) {
 
									changes = true;
 
									_legend_from_industries[i].show_on_map = new_state;
 
								}
 
							}
 
							if (!changes) {
 
								/* Nothing changed? Then show all (again). */
 
								for (int i = 0; i != _smallmap_industry_count; i++) {
 
									_legend_from_industries[i].show_on_map = true;
 
								}
 
							}
 
						} else {
 
							_legend_from_industries[industry_pos].show_on_map = !_legend_from_industries[industry_pos].show_on_map;
 
						}
 
					if (click_pos >= 0 && click_pos < _smallmap_industry_count) {
 
						this->SelectLegendItem(click_pos, _legend_from_industries, _smallmap_industry_count);
 
					}
 
				} else if (this->map_type == SMT_OWNER) {
 
					/* If click on companies label, find right company and enable/disable it. */
 
					int company_pos = GetPositionOnLegend(pt);
 
					if (company_pos < NUM_NO_COMPANY_ENTRIES) break;
 
					if (company_pos < _smallmap_company_count) {
 
						if (_ctrl_pressed) {
 
							/* Disable all, except the clicked one */
 
							bool changes = false;
 
							for (int i = NUM_NO_COMPANY_ENTRIES; i != _smallmap_company_count; i++) {
 
								bool new_state = i == company_pos;
 
								if (_legend_land_owners[i].show_on_map != new_state) {
 
									changes = true;
 
									_legend_land_owners[i].show_on_map = new_state;
 
								}
 
							}
 
							if (!changes) {
 
								/* Nothing changed? Then show all (again). */
 
								for (int i = NUM_NO_COMPANY_ENTRIES; i != _smallmap_company_count; i++) {
 
									_legend_land_owners[i].show_on_map = true;
 
								}
 
							}
 
						} else {
 
							_legend_land_owners[company_pos].show_on_map = !_legend_land_owners[company_pos].show_on_map;
 
						}
 
					if (click_pos < _smallmap_company_count) {
 
						this->SelectLegendItem(click_pos, _legend_land_owners, _smallmap_company_count, NUM_NO_COMPANY_ENTRIES);
 
					}
 
				}
 
				this->SetDirty();
 
@@ -1332,30 +1340,25 @@ int SmallMapWindow::GetPositionOnLegend(
 
			break;
 

	
 
		case WID_SM_ENABLE_ALL:
 
			if (this->map_type == SMT_INDUSTRY) {
 
				for (int i = 0; i != _smallmap_industry_count; i++) {
 
					_legend_from_industries[i].show_on_map = true;
 
				}
 
			} else if (this->map_type == SMT_OWNER) {
 
				for (int i = NUM_NO_COMPANY_ENTRIES; i != _smallmap_company_count; i++) {
 
					_legend_land_owners[i].show_on_map = true;
 
				}
 
			/* FALL THROUGH */
 
		case WID_SM_DISABLE_ALL: {
 
			LegendAndColour *tbl = NULL;
 
			switch (this->map_type) {
 
				case SMT_INDUSTRY:
 
					tbl = _legend_from_industries;
 
					break;
 
				case SMT_OWNER:
 
					tbl = &(_legend_land_owners[NUM_NO_COMPANY_ENTRIES]);
 
					break;
 
				default:
 
					NOT_REACHED();
 
			}
 
			for (;!tbl->end; ++tbl) {
 
				tbl->show_on_map = (widget == WID_SM_ENABLE_ALL);
 
			}
 
			this->SetDirty();
 
			break;
 

	
 
		case WID_SM_DISABLE_ALL:
 
			if (this->map_type == SMT_INDUSTRY) {
 
				for (int i = 0; i != _smallmap_industry_count; i++) {
 
					_legend_from_industries[i].show_on_map = false;
 
				}
 
			} else {
 
				for (int i = NUM_NO_COMPANY_ENTRIES; i != _smallmap_company_count; i++) {
 
					_legend_land_owners[i].show_on_map = false;
 
				}
 
			}
 
			this->SetDirty();
 
			break;
 
		}
 

	
 
		case WID_SM_SHOW_HEIGHT: // Enable/disable showing of heightmap.
 
			_smallmap_show_heightmap = !_smallmap_show_heightmap;
src/smallmap_gui.h
Show inline comments
 
@@ -139,8 +139,19 @@ public:
 
		return width / this->column_width;
 
	}
 

	
 
	uint GetLegendHeight(uint num_columns) const;
 
	/**
 
	 * Compute height given a number of columns.
 
	 * @param num_columns Number of columns.
 
	 * @return Needed height for displaying the smallmap legends in pixels.
 
	 */
 
	inline uint GetLegendHeight(uint num_columns) const
 
	{
 
		return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM +
 
				this->GetNumberRowsLegend(num_columns) * FONT_HEIGHT_SMALL;
 
	}
 

	
 
	uint GetNumberRowsLegend(uint columns) const;
 
	void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item = 0);
 
	void SwitchMapType(SmallMapType map_type);
 
	void SetNewScroll(int sx, int sy, int sub);
 
	void SmallMapCenterOnCurrentPos();
0 comments (0 inline, 0 general)