/* Copyright (C) 2017 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __gtk2_ardour_beatbox_gui_h__ #define __gtk2_ardour_beatbox_gui_h__ #include #include #include #include #include #include #include #include #include #include "gtkmm2ext/colors.h" #include "widgets/ardour_button.h" #include "canvas/box.h" #include "canvas/canvas.h" #include "canvas/constraint_packer.h" #include "canvas/rectangle.h" #include "ardour/step_sequencer.h" #include "widgets/ardour_button.h" #include "widgets/ardour_dropdown.h" #include "ardour_dialog.h" namespace PBD { class PropertyChange; } namespace ArdourCanvas { class Item; class StepButton; class Polygon; class Text; class VBox; class Widget; } namespace ARDOUR { class BeatBox; } class SequencerView; class SequenceView; class StepView; class FloatingTextEntry; class SequencerStepIndicator; class SequencerView : public ArdourCanvas::ConstraintPacker, public sigc::trackable { public: enum Mode { Velocity, Pitch, Duration, Octave, Group, Timing, }; SequencerView (ARDOUR::StepSequencer&, ArdourCanvas::Item*); ARDOUR::StepSequencer& sequencer() const { return _sequencer; } SequenceView& sequence_view (size_t n) const; Mode mode() const { return _mode; } void set_mode (Mode m); void render (ArdourCanvas::Rect const &, Cairo::RefPtr) const; void update (); static double rhs_xoffset; static double mode_button_width; static double mode_button_height; static double mode_button_spacing; static double mode_button_xdim; static double mode_button_ydim; private: ARDOUR::StepSequencer& _sequencer; typedef std::vector StepIndicators; StepIndicators step_indicators; typedef std::vector SequenceViews; SequenceViews sequence_views; double _width; double _height; Mode _mode; ArdourCanvas::ConstraintPacker* button_packer; ArdourCanvas::ConstraintPacker* step_indicator_box; ArdourCanvas::ConstraintPacker* sequence_hbox; ArdourCanvas::ConstraintPacker* lhs_vbox; ArdourCanvas::ConstraintPacker* steps_vbox; ArdourCanvas::ConstraintPacker* rhs_vbox; ArdourCanvas::Rectangle* velocity_mode_button; ArdourCanvas::Rectangle* pitch_mode_button; ArdourCanvas::Rectangle* octave_mode_button; ArdourCanvas::Rectangle* gate_mode_button; ArdourCanvas::Rectangle* timing_mode_button; ArdourCanvas::Text* velocity_mode_text; ArdourCanvas::Text* pitch_mode_text; ArdourCanvas::Text* octave_mode_text; ArdourCanvas::Text* gate_mode_text; ArdourCanvas::Text* timing_mode_text; static Gtkmm2ext::Color current_mode_color; static Gtkmm2ext::Color not_current_mode_color; void sequencer_changed (PBD::PropertyChange const &); bool mode_button_event (GdkEvent*, SequencerView::Mode); PBD::ScopedConnection sequencer_connection; }; class SequenceView : public sigc::trackable { public: SequenceView (SequencerView&, ARDOUR::StepSequence&, ArdourCanvas::Canvas* canvas); void view_mode_changed (); SequencerView::Mode mode() const { return sv.mode(); } ARDOUR::StepSequencer& sequencer() const { return sv.sequencer(); } ArdourCanvas::ConstraintPacker* lhs_box; ArdourCanvas::ConstraintPacker* rhs_box; ArdourCanvas::ConstraintPacker* step_box; private: SequencerView& sv; ARDOUR::StepSequence& sequence; ArdourCanvas::Text* number_text; ArdourCanvas::Text* name_text; ArdourCanvas::Text* root_text; ArdourCanvas::Rectangle* step_cnt_button; ArdourCanvas::Rectangle* speed_slide; bool name_text_event (GdkEvent*); void edit_name (); void name_edited (std::string, int); FloatingTextEntry* floating_entry; typedef std::vector StepViews; StepViews step_views; void sequence_changed (); PBD::ScopedConnection sequence_connection; }; class StepView : public ArdourCanvas::Rectangle, public sigc::trackable { public: StepView (SequenceView&, ARDOUR::Step&, ArdourCanvas::Canvas* canvas); void render (ArdourCanvas::Rect const &, Cairo::RefPtr) const; bool on_event (GdkEvent*); void view_mode_changed (); ARDOUR::StepSequencer& sequencer() const { return sv.sequencer(); } private: ARDOUR::Step& _step; SequenceView& sv; ArdourCanvas::Text* text; bool grabbed; std::pair grab_at; std::pair last_motion; bool motion_event (GdkEventMotion*); bool button_press_event (GdkEventButton*); bool button_release_event (GdkEventButton*); bool scroll_event (GdkEventScroll*); void adjust_step_pitch (int amt); void adjust_step_velocity (int amt); void adjust_step_duration (ARDOUR::Step::DurationRatio const &); void adjust_step_octave (int amt); void adjust_step_timing (double fract); void step_changed (PBD::PropertyChange const &); PBD::ScopedConnection step_connection; void set_octave_text (); void set_group_text (); void set_timing_text (); static Gtkmm2ext::Color on_fill_color; static Gtkmm2ext::Color off_fill_color; }; class SequencerStepIndicator : public ArdourCanvas::Rectangle, public sigc::trackable { public: SequencerStepIndicator (SequencerView&, ArdourCanvas::Canvas*, size_t n); void render (ArdourCanvas::Rect const &, Cairo::RefPtr) const; bool on_event (GdkEvent*); void set_current (bool); private: SequencerView& sv; size_t number; ArdourCanvas::Polygon* poly; ArdourCanvas::Text* text; bool being_dragged; static int dragging; bool motion_event (GdkEventMotion*); bool button_press_event (GdkEventButton*); bool button_release_event (GdkEventButton*); void set_text (); void sequencer_changed (PBD::PropertyChange const &); PBD::ScopedConnection sequencer_connection; static Gtkmm2ext::Color current_color; static Gtkmm2ext::Color other_color; static Gtkmm2ext::Color current_text_color; static Gtkmm2ext::Color other_text_color; static Gtkmm2ext::Color bright_outline_color; }; class BBGUI : public ArdourDialog { public: BBGUI (std::shared_ptr bb); ~BBGUI (); double width() const { return _width; } double height() const { return _height; } protected: void on_map (); void on_unmap (); private: std::shared_ptr bbox; double _width; double _height; Gtk::Adjustment horizontal_adjustment; Gtk::Adjustment vertical_adjustment; ArdourCanvas::GtkCanvasViewport* _canvas_viewport; ArdourCanvas::GtkCanvas* _canvas; SequencerView* _sequencer; ArdourWidgets::ArdourButton start_button; void toggle_play (); ArdourWidgets::ArdourButton export_as_region_button; void export_as_region (); Gtk::HBox canvas_hbox; Gtk::VScrollbar vscrollbar; void clear (); void update (); void update_sequencer (); sigc::connection timer_connection; void sequencer_changed (PBD::PropertyChange const &); PBD::ScopedConnection sequencer_connection; }; #endif /* __gtk2_ardour_beatbox_gui_h__ */