Closes #150: Zoom in/out with mouse scroll wheel.

develop
Kolan Sh 2018-01-23 21:55:45 +03:00
parent 6bb5fcce57
commit 76b51db49e
2 changed files with 66 additions and 8 deletions

View File

@ -45,6 +45,11 @@ namespace CairoChart {
*/ */
public LineStyle selection_style = LineStyle (); public LineStyle selection_style = LineStyle ();
/**
* Zoom Scroll speed.
*/
public double zoom_scroll_speed = 64.0;
/** /**
* Plot area bounds. * Plot area bounds.
*/ */
@ -182,7 +187,7 @@ namespace CairoChart {
} }
/** /**
* Zooms the ``Chart``. * Zooms in the ``Chart``.
* @param area selected zoom area. * @param area selected zoom area.
*/ */
public virtual void zoom_in (Area area) { public virtual void zoom_in (Area area) {
@ -262,6 +267,8 @@ namespace CairoChart {
public virtual void move (Point delta) { public virtual void move (Point delta) {
var d = delta; var d = delta;
if (plarea.width.abs() < 1 || plarea.height.abs() < 1) return;
d.x /= -plarea.width; d.y /= -plarea.height; d.x /= -plarea.width; d.y /= -plarea.height;
var z = zoom.copy(); var z = zoom.copy();
@ -277,13 +284,10 @@ namespace CairoChart {
d.x *= z.width; d.y *= z.height; d.x *= z.width; d.y *= z.height;
var px1 = plarea.x1;
var py1 = plarea.y1;
if (x0 + d.x < plarea.x0) d.x = plarea.x0 - x0; if (x0 + d.x < plarea.x0) d.x = plarea.x0 - x0;
if (x1 + d.x > px1) d.x = px1 - x1; if (x1 + d.x > plarea.x1) d.x = plarea.x1 - x1;
if (y0 + d.y < plarea.y0) d.y = plarea.y0 - y0; if (y0 + d.y < plarea.y0) d.y = plarea.y0 - y0;
if (y1 + d.y > py1) d.y = py1 - y1; if (y1 + d.y > plarea.y1) d.y = plarea.y1 - y1;
zoom_in( zoom_in(
new Area.with_rel( new Area.with_rel(
@ -295,6 +299,52 @@ namespace CairoChart {
); );
} }
/**
* Zooms in the ``Chart`` by event point (scrolling).
* @param p event position.
*/
public virtual void zoom_scroll_in (Point p) {
var w = plarea.width, h = plarea.height;
if (w < 8 || h < 8) return;
zoom_in (
new Area.with_abs(
plarea.x0 + (p.x - plarea.x0) / w * zoom_scroll_speed,
plarea.y0 + (p.y - plarea.y0) / h * zoom_scroll_speed,
plarea.x1 - (plarea.x1 - p.x) / w * zoom_scroll_speed,
plarea.y1 - (plarea.y1 - p.y) / h * zoom_scroll_speed
)
);
}
/**
* Zooms out the ``Chart`` by event point (scrolling).
* @param p event position.
*/
public virtual void zoom_scroll_out (Point p) {
var z = zoom.copy(), pa = plarea.copy();
var w = plarea.width, h = plarea.height;
if (w < 8 || h < 8) return;
zoom_out();
var x0 = plarea.x0 + plarea.width * z.x0;
var x1 = plarea.x0 + plarea.width * z.x1;
var y0 = plarea.y0 + plarea.height * z.y0;
var y1 = plarea.y0 + plarea.height * z.y1;
var dx0 = (p.x - pa.x0) / w * zoom_scroll_speed;
var dx1 = (pa.x1 - p.x) / w * zoom_scroll_speed;
var dy0 = (p.y - pa.y0) / h * zoom_scroll_speed;
var dy1 = (pa.y1 - p.y) / h * zoom_scroll_speed;
if (x0 - dx0 < plarea.x0) x0 = plarea.x0; else x0 -= dx0;
if (x1 + dx1 > plarea.x1) x1 = plarea.x1; else x1 += dx1;
if (y0 - dy0 < plarea.y0) y0 = plarea.y0; else y0 -= dy0;
if (y1 + dy1 > plarea.y1) y1 = plarea.y1; else y1 += dy1;
zoom_in (new Area.with_abs(x0, y0, x1, y1));
}
protected virtual void fix_evarea () { protected virtual void fix_evarea () {
if (evarea.width < 0) evarea.width = 0; if (evarea.width < 0) evarea.width = 0;
if (evarea.height < 0) evarea.height = 0; if (evarea.height < 0) evarea.height = 0;

View File

@ -287,6 +287,7 @@ int main (string[] args) {
da.set_events ( Gdk.EventMask.BUTTON_PRESS_MASK da.set_events ( Gdk.EventMask.BUTTON_PRESS_MASK
|Gdk.EventMask.BUTTON_RELEASE_MASK |Gdk.EventMask.BUTTON_RELEASE_MASK
|Gdk.EventMask.POINTER_MOTION_MASK |Gdk.EventMask.POINTER_MOTION_MASK
|Gdk.EventMask.SCROLL_MASK
); );
var chart = chart1; var chart = chart1;
@ -571,11 +572,18 @@ int main (string[] args) {
return true; // return ret; return true; // return ret;
}); });
da.add_events(Gdk.EventMask.SCROLL_MASK);
da.scroll_event.connect((event) => { da.scroll_event.connect((event) => {
switch (event.direction) {
case Gdk.ScrollDirection.UP:
chart.zoom_scroll_in(Point(event.x, event.y));
break;
case Gdk.ScrollDirection.DOWN:
chart.zoom_scroll_out(Point(event.x, event.y));
break;
}
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
//var ret = chart.scroll_notify_event(event); //var ret = chart.scroll_notify_event(event);
return true; // return ret; return true; // return ret;
}); });