4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file subsidy_gui.cpp GUI for subsidies. */
15 #include "window_gui.h"
16 #include "strings_func.h"
17 #include "date_func.h"
18 #include "viewport_func.h"
20 #include "subsidy_func.h"
21 #include "subsidy_base.h"
22 #include "core/geometry_func.hpp"
24 #include "widgets/subsidy_widget.h"
26 #include "table/strings.h"
28 #include "safeguards.h"
30 struct SubsidyListWindow
: Window
{
33 SubsidyListWindow(WindowDesc
*desc
, WindowNumber window_number
) : Window(desc
)
35 this->CreateNestedTree();
36 this->vscroll
= this->GetScrollbar(WID_SUL_SCROLLBAR
);
37 this->FinishInitNested(window_number
);
38 this->OnInvalidateData(0);
41 virtual void OnClick(Point pt
, int widget
, int click_count
)
43 if (widget
!= WID_SUL_PANEL
) return;
45 int y
= this->vscroll
->GetScrolledRowFromWidget(pt
.y
, this, WID_SUL_PANEL
, WD_FRAMERECT_TOP
);
48 FOR_ALL_SUBSIDIES(s
) {
49 if (!s
->IsAwarded()) {
64 y
-= 2; // "Services already subsidised:"
67 FOR_ALL_SUBSIDIES(s
) {
78 void HandleClick(const Subsidy
*s
)
80 /* determine src coordinate for subsidy and try to scroll to it */
82 switch (s
->src_type
) {
83 case ST_INDUSTRY
: xy
= Industry::Get(s
->src
)->location
.tile
; break;
84 case ST_TOWN
: xy
= Town::Get(s
->src
)->xy
; break;
85 default: NOT_REACHED();
88 if (_ctrl_pressed
|| !ScrollMainWindowToTile(xy
)) {
89 if (_ctrl_pressed
) ShowExtraViewPortWindow(xy
);
91 /* otherwise determine dst coordinate for subsidy and scroll to it */
92 switch (s
->dst_type
) {
93 case ST_INDUSTRY
: xy
= Industry::Get(s
->dst
)->location
.tile
; break;
94 case ST_TOWN
: xy
= Town::Get(s
->dst
)->xy
; break;
95 default: NOT_REACHED();
99 ShowExtraViewPortWindow(xy
);
101 ScrollMainWindowToTile(xy
);
107 * Count the number of lines in this window.
108 * @return the number of lines
112 /* Count number of (non) awarded subsidies */
113 uint num_awarded
= 0;
114 uint num_not_awarded
= 0;
116 FOR_ALL_SUBSIDIES(s
) {
117 if (!s
->IsAwarded()) {
124 /* Count the 'none' lines */
125 if (num_awarded
== 0) num_awarded
= 1;
126 if (num_not_awarded
== 0) num_not_awarded
= 1;
128 /* Offered, accepted and an empty line before the accepted ones. */
129 return 3 + num_awarded
+ num_not_awarded
;
132 virtual void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
)
134 if (widget
!= WID_SUL_PANEL
) return;
135 Dimension d
= maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE
), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE
));
137 resize
->height
= d
.height
;
140 d
.width
+= padding
.width
+ WD_FRAMERECT_RIGHT
+ WD_FRAMERECT_LEFT
;
141 d
.height
+= padding
.height
+ WD_FRAMERECT_TOP
+ WD_FRAMERECT_BOTTOM
;
142 *size
= maxdim(*size
, d
);
145 virtual void DrawWidget(const Rect
&r
, int widget
) const
147 if (widget
!= WID_SUL_PANEL
) return;
150 ConvertDateToYMD(_date
, &ymd
);
152 int right
= r
.right
- WD_FRAMERECT_RIGHT
;
153 int y
= r
.top
+ WD_FRAMERECT_TOP
;
154 int x
= r
.left
+ WD_FRAMERECT_LEFT
;
156 int pos
= -this->vscroll
->GetPosition();
157 const int cap
= this->vscroll
->GetCapacity();
159 /* Section for drawing the offered subsidies */
160 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_OFFERED_TITLE
);
165 FOR_ALL_SUBSIDIES(s
) {
166 if (!s
->IsAwarded()) {
167 if (IsInsideMM(pos
, 0, cap
)) {
168 /* Displays the two offered towns */
169 SetupSubsidyDecodeParam(s
, true);
170 SetDParam(7, _date
- ymd
.day
+ s
->remaining
* 32);
171 DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_OFFERED_FROM_TO
);
179 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_NONE
);
183 /* Section for drawing the already granted subsidies */
185 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_SUBSIDISED_TITLE
);
189 FOR_ALL_SUBSIDIES(s
) {
190 if (s
->IsAwarded()) {
191 if (IsInsideMM(pos
, 0, cap
)) {
192 SetupSubsidyDecodeParam(s
, true);
193 SetDParam(7, s
->awarded
);
194 SetDParam(8, _date
- ymd
.day
+ s
->remaining
* 32);
196 /* Displays the two connected stations */
197 DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_SUBSIDISED_FROM_TO
);
205 if (IsInsideMM(pos
, 0, cap
)) DrawString(x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_NONE
);
210 virtual void OnResize()
212 this->vscroll
->SetCapacityFromWidget(this, WID_SUL_PANEL
);
216 * Some data on this window has become invalid.
217 * @param data Information about the changed data.
218 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
220 virtual void OnInvalidateData(int data
= 0, bool gui_scope
= true)
222 if (!gui_scope
) return;
223 this->vscroll
->SetCount(this->CountLines());
227 static const NWidgetPart _nested_subsidies_list_widgets
[] = {
228 NWidget(NWID_HORIZONTAL
),
229 NWidget(WWT_CLOSEBOX
, COLOUR_BROWN
),
230 NWidget(WWT_CAPTION
, COLOUR_BROWN
), SetDataTip(STR_SUBSIDIES_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
231 NWidget(WWT_SHADEBOX
, COLOUR_BROWN
),
232 NWidget(WWT_DEFSIZEBOX
, COLOUR_BROWN
),
233 NWidget(WWT_STICKYBOX
, COLOUR_BROWN
),
235 NWidget(NWID_HORIZONTAL
),
236 NWidget(WWT_PANEL
, COLOUR_BROWN
, WID_SUL_PANEL
), SetDataTip(0x0, STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER
), SetResize(1, 1), SetScrollbar(WID_SUL_SCROLLBAR
), EndContainer(),
237 NWidget(NWID_VERTICAL
),
238 NWidget(NWID_VSCROLLBAR
, COLOUR_BROWN
, WID_SUL_SCROLLBAR
),
239 NWidget(WWT_RESIZEBOX
, COLOUR_BROWN
),
244 static WindowDesc
_subsidies_list_desc(
245 WDP_AUTO
, "list_subsidies", 500, 127,
246 WC_SUBSIDIES_LIST
, WC_NONE
,
248 _nested_subsidies_list_widgets
, lengthof(_nested_subsidies_list_widgets
)
252 void ShowSubsidiesList()
254 AllocateWindowDescFront
<SubsidyListWindow
>(&_subsidies_list_desc
, 0);