mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-02-12 01:24:54 +00:00
(svn r25020) -Codechange: refactor SmallMapWindow to make adding map types easier and unduplicate some code (fonsinchen)
This commit is contained in:
parent
dfdced2239
commit
52aeef1a79
@ -996,17 +996,6 @@ SmallMapWindow::SmallMapWindow(const WindowDesc *desc, int window_number) : Wind
|
||||
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(uint num_columns) const
|
||||
|
||||
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(uint num_columns) const
|
||||
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(uint num_columns) const
|
||||
|
||||
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
|
||||
|
||||
@ -1171,6 +1170,54 @@ void SmallMapWindow::SwitchMapType(SmallMapType map_type)
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -1181,7 +1228,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
|
||||
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(Point pt)
|
||||
|
||||
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(Point pt)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* 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_SHOW_HEIGHT: // Enable/disable showing of heightmap.
|
||||
_smallmap_show_heightmap = !_smallmap_show_heightmap;
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user