Browse Source

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

tags/v0.2.0^2
Kolan Sh 1 year ago
parent
commit
76b51db49e
2 changed files with 66 additions and 8 deletions
  1. 56
    6
      src/Chart.vala
  2. 10
    2
      test/ChartTest.vala

+ 56
- 6
src/Chart.vala View File

@@ -45,6 +45,11 @@ namespace CairoChart {
45 45
 		 */
46 46
 		public LineStyle selection_style = LineStyle ();
47 47
 
48
+		/**
49
+		 * Zoom Scroll speed.
50
+		 */
51
+		public double zoom_scroll_speed = 64.0;
52
+
48 53
 		/**
49 54
 		 * Plot area bounds.
50 55
 		 */
@@ -182,7 +187,7 @@ namespace CairoChart {
182 187
 		}
183 188
 
184 189
 		/**
185
-		 * Zooms the ``Chart``.
190
+		 * Zooms in the ``Chart``.
186 191
 		 * @param area selected zoom area.
187 192
 		 */
188 193
 		public virtual void zoom_in (Area area) {
@@ -262,6 +267,8 @@ namespace CairoChart {
262 267
 		public virtual void move (Point delta) {
263 268
 			var d = delta;
264 269
 
270
+			if (plarea.width.abs() < 1 || plarea.height.abs() < 1) return;
271
+
265 272
 			d.x /= -plarea.width; d.y /= -plarea.height;
266 273
 
267 274
 			var z = zoom.copy();
@@ -277,13 +284,10 @@ namespace CairoChart {
277 284
 
278 285
 			d.x *= z.width; d.y *= z.height;
279 286
 
280
-			var px1 = plarea.x1;
281
-			var py1 = plarea.y1;
282
-
283 287
 			if (x0 + d.x < plarea.x0) d.x = plarea.x0 - x0;
284
-			if (x1 + d.x > px1) d.x = px1 - x1;
288
+			if (x1 + d.x > plarea.x1) d.x = plarea.x1 - x1;
285 289
 			if (y0 + d.y < plarea.y0) d.y = plarea.y0 - y0;
286
-			if (y1 + d.y > py1) d.y = py1 - y1;
290
+			if (y1 + d.y > plarea.y1) d.y = plarea.y1 - y1;
287 291
 
288 292
 			zoom_in(
289 293
 				new Area.with_rel(
@@ -295,6 +299,52 @@ namespace CairoChart {
295 299
 			);
296 300
 		}
297 301
 
302
+		/**
303
+		 * Zooms in the ``Chart`` by event point (scrolling).
304
+		 * @param p event position.
305
+		 */
306
+		public virtual void zoom_scroll_in (Point p) {
307
+			var w = plarea.width, h = plarea.height;
308
+			if (w < 8 || h < 8) return;
309
+			zoom_in (
310
+				new Area.with_abs(
311
+					plarea.x0 + (p.x - plarea.x0) / w * zoom_scroll_speed,
312
+					plarea.y0 + (p.y - plarea.y0) / h * zoom_scroll_speed,
313
+					plarea.x1 - (plarea.x1 - p.x) / w * zoom_scroll_speed,
314
+					plarea.y1 - (plarea.y1 - p.y) / h * zoom_scroll_speed
315
+				)
316
+			);
317
+		}
318
+
319
+		/**
320
+		 * Zooms out the ``Chart`` by event point (scrolling).
321
+		 * @param p event position.
322
+		 */
323
+		public virtual void zoom_scroll_out (Point p) {
324
+			var z = zoom.copy(), pa = plarea.copy();
325
+			var w = plarea.width, h = plarea.height;
326
+			if (w < 8 || h < 8) return;
327
+
328
+			zoom_out();
329
+
330
+			var x0 = plarea.x0 + plarea.width * z.x0;
331
+			var x1 = plarea.x0 + plarea.width * z.x1;
332
+			var y0 = plarea.y0 + plarea.height * z.y0;
333
+			var y1 = plarea.y0 + plarea.height * z.y1;
334
+
335
+			var dx0 = (p.x - pa.x0) / w * zoom_scroll_speed;
336
+			var dx1 = (pa.x1 - p.x) / w * zoom_scroll_speed;
337
+			var dy0 = (p.y - pa.y0) / h * zoom_scroll_speed;
338
+			var dy1 = (pa.y1 - p.y) / h * zoom_scroll_speed;
339
+
340
+			if (x0 - dx0 < plarea.x0) x0 = plarea.x0; else x0 -= dx0;
341
+			if (x1 + dx1 > plarea.x1) x1 = plarea.x1; else x1 += dx1;
342
+			if (y0 - dy0 < plarea.y0) y0 = plarea.y0; else y0 -= dy0;
343
+			if (y1 + dy1 > plarea.y1) y1 = plarea.y1; else y1 += dy1;
344
+
345
+			zoom_in (new Area.with_abs(x0, y0, x1, y1));
346
+		}
347
+
298 348
 		protected virtual void fix_evarea () {
299 349
 			if (evarea.width < 0) evarea.width = 0;
300 350
 			if (evarea.height < 0) evarea.height = 0;

+ 10
- 2
test/ChartTest.vala View File

@@ -287,6 +287,7 @@ int main (string[] args) {
287 287
 	da.set_events ( Gdk.EventMask.BUTTON_PRESS_MASK
288 288
 	               |Gdk.EventMask.BUTTON_RELEASE_MASK
289 289
 	               |Gdk.EventMask.POINTER_MOTION_MASK
290
+	               |Gdk.EventMask.SCROLL_MASK
290 291
 	);
291 292
 
292 293
 	var chart = chart1;
@@ -571,11 +572,18 @@ int main (string[] args) {
571 572
 
572 573
 		return true; // return ret;
573 574
 	});
574
-	da.add_events(Gdk.EventMask.SCROLL_MASK);
575 575
 	da.scroll_event.connect((event) => {
576
+		switch (event.direction) {
577
+		case Gdk.ScrollDirection.UP:
578
+			chart.zoom_scroll_in(Point(event.x, event.y));
579
+			break;
580
+		case Gdk.ScrollDirection.DOWN:
581
+			chart.zoom_scroll_out(Point(event.x, event.y));
582
+			break;
583
+		}
584
+		da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
576 585
 
577 586
 		//var ret = chart.scroll_notify_event(event);
578
-
579 587
 		return true; // return ret;
580 588
 	});
581 589
 

Loading…
Cancel
Save