mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-07 14:15:46 +01:00
[Summary] Implementing the panners with KNOB
This commit is contained in:
parent
af40d1620a
commit
252edfad87
7 changed files with 139 additions and 485 deletions
|
|
@ -51,17 +51,6 @@ using namespace std;
|
|||
using namespace Gtk;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
static const int pos_box_size = 9;
|
||||
static const int lr_box_size = 15;
|
||||
static const int step_down = 10;
|
||||
static const int top_step = 2;
|
||||
|
||||
MonoPanner::ColorScheme MonoPanner::colors;
|
||||
bool MonoPanner::have_colors = false;
|
||||
|
||||
Pango::AttrList MonoPanner::panner_font_attributes;
|
||||
bool MonoPanner::have_font = false;
|
||||
|
||||
MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::PannerShell> p)
|
||||
: PannerInterface (p->panner())
|
||||
, _panner_shell (p)
|
||||
|
|
@ -73,27 +62,16 @@ MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::PannerShell> p)
|
|||
, position_binder (position_control)
|
||||
, _dragging (false)
|
||||
{
|
||||
if (!have_colors) {
|
||||
set_colors ();
|
||||
have_colors = true;
|
||||
}
|
||||
if (!have_font) {
|
||||
Pango::FontDescription font;
|
||||
Pango::AttrFontDesc* font_attr;
|
||||
font = Pango::FontDescription ("ArdourMono");
|
||||
font.set_weight (Pango::WEIGHT_BOLD);
|
||||
font.set_size(9 * PANGO_SCALE);
|
||||
font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
|
||||
panner_font_attributes.change(*font_attr);
|
||||
delete font_attr;
|
||||
have_font = true;
|
||||
if (_knob_image[0] == 0) {
|
||||
for (size_t i=0; i < (sizeof(_knob_image)/sizeof(_knob_image[0])); i++) {
|
||||
_knob_image[i] = load_pixbuf (_knob_image_files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context());
|
||||
|
||||
_panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::bypass_handler, this), gui_context());
|
||||
_panner_shell->PannableChanged.connect (panshell_connections, invalidator (*this), boost::bind (&MonoPanner::pannable_handler, this), gui_context());
|
||||
ColorsChanged.connect (sigc::mem_fun (*this, &MonoPanner::color_handler));
|
||||
|
||||
set_tooltip ();
|
||||
}
|
||||
|
|
@ -130,149 +108,16 @@ MonoPanner::set_tooltip ()
|
|||
bool
|
||||
MonoPanner::on_expose_event (GdkEventExpose*)
|
||||
{
|
||||
Glib::RefPtr<Gdk::Window> win (get_window());
|
||||
Glib::RefPtr<Gdk::GC> gc (get_style()->get_base_gc (get_state()));
|
||||
Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
|
||||
unsigned pos = (unsigned)(rint (100.0 * position_control->get_value ())); /* 0..100 */
|
||||
|
||||
int width, height;
|
||||
double pos = position_control->get_value (); /* 0..1 */
|
||||
uint32_t o, f, t, b, pf, po;
|
||||
const double corner_radius = 5;
|
||||
double x = (get_width() - _knob_image[pos]->get_width())/2.0;
|
||||
double y = (get_height() - _knob_image[pos]->get_height())/2.0;
|
||||
|
||||
width = get_width();
|
||||
height = get_height ();
|
||||
|
||||
o = colors.outline;
|
||||
f = colors.fill;
|
||||
t = colors.text;
|
||||
b = colors.background;
|
||||
pf = colors.pos_fill;
|
||||
po = colors.pos_outline;
|
||||
|
||||
if (_panner_shell->bypassed()) {
|
||||
b = 0x20202040;
|
||||
f = 0x404040ff;
|
||||
o = 0x606060ff;
|
||||
po = 0x606060ff;
|
||||
pf = 0x404040ff;
|
||||
t = 0x606060ff;
|
||||
}
|
||||
|
||||
/* background */
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b));
|
||||
context->rectangle (0, 0, width, height);
|
||||
context->fill ();
|
||||
|
||||
|
||||
double usable_width = width - pos_box_size;
|
||||
|
||||
/* compute the centers of the L/R boxes based on the current stereo width */
|
||||
if (fmod (usable_width,2.0) == 0) {
|
||||
usable_width -= 1.0;
|
||||
}
|
||||
const double half_lr_box = lr_box_size/2.0;
|
||||
const double left = 4 + half_lr_box; // center of left box
|
||||
const double right = width - 4 - half_lr_box; // center of right box
|
||||
|
||||
/* center line */
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->set_line_width (1.0);
|
||||
context->move_to ((pos_box_size/2.0) + (usable_width/2.0), 0);
|
||||
context->line_to ((pos_box_size/2.0) + (usable_width/2.0), height);
|
||||
context->stroke ();
|
||||
|
||||
context->set_line_width (1.0);
|
||||
/* left box */
|
||||
|
||||
rounded_left_half_rectangle (context,
|
||||
left - half_lr_box + .5,
|
||||
half_lr_box + step_down,
|
||||
lr_box_size, lr_box_size, corner_radius);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
|
||||
context->fill_preserve ();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->stroke();
|
||||
|
||||
/* add text */
|
||||
int tw, th;
|
||||
Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(get_pango_context());
|
||||
layout->set_attributes (panner_font_attributes);
|
||||
|
||||
layout->set_text (_("L"));
|
||||
layout->get_pixel_size(tw, th);
|
||||
context->move_to (rint(left - tw/2), rint(lr_box_size + step_down - th/2));
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
|
||||
pango_cairo_show_layout (context->cobj(), layout->gobj());
|
||||
|
||||
/* right box */
|
||||
rounded_right_half_rectangle (context,
|
||||
right - half_lr_box - .5,
|
||||
half_lr_box + step_down,
|
||||
lr_box_size, lr_box_size, corner_radius);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
|
||||
context->fill_preserve ();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->stroke();
|
||||
|
||||
/* add text */
|
||||
layout->set_text (_("R"));
|
||||
layout->get_pixel_size(tw, th);
|
||||
context->move_to (rint(right - tw/2), rint(lr_box_size + step_down - th/2));
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
|
||||
pango_cairo_show_layout (context->cobj(), layout->gobj());
|
||||
|
||||
/* 2 lines that connect them both */
|
||||
context->set_line_width (1.0);
|
||||
|
||||
if (_panner_shell->panner_gui_uri() != "http://ardour.org/plugin/panner_balance#ui") {
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->move_to (left + half_lr_box, half_lr_box + step_down);
|
||||
context->line_to (right - half_lr_box, half_lr_box + step_down);
|
||||
context->stroke ();
|
||||
|
||||
context->move_to (left + half_lr_box, half_lr_box+step_down+lr_box_size);
|
||||
context->line_to (right - half_lr_box, half_lr_box+step_down+lr_box_size);
|
||||
context->stroke ();
|
||||
} else {
|
||||
context->move_to (left + half_lr_box, half_lr_box+step_down+lr_box_size);
|
||||
context->line_to (left + half_lr_box, half_lr_box + step_down);
|
||||
context->line_to ((pos_box_size/2.0) + (usable_width/2.0), half_lr_box+step_down+lr_box_size);
|
||||
context->line_to (right - half_lr_box, half_lr_box + step_down);
|
||||
context->line_to (right - half_lr_box, half_lr_box+step_down+lr_box_size);
|
||||
context->close_path();
|
||||
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
|
||||
context->fill_preserve ();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->stroke ();
|
||||
}
|
||||
|
||||
/* draw the position indicator */
|
||||
double spos = (pos_box_size/2.0) + (usable_width * pos);
|
||||
|
||||
context->set_line_width (2.0);
|
||||
context->move_to (spos + (pos_box_size/2.0), top_step); /* top right */
|
||||
context->rel_line_to (0.0, pos_box_size); /* lower right */
|
||||
context->rel_line_to (-pos_box_size/2.0, 4.0); /* bottom point */
|
||||
context->rel_line_to (-pos_box_size/2.0, -4.0); /* lower left */
|
||||
context->rel_line_to (0.0, -pos_box_size); /* upper left */
|
||||
context->close_path ();
|
||||
|
||||
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(po), UINT_RGBA_G_FLT(po), UINT_RGBA_B_FLT(po), UINT_RGBA_A_FLT(po));
|
||||
context->stroke_preserve ();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(pf), UINT_RGBA_G_FLT(pf), UINT_RGBA_B_FLT(pf), UINT_RGBA_A_FLT(pf));
|
||||
context->fill ();
|
||||
|
||||
/* marker line */
|
||||
context->set_line_width (1.0);
|
||||
context->move_to (spos, pos_box_size + 5);
|
||||
context->rel_line_to (0, half_lr_box+step_down);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(po), UINT_RGBA_G_FLT(po), UINT_RGBA_B_FLT(po), UINT_RGBA_A_FLT(po));
|
||||
context->stroke ();
|
||||
|
||||
/* done */
|
||||
cairo_rectangle (context->cobj(), x, y, _knob_image[pos]->get_width(), _knob_image[pos]->get_height());
|
||||
|
||||
gdk_cairo_set_source_pixbuf (context->cobj(), _knob_image[pos]->gobj(), x, y);
|
||||
cairo_fill (context->cobj());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -482,24 +327,6 @@ MonoPanner::on_key_press_event (GdkEventKey* ev)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MonoPanner::set_colors ()
|
||||
{
|
||||
colors.fill = ARDOUR_UI::config()->get_canvasvar_MonoPannerFill();
|
||||
colors.outline = ARDOUR_UI::config()->get_canvasvar_MonoPannerOutline();
|
||||
colors.text = ARDOUR_UI::config()->get_canvasvar_MonoPannerText();
|
||||
colors.background = ARDOUR_UI::config()->get_canvasvar_MonoPannerBackground();
|
||||
colors.pos_outline = ARDOUR_UI::config()->get_canvasvar_MonoPannerPositionOutline();
|
||||
colors.pos_fill = ARDOUR_UI::config()->get_canvasvar_MonoPannerPositionFill();
|
||||
}
|
||||
|
||||
void
|
||||
MonoPanner::color_handler ()
|
||||
{
|
||||
set_colors ();
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
void
|
||||
MonoPanner::bypass_handler ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class MonoPanner : public PannerInterface
|
|||
MonoPanner (boost::shared_ptr<ARDOUR::PannerShell>);
|
||||
~MonoPanner ();
|
||||
|
||||
boost::shared_ptr<PBD::Controllable> get_controllable() const { return position_control; }
|
||||
boost::shared_ptr<PBD::Controllable> get_controllable() const { return position_control; }
|
||||
|
||||
sigc::signal<void> StartGesture;
|
||||
sigc::signal<void> StopGesture;
|
||||
|
|
@ -52,43 +52,27 @@ class MonoPanner : public PannerInterface
|
|||
bool on_button_press_event (GdkEventButton*);
|
||||
bool on_button_release_event (GdkEventButton*);
|
||||
bool on_motion_notify_event (GdkEventMotion*);
|
||||
bool on_scroll_event (GdkEventScroll*);
|
||||
bool on_key_press_event (GdkEventKey*);
|
||||
bool on_scroll_event (GdkEventScroll*);
|
||||
bool on_key_press_event (GdkEventKey*);
|
||||
|
||||
private:
|
||||
PannerEditor* editor ();
|
||||
boost::shared_ptr<ARDOUR::PannerShell> _panner_shell;
|
||||
|
||||
boost::shared_ptr<PBD::Controllable> position_control;
|
||||
PBD::ScopedConnectionList panvalue_connections;
|
||||
PBD::ScopedConnectionList panshell_connections;
|
||||
int drag_start_x;
|
||||
int last_drag_x;
|
||||
double accumulated_delta;
|
||||
bool detented;
|
||||
boost::shared_ptr<PBD::Controllable> position_control;
|
||||
PBD::ScopedConnectionList panvalue_connections;
|
||||
PBD::ScopedConnectionList panshell_connections;
|
||||
int drag_start_x;
|
||||
int last_drag_x;
|
||||
double accumulated_delta;
|
||||
bool detented;
|
||||
|
||||
BindingProxy position_binder;
|
||||
BindingProxy position_binder;
|
||||
|
||||
void set_tooltip ();
|
||||
|
||||
struct ColorScheme {
|
||||
uint32_t outline;
|
||||
uint32_t fill;
|
||||
uint32_t text;
|
||||
uint32_t background;
|
||||
uint32_t pos_outline;
|
||||
uint32_t pos_fill;
|
||||
};
|
||||
void set_tooltip ();
|
||||
|
||||
bool _dragging;
|
||||
|
||||
static Pango::AttrList panner_font_attributes;
|
||||
static bool have_font;
|
||||
|
||||
static ColorScheme colors;
|
||||
static void set_colors ();
|
||||
static bool have_colors;
|
||||
void color_handler ();
|
||||
void bypass_handler ();
|
||||
void pannable_handler ();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@
|
|||
#include <gtkmm.h>
|
||||
#include "gtkmm2ext/keyboard.h"
|
||||
#include "gtkmm2ext/persistent_tooltip.h"
|
||||
|
||||
#include "pbd/file_utils.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include "ardour/filesystem_paths.h"
|
||||
|
||||
#include "panner_interface.h"
|
||||
#include "panner_editor.h"
|
||||
#include "global_signals.h"
|
||||
|
|
@ -31,19 +37,59 @@ using namespace Gtk;
|
|||
using namespace ARDOUR;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
const char* PannerInterface::_knob_image_files[101] = {
|
||||
"001.png", "002.png", "003.png", "004.png", "005.png", "006.png", "007.png", "008.png", "009.png", "010.png",
|
||||
"011.png", "012.png", "013.png", "014.png", "015.png", "016.png", "017.png", "018.png", "019.png", "020.png",
|
||||
"021.png", "022.png", "023.png", "024.png", "025.png", "026.png", "027.png", "028.png", "029.png", "030.png",
|
||||
"031.png", "032.png", "033.png", "034.png", "035.png", "036.png", "037.png", "038.png", "039.png", "040.png",
|
||||
"041.png", "042.png", "043.png", "044.png", "045.png", "046.png", "047.png", "048.png", "049.png", "050.png",
|
||||
"051.png", "052.png", "053.png", "054.png", "055.png", "056.png", "057.png", "058.png", "059.png", "060.png",
|
||||
"061.png", "062.png", "063.png", "064.png", "065.png", "066.png", "067.png", "068.png", "069.png", "070.png",
|
||||
"071.png", "072.png", "073.png", "074.png", "075.png", "076.png", "077.png", "078.png", "079.png", "080.png",
|
||||
"081.png", "082.png", "083.png", "084.png", "085.png", "086.png", "087.png", "088.png", "089.png", "090.png",
|
||||
"091.png", "092.png", "093.png", "094.png", "095.png", "096.png", "097.png", "098.png", "099.png", "100.png",
|
||||
"101.png"
|
||||
};
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> PannerInterface::_knob_image[101];
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf>
|
||||
PannerInterface::load_pixbuf (const std::string& name)
|
||||
{
|
||||
PBD::Searchpath spath(ARDOUR::ardour_data_search_path());
|
||||
|
||||
spath.add_subdirectory_to_paths("icons/stereo_panner");
|
||||
|
||||
std::string data_file_path;
|
||||
|
||||
if (!PBD::find_file_in_search_path (spath, name, data_file_path)) {
|
||||
PBD::fatal << string_compose (_("cannot find icon image for %1 using %2"), name, spath.to_string()) << endmsg;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> img;
|
||||
try {
|
||||
img = Gdk::Pixbuf::create_from_file (data_file_path);
|
||||
} catch (const Gdk::PixbufError &e) {
|
||||
cerr << "Caught PixbufError: " << e.what() << endl;
|
||||
} catch (...) {
|
||||
PBD::error << string_compose (_("Caught exception while loading icon named %1"), name) << endmsg;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
PannerInterface::PannerInterface (boost::shared_ptr<Panner> p)
|
||||
: _panner (p)
|
||||
, _tooltip (this)
|
||||
, _editor (0)
|
||||
{
|
||||
set_flags (Gtk::CAN_FOCUS);
|
||||
|
||||
add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|
|
||||
Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|
|
||||
Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|
|
||||
Gdk::SCROLL_MASK|
|
||||
Gdk::POINTER_MOTION_MASK);
|
||||
set_flags (Gtk::CAN_FOCUS);
|
||||
|
||||
add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|
|
||||
Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|
|
||||
Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|
|
||||
Gdk::SCROLL_MASK|
|
||||
Gdk::POINTER_MOTION_MASK);
|
||||
}
|
||||
|
||||
PannerInterface::~PannerInterface ()
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ protected:
|
|||
|
||||
void value_change ();
|
||||
|
||||
bool on_enter_notify_event (GdkEventCrossing *);
|
||||
bool on_leave_notify_event (GdkEventCrossing *);
|
||||
bool on_enter_notify_event (GdkEventCrossing *);
|
||||
bool on_leave_notify_event (GdkEventCrossing *);
|
||||
bool on_key_release_event (GdkEventKey *);
|
||||
bool on_button_press_event (GdkEventButton*);
|
||||
bool on_button_release_event (GdkEventButton*);
|
||||
|
|
@ -74,6 +74,10 @@ protected:
|
|||
boost::shared_ptr<ARDOUR::Panner> _panner;
|
||||
PannerPersistentTooltip _tooltip;
|
||||
|
||||
static Glib::RefPtr<Gdk::Pixbuf> load_pixbuf (const std::string& name);
|
||||
static Glib::RefPtr<Gdk::Pixbuf> _knob_image[101];
|
||||
static const char* _knob_image_files[101];
|
||||
|
||||
private:
|
||||
virtual PannerEditor* editor () = 0;
|
||||
PannerEditor* _editor;
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ PannerUI::PannerUI (Session* s)
|
|||
pan_astate_menu = 0;
|
||||
pan_astyle_menu = 0;
|
||||
in_pan_update = false;
|
||||
_stereo_panner = 0;
|
||||
_stereo_panner = 0;
|
||||
_mono_panner = 0;
|
||||
_ignore_width_change = false;
|
||||
_ignore_position_change = false;
|
||||
_ignore_width_change = false;
|
||||
_ignore_position_change = false;
|
||||
|
||||
pan_automation_style_button.set_name ("MixerAutomationModeButton");
|
||||
pan_automation_state_button.set_name ("MixerAutomationPlaybackButton");
|
||||
|
|
@ -93,8 +93,8 @@ PannerUI::PannerUI (Session* s)
|
|||
void
|
||||
PannerUI::set_panner (boost::shared_ptr<PannerShell> ps, boost::shared_ptr<Panner> p)
|
||||
{
|
||||
/* note that the panshell might not change here (i.e. ps == _panshell)
|
||||
*/
|
||||
/* note that the panshell might not change here (i.e. ps == _panshell)
|
||||
*/
|
||||
|
||||
connections.drop_connections ();
|
||||
|
||||
|
|
@ -104,17 +104,17 @@ PannerUI::set_panner (boost::shared_ptr<PannerShell> ps, boost::shared_ptr<Panne
|
|||
delete pan_astate_menu;
|
||||
pan_astate_menu = 0;
|
||||
|
||||
_panshell = ps;
|
||||
_panshell = ps;
|
||||
_panner = p;
|
||||
|
||||
delete twod_panner;
|
||||
twod_panner = 0;
|
||||
|
||||
delete _stereo_panner;
|
||||
_stereo_panner = 0;
|
||||
delete _stereo_panner;
|
||||
_stereo_panner = 0;
|
||||
|
||||
delete _mono_panner;
|
||||
_mono_panner = 0;
|
||||
delete _mono_panner;
|
||||
_mono_panner = 0;
|
||||
|
||||
if (!_panner) {
|
||||
return;
|
||||
|
|
@ -122,13 +122,13 @@ PannerUI::set_panner (boost::shared_ptr<PannerShell> ps, boost::shared_ptr<Panne
|
|||
|
||||
_panshell->Changed.connect (connections, invalidator (*this), boost::bind (&PannerUI::panshell_changed, this), gui_context());
|
||||
|
||||
/* new panner object, force complete reset of panner GUI
|
||||
*/
|
||||
/* new panner object, force complete reset of panner GUI
|
||||
*/
|
||||
|
||||
_current_nouts = 0;
|
||||
_current_nins = 0;
|
||||
_current_nouts = 0;
|
||||
_current_nins = 0;
|
||||
|
||||
setup_pan ();
|
||||
setup_pan ();
|
||||
update_pan_sensitive ();
|
||||
pan_automation_state_changed ();
|
||||
}
|
||||
|
|
@ -198,8 +198,8 @@ PannerUI::~PannerUI ()
|
|||
delete pan_menu;
|
||||
delete pan_astyle_menu;
|
||||
delete pan_astate_menu;
|
||||
delete _stereo_panner;
|
||||
delete _mono_panner;
|
||||
delete _stereo_panner;
|
||||
delete _mono_panner;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -250,8 +250,8 @@ PannerUI::setup_pan ()
|
|||
boost::shared_ptr<Pannable> pannable = _panner->pannable();
|
||||
|
||||
_stereo_panner = new StereoPanner (_panshell);
|
||||
_stereo_panner->set_size_request (-1, pan_bar_height);
|
||||
pan_vbox.pack_start (*_stereo_panner, false, false);
|
||||
// _stereo_panner->set_size_request (-1, pan_bar_height);
|
||||
pan_vbox.pack_start (*_stereo_panner, true, true);
|
||||
|
||||
boost::shared_ptr<AutomationControl> ac;
|
||||
|
||||
|
|
@ -285,10 +285,10 @@ PannerUI::setup_pan ()
|
|||
|
||||
_mono_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event));
|
||||
|
||||
_mono_panner->set_size_request (-1, pan_bar_height);
|
||||
// _mono_panner->set_size_request (-1, pan_bar_height);
|
||||
|
||||
update_pan_sensitive ();
|
||||
pan_vbox.pack_start (*_mono_panner, false, false);
|
||||
pan_vbox.pack_start (*_mono_panner, true, true);
|
||||
}
|
||||
else if (_current_uri == "http://ardour.org/plugin/panner_vbap#ui")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,17 +50,6 @@ using namespace std;
|
|||
using namespace Gtk;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
static const int pos_box_size = 8;
|
||||
static const int lr_box_size = 15;
|
||||
static const int step_down = 10;
|
||||
static const int top_step = 2;
|
||||
|
||||
StereoPanner::ColorScheme StereoPanner::colors[3];
|
||||
bool StereoPanner::have_colors = false;
|
||||
|
||||
Pango::AttrList StereoPanner::panner_font_attributes;
|
||||
bool StereoPanner::have_font = false;
|
||||
|
||||
using namespace ARDOUR;
|
||||
|
||||
StereoPanner::StereoPanner (boost::shared_ptr<PannerShell> p)
|
||||
|
|
@ -79,20 +68,10 @@ StereoPanner::StereoPanner (boost::shared_ptr<PannerShell> p)
|
|||
, width_binder (width_control)
|
||||
, _dragging (false)
|
||||
{
|
||||
if (!have_colors) {
|
||||
set_colors ();
|
||||
have_colors = true;
|
||||
}
|
||||
if (!have_font) {
|
||||
Pango::FontDescription font;
|
||||
Pango::AttrFontDesc* font_attr;
|
||||
font = Pango::FontDescription ("ArdourMono");
|
||||
font.set_weight (Pango::WEIGHT_BOLD);
|
||||
font.set_size(9 * PANGO_SCALE);
|
||||
font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
|
||||
panner_font_attributes.change(*font_attr);
|
||||
delete font_attr;
|
||||
have_font = true;
|
||||
if (_knob_image[0] == 0) {
|
||||
for (size_t i=0; i < (sizeof(_knob_image)/sizeof(_knob_image[0])); i++) {
|
||||
_knob_image[i] = load_pixbuf (_knob_image_files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
position_control->Changed.connect (panvalue_connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
|
||||
|
|
@ -101,8 +80,6 @@ StereoPanner::StereoPanner (boost::shared_ptr<PannerShell> p)
|
|||
_panner_shell->Changed.connect (panshell_connections, invalidator (*this), boost::bind (&StereoPanner::bypass_handler, this), gui_context());
|
||||
_panner_shell->PannableChanged.connect (panshell_connections, invalidator (*this), boost::bind (&StereoPanner::pannable_handler, this), gui_context());
|
||||
|
||||
ColorsChanged.connect (sigc::mem_fun (*this, &StereoPanner::color_handler));
|
||||
|
||||
set_tooltip ();
|
||||
}
|
||||
|
||||
|
|
@ -138,155 +115,16 @@ StereoPanner::set_tooltip ()
|
|||
bool
|
||||
StereoPanner::on_expose_event (GdkEventExpose*)
|
||||
{
|
||||
Glib::RefPtr<Gdk::Window> win (get_window());
|
||||
Glib::RefPtr<Gdk::GC> gc (get_style()->get_base_gc (get_state()));
|
||||
Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
|
||||
Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(get_pango_context());
|
||||
layout->set_attributes (panner_font_attributes);
|
||||
unsigned pos = (unsigned)(rint (100.0 * position_control->get_value ())); /* 0..100 */
|
||||
|
||||
int tw, th;
|
||||
int width, height;
|
||||
const double pos = position_control->get_value (); /* 0..1 */
|
||||
const double swidth = width_control->get_value (); /* -1..+1 */
|
||||
const double fswidth = fabs (swidth);
|
||||
const double corner_radius = 5.0;
|
||||
uint32_t o, f, t, b, r;
|
||||
State state;
|
||||
double x = (get_width() - _knob_image[pos]->get_width())/2.0;
|
||||
double y = (get_height() - _knob_image[pos]->get_height())/2.0;
|
||||
|
||||
width = get_width();
|
||||
height = get_height ();
|
||||
|
||||
if (swidth == 0.0) {
|
||||
state = Mono;
|
||||
} else if (swidth < 0.0) {
|
||||
state = Inverted;
|
||||
} else {
|
||||
state = Normal;
|
||||
}
|
||||
|
||||
o = colors[state].outline;
|
||||
f = colors[state].fill;
|
||||
t = colors[state].text;
|
||||
b = colors[state].background;
|
||||
r = colors[state].rule;
|
||||
|
||||
if (_panner_shell->bypassed()) {
|
||||
b = 0x20202040;
|
||||
f = 0x404040ff;
|
||||
o = 0x606060ff;
|
||||
t = 0x606060ff;
|
||||
r = 0x606060ff;
|
||||
}
|
||||
|
||||
/* background */
|
||||
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b));
|
||||
cairo_rectangle (context->cobj(), 0, 0, width, height);
|
||||
context->fill_preserve ();
|
||||
context->clip();
|
||||
|
||||
/* the usable width is reduced from the real width, because we need space for
|
||||
the two halves of LR boxes that will extend past the actual left/right
|
||||
positions (indicated by the vertical line segment above them).
|
||||
*/
|
||||
|
||||
double usable_width = width - lr_box_size;
|
||||
|
||||
/* compute the centers of the L/R boxes based on the current stereo width */
|
||||
|
||||
if (fmod (usable_width,2.0) == 0) {
|
||||
/* even width, but we need odd, so that there is an exact center.
|
||||
So, offset cairo by 1, and reduce effective width by 1
|
||||
*/
|
||||
usable_width -= 1.0;
|
||||
context->translate (1.0, 0.0);
|
||||
}
|
||||
|
||||
const double half_lr_box = lr_box_size/2.0;
|
||||
const double center = rint(half_lr_box + (usable_width * pos));
|
||||
const double pan_spread = rint((fswidth * (usable_width-1.0))/2.0);
|
||||
const double left = center - pan_spread;
|
||||
const double right = center + pan_spread;
|
||||
|
||||
/* center line */
|
||||
context->set_line_width (1.0);
|
||||
context->move_to ((usable_width + lr_box_size)/2.0, 0);
|
||||
context->rel_line_to (0, height);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(r), UINT_RGBA_G_FLT(r), UINT_RGBA_B_FLT(r), UINT_RGBA_A_FLT(r));
|
||||
context->stroke ();
|
||||
|
||||
/* compute & draw the line through the box */
|
||||
context->set_line_width (2);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->move_to (left, top_step + (pos_box_size/2.0) + step_down + 1.0);
|
||||
context->line_to (left, top_step + (pos_box_size/2.0));
|
||||
context->line_to (right, top_step + (pos_box_size/2.0));
|
||||
context->line_to (right, top_step + (pos_box_size/2.0) + step_down + 1.0);
|
||||
context->stroke ();
|
||||
|
||||
context->set_line_width (1.0);
|
||||
|
||||
/* left box */
|
||||
if (state != Mono) {
|
||||
rounded_rectangle (context, left - half_lr_box,
|
||||
half_lr_box+step_down,
|
||||
lr_box_size, lr_box_size, corner_radius);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
|
||||
context->fill_preserve();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->stroke();
|
||||
|
||||
/* add text */
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
|
||||
if (swidth < 0.0) {
|
||||
layout->set_text (_("R"));
|
||||
} else {
|
||||
layout->set_text (_("L"));
|
||||
}
|
||||
layout->get_pixel_size(tw, th);
|
||||
context->move_to (rint(left - tw/2), rint(lr_box_size + step_down - th/2));
|
||||
pango_cairo_show_layout (context->cobj(), layout->gobj());
|
||||
}
|
||||
|
||||
/* right box */
|
||||
rounded_rectangle (context, right - half_lr_box,
|
||||
half_lr_box+step_down,
|
||||
lr_box_size, lr_box_size, corner_radius);
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
|
||||
context->fill_preserve();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->stroke();
|
||||
|
||||
/* add text */
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
|
||||
|
||||
if (state == Mono) {
|
||||
layout->set_text (_("M"));
|
||||
} else {
|
||||
if (swidth < 0.0) {
|
||||
layout->set_text (_("L"));
|
||||
} else {
|
||||
layout->set_text (_("R"));
|
||||
}
|
||||
}
|
||||
layout->get_pixel_size(tw, th);
|
||||
context->move_to (rint(right - tw/2), rint(lr_box_size + step_down - th/2));
|
||||
pango_cairo_show_layout (context->cobj(), layout->gobj());
|
||||
|
||||
/* draw the central box */
|
||||
context->set_line_width (2.0);
|
||||
context->move_to (center + (pos_box_size/2.0), top_step); /* top right */
|
||||
context->rel_line_to (0.0, pos_box_size); /* lower right */
|
||||
context->rel_line_to (-pos_box_size/2.0, 4.0); /* bottom point */
|
||||
context->rel_line_to (-pos_box_size/2.0, -4.0); /* lower left */
|
||||
context->rel_line_to (0.0, -pos_box_size); /* upper left */
|
||||
context->close_path ();
|
||||
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
|
||||
context->stroke_preserve ();
|
||||
context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
|
||||
context->fill ();
|
||||
cairo_rectangle (context->cobj(), x, y, _knob_image[pos]->get_width(), _knob_image[pos]->get_height());
|
||||
|
||||
gdk_cairo_set_source_pixbuf (context->cobj(), _knob_image[pos]->gobj(), x, y);
|
||||
cairo_fill (context->cobj());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -405,19 +243,18 @@ StereoPanner::on_button_press_event (GdkEventButton* ev)
|
|||
double pos = position_control->get_value (); /* 0..1 */
|
||||
double swidth = width_control->get_value (); /* -1..+1 */
|
||||
double fswidth = fabs (swidth);
|
||||
int usable_width = get_width() - lr_box_size;
|
||||
double center = (lr_box_size/2.0) + (usable_width * pos);
|
||||
int usable_width = get_width();
|
||||
double center = usable_width * pos;
|
||||
int left = lrint (center - (fswidth * usable_width / 2.0)); // center of leftmost box
|
||||
int right = lrint (center + (fswidth * usable_width / 2.0)); // center of rightmost box
|
||||
const int half_box = lr_box_size/2;
|
||||
|
||||
if (ev->x >= (left - half_box) && ev->x < (left + half_box)) {
|
||||
if (ev->x >= left && ev->x < left) {
|
||||
if (swidth < 0.0) {
|
||||
dragging_right = true;
|
||||
} else {
|
||||
dragging_left = true;
|
||||
}
|
||||
} else if (ev->x >= (right - half_box) && ev->x < (right + half_box)) {
|
||||
} else if (ev->x >= right && ev->x < right) {
|
||||
if (swidth < 0.0) {
|
||||
dragging_left = true;
|
||||
} else {
|
||||
|
|
@ -522,7 +359,7 @@ StereoPanner::on_motion_notify_event (GdkEventMotion* ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
int usable_width = get_width() - lr_box_size;
|
||||
int usable_width = get_width();
|
||||
double delta = (ev->x - last_drag_x) / (double) usable_width;
|
||||
double current_width = width_control->get_value ();
|
||||
|
||||
|
|
@ -660,35 +497,6 @@ StereoPanner::on_key_press_event (GdkEventKey* ev)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StereoPanner::set_colors ()
|
||||
{
|
||||
colors[Normal].fill = ARDOUR_UI::config()->get_canvasvar_StereoPannerFill();
|
||||
colors[Normal].outline = ARDOUR_UI::config()->get_canvasvar_StereoPannerOutline();
|
||||
colors[Normal].text = ARDOUR_UI::config()->get_canvasvar_StereoPannerText();
|
||||
colors[Normal].background = ARDOUR_UI::config()->get_canvasvar_StereoPannerBackground();
|
||||
colors[Normal].rule = ARDOUR_UI::config()->get_canvasvar_StereoPannerRule();
|
||||
|
||||
colors[Mono].fill = ARDOUR_UI::config()->get_canvasvar_StereoPannerMonoFill();
|
||||
colors[Mono].outline = ARDOUR_UI::config()->get_canvasvar_StereoPannerMonoOutline();
|
||||
colors[Mono].text = ARDOUR_UI::config()->get_canvasvar_StereoPannerMonoText();
|
||||
colors[Mono].background = ARDOUR_UI::config()->get_canvasvar_StereoPannerMonoBackground();
|
||||
colors[Mono].rule = ARDOUR_UI::config()->get_canvasvar_StereoPannerRule();
|
||||
|
||||
colors[Inverted].fill = ARDOUR_UI::config()->get_canvasvar_StereoPannerInvertedFill();
|
||||
colors[Inverted].outline = ARDOUR_UI::config()->get_canvasvar_StereoPannerInvertedOutline();
|
||||
colors[Inverted].text = ARDOUR_UI::config()->get_canvasvar_StereoPannerInvertedText();
|
||||
colors[Inverted].background = ARDOUR_UI::config()->get_canvasvar_StereoPannerInvertedBackground();
|
||||
colors[Inverted].rule = ARDOUR_UI::config()->get_canvasvar_StereoPannerRule();
|
||||
}
|
||||
|
||||
void
|
||||
StereoPanner::color_handler ()
|
||||
{
|
||||
set_colors ();
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
void
|
||||
StereoPanner::bypass_handler ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,54 +55,39 @@ class StereoPanner : public PannerInterface
|
|||
bool on_button_press_event (GdkEventButton*);
|
||||
bool on_button_release_event (GdkEventButton*);
|
||||
bool on_motion_notify_event (GdkEventMotion*);
|
||||
bool on_scroll_event (GdkEventScroll*);
|
||||
bool on_key_press_event (GdkEventKey*);
|
||||
bool on_scroll_event (GdkEventScroll*);
|
||||
bool on_key_press_event (GdkEventKey*);
|
||||
|
||||
private:
|
||||
PannerEditor* editor ();
|
||||
boost::shared_ptr<ARDOUR::PannerShell> _panner_shell;
|
||||
|
||||
boost::shared_ptr<PBD::Controllable> position_control;
|
||||
boost::shared_ptr<PBD::Controllable> width_control;
|
||||
PBD::ScopedConnectionList panvalue_connections;
|
||||
PBD::ScopedConnectionList panshell_connections;
|
||||
bool dragging;
|
||||
bool dragging_position;
|
||||
bool dragging_left;
|
||||
bool dragging_right;
|
||||
int drag_start_x;
|
||||
int last_drag_x;
|
||||
double accumulated_delta;
|
||||
bool detented;
|
||||
boost::shared_ptr<PBD::Controllable> position_control;
|
||||
boost::shared_ptr<PBD::Controllable> width_control;
|
||||
PBD::ScopedConnectionList panvalue_connections;
|
||||
PBD::ScopedConnectionList panshell_connections;
|
||||
bool dragging;
|
||||
bool dragging_position;
|
||||
bool dragging_left;
|
||||
bool dragging_right;
|
||||
int drag_start_x;
|
||||
int last_drag_x;
|
||||
double accumulated_delta;
|
||||
bool detented;
|
||||
|
||||
BindingProxy position_binder;
|
||||
BindingProxy width_binder;
|
||||
BindingProxy position_binder;
|
||||
BindingProxy width_binder;
|
||||
|
||||
void set_tooltip ();
|
||||
void set_tooltip ();
|
||||
|
||||
struct ColorScheme {
|
||||
uint32_t outline;
|
||||
uint32_t fill;
|
||||
uint32_t text;
|
||||
uint32_t background;
|
||||
uint32_t rule;
|
||||
};
|
||||
|
||||
enum State {
|
||||
Normal,
|
||||
Mono,
|
||||
Inverted
|
||||
};
|
||||
enum State {
|
||||
Normal,
|
||||
Mono,
|
||||
Inverted
|
||||
};
|
||||
|
||||
bool _dragging;
|
||||
|
||||
static Pango::AttrList panner_font_attributes;
|
||||
static bool have_font;
|
||||
|
||||
static ColorScheme colors[3];
|
||||
static void set_colors ();
|
||||
static bool have_colors;
|
||||
void color_handler ();
|
||||
void bypass_handler ();
|
||||
void pannable_handler ();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue