1 /* This file is part of Ganv. 2 * Copyright 2007-2015 David Robillard <http://drobilla.net> 3 * 4 * Ganv is free software: you can redistribute it and/or modify it under the 5 * terms of the GNU General Public License as published by the Free Software 6 * Foundation, either version 3 of the License, or any later version. 7 * 8 * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY 9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. 11 * 12 * You should have received a copy of the GNU General Public License along 13 * with Ganv. If not, see <http://www.gnu.org/licenses/>. 14 */ 15 16 #ifndef GANV_CANVAS_H 17 #define GANV_CANVAS_H 18 19 #include "ganv/item.h" 20 #include "ganv/types.h" 21 22 #include <cairo.h> 23 #include <gdk/gdk.h> 24 #include <glib-object.h> 25 #include <glib.h> 26 #include <gtk/gtk.h> 27 28 G_BEGIN_DECLS 29 30 #define GANV_TYPE_CANVAS (ganv_canvas_get_type()) 31 #define GANV_CANVAS(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_CANVAS, GanvCanvas)) 32 #define GANV_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_CANVAS, GanvCanvasClass)) 33 #define GANV_IS_CANVAS(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_CANVAS)) 34 #define GANV_IS_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_CANVAS)) 35 #define GANV_CANVAS_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_CANVAS, GanvCanvasClass)) 36 37 struct _GanvCanvasClass; 38 39 typedef struct GanvCanvasImpl GanvCanvasPrivate; 40 typedef struct _GanvCanvasClass GanvCanvasClass; 41 42 /** 43 * GanvDirection: 44 * @GANV_DIRECTION_DOWN: Signal flows from top to bottom. 45 * @GANV_DIRECTION_RIGHT: Signal flows from left to right. 46 * 47 * Specifies the direction of signal flow on the canvas, which affects the 48 * appearance of modules and how the canvas is auto-arranged. 49 */ 50 typedef enum { 51 GANV_DIRECTION_DOWN, 52 GANV_DIRECTION_RIGHT 53 } GanvDirection; 54 55 struct _GanvCanvas { 56 GtkLayout layout; 57 GanvCanvasPrivate* impl; 58 }; 59 60 struct _GanvCanvasClass { 61 GtkLayoutClass parent_class; 62 63 /* Reserved for future expansion */ 64 gpointer spare_vmethods[4]; 65 }; 66 67 GType ganv_canvas_get_type(void) G_GNUC_CONST; 68 69 /** 70 * GanvEdgeFunc: 71 * @edge: Canvas edge. 72 * @data: User callback data. 73 * 74 * A node function that takes a user data argument (for callbacks). 75 * 76 * Note that in the Gtk world it is considered safe to cast a function to a 77 * function with more arguments and call the resulting pointer, so functions 78 * like ganv_edge_select can safely be used where a GanvEdgeFunc is expected. 79 */ 80 typedef void (*GanvEdgeFunc)(GanvEdge* edge, void* data); 81 82 /** 83 * GanvNodeFunc: 84 * @node: Canvas node. 85 * @data: User callback data. 86 * 87 * A node function that takes a user data argument (for callbacks). 88 * 89 * Note that in the Gtk world it is considered safe to cast a function to a 90 * function with more arguments and call the resulting pointer, so functions 91 * like ganv_node_select can safely be used where a GanvNodeFunc is expected. 92 */ 93 typedef void (*GanvNodeFunc)(GanvNode* node, void* data); 94 95 typedef int (*GanvPortOrderFunc)(const GanvPort*, const GanvPort*, void* data); 96 97 /** 98 * ganv_canvas_new: 99 * 100 * Return value: A newly-created canvas. 101 */ 102 GanvCanvas* 103 ganv_canvas_new(double width, double height); 104 105 /** 106 * ganv_canvas_set_wrapper: 107 * 108 * Set the opaque wrapper object for the canvas. 109 */ 110 void 111 ganv_canvas_set_wrapper(GanvCanvas* canvas, void* wrapper); 112 113 /** 114 * ganv_canvas_get_wrapper: 115 * 116 * Return an opaque pointer to the wrapper for the canvas. 117 */ 118 void* 119 ganv_canvas_get_wrapper(GanvCanvas* canvas); 120 121 /** 122 * ganv_canvas_clear: 123 * 124 * Remove all items from the canvas. 125 */ 126 void 127 ganv_canvas_clear(GanvCanvas* canvas); 128 129 /** 130 * ganv_canvas_empty: 131 * 132 * Return value: True if there are no items on the canvas. 133 */ 134 gboolean 135 ganv_canvas_empty(const GanvCanvas* canvas); 136 137 /** 138 * ganv_canvas_get_size: 139 * 140 * Gets the width and height of the canvas. 141 */ 142 void 143 ganv_canvas_get_size(GanvCanvas* canvas, double* width, double* height); 144 145 /** 146 * ganv_canvas_resize: 147 * 148 * Resize the canvas to the given dimensions. 149 */ 150 void 151 ganv_canvas_resize(GanvCanvas* canvas, double width, double height); 152 153 /** 154 * ganv_canvas_root: 155 * @canvas: A canvas. 156 * 157 * Return value: (transfer none): The root group of the canvas. 158 */ 159 GanvItem* 160 ganv_canvas_root(GanvCanvas* canvas); 161 162 /** 163 * ganv_canvas_set_scroll_region: 164 * @canvas: A canvas. 165 * @x1: Leftmost limit of the scrolling region. 166 * @y1: Upper limit of the scrolling region. 167 * @x2: Rightmost limit of the scrolling region. 168 * @y2: Lower limit of the scrolling region. 169 * 170 * Sets the scrolling region of a canvas to the specified rectangle. The 171 * canvas will then be able to scroll only within this region. The view of the 172 * canvas is adjusted as appropriate to display as much of the new region as 173 * possible. 174 */ 175 void 176 ganv_canvas_set_scroll_region(GanvCanvas* canvas, 177 double x1, double y1, double x2, double y2); 178 179 /** 180 * ganv_canvas_get_scroll_region: 181 * @canvas: A canvas. 182 * @x1: Leftmost limit of the scrolling region (return value). 183 * @y1: Upper limit of the scrolling region (return value). 184 * @x2: Rightmost limit of the scrolling region (return value). 185 * @y2: Lower limit of the scrolling region (return value). 186 * 187 * Queries the scrolling region of a canvas. 188 */ 189 void 190 ganv_canvas_get_scroll_region(GanvCanvas* canvas, 191 double* x1, double* y1, double* x2, double* y2); 192 193 /** 194 * ganv_canvas_set_center_scroll_region: 195 * @canvas: A canvas. 196 * @center_scroll_region: Whether to center the scrolling region in the canvas 197 * window when it is smaller than the canvas' allocation. 198 * 199 * When the scrolling region of the canvas is smaller than the canvas window, 200 * e.g. the allocation of the canvas, it can be either centered on the window 201 * or simply made to be on the upper-left corner on the window. This function 202 * lets you configure this property. 203 */ 204 void 205 ganv_canvas_set_center_scroll_region(GanvCanvas* canvas, 206 gboolean center_scroll_region); 207 208 /** 209 * ganv_canvas_get_center_scroll_region: 210 * @canvas: A canvas. 211 * 212 * Returns whether the canvas is set to center the scrolling region in the 213 * window if the former is smaller than the canvas' allocation. 214 * 215 * Returns: Whether the scroll region is being centered in the canvas window. 216 */ 217 gboolean 218 ganv_canvas_get_center_scroll_region(const GanvCanvas* canvas); 219 220 /** 221 * ganv_canvas_scroll_to: 222 * @canvas: A canvas. 223 * @cx: Horizontal scrolling offset in canvas pixel units. 224 * @cy: Vertical scrolling offset in canvas pixel units. 225 * 226 * Makes a canvas scroll to the specified offsets, given in canvas pixel units. 227 * The canvas will adjust the view so that it is not outside the scrolling 228 * region. This function is typically not used, as it is better to hook 229 * scrollbars to the canvas layout's scrolling adjusments. 230 */ 231 void 232 ganv_canvas_scroll_to(GanvCanvas* canvas, int cx, int cy); 233 234 /** 235 * ganv_canvas_get_scroll_offsets: 236 * @canvas: A canvas. 237 * @cx: Horizontal scrolling offset (return value). 238 * @cy: Vertical scrolling offset (return value). 239 * 240 * Queries the scrolling offsets of a canvas. The values are returned in canvas 241 * pixel units. 242 */ 243 void 244 ganv_canvas_get_scroll_offsets(const GanvCanvas* canvas, int* cx, int* cy); 245 246 /** 247 * ganv_canvas_w2c_affine: 248 * @canvas: A canvas. 249 * @matrix: An affine transformation matrix (return value). 250 * 251 * Gets the affine transform that converts from world coordinates to canvas 252 * pixel coordinates. 253 */ 254 void 255 ganv_canvas_w2c_affine(GanvCanvas* canvas, cairo_matrix_t* matrix); 256 257 /** 258 * ganv_canvas_w2c: 259 * @canvas: A canvas. 260 * @wx: World X coordinate. 261 * @wy: World Y coordinate. 262 * @cx: X pixel coordinate (return value). 263 * @cy: Y pixel coordinate (return value). 264 * 265 * Converts world coordinates into canvas pixel coordinates. 266 */ 267 void 268 ganv_canvas_w2c(GanvCanvas* canvas, double wx, double wy, int* cx, int* cy); 269 270 /** 271 * ganv_canvas_w2c_d: 272 * @canvas: A canvas. 273 * @wx: World X coordinate. 274 * @wy: World Y coordinate. 275 * @cx: X pixel coordinate (return value). 276 * @cy: Y pixel coordinate (return value). 277 * 278 * Converts world coordinates into canvas pixel coordinates. This version 279 * uses floating point coordinates for greater precision. 280 */ 281 void 282 ganv_canvas_w2c_d(GanvCanvas* canvas, 283 double wx, 284 double wy, 285 double* cx, 286 double* cy); 287 288 /** 289 * ganv_canvas_c2w: 290 * @canvas: A canvas. 291 * @cx: Canvas pixel X coordinate. 292 * @cy: Canvas pixel Y coordinate. 293 * @wx: X world coordinate (return value). 294 * @wy: Y world coordinate (return value). 295 * 296 * Converts canvas pixel coordinates to world coordinates. 297 */ 298 void 299 ganv_canvas_c2w(GanvCanvas* canvas, int cx, int cy, double* wx, double* wy); 300 301 /** 302 * ganv_canvas_window_to_world: 303 * @canvas: A canvas. 304 * @winx: Window-relative X coordinate. 305 * @winy: Window-relative Y coordinate. 306 * @worldx: X world coordinate (return value). 307 * @worldy: Y world coordinate (return value). 308 * 309 * Converts window-relative coordinates into world coordinates. You can use 310 * this when you need to convert mouse coordinates into world coordinates, for 311 * example. 312 */ 313 void 314 ganv_canvas_window_to_world(GanvCanvas* canvas, 315 double winx, 316 double winy, 317 double* worldx, 318 double* worldy); 319 320 /** 321 * ganv_canvas_world_to_window: 322 * @canvas: A canvas. 323 * @worldx: World X coordinate. 324 * @worldy: World Y coordinate. 325 * @winx: X window-relative coordinate. 326 * @winy: Y window-relative coordinate. 327 * 328 * Converts world coordinates into window-relative coordinates. 329 */ 330 void 331 ganv_canvas_world_to_window(GanvCanvas* canvas, 332 double worldx, 333 double worldy, 334 double* winx, 335 double* winy); 336 337 /** 338 * ganv_canvas_get_item_at: 339 * @canvas: A canvas. 340 * @x: X position in world coordinates. 341 * @y: Y position in world coordinates. 342 * 343 * Looks for the item that is under the specified position, which must be 344 * specified in world coordinates. 345 * 346 * Returns: (transfer none): The sought item, or NULL if no item is at the 347 * specified coordinates. 348 */ 349 GanvItem* 350 ganv_canvas_get_item_at(GanvCanvas* canvas, double x, double y); 351 352 /** 353 * ganv_canvas_get_edge: 354 * 355 * Get the edge between two nodes, or NULL if none exists. 356 * 357 * Return value: (transfer none): The root group of @canvas. 358 */ 359 GanvEdge* 360 ganv_canvas_get_edge(GanvCanvas* canvas, 361 GanvNode* tail, 362 GanvNode* head); 363 364 /** 365 * ganv_canvas_remove_edge: 366 * 367 * Remove @edge from the canvas. 368 */ 369 void 370 ganv_canvas_remove_edge(GanvCanvas* canvas, 371 GanvEdge* edge); 372 373 /** 374 * ganv_canvas_remove_edge_between: 375 * 376 * Remove the edge from @tail to @head if one exists. 377 */ 378 void 379 ganv_canvas_remove_edge_between(GanvCanvas* canvas, 380 GanvNode* tail, 381 GanvNode* head); 382 383 /** 384 * ganv_canvas_get_direction: 385 * 386 * Return the direction of signal flow. 387 */ 388 GanvDirection 389 ganv_canvas_get_direction(GanvCanvas* canvas); 390 391 /** 392 * ganv_canvas_set_direction: 393 * 394 * Set the direction of signal flow. 395 */ 396 void 397 ganv_canvas_set_direction(GanvCanvas* canvas, GanvDirection dir); 398 399 /** 400 * ganv_canvas_arrange: 401 * 402 * Automatically arrange the canvas contents. 403 */ 404 void 405 ganv_canvas_arrange(GanvCanvas* canvas); 406 407 /** 408 * ganv_canvas_export_image: 409 * 410 * Draw the canvas to an image file. The file type is determined by extension, 411 * currently supported: pdf, ps, svg, dot. 412 * 413 * Returns: 0 on success. 414 */ 415 int 416 ganv_canvas_export_image(GanvCanvas* canvas, 417 const char* filename, 418 gboolean draw_background); 419 420 /** 421 * ganv_canvas_export_dot: 422 * 423 * Write a Graphviz DOT description of the canvas to a file. 424 */ 425 void 426 ganv_canvas_export_dot(GanvCanvas* canvas, const char* filename); 427 428 /** 429 * ganv_canvas_supports_sprung_layout: 430 * 431 * Returns: true iff ganv is compiled with sprung layout support. 432 */ 433 gboolean 434 ganv_canvas_supports_sprung_layout(const GanvCanvas* canvas); 435 436 /** 437 * ganv_canvas_set_sprung_layout: 438 * 439 * Enable or disable "live" force-directed canvas layout. 440 * 441 * Returns: true iff sprung layout was enabled. 442 */ 443 gboolean 444 ganv_canvas_set_sprung_layout(GanvCanvas* canvas, gboolean sprung_layout); 445 446 /** 447 * ganv_canvas_get_locked: 448 * 449 * Return true iff the canvas is locked and nodes may not move. 450 */ 451 gboolean 452 ganv_canvas_get_locked(const GanvCanvas* canvas); 453 454 /** 455 * ganv_canvas_for_each_node: 456 * @canvas: The canvas. 457 * @f: (scope call): A function to call on every node on @canvas. 458 * @data: Data to pass to @f. 459 */ 460 void 461 ganv_canvas_for_each_node(GanvCanvas* canvas, 462 GanvNodeFunc f, 463 void* data); 464 465 /** 466 * ganv_canvas_for_each_selected_node: 467 * @canvas: The canvas. 468 * @f: (scope call): A function to call on every selected node on @canvas. 469 * @data: Data to pass to @f. 470 */ 471 void 472 ganv_canvas_for_each_selected_node(GanvCanvas* canvas, 473 GanvNodeFunc f, 474 void* data); 475 476 /** 477 * ganv_canvas_for_each_edge: 478 * @canvas: The canvas. 479 * @f: (scope call): A function to call on every edge on @canvas. 480 * @data: Data to pass to @f. 481 */ 482 void 483 ganv_canvas_for_each_edge(GanvCanvas* canvas, 484 GanvEdgeFunc f, 485 void* data); 486 487 /** 488 * ganv_canvas_for_each_edge_from: 489 * @canvas: The canvas. 490 * @tail: The tail to enumerate every edge for. 491 * @f: (scope call): A function to call on every edge leaving @tail. 492 */ 493 void 494 ganv_canvas_for_each_edge_from(GanvCanvas* canvas, 495 const GanvNode* tail, 496 GanvEdgeFunc f, 497 void* data); 498 499 /** 500 * ganv_canvas_for_each_edge_to: 501 * @canvas: The canvas. 502 * @head: The head to enumerate every edge for. 503 * @f: (scope call): A function to call on every edge entering @head. 504 */ 505 void 506 ganv_canvas_for_each_edge_to(GanvCanvas* canvas, 507 const GanvNode* head, 508 GanvEdgeFunc f, 509 void* data); 510 511 /** 512 * ganv_canvas_for_each_edge_on: 513 * @canvas: The canvas. 514 * @node: The node to enumerate every edge for. 515 * @f: (scope call): A function to call on every edge attached to @node. 516 */ 517 void 518 ganv_canvas_for_each_edge_on(GanvCanvas* canvas, 519 const GanvNode* node, 520 GanvEdgeFunc f, 521 void* data); 522 523 /** 524 * ganv_canvas_for_each_selected_edge: 525 * @canvas: The canvas. 526 * @f: (scope call): A function to call on every edge attached to @node. 527 * @data: Data to pass to @f. 528 */ 529 void 530 ganv_canvas_for_each_selected_edge(GanvCanvas* canvas, 531 GanvEdgeFunc f, 532 void* data); 533 534 /** 535 * ganv_canvas_select_all: 536 * 537 * Select all items on the canvas. 538 */ 539 void 540 ganv_canvas_select_all(GanvCanvas* canvas); 541 542 /** 543 * ganv_canvas_clear_selection: 544 * 545 * Deselect any selected items on the canvas. 546 */ 547 void 548 ganv_canvas_clear_selection(GanvCanvas* canvas); 549 550 /** 551 * ganv_canvas_get_zoom: 552 * 553 * Return the current zoom factor (pixels per unit). 554 */ 555 double 556 ganv_canvas_get_zoom(const GanvCanvas* canvas); 557 558 /** 559 * ganv_canvas_set_zoom: 560 * @canvas: A canvas. 561 * @zoom: The number of pixels that correspond to one canvas unit. 562 * 563 * The anchor point for zooming, i.e. the point that stays fixed and all others 564 * zoom inwards or outwards from it, depends on whether the canvas is set to 565 * center the scrolling region or not. You can control this using the 566 * ganv_canvas_set_center_scroll_region() function. If the canvas is set to 567 * center the scroll region, then the center of the canvas window is used as 568 * the anchor point for zooming. Otherwise, the upper-left corner of the 569 * canvas window is used as the anchor point. 570 */ 571 void 572 ganv_canvas_set_zoom(GanvCanvas* canvas, double zoom); 573 574 /** 575 * ganv_canvas_zoom_full: 576 * 577 * Zoom so all canvas contents are visible. 578 */ 579 void 580 ganv_canvas_zoom_full(GanvCanvas* canvas); 581 582 /** 583 * ganv_canvas_get_default_font_size: 584 * 585 * Get the default font size in points. 586 */ 587 double 588 ganv_canvas_get_default_font_size(const GanvCanvas* canvas); 589 590 /** 591 * ganv_canvas_get_font_size: 592 * 593 * Get the current font size in points. 594 */ 595 double 596 ganv_canvas_get_font_size(const GanvCanvas* canvas); 597 598 /** 599 * ganv_canvas_set_font_size: 600 * 601 * Set the current font size in points. 602 */ 603 void 604 ganv_canvas_set_font_size(GanvCanvas* canvas, double points); 605 606 /** 607 * ganv_canvas_get_move_cursor: 608 * 609 * Return the cursor to use while dragging canvas objects. 610 */ 611 GdkCursor* 612 ganv_canvas_get_move_cursor(const GanvCanvas* canvas); 613 614 /** 615 * ganv_canvas_move_contents_to: 616 * 617 * Shift all canvas contents so the top-left object is at (x, y). 618 */ 619 void 620 ganv_canvas_move_contents_to(GanvCanvas* canvas, double x, double y); 621 622 /** 623 * ganv_canvas_set_port_order: 624 * @canvas The canvas to set the default port order on. 625 * @port_cmp Port comparison function. 626 * @data Data to be passed to order. 627 * 628 * Set a comparator function to use as the default order for ports on modules. 629 * If left unset, ports are shown in the order they are added. 630 */ 631 void 632 ganv_canvas_set_port_order(GanvCanvas* canvas, 633 GanvPortOrderFunc port_cmp, 634 void* data); 635 636 637 G_END_DECLS 638 639 #endif /* GANV_CANVAS_H */ 640