Skip to content

Commit

Permalink
Multi-stop gradients (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
aroffringa authored Oct 10, 2019
1 parent a07671e commit ef504f4
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 23 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ set(GUIFILES
gui/timesequencepropertieswindow.cpp
gui/visualizationwindow.cpp
gui/components/colorselectwidget.cpp
gui/components/colorsequencewidget.cpp
gui/components/durationinput.cpp
gui/components/foldercombo.cpp
gui/components/objectlist.cpp
Expand Down
37 changes: 37 additions & 0 deletions gui/components/colorsequencewidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "colorsequencewidget.h"

#include "../gradientwindow.h"

#include <glibmm/main.h>
#include <gtkmm/main.h>

void ColorSequenceWidget::onGradient()
{
if(!_allEqual.get_active() && _widgets.size() > 2)
{
GradientWindow window(_widgets.size());
window.set_modal(true);
Gtk::Main::run(window);

if(window.Result())
{
std::vector<Color> colors = window.GetColors();
_widgets.front()->SetColor(colors.front());
_widgets.back()->SetColor(colors.back());

for(size_t i=1; i<_widgets.size()-1; ++i)
{
double floatIndex = double(i) * (colors.size() - 1) / (_widgets.size() - 1);
Color leftColor = colors[floor(floatIndex)];
Color rightColor = colors[floor(floatIndex)+1];
double balance = floatIndex - floor(floatIndex);
unsigned
red = (rightColor.Red() * balance + leftColor.Red() * (1.0 - balance)),
green = (rightColor.Green() * balance + leftColor.Green() * (1.0 - balance)),
blue = (rightColor.Blue() * balance + leftColor.Blue() * (1.0 - balance));
_widgets[i]->SetColor(Color(red, green, blue));
}
}
}
}

33 changes: 10 additions & 23 deletions gui/components/colorsequencewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
class ColorSequenceWidget : public Gtk::VBox
{
public:
ColorSequenceWidget(Gtk::Window* parent) :
ColorSequenceWidget(Gtk::Window* parent, bool showGradientButton = true) :
_frame("Colors"),
_allEqual("Use one color for all"),
_plusButton("+"),
Expand All @@ -33,9 +33,12 @@ class ColorSequenceWidget : public Gtk::VBox
_minButton.signal_clicked().connect(sigc::mem_fun(*this, &ColorSequenceWidget::onDecreaseColors));
_buttonBox.pack_start(_minButton);

_gradientButton.set_sensitive(false);
_gradientButton.signal_clicked().connect(sigc::mem_fun(*this, &ColorSequenceWidget::onGradient));
_buttonBox.pack_start(_gradientButton);
if(showGradientButton)
{
_gradientButton.set_sensitive(false);
_gradientButton.signal_clicked().connect(sigc::mem_fun(*this, &ColorSequenceWidget::onGradient));
_buttonBox.pack_start(_gradientButton);
}

_plusButton.signal_clicked().connect(sigc::mem_fun(*this, &ColorSequenceWidget::onIncreaseColors));
_buttonBox.pack_start(_plusButton);
Expand Down Expand Up @@ -153,25 +156,9 @@ class ColorSequenceWidget : public Gtk::VBox
queue_resize();
}
}
void onGradient()
{
if(!_allEqual.get_active() && _widgets.size() > 2)
{
Color frontColor = _widgets.front()->GetColor();
Color backColor = _widgets.back()->GetColor();
for(size_t i=1; i+1<_widgets.size(); ++i)
{
unsigned
red = (backColor.Red() * i +
frontColor.Red() * (_widgets.size() - 1 - i)) / (_widgets.size() - 1),
green = (backColor.Green() * i +
frontColor.Green() * (_widgets.size() - 1 - i)) / (_widgets.size() - 1),
blue = (backColor.Blue() * i +
frontColor.Blue() * (_widgets.size() - 1 - i)) / (_widgets.size() - 1);
_widgets[i]->SetColor(Color(red, green, blue));
}
}
}

void onGradient();

void onFirstColorChange()
{
if(_allEqual.get_active())
Expand Down
43 changes: 43 additions & 0 deletions gui/gradientwindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "components/colorsequencewidget.h"

#include <gtkmm/window.h>

class GradientWindow : public Gtk::Window
{
public:
GradientWindow(size_t maxCount) :
_colorSequence(this, false),
_cancelButton("Cancel"),
_okayButton("Okay"),
_result(false)
{
set_size_request(250, 300);
_colorSequence.SetMinCount(2);
_colorSequence.SetMaxCount(maxCount);
_box.pack_start(_colorSequence);

_cancelButton.signal_clicked().connect([&] { hide(); });
_buttonBox.pack_start(_cancelButton);
_okayButton.signal_clicked().connect([&] { _result = true; hide(); });
_buttonBox.pack_start(_okayButton);

_box.pack_start(_buttonBox);

add(_box);
show_all_children();
}

bool Result() const { return _result; }

std::vector<Color> GetColors() const
{
return _colorSequence.GetColors();
}

private:
Gtk::VBox _box;
ColorSequenceWidget _colorSequence;
Gtk::ButtonBox _buttonBox;
Gtk::Button _cancelButton, _okayButton;
bool _result;
};

0 comments on commit ef504f4

Please sign in to comment.