summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Nusser <andre.nusser@googlemail.com>2018-06-16 12:52:48 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2018-08-12 11:13:53 +0200
commit8ad5f7c39db55cab3f78fdefab323435261941fd (patch)
treefb5a3f4a29716a83e18a96b70ec9162d9e93b8c6
parent20bdae6c72192c87bf95c6ac86c8cc049aa1ab5a (diff)
Add hovering to visualization.
-rw-r--r--plugingui/colour.h9
-rw-r--r--plugingui/drumkittab.cc91
-rw-r--r--plugingui/drumkittab.h16
-rw-r--r--plugingui/painter.h14
-rw-r--r--src/grid.h23
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::
diff --git a/src/grid.h b/src/grid.h
index 6d3933b..85c7465 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -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;
+}