← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/pc_on_buttons into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/pc_on_buttons into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/pc_on_buttons/+merge/278191

This adds player color to building buttons. You can see it in action when building a new building or in the building statistics window.

The images with player color are cached in the AnimationManager.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/pc_on_buttons into lp:widelands.
=== modified file 'src/graphic/animation.cc'
--- src/graphic/animation.cc	2015-11-06 12:19:22 +0000
+++ src/graphic/animation.cc	2015-11-20 18:25:18 +0000
@@ -39,6 +39,7 @@
 #include "graphic/image.h"
 #include "graphic/image_cache.h"
 #include "graphic/surface.h"
+#include "graphic/texture.h"
 #include "io/filesystem/layered_filesystem.h"
 #include "logic/bob.h"
 #include "logic/instances.h"
@@ -123,7 +124,8 @@
 	uint16_t nr_frames() const override;
 	uint32_t frametime() const override;
 	const Point& hotspot() const override;
-	const std::string& representative_image_from_disk_filename() const override;
+	Image* representative_image(const RGBColor* clr) const override;
+	const std::string& representative_image_filename() const override;
 	virtual void blit(uint32_t time, const Point&, const Rect& srcrc, const RGBColor* clr, Surface*)
 		const override;
 	void trigger_soundfx(uint32_t framenumber, uint32_t stereo_position) const override;
@@ -297,7 +299,33 @@
 	return hotspot_;
 }
 
-const std::string& NonPackedAnimation::representative_image_from_disk_filename() const {
+Image* NonPackedAnimation::representative_image(const RGBColor* clr) const {
+	assert(!image_files_.empty());
+
+	const Image* image = g_gr->images().get(image_files_[0]);
+	int w = image->width();
+	int h = image->height();
+
+	Texture* rv = new Texture(w, h);
+	if (!hasplrclrs_ || clr == nullptr) {
+		::blit(Rect(Point(0, 0), w, h),
+				 *image,
+				 Rect(Point(0, 0), w, h),
+				 1.,
+				 BlendMode::UseAlpha,
+				 rv);
+	} else {
+		blit_blended(Rect(Point(0, 0), w, h),
+						 *image,
+						 *g_gr->images().get(pc_mask_image_files_[0]),
+						 Rect(Point(0, 0), w, h),
+						 *clr,
+						 rv);
+	}
+	return rv;
+}
+
+const std::string& NonPackedAnimation::representative_image_filename() const {
 	return image_files_[0];
 }
 
@@ -383,20 +411,24 @@
 */
 
 uint32_t AnimationManager::load(const LuaTable& table) {
-	m_animations.push_back(new NonPackedAnimation(table));
-	return m_animations.size();
+	animations_.push_back(std::unique_ptr<Animation>(new NonPackedAnimation(table)));
+	return animations_.size();
 }
 
 const Animation& AnimationManager::get_animation(uint32_t id) const
 {
-	if (!id || id > m_animations.size())
+	if (!id || id > animations_.size())
 		throw wexception("Requested unknown animation with id: %i", id);
 
-	return *m_animations[id - 1];
+	return *animations_[id - 1].get();
 }
 
-AnimationManager::~AnimationManager()
-{
-	for (vector<Animation*>::iterator it = m_animations.begin(); it != m_animations.end(); ++it)
-		delete *it;
+const Image* AnimationManager::get_representative_image(uint32_t id, const RGBColor* clr) {
+	if (representative_images_.count(id) != 1) {
+		representative_images_.insert(
+					std::make_pair(
+						id,
+						std::unique_ptr<Image>(g_gr->animations().get_animation(id).representative_image(clr))));
+	}
+	return representative_images_.at(id).get();
 }

=== modified file 'src/graphic/animation.h'
--- src/graphic/animation.h	2015-11-06 12:19:22 +0000
+++ src/graphic/animation.h	2015-11-20 18:25:18 +0000
@@ -22,6 +22,7 @@
 
 #include <cstring>
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -67,13 +68,17 @@
 	/// so the caller has to adjust for the hotspot himself.
 	virtual const Point& hotspot() const = 0;
 
-	/// Returns the disk filename for the first image in the animation
-	virtual const std::string& representative_image_from_disk_filename() const = 0;
+	/// An image of the first frame, blended with the given player color.
+	/// The 'clr' is the player color used for blending - the parameter can be
+	/// 'nullptr', in which case the neutral image will be returned.
+	virtual Image* representative_image(const RGBColor* clr) const = 0;
+	/// The filename of the image used for the first frame, without player color.
+	virtual const std::string& representative_image_filename() const = 0;
 
 	/// Blit the animation frame that should be displayed at the given time index
 	/// so that the given point is at the top left of the frame. Srcrc defines
 	/// the part of the animation that should be blitted. The 'clr' is the player
-	/// color used for blitting - the parameter can be nullptr in which case the
+	/// color used for blitting - the parameter can be 'nullptr', in which case the
 	/// neutral image will be blitted. The Surface is the target for the blit
 	/// operation and must be non-null.
 	virtual void blit(uint32_t time, const Point&, const Rect& srcrc, const RGBColor* clr, Surface*) const = 0;
@@ -90,7 +95,6 @@
 */
 class AnimationManager {
 public:
-	~AnimationManager();
 	/**
 	 * Loads an animation, graphics sound and everything from a Lua table.
 	 *
@@ -104,10 +108,14 @@
 	/// unknown.
 	const Animation& get_animation(uint32_t id) const;
 
+	/// Returns the representative image, using the given player color.
+	/// If this image has been generated before, it is pulled from the cache using
+	/// the clr argument that was used previously.
+	const Image* get_representative_image(uint32_t id, const RGBColor* clr = nullptr);
+
 private:
-	// TODO(SirVer): this vector should be changed to unique__ptr (spelled wrong to avoid message by CodeCheck)
-	//  instead of raw pointers to get rid of the destructor
-	std::vector<Animation*> m_animations;
+	std::vector<std::unique_ptr<Animation>> animations_;
+	std::map<uint32_t, std::unique_ptr<Image>> representative_images_;
 };
 
 #endif  // end of include guard: WL_GRAPHIC_ANIMATION_H

=== modified file 'src/logic/instances.cc'
--- src/logic/instances.cc	2015-11-02 19:29:03 +0000
+++ src/logic/instances.cc	2015-11-20 18:25:18 +0000
@@ -249,7 +249,7 @@
 			throw GameDataError("Map object %s has animations but no idle animation", init_name.c_str());
 		}
 		representative_image_filename_ = g_gr->animations().get_animation(get_animation("idle"))
-													.representative_image_from_disk_filename();
+													.representative_image_filename();
 	}
 	if (table.has_key("icon")) {
 		icon_filename_ = table.get_string("icon");
@@ -310,9 +310,9 @@
 	return "";
 }
 
-const Image* MapObjectDescr::representative_image() const {
-	if (!representative_image_filename_.empty()) {
-		return g_gr->images().get(representative_image_filename_);
+const Image* MapObjectDescr::representative_image(const RGBColor* player_color) const {
+	if (is_animation_known("idle")) {
+		return g_gr->animations().get_representative_image(get_animation("idle"), player_color);
 	}
 	return nullptr;
 }

=== modified file 'src/logic/instances.h'
--- src/logic/instances.h	2015-10-21 16:43:30 +0000
+++ src/logic/instances.h	2015-11-20 18:25:18 +0000
@@ -32,6 +32,7 @@
 
 #include "base/log.h"
 #include "base/macros.h"
+#include "graphic/color.h"
 #include "graphic/image.h"
 #include "logic/cmd_queue.h"
 #include "logic/widelands.h"
@@ -139,7 +140,7 @@
 
 	/// Returns the image for the first frame of the idle animation if the MapObject has animations,
 	/// nullptr otherwise
-	const Image* representative_image() const;
+	const Image* representative_image(const RGBColor* player_color = nullptr) const;
 	/// Returns the image fileneme for first frame of the idle animation if the MapObject has animations,
 	/// is empty otherwise
 	const std::string& representative_image_filename() const;

=== modified file 'src/logic/partially_finished_building.cc'
--- src/logic/partially_finished_building.cc	2015-11-11 09:52:55 +0000
+++ src/logic/partially_finished_building.cc	2015-11-20 18:25:18 +0000
@@ -149,7 +149,7 @@
 */
 const Image* PartiallyFinishedBuilding::representative_image() const
 {
-	return m_building->representative_image();
+	return m_building->representative_image(&owner().get_playercolor());
 }
 
 

=== modified file 'src/wui/building_statistics_menu.cc'
--- src/wui/building_statistics_menu.cc	2015-11-17 14:36:25 +0000
+++ src/wui/building_statistics_menu.cc	2015-11-20 18:25:18 +0000
@@ -394,7 +394,8 @@
 														kBuildGridCellWidth,
 														kBuildGridCellHeight,
 														g_gr->images().get("pics/but1.png"),
-														descr.representative_image(),
+														descr.representative_image(&iplayer().get_player()
+																							->get_playercolor()),
 														"",
 														false,
 														true);

=== modified file 'src/wui/fieldaction.cc'
--- src/wui/fieldaction.cc	2015-11-11 09:53:54 +0000
+++ src/wui/fieldaction.cc	2015-11-20 18:25:18 +0000
@@ -56,7 +56,7 @@
 // The BuildGrid presents a selection of buildable buildings
 struct BuildGrid : public UI::IconGrid {
 	BuildGrid(UI::Panel* parent,
-	          const Widelands::TribeDescr& tribe,
+				 Widelands::Player* plr,
 	          int32_t x,
 	          int32_t y,
 	          int32_t cols);
@@ -73,14 +73,14 @@
 	void mousein_slot(int32_t idx);
 
 private:
-	const Widelands::TribeDescr& tribe_;
+	Widelands::Player* plr_;
 };
 
 BuildGrid::BuildGrid(
-		UI::Panel* parent, const Widelands::TribeDescr& tribe,
+		UI::Panel* parent, Widelands::Player* plr,
 		int32_t x, int32_t y, int32_t cols) :
 	UI::IconGrid(parent, x, y, kBuildGridCellSize, kBuildGridCellSize, cols),
-	tribe_(tribe)
+	plr_(plr)
 {
 	clicked.connect(boost::bind(&BuildGrid::click_slot, this, _1));
 	mouseout.connect(boost::bind(&BuildGrid::mouseout_slot, this, _1));
@@ -95,15 +95,16 @@
 void BuildGrid::add(Widelands::DescriptionIndex id)
 {
 	const Widelands::BuildingDescr & descr =
-		*tribe_.get_building_descr(Widelands::DescriptionIndex(id));
+		*plr_->tribe().get_building_descr(Widelands::DescriptionIndex(id));
+
 	// TODO(sirver): change this to take a Button subclass instead of
 	// parameters. This will allow overriding the way it is rendered
 	// to bring back player colors.
 	UI::IconGrid::add(descr.name(),
-							descr.representative_image(),
+							descr.representative_image(&plr_->get_playercolor()),
 	                  reinterpret_cast<void*>(id),
 	                  descr.descname() + "<br><font size=11>" + _("Construction costs:") +
-	                     "</font><br>" + waremap_to_richtext(tribe_, descr.buildcost()));
+								"</font><br>" + waremap_to_richtext(plr_->tribe(), descr.buildcost()));
 }
 
 
@@ -531,7 +532,7 @@
 
 		// Allocate the tab's grid if necessary
 		if (!*ppgrid) {
-			*ppgrid = new BuildGrid(&m_tabpanel, tribe, 0, 0, 5);
+			*ppgrid = new BuildGrid(&m_tabpanel, m_plr, 0, 0, 5);
 			(*ppgrid)->buildclicked.connect(boost::bind(&FieldActionWindow::act_build, this, _1));
 			(*ppgrid)->buildmouseout.connect
 				(boost::bind(&FieldActionWindow::building_icon_mouse_out, this, _1));


Follow ups