widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #01196
[Merge] lp:~widelands-dev/widelands/csite_improvement into lp:widelands
cghislai has proposed merging lp:~widelands-dev/widelands/csite_improvement into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #580905 in widelands: "write building status in a different font color for construction sites"
https://bugs.launchpad.net/widelands/+bug/580905
Bug #722087 in widelands: "hard to empty warehouse"
https://bugs.launchpad.net/widelands/+bug/722087
Bug #803284 in widelands: "While building, show range of the building on construction site"
https://bugs.launchpad.net/widelands/+bug/803284
Bug #1108083 in widelands: "Construction site window does not display specific building name"
https://bugs.launchpad.net/widelands/+bug/1108083
Bug #1132238 in widelands: "Open buildingwindow after closing of constructionsitewindow when construction has finished"
https://bugs.launchpad.net/widelands/+bug/1132238
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/csite_improvement/+merge/174623
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 building shown for construction sites
- Building name shown in construction site windows
- Building window opened when construction site window was open when build finishes
--
https://code.launchpad.net/~widelands-dev/widelands/csite_improvement/+merge/174623
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/csite_improvement into lp:widelands.
=== modified file 'src/constants.h'
--- src/constants.h 2013-07-13 14:32:49 +0000
+++ src/constants.h 2013-07-14 16:56:24 +0000
@@ -80,9 +80,11 @@
#define PROSA_FONT_CLR_FG RGBColor(255, 255, 0)
/// Colors for good/ok/bad
-#define UI_FONT_CLR_BAD_HEX "ff0000"
-#define UI_FONT_CLR_OK_HEX "ffff00"
-#define UI_FONT_CLR_GOOD_HEX "325b1f"
+#define UI_FONT_CLR_BRIGHT_HEX "fff666"
+#define UI_FONT_CLR_DARK_HEX "a39013"
+#define UI_FONT_CLR_BAD_HEX "bb0000"
+#define UI_FONT_CLR_OK_HEX "ffe11e"
+#define UI_FONT_CLR_GOOD_HEX "55ff46"
//@}
/** \name Text colors
=== modified file 'src/logic/building.h'
--- src/logic/building.h 2013-07-14 10:38:26 +0000
+++ src/logic/building.h 2013-07-14 16:56:24 +0000
@@ -183,7 +183,7 @@
virtual bool burn_on_destroy();
virtual void destroy(Editor_Game_Base &);
- void show_options(Interactive_GameBase &, bool avoid_fastclick = false);
+ void show_options(Interactive_GameBase &, bool avoid_fastclick = false, Point pos = Point(- 1, - 1));
void hide_options();
void refresh_options(Interactive_GameBase &);
=== modified file 'src/logic/constructionsite.cc'
--- src/logic/constructionsite.cc 2013-07-14 10:38:26 +0000
+++ src/logic/constructionsite.cc 2013-07-14 16:56:24 +0000
@@ -35,6 +35,8 @@
#include "worker.h"
#include "constructionsite.h"
+#include <wui/interactive_base.h>
+#include <wui/interactive_gamebase.h>
namespace Widelands {
@@ -87,13 +89,11 @@
{
unsigned int percent = (get_built_per64k() * 100) >> 16;
- std::string clr = UI_FONT_CLR_OK_HEX;
- if (percent <= 25) clr = UI_FONT_CLR_BAD_HEX;
- else if (percent >= 75) clr = UI_FONT_CLR_GOOD_HEX;
-
- std::string perc_s = (boost::format("<font color=%s>%i</font>") % clr % percent).str();
-
- return (boost::format(_("%s%% built")) % perc_s.c_str()).str();
+
+ std::string perc_s =
+ (boost::format("<font color=%1$s>%2$i%% built</font>") % UI_FONT_CLR_DARK_HEX % percent).str();
+
+ return perc_s;
}
/*
@@ -183,6 +183,13 @@
builder->reset_tasks(ref_cast<Game, Editor_Game_Base>(egbase));
builder->set_location(&b);
}
+ if (m_optionswindow) {
+ Point window_position = m_optionswindow->get_pos();
+ hide_options();
+ Interactive_GameBase & igbase =
+ ref_cast<Interactive_GameBase, Interactive_Base>(*egbase.get_ibase());
+ b.show_options(igbase, false, window_position);
+ }
}
}
=== modified file 'src/logic/productionsite.cc'
--- src/logic/productionsite.cc 2013-05-25 09:30:35 +0000
+++ src/logic/productionsite.cc 2013-07-14 16:56:24 +0000
@@ -18,6 +18,8 @@
*/
#include <libintl.h>
+#include <cstdio>
+#include <boost/format.hpp>
#include "helper.h"
#include "i18n.h"
@@ -243,20 +245,21 @@
for (uint32_t i = nr_working_positions; i;)
nr_workers += m_working_positions[--i].worker ? 1 : 0;
if (!nr_workers)
- return _("(not occupied)");
+ return
+ (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_BAD_HEX % _("(not occupied)")).str();
else if (uint32_t const nr_requests = nr_working_positions - nr_workers) {
char buffer[1000];
snprintf
(buffer, sizeof(buffer), "%s",
ngettext("Worker missing", "Workers missing", nr_requests));
- return buffer;
+ return (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_BAD_HEX % buffer).str();
}
if (m_statistics_changed)
calc_statistics();
if (m_is_stopped)
- return _("(stopped)");
+ return (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_BRIGHT_HEX % _("(stopped)")).str();
return m_statistics_buffer;
}
@@ -315,20 +318,42 @@
++lastOk;
}
}
- uint8_t const percOk = (ok * 100) / STATISTICS_VECTOR_LENGTH;
- uint8_t const lastPercOk = (lastOk * 100) / (STATISTICS_VECTOR_LENGTH / 2);
-
- const std::string trend =
- lastPercOk > percOk ? "+" : lastPercOk < percOk ? "-" : "=";
+ // Somehow boost::format doesn't handle correctly uint8_t in this case
+ unsigned int percOk = (ok * 100) / STATISTICS_VECTOR_LENGTH;
+ unsigned int lastPercOk = (lastOk * 100) / (STATISTICS_VECTOR_LENGTH / 2);
+
+ std::string color;
+ if (percOk < 33)
+ color = UI_FONT_CLR_BAD_HEX;
+ else if (percOk < 66)
+ color = UI_FONT_CLR_OK_HEX;
+ else
+ color = UI_FONT_CLR_GOOD_HEX;
+ const std::string perc_str =
+ (boost::format("<font color=%1$s>%2$i%%</font>") % color % percOk).str();
+
+ std::string trend;
+ if (lastPercOk > percOk) {
+ color = UI_FONT_CLR_GOOD_HEX;
+ trend = "+";
+ } else if (lastPercOk < percOk) {
+ color = UI_FONT_CLR_BAD_HEX;
+ trend = "-";
+ } else {
+ color = UI_FONT_CLR_BRIGHT_HEX;
+ trend = "=";
+ }
+ const std::string trend_str =
+ (boost::format("<font color=%s>%s</font>") % color % trend).str();
if (0 < percOk and percOk < 100)
snprintf
(m_statistics_buffer, sizeof(m_statistics_buffer),
- "%d%% %s", percOk, trend.c_str());
+ "%s %s", perc_str.c_str(), trend_str.c_str());
else
snprintf
(m_statistics_buffer, sizeof(m_statistics_buffer),
- "%d%%", percOk);
+ "%s", perc_str.c_str());
m_last_stat_percent = percOk;
=== modified file 'src/logic/productionsite.h'
--- src/logic/productionsite.h 2013-04-22 20:15:00 +0000
+++ src/logic/productionsite.h 2013-07-14 16:56:24 +0000
@@ -256,7 +256,7 @@
Input_Queues m_input_queues; ///< input queues for all inputs
std::vector<bool> m_statistics;
bool m_statistics_changed;
- char m_statistics_buffer[40];
+ char m_statistics_buffer[128];
char m_result_buffer [213];
uint8_t m_last_stat_percent;
bool m_is_stopped;
=== modified file 'src/ui_basic/window.h'
--- src/ui_basic/window.h 2013-02-09 23:18:23 +0000
+++ src/ui_basic/window.h 2013-07-14 16:56:24 +0000
@@ -87,7 +87,6 @@
bool handle_mousemove
(Uint8 state, int32_t mx, int32_t my, int32_t xdiff, int32_t ydiff);
bool handle_alt_drag (int32_t mx, int32_t my);
-
protected:
virtual void layout();
virtual void update_desired_size();
=== modified file 'src/wui/building_ui.cc'
--- src/wui/building_ui.cc 2013-07-09 05:53:39 +0000
+++ src/wui/building_ui.cc 2013-07-14 16:56:24 +0000
@@ -28,7 +28,7 @@
* Create the building's options window if necessary and bring it to
* the top to be seen by the player.
*/
-void Building::show_options(Interactive_GameBase & igbase, bool avoid_fastclick)
+void Building::show_options(Interactive_GameBase & igbase, bool avoid_fastclick, Point pos)
{
if (m_optionswindow) {
if (m_optionswindow->is_minimal())
@@ -42,6 +42,9 @@
// get properly initialized
m_optionswindow->think();
}
+ if (pos.x >= 0 && pos.y >= 0) {
+ m_optionswindow->set_pos(pos);
+ }
}
/**
=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc 2013-07-13 15:58:52 +0000
+++ src/wui/buildingwindow.cc 2013-07-14 16:56:24 +0000
@@ -23,6 +23,7 @@
#include "graphic/image.h"
#include "graphic/rendertarget.h"
#include "interactive_player.h"
+#include "logic/constructionsite.h"
#include "logic/dismantlesite.h"
#include "logic/maphollowregion.h"
#include "logic/militarysite.h"
@@ -88,6 +89,14 @@
show_workarea();
+ if (is_a(Widelands::ConstructionSite, &m_building)) {
+ upcast(Widelands::ConstructionSite, csite, &m_building);
+ char cs_title[256];
+ // Show name in parenthesis as it may take all width already
+ sprintf(cs_title, _("(%s)"), csite->building().descname().c_str());
+ set_title(cs_title);
+ }
+
set_fastclick_panel(this);
}
@@ -515,7 +524,13 @@
if (m_workarea_job_id)
return; // already shown, nothing to be done
- const Workarea_Info & workarea_info = m_building.descr().m_workarea_info;
+ Workarea_Info workarea_info;
+ if (is_a(Widelands::ConstructionSite, &m_building)) {
+ upcast(Widelands::ConstructionSite, csite, &m_building);
+ workarea_info = csite->building().m_workarea_info;
+ } else {
+ workarea_info = m_building.descr().m_workarea_info;
+ }
if (workarea_info.size() == 0)
return; // building has no workarea
=== modified file 'src/wui/waresdisplay.cc'
--- src/wui/waresdisplay.cc 2013-03-01 23:12:08 +0000
+++ src/wui/waresdisplay.cc 2013-07-14 16:56:24 +0000
@@ -63,8 +63,12 @@
m_hidden
(m_type == Widelands::wwWORKER ? m_tribe.get_nrworkers()
: m_tribe.get_nrwares(), false),
+ m_in_selection
+ (m_type == Widelands::wwWORKER ? m_tribe.get_nrworkers()
+ : m_tribe.get_nrwares(), false),
m_selectable(selectable),
m_horizontal(horizontal),
+ m_selection_anchor(Widelands::Ware_Index::Null()),
m_callback_function(callback_function)
{
//resize the configuration of our wares if they won't fit in the current window
@@ -104,6 +108,9 @@
.c_str()
:
"");
+ if (m_selection_anchor) {
+ update_anchor_selection(x, y);
+ }
return true;
}
@@ -117,6 +124,10 @@
if (m_selectable) {
toggle_ware(ware);
+ // mouserelase may be skipped sometimes here
+ if (!m_selection_anchor) {
+ m_selection_anchor = ware;
+ }
}
return true;
}
@@ -124,6 +135,32 @@
return UI::Panel::handle_mousepress(btn, x, y);
}
+bool AbstractWaresDisplay::handle_mouserelease(Uint8 btn, int32_t x, int32_t y)
+{
+ if (btn == SDL_BUTTON_LEFT) {
+ if (m_selection_anchor) {
+ Widelands::Ware_Index const number = m_type == Widelands::wwWORKER ?
+ m_tribe.get_nrworkers() : m_tribe.get_nrwares();
+ for (Widelands::Ware_Index i = Widelands::Ware_Index::First();
+ i < number; ++i) {
+ if (!m_in_selection[i]) {
+ continue;
+ }
+ if (ware_selected(m_selection_anchor)) {
+ select_ware(i);
+ } else {
+ unselect_ware(i);
+ }
+ }
+ m_selection_anchor = Widelands::Ware_Index::Null();
+ std::fill(m_in_selection.begin(), m_in_selection.end(), false);
+ return true;
+ }
+ }
+ return UI::Panel::handle_mouserelease(btn, x, y);
+}
+
+
/**
* Returns the index of the ware under the given coordinates, or
* WareIndex::Null() if the given point is outside the range.
@@ -151,6 +188,62 @@
return Widelands::Ware_Index::Null();
}
+void AbstractWaresDisplay::update_anchor_selection(int32_t x, int32_t y)
+{
+ if (!m_selection_anchor || x < 0 || y < 0) {
+ return;
+ }
+
+ std::fill(m_in_selection.begin(), m_in_selection.end(), false);
+ Point pos0 = ware_position(m_selection_anchor);
+ int32_t x0 = pos0.x + 3; // Make sure the anchor row/col is selected in reverse order
+ int32_t y0 = pos0.y + 3;
+
+ unsigned int i0 = x0 / (WARE_MENU_PIC_WIDTH + 4);
+ unsigned int j0 = y0 / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 3);
+ unsigned int i = x / (WARE_MENU_PIC_WIDTH + 4);
+ unsigned int j = y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 3);
+ unsigned int s;
+ if (m_horizontal) {
+ s = i0;
+ i0 = j0;
+ j0 = s;
+ s = i;
+ i = j;
+ j = s;
+ }
+
+ // Ensure topleft to bottomright
+ if (i0 > i) {
+ s = i0;
+ i0 = i;
+ i = s;
+ }
+ if (j0 > j) {
+ s = j0;
+ j0 = j;
+ j = s;
+ }
+
+ for (unsigned int cur_i = i0; cur_i <= i; cur_i++) {
+ if (cur_i >= icons_order().size()) {
+ continue;
+ }
+ for (unsigned cur_j = j0; cur_j <= j; cur_j++) {
+ if (cur_j >= icons_order()[cur_i].size()) {
+ continue;
+ }
+ Widelands::Ware_Index ware = icons_order()[cur_i][cur_j];
+ if (m_hidden[ware]) {
+ continue;
+ }
+ m_in_selection[ware] = true;
+ }
+ }
+ update();
+}
+
+
void AbstractWaresDisplay::layout()
{
@@ -241,9 +334,18 @@
{
Point p = ware_position(id);
+ bool draw_selected = m_selected[id];
+ if (m_selection_anchor) {
+ if (ware_selected(m_selection_anchor)) {
+ draw_selected |= m_in_selection[id];
+ } else {
+ draw_selected &= !m_in_selection[id];
+ }
+ }
+
// draw a background
const Image* bgpic =
- g_gr->images().get(ware_selected(id) ? "pics/ware_list_bg_selected.png" : "pics/ware_list_bg.png");
+ g_gr->images().get(draw_selected ? "pics/ware_list_bg_selected.png" : "pics/ware_list_bg.png");
uint16_t w = bgpic->width();
dst.blit(p, bgpic);
@@ -378,3 +480,4 @@
}
return ret;
}
+
=== modified file 'src/wui/waresdisplay.h'
--- src/wui/waresdisplay.h 2013-02-09 22:51:15 +0000
+++ src/wui/waresdisplay.h 2013-07-14 16:56:24 +0000
@@ -58,6 +58,7 @@
(uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);
+ bool handle_mouserelease(Uint8 btn, int32_t x, int32_t y);
// Wares may be selected (highlighted)
@@ -100,13 +101,17 @@
typedef std::vector<const Widelands::WareList *> vector_type;
typedef std::vector<bool> selection_type;
+ void update_anchor_selection(int32_t x, int32_t y);
+
const Widelands::Tribe_Descr & m_tribe;
Widelands::WareWorker m_type;
UI::Textarea m_curware;
selection_type m_selected;
selection_type m_hidden;
+ selection_type m_in_selection;
bool m_selectable;
bool m_horizontal;
+ Widelands::Ware_Index m_selection_anchor;
boost::function<void(Widelands::Ware_Index, bool)> m_callback_function;
};
Follow ups