diff options
| -rw-r--r-- | plugingui/colour.h | 9 | ||||
| -rw-r--r-- | plugingui/drumkittab.cc | 91 | ||||
| -rw-r--r-- | plugingui/drumkittab.h | 16 | ||||
| -rw-r--r-- | plugingui/painter.h | 14 | ||||
| -rw-r--r-- | src/grid.h | 23 | 
5 files changed, 104 insertions, 49 deletions
| diff --git a/plugingui/colour.h b/plugingui/colour.h index 0bfe80d..3a135fc 100644 --- a/plugingui/colour.h +++ b/plugingui/colour.h @@ -54,13 +54,4 @@ private:  	std::array<float, 4> data;  }; -struct ColourHasher -{ -	// TODO: replace by something reasonable -	std::size_t operator()(const Colour& colour) const -	{ -		return 7*colour.red() + 11*colour.green() + 13*colour.blue()/* + 17*colour.alpha()*/; -	} -}; -  } // GUI:: diff --git a/plugingui/drumkittab.cc b/plugingui/drumkittab.cc index 388f43e..acc2c89 100644 --- a/plugingui/drumkittab.cc +++ b/plugingui/drumkittab.cc @@ -34,6 +34,9 @@  #include "painter.h"  #include "settings.h" +// TODO: +// make consistent with clicks etc +  namespace GUI  { @@ -53,7 +56,9 @@ DrumkitTab::DrumkitTab(Widget* parent,  	velocity_label.resizeToText();  	instrument_name_label.move(velocity_label.width()+30, height()-instrument_name_label.height()-5); -	updateInstrumentLabel(); +	updateInstrumentLabel(-1); + +	pos_to_colour_index.setDefaultValue(-1);  }  void DrumkitTab::resize(std::size_t width, std::size_t height) @@ -126,7 +131,20 @@ void DrumkitTab::scrollEvent(ScrollEvent* scrollEvent)  	updateVelocityLabel();  	velocity_label.resizeToText(); -	triggerAudition(scrollEvent->x, scrollEvent->y, false); +	triggerAudition(scrollEvent->x, scrollEvent->y); +} + +void DrumkitTab::mouseMoveEvent(MouseMoveEvent* mouseMoveEvent) +{ +	// change to image coordinates +	auto const x = mouseMoveEvent->x - drumkit_image_x; +	auto const y = mouseMoveEvent->y - drumkit_image_y; + +	auto index = pos_to_colour_index(x, y); + +	highlightInstrument(index); +	updateInstrumentLabel(index); +	redraw();  }  void DrumkitTab::mouseLeaveEvent() @@ -135,39 +153,45 @@ void DrumkitTab::mouseLeaveEvent()  		Painter painter(*this);  		painter.clear();  		painter.drawImage(drumkit_image_x, drumkit_image_y, *drumkit_image); -		redraw();  		shows_overlay = false; +		redraw();  	}  } -void DrumkitTab::triggerAudition(int x, int y, bool show_hit) +void DrumkitTab::triggerAudition(int x, int y)  { -	// FIXME: introduce matrix/grid class and then make notation more beautiful. -	auto pos = (x - drumkit_image_x) + (y - drumkit_image_y)*map_image->width(); -	auto index = pos_to_colour_index[pos]; -	if (index == -1) -	{ -		return; -	} -	auto const& colour = colours[index]; -	auto const& instrument = to_instrument_name[index]; +	// change to image coordinates +	x -= drumkit_image_x; +	y -= drumkit_image_y; + +	auto index = pos_to_colour_index(x, y); +	if (index == -1) { return; }  	++settings.audition_counter; -	settings.audition_instrument = instrument; +	settings.audition_instrument = to_instrument_name[index];  	settings.audition_velocity = current_velocity; -	if (show_hit) -	{ -		Painter painter(*this); -		painter.drawRestrictedImage(drumkit_image_x, drumkit_image_y, colour, *map_image); -		shows_instrument_overlay = true; -	} +	redraw(); +} -	current_instrument = instrument; -	updateInstrumentLabel(); +void DrumkitTab::highlightInstrument(int index) +{ +	if (index == current_index) { return; } +	current_index = index; -	redraw(); +	Painter painter(*this); +	painter.clear(); +	painter.drawImage(drumkit_image_x, drumkit_image_y, *drumkit_image); +	shows_overlay = false; + +	if (index != -1) { +		auto const& colour = colours[index]; +		auto const& positions = colour_index_to_positions[index]; +		painter.draw(positions.begin(), positions.end(), drumkit_image_x, drumkit_image_y, colour); + +		shows_instrument_overlay = true; +	}  }  void DrumkitTab::updateVelocityLabel() @@ -177,8 +201,9 @@ void DrumkitTab::updateVelocityLabel()  	velocity_label.setText("Velocity: " + stream.str());  } -void DrumkitTab::updateInstrumentLabel() +void DrumkitTab::updateInstrumentLabel(int index)  { +	current_instrument = (index == -1 ? "" : to_instrument_name[index]);  	instrument_name_label.setText("Instrument: " + current_instrument);  	instrument_name_label.resizeToText();  } @@ -193,7 +218,8 @@ void DrumkitTab::init(std::string const& image_file, std::string const& map_file  	auto const width = map_image->width();  	colours.clear(); -	pos_to_colour_index.assign(height*width, -1); +	pos_to_colour_index.assign(width, height, -1); +	colour_index_to_positions.clear();  	to_instrument_name.clear();  	for (std::size_t y = 0; y < map_image->height(); ++y) @@ -202,19 +228,20 @@ void DrumkitTab::init(std::string const& image_file, std::string const& map_file  		{  			auto colour = map_image->getPixel(x, y); -			if (colour.alpha() == 1.) -			{ -				continue; -			} +			if (colour.alpha() == 0.) { continue; }  			auto it = std::find(colours.begin(), colours.end(), colour); +			int index = std::distance(colours.begin(), it); +  			if (it == colours.end())  			{ -				colours.push_back(colour); +				// XXX: avoids low alpha values due to feathering of edges +				colours.emplace_back(colour.red(), colour.green(), colour.blue(), 0.7); +				colour_index_to_positions.emplace_back();  			} -			int index = std::distance(colours.begin(), it); -			pos_to_colour_index[x + y*width] = index; +			pos_to_colour_index(x, y) = index; +			colour_index_to_positions[index].emplace_back(x, y);  		}  	} diff --git a/plugingui/drumkittab.h b/plugingui/drumkittab.h index 1c99e6d..e42eb93 100644 --- a/plugingui/drumkittab.h +++ b/plugingui/drumkittab.h @@ -30,6 +30,8 @@  #include <memory>  #include <string> +#include <grid.h> +  #include "image.h"  #include "label.h"  #include "widget.h" @@ -55,6 +57,7 @@ public:  	void resize(std::size_t width, std::size_t height) override;  	void buttonEvent(ButtonEvent* buttonEvent) override;  	void scrollEvent(ScrollEvent* scrollEvent) override; +	void mouseMoveEvent(MouseMoveEvent* mouseMoveEvent) override;  	void mouseLeaveEvent() override;  	void init(std::string const& image_file, std::string const& map_file); @@ -62,9 +65,15 @@ public:  private:  	float current_velocity{.5};  	std::string current_instrument{""}; +	int current_index{-1}; + +	using IndexGrid = Grid<int>; +	using Position = IndexGrid::Pos; +	using Positions = std::vector<Position>;  	std::vector<Colour> colours; -	std::vector<int> pos_to_colour_index; +	IndexGrid pos_to_colour_index; +	std::vector<Positions> colour_index_to_positions;  	std::vector<std::string> to_instrument_name;  	struct ColourInstrumentPair @@ -95,9 +104,10 @@ private:  	// SettingsNotifier& settings_notifier;  	// Config& config; -	void triggerAudition(int x, int y, bool show_hit = true); +	void triggerAudition(int x, int y); +	void highlightInstrument(int index);  	void updateVelocityLabel(); -	void updateInstrumentLabel(); +	void updateInstrumentLabel(int index);  };  } // GUI:: diff --git a/plugingui/painter.h b/plugingui/painter.h index fc4ce2b..2630b0c 100644 --- a/plugingui/painter.h +++ b/plugingui/painter.h @@ -29,11 +29,11 @@  #include <string>  #include "colour.h" +#include "pixelbuffer.h"  namespace GUI  { -class PixelBufferAlpha;  class Font;  class Drawable;  class Image; @@ -60,6 +60,9 @@ public:  	void drawImageStretched(int x, int y, const Drawable& image,  	                        int width, int height); +	template<typename Iterator> +	void draw(Iterator begin, Iterator end, int x_offset, int y_offset, Colour const& colour); +  	typedef struct {  		Image* topLeft;  		Image* top; @@ -90,4 +93,13 @@ private:  	Colour colour;  }; +template<typename Iterator> +void Painter::draw(Iterator begin, Iterator end, int x_offset, int y_offset, Colour const& colour) +{ +	for (auto it = begin; it != end; ++it) +	{ +		pixbuf.addPixel(x_offset + it->x, y_offset + it->y, colour); +	} +} +  } // GUI:: @@ -53,15 +53,18 @@ public:  	T operator()(Index x, Index y) const;  	T& operator()(Pos pos);  	T& operator()(Index x, Index y); +	std::vector<T> const& getAllEntries() const;  	void resize(Index width, Index height);  	void assign(Index width, Index height, T value); +	void setDefaultValue(T value);  private:  	Index _width;  	Index _height;  	std::vector<T> _entries; +	T default_value;  };  template <typename T> @@ -99,25 +102,31 @@ auto Grid<T>::height() const -> Index  template <typename T>  T Grid<T>::operator()(Pos pos) const  { -	return _entries.at(pos.x + _width*pos.y); +	return is_valid(pos) ? _entries[pos.x + _width*pos.y] : default_value;  }  template <typename T>  T Grid<T>::operator()(Index x, Index y) const  { -	return _entries.at(x + _width*y); +	return is_valid(x, y) ? _entries[x + _width*y] : default_value;  }  template <typename T>  T& Grid<T>::operator()(Pos pos)  { -	return _entries.at(pos.x + _width*pos.y); +	return is_valid(pos) ? _entries[pos.x + _width*pos.y] : default_value;  }  template <typename T>  T& Grid<T>::operator()(Index x, Index y)  { -	return _entries.at(x + _width*y); +	return is_valid(x, y) ? _entries[x + _width*y] : default_value; +} + +template <typename T> +std::vector<T> const& Grid<T>::getAllEntries() const +{ +	return _entries;  }  template <typename T> @@ -135,3 +144,9 @@ void Grid<T>::assign(Index width, Index height, T value)  	_height = height;  	_entries.assign(_width*_height, value);  } + +template <typename T> +void Grid<T>::setDefaultValue(T value) +{ +	default_value = value; +} | 
