Merge lp:~widelands-dev/widelands/csite_improvement into lp:widelands

Proposed by cghislai
Status: Merged
Merged at revision: 6654
Proposed branch: lp:~widelands-dev/widelands/csite_improvement
Merge into: lp:widelands
Diff against target: 599 lines (+260/-61)
11 files modified
src/constants.h (+5/-3)
src/logic/building.h (+1/-1)
src/logic/constructionsite.cc (+18/-11)
src/logic/item_ware_descr.h (+2/-0)
src/logic/productionsite.cc (+50/-25)
src/logic/productionsite.h (+1/-1)
src/ui_basic/table.cc (+4/-0)
src/wui/building_ui.cc (+4/-1)
src/wui/buildingwindow.cc (+10/-2)
src/wui/waresdisplay.cc (+146/-15)
src/wui/waresdisplay.h (+19/-2)
To merge this branch: bzr merge lp:~widelands-dev/widelands/csite_improvement
Reviewer Review Type Date Requested Status
SirVer Approve
Review via email: mp+174623@code.launchpad.net

Description of the change

This contains a bunch of improvements not all related to construction sites
- Colored string for production efficiency and trends
- Anchored selection for ware selection in warehouses/economy settings
- Range of building shown for construction sites
- Building name shown in construction site windows
- Building window opened when construction site window was open and construction ended

To post a comment you must log in.
Revision history for this message
SirVer (sirver) wrote :

I'll try to have a look at this during this week - I will be a bit busy though, so no promises. If anybody else can review this, go ahead of course :).

Revision history for this message
SirVer (sirver) wrote :

Okay, a bunch of minor comments. I did not understand what the anchoring does - I would love to see some comments about this someplace.

review: Needs Fixing
Revision history for this message
SirVer (sirver) wrote :

And I forgot to mention: I much appreciate you adding {} in more places while going over the code :). I find this so much more readable.

Revision history for this message
cghislai (charlyghislain) wrote :

I loaclly merged the bug657285 branch in order to test this under opengl without crashing.
Everything works as intended.

Revision history for this message
SirVer (sirver) wrote :

Lgtm. I fixed very small nits and merged this.

review: Approve
Revision history for this message
SirVer (sirver) wrote :

Charly, could you go over the bugs and mark them fixed as appropriate?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/constants.h'
--- src/constants.h 2013-07-16 00:37:26 +0000
+++ src/constants.h 2013-07-21 14:41:26 +0000
@@ -80,9 +80,11 @@
80#define PROSA_FONT_CLR_FG RGBColor(255, 255, 0)80#define PROSA_FONT_CLR_FG RGBColor(255, 255, 0)
8181
82/// Colors for good/ok/bad82/// Colors for good/ok/bad
83#define UI_FONT_CLR_BAD_HEX "ff0000"83#define UI_FONT_CLR_BRIGHT_HEX "fffaaa"
84#define UI_FONT_CLR_OK_HEX "ffff00"84#define UI_FONT_CLR_DARK_HEX "a39013"
85#define UI_FONT_CLR_GOOD_HEX "325b1f"85#define UI_FONT_CLR_BAD_HEX "bb0000"
86#define UI_FONT_CLR_OK_HEX "ffe11e"
87#define UI_FONT_CLR_GOOD_HEX "00bb00"
86//@}88//@}
8789
88/** \name Text colors90/** \name Text colors
8991
=== modified file 'src/logic/building.h'
--- src/logic/building.h 2013-07-16 10:17:53 +0000
+++ src/logic/building.h 2013-07-21 14:41:26 +0000
@@ -184,7 +184,7 @@
184 virtual bool burn_on_destroy();184 virtual bool burn_on_destroy();
185 virtual void destroy(Editor_Game_Base &);185 virtual void destroy(Editor_Game_Base &);
186186
187 void show_options(Interactive_GameBase &, bool avoid_fastclick = false);187 void show_options(Interactive_GameBase &, bool avoid_fastclick = false, Point pos = Point(- 1, - 1));
188 void hide_options();188 void hide_options();
189 void refresh_options(Interactive_GameBase &);189 void refresh_options(Interactive_GameBase &);
190190
191191
=== modified file 'src/logic/constructionsite.cc'
--- src/logic/constructionsite.cc 2013-07-18 06:31:11 +0000
+++ src/logic/constructionsite.cc 2013-07-21 14:41:26 +0000
@@ -25,12 +25,14 @@
25#include "upcast.h"25#include "upcast.h"
26#include "wexception.h"26#include "wexception.h"
2727
28#include "graphic/animation.h"
29#include "economy/wares_queue.h"28#include "economy/wares_queue.h"
30#include "game.h"29#include "game.h"
30#include "graphic/animation.h"
31#include "graphic/graphic.h"31#include "graphic/graphic.h"
32#include "graphic/rendertarget.h"32#include "graphic/rendertarget.h"
33#include "sound/sound_handler.h"33#include "sound/sound_handler.h"
34#include "ui_basic/window.h"
35#include "wui/interactive_gamebase.h"
34#include "tribe.h"36#include "tribe.h"
35#include "worker.h"37#include "worker.h"
3638
@@ -86,14 +88,9 @@
86std::string ConstructionSite::get_statistics_string()88std::string ConstructionSite::get_statistics_string()
87{89{
88 unsigned int percent = (get_built_per64k() * 100) >> 16;90 unsigned int percent = (get_built_per64k() * 100) >> 16;
8991 std::string perc_s =
90 std::string clr = UI_FONT_CLR_OK_HEX;92 (boost::format("<font color=%1$s>%2$i%% built</font>") % UI_FONT_CLR_DARK_HEX % percent).str();
91 if (percent <= 25) clr = UI_FONT_CLR_BAD_HEX;93 return perc_s;
92 else if (percent >= 75) clr = UI_FONT_CLR_GOOD_HEX;
93
94 std::string perc_s = (boost::format("<font color=%s>%i</font>") % clr % percent).str();
95
96 return (boost::format(_("%s%% built")) % perc_s.c_str()).str();
97}94}
9895
99/*96/*
@@ -102,9 +99,11 @@
102=======99=======
103*/100*/
104WaresQueue & ConstructionSite::waresqueue(Ware_Index const wi) {101WaresQueue & ConstructionSite::waresqueue(Ware_Index const wi) {
105 container_iterate_const(Wares, m_wares, i)102 container_iterate_const(Wares, m_wares, i) {
106 if ((*i.current)->get_ware() == wi)103 if ((*i.current)->get_ware() == wi) {
107 return **i.current;104 return **i.current;
105 }
106 }
108 throw wexception107 throw wexception
109 ("%s (%u) (building %s) has no WaresQueue for %u",108 ("%s (%u) (building %s) has no WaresQueue for %u",
110 name().c_str(), serial(), m_building->name().c_str(), wi.value());109 name().c_str(), serial(), m_building->name().c_str(), wi.value());
@@ -183,6 +182,14 @@
183 builder->reset_tasks(ref_cast<Game, Editor_Game_Base>(egbase));182 builder->reset_tasks(ref_cast<Game, Editor_Game_Base>(egbase));
184 builder->set_location(&b);183 builder->set_location(&b);
185 }184 }
185 // Open the new building window if needed
186 if (m_optionswindow) {
187 Point window_position = m_optionswindow->get_pos();
188 hide_options();
189 Interactive_GameBase & igbase =
190 ref_cast<Interactive_GameBase, Interactive_Base>(*egbase.get_ibase());
191 b.show_options(igbase, false, window_position);
192 }
186 }193 }
187}194}
188195
189196
=== modified file 'src/logic/item_ware_descr.h'
--- src/logic/item_ware_descr.h 2013-02-10 19:36:24 +0000
+++ src/logic/item_ware_descr.h 2013-07-21 14:41:26 +0000
@@ -36,6 +36,8 @@
3636
37#define WARE_MENU_PIC_WIDTH 24 //< Default width for ware's menu icons37#define WARE_MENU_PIC_WIDTH 24 //< Default width for ware's menu icons
38#define WARE_MENU_PIC_HEIGHT 24 //< Default height for ware's menu icons38#define WARE_MENU_PIC_HEIGHT 24 //< Default height for ware's menu icons
39#define WARE_MENU_PIC_PAD_X 3 //< Default padding between menu icons
40#define WARE_MENU_PIC_PAD_Y 4 //< Default padding between menu icons
3941
40namespace Widelands {42namespace Widelands {
4143
4244
=== modified file 'src/logic/productionsite.cc'
--- src/logic/productionsite.cc 2013-07-18 16:47:56 +0000
+++ src/logic/productionsite.cc 2013-07-21 14:41:26 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20#include <libintl.h>20#include <libintl.h>
21#include <boost/format.hpp>
2122
22#include "helper.h"23#include "helper.h"
23#include "i18n.h"24#include "i18n.h"
@@ -242,21 +243,23 @@
242 uint32_t nr_workers = 0;243 uint32_t nr_workers = 0;
243 for (uint32_t i = nr_working_positions; i;)244 for (uint32_t i = nr_working_positions; i;)
244 nr_workers += m_working_positions[--i].worker ? 1 : 0;245 nr_workers += m_working_positions[--i].worker ? 1 : 0;
245 if (!nr_workers)246 if (!nr_workers) {
246 return _("(not occupied)");247 return
247 else if (uint32_t const nr_requests = nr_working_positions - nr_workers) {248 (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_BAD_HEX % _("(not occupied)")).str();
248 char buffer[1000];249 } else if (uint32_t const nr_requests = nr_working_positions - nr_workers) {
249 snprintf250 return
250 (buffer, sizeof(buffer), "%s",251 (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_BAD_HEX %
251 ngettext("Worker missing", "Workers missing", nr_requests));252 ngettext(_("Worker missing"), _("Workers missing"), nr_requests))
252 return buffer;253 .str();
253 }254 }
254255
255 if (m_statistics_changed)256 if (m_statistics_changed) {
256 calc_statistics();257 calc_statistics();
258 }
257259
258 if (m_is_stopped)260 if (m_is_stopped) {
259 return _("(stopped)");261 return (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_BRIGHT_HEX % _("(stopped)")).str();
262 }
260263
261 return m_statistics_buffer;264 return m_statistics_buffer;
262}265}
@@ -315,21 +318,43 @@
315 ++lastOk;318 ++lastOk;
316 }319 }
317 }320 }
318 uint8_t const percOk = (ok * 100) / STATISTICS_VECTOR_LENGTH;321 // Somehow boost::format doesn't handle correctly uint8_t in this case
319 uint8_t const lastPercOk = (lastOk * 100) / (STATISTICS_VECTOR_LENGTH / 2);322 unsigned int percOk = (ok * 100) / STATISTICS_VECTOR_LENGTH;
320323 unsigned int lastPercOk = (lastOk * 100) / (STATISTICS_VECTOR_LENGTH / 2);
321 const std::string trend =324
322 lastPercOk > percOk ? "+" : lastPercOk < percOk ? "-" : "=";325 std::string color;
323326 if (percOk < 33)
324 if (0 < percOk and percOk < 100)327 color = UI_FONT_CLR_BAD_HEX;
325 snprintf328 else if (percOk < 66)
326 (m_statistics_buffer, sizeof(m_statistics_buffer),329 color = UI_FONT_CLR_OK_HEX;
327 "%d%% %s", percOk, trend.c_str());
328 else330 else
329 snprintf331 color = UI_FONT_CLR_GOOD_HEX;
330 (m_statistics_buffer, sizeof(m_statistics_buffer),332 const std::string perc_str =
331 "%d%%", percOk);333 (boost::format("<font color=%1$s>%2$i%%</font>") % color % percOk).str();
332334
335 std::string trend;
336 if (lastPercOk > percOk) {
337 color = UI_FONT_CLR_GOOD_HEX;
338 trend = "+";
339 } else if (lastPercOk < percOk) {
340 color = UI_FONT_CLR_BAD_HEX;
341 trend = "-";
342 } else {
343 color = UI_FONT_CLR_BRIGHT_HEX;
344 trend = "=";
345 }
346 const std::string trend_str =
347 (boost::format("<font color=%s>%s</font>") % color % trend).str();
348
349 if (0 < percOk and percOk < 100) {
350 snprintf
351 (m_statistics_buffer, sizeof(m_statistics_buffer),
352 "%s %s", perc_str.c_str(), trend_str.c_str());
353 } else {
354 snprintf
355 (m_statistics_buffer, sizeof(m_statistics_buffer),
356 "%s", perc_str.c_str());
357 }
333 m_last_stat_percent = percOk;358 m_last_stat_percent = percOk;
334359
335 m_statistics_changed = false;360 m_statistics_changed = false;
336361
=== modified file 'src/logic/productionsite.h'
--- src/logic/productionsite.h 2013-04-22 20:15:00 +0000
+++ src/logic/productionsite.h 2013-07-21 14:41:26 +0000
@@ -256,7 +256,7 @@
256 Input_Queues m_input_queues; ///< input queues for all inputs256 Input_Queues m_input_queues; ///< input queues for all inputs
257 std::vector<bool> m_statistics;257 std::vector<bool> m_statistics;
258 bool m_statistics_changed;258 bool m_statistics_changed;
259 char m_statistics_buffer[40];259 char m_statistics_buffer[128];
260 char m_result_buffer [213];260 char m_result_buffer [213];
261 uint8_t m_last_stat_percent;261 uint8_t m_last_stat_percent;
262 bool m_is_stopped;262 bool m_is_stopped;
263263
=== modified file 'src/ui_basic/table.cc'
--- src/ui_basic/table.cc 2013-07-21 08:25:22 +0000
+++ src/ui_basic/table.cc 2013-07-21 14:41:26 +0000
@@ -293,6 +293,10 @@
293 point.x += picw;293 point.x += picw;
294 }294 }
295295
296 if (entry_string.empty()) {
297 curx += curw;
298 continue;
299 }
296 const Image* entry_text_im = UI::g_fh1->render(as_uifont(entry_string, m_fontsize));300 const Image* entry_text_im = UI::g_fh1->render(as_uifont(entry_string, m_fontsize));
297 uint16_t text_width = entry_text_im->width();301 uint16_t text_width = entry_text_im->width();
298 if (alignment & Align_Right) {302 if (alignment & Align_Right) {
299303
=== modified file 'src/wui/building_ui.cc'
--- src/wui/building_ui.cc 2013-07-21 08:25:22 +0000
+++ src/wui/building_ui.cc 2013-07-21 14:41:26 +0000
@@ -30,7 +30,7 @@
30 * Create the building's options window if necessary and bring it to30 * Create the building's options window if necessary and bring it to
31 * the top to be seen by the player.31 * the top to be seen by the player.
32 */32 */
33void Building::show_options(Interactive_GameBase & igbase, bool avoid_fastclick)33void Building::show_options(Interactive_GameBase & igbase, bool avoid_fastclick, Point pos)
34{34{
35 if (m_optionswindow) {35 if (m_optionswindow) {
36 if (m_optionswindow->is_minimal())36 if (m_optionswindow->is_minimal())
@@ -45,6 +45,9 @@
45 // get properly initialized45 // get properly initialized
46 m_optionswindow->think();46 m_optionswindow->think();
47 }47 }
48 if (pos.x >= 0 && pos.y >= 0) {
49 m_optionswindow->set_pos(pos);
50 }
48}51}
4952
50/**53/**
5154
=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc 2013-07-21 08:25:22 +0000
+++ src/wui/buildingwindow.cc 2013-07-21 14:41:26 +0000
@@ -23,6 +23,7 @@
23#include "graphic/image.h"23#include "graphic/image.h"
24#include "graphic/rendertarget.h"24#include "graphic/rendertarget.h"
25#include "interactive_player.h"25#include "interactive_player.h"
26#include "logic/constructionsite.h"
26#include "logic/dismantlesite.h"27#include "logic/dismantlesite.h"
27#include "logic/maphollowregion.h"28#include "logic/maphollowregion.h"
28#include "logic/militarysite.h"29#include "logic/militarysite.h"
@@ -35,8 +36,9 @@
35#include "upcast.h"36#include "upcast.h"
36#include "waresqueuedisplay.h"37#include "waresqueuedisplay.h"
3738
39#include <boost/format.hpp>
40
38#include "buildingwindow.h"41#include "buildingwindow.h"
39#include "logic/militarysite.h"
4042
41static const char * pic_bulldoze = "pics/menu_bld_bulldoze.png";43static const char * pic_bulldoze = "pics/menu_bld_bulldoze.png";
42static const char * pic_dismantle = "pics/menu_bld_dismantle.png";44static const char * pic_dismantle = "pics/menu_bld_dismantle.png";
@@ -78,10 +80,16 @@
7880
79 set_center_panel(vbox);81 set_center_panel(vbox);
80 set_think(true);82 set_think(true);
83 set_fastclick_panel(this);
8184
82 show_workarea();85 show_workarea();
8386
84 set_fastclick_panel(this);87 // Title for construction site
88 if (upcast(Widelands::ConstructionSite, csite, &m_building)) {
89 // Show name in parenthesis as it may take all width already
90 const std::string title = (boost::format("(%s)") % csite->building().descname()).str();
91 set_title(title);
92 }
85}93}
8694
8795
8896
=== modified file 'src/wui/waresdisplay.cc'
--- src/wui/waresdisplay.cc 2013-03-01 23:12:08 +0000
+++ src/wui/waresdisplay.cc 2013-07-21 14:41:26 +0000
@@ -63,12 +63,16 @@
63 m_hidden63 m_hidden
64 (m_type == Widelands::wwWORKER ? m_tribe.get_nrworkers()64 (m_type == Widelands::wwWORKER ? m_tribe.get_nrworkers()
65 : m_tribe.get_nrwares(), false),65 : m_tribe.get_nrwares(), false),
66 m_in_selection
67 (m_type == Widelands::wwWORKER ? m_tribe.get_nrworkers()
68 : m_tribe.get_nrwares(), false),
66 m_selectable(selectable),69 m_selectable(selectable),
67 m_horizontal(horizontal),70 m_horizontal(horizontal),
71 m_selection_anchor(Widelands::Ware_Index::Null()),
68 m_callback_function(callback_function)72 m_callback_function(callback_function)
69{73{
70 //resize the configuration of our wares if they won't fit in the current window74 //resize the configuration of our wares if they won't fit in the current window
71 int number = (g_gr->get_yres() - 160) / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 3);75 int number = (g_gr->get_yres() - 160) / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);
72 const_cast<Widelands::Tribe_Descr &>(m_tribe).resize_ware_orders(number);76 const_cast<Widelands::Tribe_Descr &>(m_tribe).resize_ware_orders(number);
7377
74 // Find out geometry from icons_order78 // Find out geometry from icons_order
@@ -85,13 +89,13 @@
8589
86 // 25 is height of m_curware text90 // 25 is height of m_curware text
87 set_desired_size91 set_desired_size
88 (columns * (WARE_MENU_PIC_WIDTH + 3) + 1,92 (columns * (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X) + 1,
89 rows * (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 3) + 1 + 25);93 rows * (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y) + 1 + 25);
90}94}
9195
9296
93bool AbstractWaresDisplay::handle_mousemove97bool AbstractWaresDisplay::handle_mousemove
94 (uint8_t, int32_t x, int32_t y, int32_t, int32_t)98 (uint8_t state, int32_t x, int32_t y, int32_t, int32_t)
95{99{
96 const Widelands::Ware_Index index = ware_at_point(x, y);100 const Widelands::Ware_Index index = ware_at_point(x, y);
97101
@@ -104,6 +108,17 @@
104 .c_str()108 .c_str()
105 :109 :
106 "");110 "");
111 if (m_selection_anchor) {
112 // Ensure mouse button is still pressed as some
113 // mouse release events do not reach us
114 if (state ^ SDL_BUTTON_LMASK) {
115 // FIXME: We should call another function that will not pass that events
116 // to our Panel superclass
117 handle_mouserelease(SDL_BUTTON_LEFT, x, y);
118 return true;
119 }
120 update_anchor_selection(x, y);
121 }
107 return true;122 return true;
108}123}
109124
@@ -112,11 +127,19 @@
112{127{
113 if (btn == SDL_BUTTON_LEFT) {128 if (btn == SDL_BUTTON_LEFT) {
114 Widelands::Ware_Index ware = ware_at_point(x, y);129 Widelands::Ware_Index ware = ware_at_point(x, y);
115 if (!ware)130 if (!ware) {
116 return false;131 return false;
117132 }
118 if (m_selectable) {133 if (!m_selectable) {
119 toggle_ware(ware);134 return true;
135 }
136 if (!m_selection_anchor) {
137 // Create the selection anchor to be able to select
138 // multiple ware by dragging.
139 m_selection_anchor = ware;
140 m_in_selection[ware] = true;
141 } else {
142 // A mouse release has been missed
120 }143 }
121 return true;144 return true;
122 }145 }
@@ -124,6 +147,35 @@
124 return UI::Panel::handle_mousepress(btn, x, y);147 return UI::Panel::handle_mousepress(btn, x, y);
125}148}
126149
150bool AbstractWaresDisplay::handle_mouserelease(Uint8 btn, int32_t x, int32_t y)
151{
152 if (btn != SDL_BUTTON_LEFT || !m_selection_anchor) {
153 return UI::Panel::handle_mouserelease(btn, x, y);
154 }
155
156 Widelands::Ware_Index const number =
157 m_type == Widelands::wwWORKER ? m_tribe.get_nrworkers() : m_tribe.get_nrwares();
158
159 bool to_be_selected = !ware_selected(m_selection_anchor);
160 for (Widelands::Ware_Index i = Widelands::Ware_Index::First(); i < number; ++i)
161 {
162 if (!m_in_selection[i]) {
163 continue;
164 }
165 if (to_be_selected) {
166 select_ware(i);
167 } else {
168 unselect_ware(i);
169 }
170 }
171
172 // Release anchor, empty selection
173 m_selection_anchor = Widelands::Ware_Index::Null();
174 std::fill(m_in_selection.begin(), m_in_selection.end(), false);
175 return true;
176}
177
178
127/**179/**
128 * Returns the index of the ware under the given coordinates, or180 * Returns the index of the ware under the given coordinates, or
129 * WareIndex::Null() if the given point is outside the range.181 * WareIndex::Null() if the given point is outside the range.
@@ -134,8 +186,8 @@
134 return Widelands::Ware_Index::Null();186 return Widelands::Ware_Index::Null();
135187
136188
137 unsigned int i = x / (WARE_MENU_PIC_WIDTH + 4);189 unsigned int i = x / (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);
138 unsigned int j = y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 3);190 unsigned int j = y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);
139 if (m_horizontal) {191 if (m_horizontal) {
140 unsigned int s = i;192 unsigned int s = i;
141 i = j;193 i = j;
@@ -151,6 +203,68 @@
151 return Widelands::Ware_Index::Null();203 return Widelands::Ware_Index::Null();
152}204}
153205
206// Update the anchored selection. An anchor has been created by mouse
207// press. Mouse move call this function with the current mouse position.
208// This function will temporary store all wares in the rectangle between anchor
209// and current pos to allow their selection on mouse release
210void AbstractWaresDisplay::update_anchor_selection(int32_t x, int32_t y)
211{
212 if (!m_selection_anchor || x < 0 || y < 0) {
213 return;
214 }
215
216 std::fill(m_in_selection.begin(), m_in_selection.end(), false);
217 Point anchor_pos = ware_position(m_selection_anchor);
218 // Add an offset to make sure the anchor line and column will be
219 // selected when selecting in topleft direction
220 int32_t anchor_x = anchor_pos.x + WARE_MENU_PIC_WIDTH / 2;
221 int32_t anchor_y = anchor_pos.y + WARE_MENU_PIC_HEIGHT / 2;
222
223 unsigned int left_ware_idx = anchor_x / (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);
224 unsigned int top_ware_idx = anchor_y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);
225 unsigned int right_ware_idx = x / (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);
226 unsigned int bottom_ware_idx = y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);
227 unsigned int tmp;
228
229 // Reverse col/row and anchor/endpoint if needed
230 if (m_horizontal) {
231 tmp = left_ware_idx;
232 left_ware_idx = top_ware_idx;
233 top_ware_idx = tmp;
234 tmp = right_ware_idx;
235 right_ware_idx = bottom_ware_idx;
236 bottom_ware_idx = tmp;
237 }
238 if (left_ware_idx > right_ware_idx) {
239 tmp = left_ware_idx;
240 left_ware_idx = right_ware_idx;
241 right_ware_idx = tmp;
242 }
243 if (top_ware_idx > bottom_ware_idx) {
244 tmp = top_ware_idx;
245 top_ware_idx = bottom_ware_idx;
246 bottom_ware_idx = tmp;
247 }
248
249 for (unsigned int cur_ware_x = left_ware_idx; cur_ware_x <= right_ware_idx; cur_ware_x++) {
250 if (cur_ware_x >= icons_order().size()) {
251 continue;
252 }
253 for (unsigned cur_ware_y = top_ware_idx; cur_ware_y <= bottom_ware_idx; cur_ware_y++) {
254 if (cur_ware_y >= icons_order()[cur_ware_x].size()) {
255 continue;
256 }
257 Widelands::Ware_Index ware = icons_order()[cur_ware_x][cur_ware_y];
258 if (m_hidden[ware]) {
259 continue;
260 }
261 m_in_selection[ware] = true;
262 }
263 }
264 update();
265}
266
267
154268
155void AbstractWaresDisplay::layout()269void AbstractWaresDisplay::layout()
156{270{
@@ -219,11 +333,15 @@
219{333{
220 Point p(2, 2);334 Point p(2, 2);
221 if (m_horizontal) {335 if (m_horizontal) {
222 p.x += icons_order_coords()[id].second * (WARE_MENU_PIC_WIDTH + 3);336 p.x += icons_order_coords()[id].second *
223 p.y += icons_order_coords()[id].first * (WARE_MENU_PIC_HEIGHT + 3 + WARE_MENU_INFO_SIZE);337 (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);
338 p.y += icons_order_coords()[id].first *
339 (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + WARE_MENU_INFO_SIZE);
224 } else {340 } else {
225 p.x += icons_order_coords()[id].first * (WARE_MENU_PIC_WIDTH + 3);341 p.x += icons_order_coords()[id].first *
226 p.y += icons_order_coords()[id].second * (WARE_MENU_PIC_HEIGHT + 3 + WARE_MENU_INFO_SIZE);342 (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);
343 p.y += icons_order_coords()[id].second *
344 (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + WARE_MENU_INFO_SIZE);
227 }345 }
228 return p;346 return p;
229}347}
@@ -241,9 +359,21 @@
241{359{
242 Point p = ware_position(id);360 Point p = ware_position(id);
243361
362 bool draw_selected = m_selected[id];
363 if (m_selection_anchor) {
364 // Draw the temporary selected wares as if they were
365 // selected.
366 // TODO: Use another pic for the temporary selection
367 if (!ware_selected(m_selection_anchor)) {
368 draw_selected |= m_in_selection[id];
369 } else {
370 draw_selected &= !m_in_selection[id];
371 }
372 }
373
244 // draw a background374 // draw a background
245 const Image* bgpic =375 const Image* bgpic =
246 g_gr->images().get(ware_selected(id) ? "pics/ware_list_bg_selected.png" : "pics/ware_list_bg.png");376 g_gr->images().get(draw_selected ? "pics/ware_list_bg_selected.png" : "pics/ware_list_bg.png");
247 uint16_t w = bgpic->width();377 uint16_t w = bgpic->width();
248378
249 dst.blit(p, bgpic);379 dst.blit(p, bgpic);
@@ -378,3 +508,4 @@
378 }508 }
379 return ret;509 return ret;
380}510}
511
381512
=== modified file 'src/wui/waresdisplay.h'
--- src/wui/waresdisplay.h 2013-07-21 08:25:22 +0000
+++ src/wui/waresdisplay.h 2013-07-21 14:41:26 +0000
@@ -56,9 +56,8 @@
5656
57 bool handle_mousemove57 bool handle_mousemove
58 (uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);58 (uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
59
60 bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);59 bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);
6160 bool handle_mouserelease(Uint8 btn, int32_t x, int32_t y);
6261
63 // Wares may be selected (highlighted)62 // Wares may be selected (highlighted)
64 void select_ware(Widelands::Ware_Index);63 void select_ware(Widelands::Ware_Index);
@@ -100,13 +99,31 @@
100 typedef std::vector<const Widelands::WareList *> vector_type;99 typedef std::vector<const Widelands::WareList *> vector_type;
101 typedef std::vector<bool> selection_type;100 typedef std::vector<bool> selection_type;
102101
102 /**
103 * Update the anchored selection. When first mouse button is
104 * pressed on a ware, it is stored in @ref m_selection_anchor.
105 * Mouse moves trigger this function to select all wares items
106 * in the rectangle between the anchor and the mouse position.
107 * They are temporary stored in @ref m_in_selection.
108 * Releasing the mouse button will performs the selection.
109 * This allows selection of multiple wares by dragging.
110 */
111 void update_anchor_selection(int32_t x, int32_t y);
112
103 const Widelands::Tribe_Descr & m_tribe;113 const Widelands::Tribe_Descr & m_tribe;
104 Widelands::WareWorker m_type;114 Widelands::WareWorker m_type;
105 UI::Textarea m_curware;115 UI::Textarea m_curware;
106 selection_type m_selected;116 selection_type m_selected;
107 selection_type m_hidden;117 selection_type m_hidden;
118 selection_type m_in_selection; //Wares in temporary anchored selection
108 bool m_selectable;119 bool m_selectable;
109 bool m_horizontal;120 bool m_horizontal;
121
122 /**
123 * The ware on which the mouse press has been performed.
124 * It is not selected directly, but will be on mouse release.
125 */
126 Widelands::Ware_Index m_selection_anchor;
110 boost::function<void(Widelands::Ware_Index, bool)> m_callback_function;127 boost::function<void(Widelands::Ware_Index, bool)> m_callback_function;
111};128};
112129

Subscribers

People subscribed via source and target branches

to status/vote changes: