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"
29 * Setup the string parameters for printing an end of a subsidy at the screen.
30 * @param i Param index to use for the type (id will be next).
31 * @param src %CargoSource being printed.
33 static void SetupSubsidyDecodeParam (uint i
, const CargoSource
&src
)
35 SetDParam (i
, (src
.type
== ST_INDUSTRY
) ?
36 STR_INDUSTRY_NAME
: STR_TOWN_NAME
);
37 SetDParam (i
+ 1, src
.id
);
41 * Setup the string parameters for printing the subsidy at the screen.
42 * @param s %Subsidy being printed.
44 static void SetupSubsidyDecodeParams (const Subsidy
*s
)
46 SetDParam (0, CargoSpec::Get(s
->cargo_type
)->name
);
47 SetupSubsidyDecodeParam (1, s
->src
);
48 SetupSubsidyDecodeParam (4, s
->dst
);
51 struct SubsidyListWindow
: Window
{
54 SubsidyListWindow (const WindowDesc
*desc
, WindowNumber window_number
) :
55 Window (desc
), vscroll (NULL
)
57 this->CreateNestedTree();
58 this->vscroll
= this->GetScrollbar(WID_SUL_SCROLLBAR
);
59 this->InitNested(window_number
);
60 this->OnInvalidateData(0);
63 virtual void OnClick(Point pt
, int widget
, int click_count
)
65 if (widget
!= WID_SUL_PANEL
) return;
67 int y
= this->vscroll
->GetScrolledRowFromWidget(pt
.y
, this, WID_SUL_PANEL
, WD_FRAMERECT_TOP
);
70 FOR_ALL_SUBSIDIES(s
) {
71 if (!s
->IsAwarded()) {
86 y
-= 2; // "Services already subsidised:"
89 FOR_ALL_SUBSIDIES(s
) {
100 static inline TileIndex
GetSubsidyTile (const CargoSource
&src
)
103 case ST_INDUSTRY
: return Industry::Get(src
.id
)->location
.tile
;
104 case ST_TOWN
: return Town::Get(src
.id
)->xy
;
105 default: NOT_REACHED();
109 void HandleClick(const Subsidy
*s
)
111 /* determine src coordinate for subsidy and try to scroll to it */
112 TileIndex xy
= GetSubsidyTile (s
->src
);
114 if (_ctrl_pressed
|| !ScrollMainWindowToTile(xy
)) {
115 if (_ctrl_pressed
) ShowExtraViewPortWindow(xy
);
117 /* otherwise determine dst coordinate for subsidy and scroll to it */
118 xy
= GetSubsidyTile (s
->dst
);
121 ShowExtraViewPortWindow(xy
);
123 ScrollMainWindowToTile(xy
);
129 * Count the number of lines in this window.
130 * @return the number of lines
134 /* Count number of (non) awarded subsidies */
135 uint num_awarded
= 0;
136 uint num_not_awarded
= 0;
138 FOR_ALL_SUBSIDIES(s
) {
139 if (!s
->IsAwarded()) {
146 /* Count the 'none' lines */
147 if (num_awarded
== 0) num_awarded
= 1;
148 if (num_not_awarded
== 0) num_not_awarded
= 1;
150 /* Offered, accepted and an empty line before the accepted ones. */
151 return 3 + num_awarded
+ num_not_awarded
;
154 virtual void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
)
156 if (widget
!= WID_SUL_PANEL
) return;
157 Dimension d
= maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE
), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE
));
159 resize
->height
= d
.height
;
162 d
.width
+= padding
.width
+ WD_FRAMERECT_RIGHT
+ WD_FRAMERECT_LEFT
;
163 d
.height
+= padding
.height
+ WD_FRAMERECT_TOP
+ WD_FRAMERECT_BOTTOM
;
164 *size
= maxdim(*size
, d
);
167 void DrawWidget (BlitArea
*dpi
, const Rect
&r
, int widget
) const OVERRIDE
169 if (widget
!= WID_SUL_PANEL
) return;
172 ConvertDateToYMD(_date
, &ymd
);
174 int right
= r
.right
- WD_FRAMERECT_RIGHT
;
175 int y
= r
.top
+ WD_FRAMERECT_TOP
;
176 int x
= r
.left
+ WD_FRAMERECT_LEFT
;
178 int pos
= -this->vscroll
->GetPosition();
179 const int cap
= this->vscroll
->GetCapacity();
181 /* Section for drawing the offered subsidies */
182 if (IsInsideMM(pos
, 0, cap
)) DrawString (dpi
, x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_OFFERED_TITLE
);
187 FOR_ALL_SUBSIDIES(s
) {
188 if (!s
->IsAwarded()) {
189 if (IsInsideMM(pos
, 0, cap
)) {
190 /* Displays the two offered towns */
191 SetupSubsidyDecodeParams (s
);
192 SetDParam(7, _date
- ymd
.day
+ s
->remaining
* 32);
193 DrawString (dpi
, x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_OFFERED_FROM_TO
);
201 if (IsInsideMM(pos
, 0, cap
)) DrawString (dpi
, x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_NONE
);
205 /* Section for drawing the already granted subsidies */
207 if (IsInsideMM(pos
, 0, cap
)) DrawString (dpi
, x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_SUBSIDISED_TITLE
);
211 FOR_ALL_SUBSIDIES(s
) {
212 if (s
->IsAwarded()) {
213 if (IsInsideMM(pos
, 0, cap
)) {
214 SetupSubsidyDecodeParams (s
);
215 SetDParam(7, s
->awarded
);
216 SetDParam(8, _date
- ymd
.day
+ s
->remaining
* 32);
218 /* Displays the two connected stations */
219 DrawString (dpi
, x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_SUBSIDISED_FROM_TO
);
227 if (IsInsideMM(pos
, 0, cap
)) DrawString (dpi
, x
, right
, y
+ pos
* FONT_HEIGHT_NORMAL
, STR_SUBSIDIES_NONE
);
232 virtual void OnResize()
234 this->vscroll
->SetCapacityFromWidget(this, WID_SUL_PANEL
);
238 * Some data on this window has become invalid.
239 * @param data Information about the changed data.
240 * @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.
242 virtual void OnInvalidateData(int data
= 0, bool gui_scope
= true)
244 if (!gui_scope
) return;
245 this->vscroll
->SetCount(this->CountLines());
249 static const NWidgetPart _nested_subsidies_list_widgets
[] = {
250 NWidget(NWID_HORIZONTAL
),
251 NWidget(WWT_CLOSEBOX
, COLOUR_BROWN
),
252 NWidget(WWT_CAPTION
, COLOUR_BROWN
), SetDataTip(STR_SUBSIDIES_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
253 NWidget(WWT_SHADEBOX
, COLOUR_BROWN
),
254 NWidget(WWT_DEFSIZEBOX
, COLOUR_BROWN
),
255 NWidget(WWT_STICKYBOX
, COLOUR_BROWN
),
257 NWidget(NWID_HORIZONTAL
),
258 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(),
259 NWidget(NWID_VERTICAL
),
260 NWidget(NWID_VSCROLLBAR
, COLOUR_BROWN
, WID_SUL_SCROLLBAR
),
261 NWidget(WWT_RESIZEBOX
, COLOUR_BROWN
),
266 static WindowDesc::Prefs
_subsidies_list_prefs ("list_subsidies");
268 static const WindowDesc
_subsidies_list_desc(
270 WC_SUBSIDIES_LIST
, WC_NONE
,
272 _nested_subsidies_list_widgets
, lengthof(_nested_subsidies_list_widgets
),
273 &_subsidies_list_prefs
277 void ShowSubsidiesList()
279 AllocateWindowDescFront
<SubsidyListWindow
>(&_subsidies_list_desc
, 0);