, _orien (orientation)
, _pattern (0)
, _hovering (false)
- , _last_drawn (-1)
, _dragging (false)
, _centered_text (true)
, _current_parent (0)
_adjustment.signal_value_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
_adjustment.signal_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
-
+ signal_grab_broken_event ().connect (mem_fun (*this, &PixFader::on_grab_broken_event));
if (_orien == VERT) {
- DrawingArea::set_size_request(_girth, _span);
+ CairoWidget::set_size_request(_girth, _span);
} else {
- DrawingArea::set_size_request(_span, _girth);
+ CairoWidget::set_size_request(_span, _girth);
}
}
if (_layout) _layout.clear (); // drop reference to existing layout
}
+void
+PixFader::flush_pattern_cache () {
+ for (list<FaderImage*>::iterator f = _patterns.begin(); f != _patterns.end(); ++f) {
+ cairo_pattern_destroy ((*f)->pattern);
+ }
+ _patterns.clear();
+}
+
+
cairo_pattern_t*
PixFader::find_pattern (double afr, double afg, double afb,
double abr, double abg, double abb,
cairo_surface_destroy (surface);
}
-bool
-PixFader::on_expose_event (GdkEventExpose* ev)
+void
+PixFader::render (cairo_t *cr, cairo_rectangle_t* area)
{
- Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
- cairo_t* cr = context->cobj();
-
- // clip to expose area
- cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
- cairo_clip (cr);
-
if (!_pattern) {
create_patterns();
}
*/
CairoWidget::set_source_rgb_a (cr, get_style()->get_bg (get_state()), 1);
- cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+ cairo_rectangle (cr, area->x, area->y, area->width, area->height);
cairo_fill (cr);
- return true;
+ return;
}
OnExpose();
/* draw the unity-position line if it's not at either end*/
if (!(_tweaks & NoShowUnityLine) && _unity_loc > CORNER_RADIUS) {
- context->set_line_width (1);
- context->set_line_cap (Cairo::LINE_CAP_ROUND);
+ cairo_set_line_width(cr, 1);
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
Gdk::Color c = get_style()->get_fg (Gtk::STATE_ACTIVE);
- context->set_source_rgba (c.get_red_p() * 1.5, c.get_green_p() * 1.5, c.get_blue_p() * 1.5, 0.85);
+ cairo_set_source_rgba (cr, c.get_red_p() * 1.5, c.get_green_p() * 1.5, c.get_blue_p() * 1.5, 0.85);
if (_orien == VERT) {
if (_unity_loc < h - CORNER_RADIUS) {
- context->move_to (1.5, _unity_loc + CORNER_OFFSET + .5);
- context->line_to (_girth - 1.5, _unity_loc + CORNER_OFFSET + .5);
- context->stroke ();
+ cairo_move_to (cr, 1.5, _unity_loc + CORNER_OFFSET + .5);
+ cairo_line_to (cr, _girth - 1.5, _unity_loc + CORNER_OFFSET + .5);
+ cairo_stroke (cr);
}
} else {
if (_unity_loc < w - CORNER_RADIUS) {
- context->move_to (_unity_loc - CORNER_OFFSET + .5, 1.5);
- context->line_to (_unity_loc - CORNER_OFFSET + .5, _girth - 1.5);
- context->stroke ();
+ cairo_move_to (cr, _unity_loc - CORNER_OFFSET + .5, 1.5);
+ cairo_line_to (cr, _unity_loc - CORNER_OFFSET + .5, _girth - 1.5);
+ cairo_stroke (cr);
}
}
}
Gtkmm2ext::rounded_rectangle (cr, CORNER_OFFSET, CORNER_OFFSET, w-CORNER_SIZE, h-CORNER_SIZE, CORNER_RADIUS);
cairo_set_source_rgba (cr, 0.505, 0.517, 0.525, 0.4);
cairo_fill (cr);
- } else if (_hovering) {
+ } else if (_hovering && CairoWidget::widget_prelight()) {
Gtkmm2ext::rounded_rectangle (cr, CORNER_OFFSET, CORNER_OFFSET, w-CORNER_SIZE, h-CORNER_SIZE, CORNER_RADIUS);
cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.1);
cairo_fill (cr);
}
-
- _last_drawn = ds;
-
- return true;
}
void
void
PixFader::on_size_allocate (Gtk::Allocation& alloc)
{
- DrawingArea::on_size_allocate(alloc);
+ int old_girth = _girth;
+ int old_span = _span;
+
+ CairoWidget::on_size_allocate(alloc);
if (_orien == VERT) {
_girth = alloc.get_width ();
_span = alloc.get_width ();
}
- if (is_realized()) {
+ if (is_realized() && ((old_girth != _girth) || (old_span != _span))) {
/* recreate patterns in case we've changed size */
create_patterns ();
}
update_unity_position ();
}
+bool
+PixFader::on_grab_broken_event (GdkEventGrabBroken* ev)
+{
+ if (_dragging) {
+ remove_modal_grab();
+ _dragging = false;
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ StopGesture ();
+ }
+ return (_tweaks & NoButtonForward) ? true : false;
+}
+
bool
PixFader::on_button_press_event (GdkEventButton* ev)
{
if (ev_pos == _grab_start) {
/* no motion - just a click */
- const double slider_pos = display_span();
ev_pos = rint(ev_pos);
if (ev->state & Keyboard::TertiaryModifier) {
_adjustment.set_value (_default_value);
} else if (ev->state & Keyboard::GainFineScaleModifier) {
_adjustment.set_value (_adjustment.get_lower());
+#if 0 // ignore clicks
} else if (ev_pos == slider_pos) {
; // click on current position, no move.
} else if ((_orien == VERT && ev_pos < slider_pos) || (_orien == HORIZ && ev_pos > slider_pos)) {
_adjustment.set_value (_adjustment.get_value() + _adjustment.get_step_increment());
} else {
_adjustment.set_value (_adjustment.get_value() - _adjustment.get_step_increment());
+#endif
}
}
return true;
if (ev->state & Keyboard::GainFineScaleModifier) {
if (ev->state & Keyboard::GainExtraFineScaleModifier) {
- scale = 0.01;
+ scale = 0.005;
} else {
- scale = 0.05;
+ scale = 0.1;
}
} else {
- scale = 0.25;
+ scale = 1.0;
}
if (_orien == VERT) {
if (ev->state & Keyboard::GainFineScaleModifier) {
if (ev->state & Keyboard::GainExtraFineScaleModifier) {
- scale = 0.05;
+ scale = 0.005;
} else {
scale = 0.1;
}
double const delta = ev_pos - _grab_loc;
_grab_loc = ev_pos;
- double fract = (delta / _span);
+ const double off = FADER_RESERVE + ((_orien == VERT) ? CORNER_OFFSET : 0);
+ const double span = _span - off;
+ double fract = (delta / span);
fract = min (1.0, fract);
fract = max (-1.0, fract);
void
PixFader::adjustment_changed ()
{
- if (display_span() != _last_drawn) {
- queue_draw ();
- }
+ queue_draw ();
}
/** @return pixel offset of the current value from the right or bottom of the fader */
float fract = (_adjustment.get_value () - _adjustment.get_lower()) / ((_adjustment.get_upper() - _adjustment.get_lower()));
int ds;
if (_orien == VERT) {
- ds = (int)rint (_span * (1.0 - fract));
+ const double off = FADER_RESERVE + CORNER_OFFSET;
+ const double span = _span - off;
+ ds = (int)rint (span * (1.0 - fract));
} else {
- ds = (int)rint (_span * fract);
+ const double off = FADER_RESERVE;
+ const double span = _span - off;
+ ds = (int)rint (span * fract + off);
}
return ds;
PixFader::update_unity_position ()
{
if (_orien == VERT) {
- _unity_loc = (int) rint (_span * (1 - ((_default_value - _adjustment.get_lower()) / (_adjustment.get_upper() - _adjustment.get_lower())))) - 1;
+ const double span = _span - FADER_RESERVE - CORNER_OFFSET;
+ _unity_loc = (int) rint (span * (1 - ((_default_value - _adjustment.get_lower()) / (_adjustment.get_upper() - _adjustment.get_lower())))) - 1;
} else {
- _unity_loc = (int) rint ((_default_value - _adjustment.get_lower()) * _span / (_adjustment.get_upper() - _adjustment.get_lower()));
+ const double span = _span - FADER_RESERVE;
+ _unity_loc = (int) rint (FADER_RESERVE + (_default_value - _adjustment.get_lower()) * span / (_adjustment.get_upper() - _adjustment.get_lower()));
}
queue_draw ();
void
PixFader::set_adjustment_from_event (GdkEventButton* ev)
{
- double fract = (_orien == VERT) ? (1.0 - (ev->y / _span)) : (ev->x / _span);
+ const double off = FADER_RESERVE + ((_orien == VERT) ? CORNER_OFFSET : 0);
+ const double span = _span - off;
+ double fract = (_orien == VERT) ? (1.0 - ((ev->y - off) / span)) : ((ev->x - off) / span);
fract = min (1.0, fract);
fract = max (0.0, fract);
_text = "";
set_text (txt, _centered_text, false);
}
- /* patterns are cached and re-created as needed
+ /* patterns are cached and re-created as needed
* during 'expose' in the GUI thread */
_pattern = 0;
queue_draw ();