mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 08:14:58 +01:00
improving object design for beatbox GUI
This commit is contained in:
parent
b9c26ee4c4
commit
f127739bcb
2 changed files with 124 additions and 63 deletions
|
|
@ -64,7 +64,6 @@ const double _step_dimen = 25;
|
||||||
BBGUI::BBGUI (boost::shared_ptr<BeatBox> bb)
|
BBGUI::BBGUI (boost::shared_ptr<BeatBox> bb)
|
||||||
: ArdourDialog (_("BeatBox"))
|
: ArdourDialog (_("BeatBox"))
|
||||||
, bbox (bb)
|
, bbox (bb)
|
||||||
, _mode (Velocity)
|
|
||||||
, horizontal_adjustment (0.0, 0.0, 800.0)
|
, horizontal_adjustment (0.0, 0.0, 800.0)
|
||||||
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
|
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
|
||||||
, vscrollbar (vertical_adjustment)
|
, vscrollbar (vertical_adjustment)
|
||||||
|
|
@ -105,10 +104,10 @@ BBGUI::BBGUI (boost::shared_ptr<BeatBox> bb)
|
||||||
mode_box.pack_start (mode_octave_button);
|
mode_box.pack_start (mode_octave_button);
|
||||||
mode_box.pack_start (mode_group_button);
|
mode_box.pack_start (mode_group_button);
|
||||||
|
|
||||||
mode_velocity_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), Velocity));
|
mode_velocity_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), SequencerGrid::Velocity));
|
||||||
mode_pitch_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), Pitch));
|
mode_pitch_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), SequencerGrid::Pitch));
|
||||||
mode_octave_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), Octave));
|
mode_octave_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), SequencerGrid::Octave));
|
||||||
mode_group_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), Group));
|
mode_group_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &BBGUI::mode_clicked), SequencerGrid::Group));
|
||||||
|
|
||||||
get_vbox()->set_spacing (12);
|
get_vbox()->set_spacing (12);
|
||||||
get_vbox()->pack_start (mode_box, false, false);
|
get_vbox()->pack_start (mode_box, false, false);
|
||||||
|
|
@ -120,8 +119,13 @@ BBGUI::BBGUI (boost::shared_ptr<BeatBox> bb)
|
||||||
export_as_region_button.signal_clicked.connect (sigc::mem_fun (*this, &BBGUI::export_as_region));
|
export_as_region_button.signal_clicked.connect (sigc::mem_fun (*this, &BBGUI::export_as_region));
|
||||||
get_action_area()->pack_end (export_as_region_button);
|
get_action_area()->pack_end (export_as_region_button);
|
||||||
|
|
||||||
PropertyChange pc;
|
bbox->sequencer().PropertyChanged.connect (sequencer_connection, invalidator (*this), boost::bind (&BBGUI::sequencer_changed, this, _1), gui_context());
|
||||||
sequencer_changed (pc);
|
|
||||||
|
{
|
||||||
|
/* trigger initial draw */
|
||||||
|
PropertyChange pc;
|
||||||
|
sequencer_changed (pc);
|
||||||
|
}
|
||||||
|
|
||||||
show_all ();
|
show_all ();
|
||||||
}
|
}
|
||||||
|
|
@ -131,9 +135,10 @@ BBGUI::~BBGUI ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BBGUI::mode_clicked (Mode m)
|
BBGUI::mode_clicked (SequencerGrid::Mode m)
|
||||||
{
|
{
|
||||||
set_mode (m);
|
cerr << "Set mode to " << m << endl;
|
||||||
|
_sequencer->set_mode (m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -279,13 +284,6 @@ BBGUI::export_as_region ()
|
||||||
boost::shared_ptr<Region> region = RegionFactory::create (src, plist, true);
|
boost::shared_ptr<Region> region = RegionFactory::create (src, plist, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
BBGUI::set_mode (BBGUI::Mode m)
|
|
||||||
{
|
|
||||||
_mode = m;
|
|
||||||
_sequencer->redraw ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BBGUI::sequencer_changed (PropertyChange const &)
|
BBGUI::sequencer_changed (PropertyChange const &)
|
||||||
{
|
{
|
||||||
|
|
@ -312,18 +310,6 @@ BBGUI::sequencer_changed (PropertyChange const &)
|
||||||
ssi->set_position (Duple (n * _step_dimen, 0.0));
|
ssi->set_position (Duple (n * _step_dimen, 0.0));
|
||||||
ssi->set_fill_color (random());
|
ssi->set_fill_color (random());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* step views, one per step per sequence */
|
|
||||||
|
|
||||||
for (size_t s = 0; s < nsequences; ++s) {
|
|
||||||
for (size_t n = 0; n < nsteps; ++n) {
|
|
||||||
StepView* sv = new StepView (*this, bbox->sequencer().sequence (s).step (n), v_scroll_group);
|
|
||||||
//sv->set (Rect (n * _step_dimen + 1, (s+1) * _step_dimen + 1, (n+1) * _step_dimen - 1, (s+2) * _step_dimen - 1));
|
|
||||||
sv->set_position (Duple (n * _step_dimen, (s+1) * _step_dimen));
|
|
||||||
sv->set (Rect (1, 1, _step_dimen - 2, _step_dimen - 2));
|
|
||||||
cerr << "step rect @ " << sv->get() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -331,21 +317,53 @@ BBGUI::sequencer_changed (PropertyChange const &)
|
||||||
SequencerGrid::SequencerGrid (StepSequencer& s, Item *parent)
|
SequencerGrid::SequencerGrid (StepSequencer& s, Item *parent)
|
||||||
: Rectangle (parent)
|
: Rectangle (parent)
|
||||||
, _sequencer (s)
|
, _sequencer (s)
|
||||||
|
, _mode (Velocity)
|
||||||
{
|
{
|
||||||
PropertyChange pc;
|
_sequencer.PropertyChanged.connect (sequencer_connection, invalidator (*this), boost::bind (&SequencerGrid::sequencer_changed, this, _1), gui_context());
|
||||||
|
|
||||||
sequencer_changed (pc);
|
{
|
||||||
|
/* trigger initial draw */
|
||||||
|
PropertyChange pc;
|
||||||
|
sequencer_changed (pc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SequencerGrid::sequencer_changed (PropertyChange const &)
|
SequencerGrid::sequencer_changed (PropertyChange const &)
|
||||||
{
|
{
|
||||||
const size_t nsteps = _sequencer.nsteps();
|
const size_t nsteps = _sequencer.nsteps();
|
||||||
|
const size_t nsequences = _sequencer.nsequences();
|
||||||
|
|
||||||
_width = _step_dimen * nsteps;
|
_width = _step_dimen * nsteps;
|
||||||
_height = _step_dimen * _sequencer.nsequences ();
|
_height = _step_dimen * nsequences;
|
||||||
|
|
||||||
set (Rect (0, 0, _width, _height));
|
set (Rect (0, 0, _width, _height));
|
||||||
|
|
||||||
|
/* step views, one per step per sequence */
|
||||||
|
|
||||||
|
clear (true);
|
||||||
|
_step_views.clear ();
|
||||||
|
|
||||||
|
for (size_t s = 0; s < nsequences; ++s) {
|
||||||
|
for (size_t n = 0; n < nsteps; ++n) {
|
||||||
|
StepView* sv = new StepView (*this, _sequencer.sequence (s).step (n), Item::parent());
|
||||||
|
sv->set_position (Duple (n * _step_dimen, (s+1) * _step_dimen));
|
||||||
|
sv->set (Rect (1, 1, _step_dimen - 2, _step_dimen - 2));
|
||||||
|
_step_views.push_back (sv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SequencerGrid::set_mode (Mode m)
|
||||||
|
{
|
||||||
|
_mode = m;
|
||||||
|
|
||||||
|
for (StepViews::iterator s = _step_views.begin(); s != _step_views.end(); ++s) {
|
||||||
|
(*s)->view_mode_changed ();
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -426,49 +444,75 @@ SequencerStepIndicator::render (Rect const & area, Cairo::RefPtr<Cairo::Context
|
||||||
render_children (area, context);
|
render_children (area, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
StepView::StepView (BBGUI& bb, Step& s, ArdourCanvas::Item* parent)
|
StepView::StepView (SequencerGrid& sg, Step& s, ArdourCanvas::Item* parent)
|
||||||
: ArdourCanvas::Rectangle (parent)
|
: ArdourCanvas::Rectangle (parent)
|
||||||
, _step (s)
|
, _step (s)
|
||||||
, bbgui (bb)
|
, _seq (sg)
|
||||||
, text (new Text (this))
|
, text (new Text (this))
|
||||||
{
|
{
|
||||||
set_fill_color (UIConfiguration::instance().color ("gtk_bright_indicator"));
|
set_fill_color (UIConfiguration::instance().color ("selection"));
|
||||||
|
|
||||||
text->set_fill_color (contrasting_text_color (fill_color()));
|
text->set_fill_color (contrasting_text_color (fill_color()));
|
||||||
|
text->set_font_description (UIConfiguration::instance ().get_SmallFont ());
|
||||||
text->hide ();
|
text->hide ();
|
||||||
|
|
||||||
Event.connect (sigc::mem_fun (*this, &StepView::on_event));
|
Event.connect (sigc::mem_fun (*this, &StepView::on_event));
|
||||||
_step.PropertyChanged.connect (step_connection, invalidator (*this), boost::bind (&StepView::step_changed, this, _1), gui_context());
|
_step.PropertyChanged.connect (step_connection, invalidator (*this), boost::bind (&StepView::step_changed, this, _1), gui_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StepView::view_mode_changed ()
|
||||||
|
{
|
||||||
|
cerr << "view mode changed\n";
|
||||||
|
|
||||||
|
if (_seq.mode() == SequencerGrid::Octave) {
|
||||||
|
cerr << "octave\n";
|
||||||
|
|
||||||
|
text->show ();
|
||||||
|
if (_step.octave_shift() >= 0) {
|
||||||
|
text->set (string_compose ("+%1", _step.octave_shift()));
|
||||||
|
} else {
|
||||||
|
text->set (string_compose ("%1", _step.octave_shift()));
|
||||||
|
}
|
||||||
|
|
||||||
|
const double w = text->width();
|
||||||
|
const double h = text->height();
|
||||||
|
|
||||||
|
cerr << "put octave text " << text->text() << " dimen " << w << " x " << h << " @ " << Duple (_step_dimen/2 - (w/2), _step_dimen/2 - (h/2)) << endl;
|
||||||
|
|
||||||
|
text->set_position (Duple (_step_dimen/2 - (w/2), _step_dimen/2 - (h/2)));
|
||||||
|
|
||||||
|
} else if (_seq.mode() == SequencerGrid::Group) {
|
||||||
|
text->show ();
|
||||||
|
} else {
|
||||||
|
text->hide ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StepView::step_changed (PropertyChange const &)
|
StepView::step_changed (PropertyChange const &)
|
||||||
{
|
{
|
||||||
cerr << "Redraw for step @ " << _step.beat() << endl;
|
|
||||||
redraw ();
|
redraw ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StepView::render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
StepView::render (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||||
{
|
{
|
||||||
if (text) {
|
if (_seq.mode() == SequencerGrid::Velocity) {
|
||||||
text->hide ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bbgui.mode() == BBGUI::Velocity) {
|
|
||||||
const double height = (_step_dimen - 4) * _step.velocity();
|
const double height = (_step_dimen - 4) * _step.velocity();
|
||||||
const Duple origin = item_to_window (Duple (0, 0));
|
const Duple origin = item_to_window (Duple (0, 0));
|
||||||
context->rectangle (origin.x + 2, origin.y + (_step_dimen - height - 2), _step_dimen - 4, height);
|
context->rectangle (origin.x + 2, origin.y + (_step_dimen - height - 2), _step_dimen - 4, height);
|
||||||
context->fill ();
|
context->fill ();
|
||||||
} else if (bbgui.mode() == BBGUI::Pitch) {
|
} else if (_seq.mode() == SequencerGrid::Pitch) {
|
||||||
const double height = (_step_dimen - 4) * (_step.note() / 128.0);
|
const double height = (_step_dimen - 4) * (_step.note() / 128.0);
|
||||||
const Duple origin = item_to_window (Duple (0, 0));
|
const Duple origin = item_to_window (Duple (0, 0));
|
||||||
context->rectangle (origin.x + 2, origin.y + (_step_dimen - height - 2), _step_dimen - 4, height);
|
context->rectangle (origin.x + 2, origin.y + (_step_dimen - height - 2), _step_dimen - 4, height);
|
||||||
context->fill ();
|
context->fill ();
|
||||||
} else if (bbgui.mode() == BBGUI::Octave) {
|
|
||||||
text->set (string_compose ("%1", _step.octave_shift()));
|
|
||||||
text->show ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now deal with any children (e.g. text) */
|
||||||
|
|
||||||
|
render_children (area, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -535,12 +579,15 @@ StepView::scroll_event (GdkEventScroll* ev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ev->state & GDK_MOD1_MASK) || bbgui.mode() == BBGUI::Pitch) {
|
if ((ev->state & GDK_MOD1_MASK) || _seq.mode() == SequencerGrid::Pitch) {
|
||||||
cerr << "adjust pitch by " << amt << endl;
|
cerr << "adjust pitch by " << amt << endl;
|
||||||
adjust_step_pitch (amt);
|
adjust_step_pitch (amt);
|
||||||
} else if (bbgui.mode() == BBGUI::Velocity) {
|
} else if (_seq.mode() == SequencerGrid::Velocity) {
|
||||||
cerr << "adjust velocity by " << amt << endl;
|
cerr << "adjust velocity by " << amt << endl;
|
||||||
adjust_step_velocity (amt);
|
adjust_step_velocity (amt);
|
||||||
|
} else if (_seq.mode() == SequencerGrid::Octave) {
|
||||||
|
adjust_step_octave (amt);
|
||||||
|
} else if (_seq.mode() == SequencerGrid::Group) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -557,3 +604,9 @@ StepView::adjust_step_velocity (int amt)
|
||||||
{
|
{
|
||||||
_step.adjust_velocity (amt);
|
_step.adjust_velocity (amt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StepView::adjust_step_octave (int amt)
|
||||||
|
{
|
||||||
|
_step.adjust_octave (amt);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,18 +63,20 @@ class Step;
|
||||||
class StepSequencer;
|
class StepSequencer;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BBGUI;
|
class SequencerGrid;
|
||||||
|
|
||||||
class StepView : public ArdourCanvas::Rectangle, public sigc::trackable {
|
class StepView : public ArdourCanvas::Rectangle, public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
StepView (BBGUI&, ARDOUR::Step&, ArdourCanvas::Item*);
|
StepView (SequencerGrid&, ARDOUR::Step&, ArdourCanvas::Item*);
|
||||||
|
|
||||||
void render (ArdourCanvas::Rect const &, Cairo::RefPtr<Cairo::Context>) const;
|
void render (ArdourCanvas::Rect const &, Cairo::RefPtr<Cairo::Context>) const;
|
||||||
bool on_event (GdkEvent*);
|
bool on_event (GdkEvent*);
|
||||||
|
|
||||||
|
void view_mode_changed ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ARDOUR::Step& _step;
|
ARDOUR::Step& _step;
|
||||||
BBGUI& bbgui;
|
SequencerGrid& _seq;
|
||||||
ArdourCanvas::Text* text;
|
ArdourCanvas::Text* text;
|
||||||
|
|
||||||
std::pair<double,double> grab_at;
|
std::pair<double,double> grab_at;
|
||||||
|
|
@ -86,6 +88,7 @@ class StepView : public ArdourCanvas::Rectangle, public sigc::trackable {
|
||||||
|
|
||||||
void adjust_step_pitch (int amt);
|
void adjust_step_pitch (int amt);
|
||||||
void adjust_step_velocity (int amt);
|
void adjust_step_velocity (int amt);
|
||||||
|
void adjust_step_octave (int amt);
|
||||||
|
|
||||||
void step_changed (PBD::PropertyChange const &);
|
void step_changed (PBD::PropertyChange const &);
|
||||||
PBD::ScopedConnection step_connection;
|
PBD::ScopedConnection step_connection;
|
||||||
|
|
@ -93,19 +96,33 @@ class StepView : public ArdourCanvas::Rectangle, public sigc::trackable {
|
||||||
void make_text ();
|
void make_text ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class SequencerGrid : public ArdourCanvas::Rectangle {
|
class SequencerGrid : public ArdourCanvas::Rectangle, public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
|
enum Mode {
|
||||||
|
Velocity,
|
||||||
|
Pitch,
|
||||||
|
Octave,
|
||||||
|
Group,
|
||||||
|
};
|
||||||
|
|
||||||
SequencerGrid (ARDOUR::StepSequencer&, ArdourCanvas::Item* parent);
|
SequencerGrid (ARDOUR::StepSequencer&, ArdourCanvas::Item* parent);
|
||||||
|
|
||||||
|
Mode mode() const { return _mode; }
|
||||||
|
void set_mode (Mode m);
|
||||||
|
|
||||||
void render (ArdourCanvas::Rect const &, Cairo::RefPtr<Cairo::Context>) const;
|
void render (ArdourCanvas::Rect const &, Cairo::RefPtr<Cairo::Context>) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ARDOUR::StepSequencer& _sequencer;
|
ARDOUR::StepSequencer& _sequencer;
|
||||||
std::vector<StepView*> step_views;
|
typedef std::vector<StepView*> StepViews;
|
||||||
|
StepViews _step_views;
|
||||||
double _width;
|
double _width;
|
||||||
double _height;
|
double _height;
|
||||||
|
Mode _mode;
|
||||||
|
|
||||||
void sequencer_changed (PBD::PropertyChange const &);
|
void sequencer_changed (PBD::PropertyChange const &);
|
||||||
|
|
||||||
|
PBD::ScopedConnection sequencer_connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SequencerStepIndicator : public ArdourCanvas::Rectangle {
|
class SequencerStepIndicator : public ArdourCanvas::Rectangle {
|
||||||
|
|
@ -119,29 +136,18 @@ class SequencerStepIndicator : public ArdourCanvas::Rectangle {
|
||||||
|
|
||||||
class BBGUI : public ArdourDialog {
|
class BBGUI : public ArdourDialog {
|
||||||
public:
|
public:
|
||||||
enum Mode {
|
|
||||||
Velocity,
|
|
||||||
Pitch,
|
|
||||||
Octave,
|
|
||||||
Group,
|
|
||||||
};
|
|
||||||
|
|
||||||
BBGUI (boost::shared_ptr<ARDOUR::BeatBox> bb);
|
BBGUI (boost::shared_ptr<ARDOUR::BeatBox> bb);
|
||||||
~BBGUI ();
|
~BBGUI ();
|
||||||
|
|
||||||
double width() const { return _width; }
|
double width() const { return _width; }
|
||||||
double height() const { return _height; }
|
double height() const { return _height; }
|
||||||
|
|
||||||
Mode mode() const { return _mode; }
|
|
||||||
void set_mode (Mode m);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void on_map ();
|
void on_map ();
|
||||||
void on_unmap ();
|
void on_unmap ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<ARDOUR::BeatBox> bbox;
|
boost::shared_ptr<ARDOUR::BeatBox> bbox;
|
||||||
Mode _mode;
|
|
||||||
double _width;
|
double _width;
|
||||||
double _height;
|
double _height;
|
||||||
|
|
||||||
|
|
@ -180,7 +186,9 @@ class BBGUI : public ArdourDialog {
|
||||||
ArdourWidgets::ArdourButton mode_octave_button;
|
ArdourWidgets::ArdourButton mode_octave_button;
|
||||||
ArdourWidgets::ArdourButton mode_group_button;
|
ArdourWidgets::ArdourButton mode_group_button;
|
||||||
|
|
||||||
void mode_clicked (Mode);
|
void mode_clicked (SequencerGrid::Mode);
|
||||||
|
|
||||||
|
PBD::ScopedConnection sequencer_connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __gtk2_ardour_beatbox_gui_h__ */
|
#endif /* __gtk2_ardour_beatbox_gui_h__ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue