From 3680d163650c1d79869952520aba2eae281da95e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 14 Dec 2011 05:29:47 +0000 Subject: Draw directly to window cairo context instead of gdk pixmap. git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@3875 a436a847-0d15-0410-975c-d299462d15a1 --- src/Canvas.cpp | 37 +++++++++---------------------------- src/box.c | 4 ++-- src/canvas-base.c | 38 +++++++------------------------------- src/circle.c | 4 ++-- src/edge.c | 16 ++++++++-------- src/group.c | 12 +++++++++++- src/module.c | 10 ++++++---- src/text.c | 4 ++-- 8 files changed, 47 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/Canvas.cpp b/src/Canvas.cpp index e901eaa..38cb4ad 100644 --- a/src/Canvas.cpp +++ b/src/Canvas.cpp @@ -131,15 +131,6 @@ struct GanvCanvasImpl { , _layout(GTK_LAYOUT(_gcanvas)) , _connect_port(NULL) , _last_selected_port(NULL) - , _base_rect(ganv_item_new( - GANV_ITEM(ganv_canvas_base_root(GANV_CANVAS_BASE(_gcanvas))), - ganv_box_get_type(), - "x1", 0.0, - "y1", 0.0, - "x2", 1.0, - "y2", 1.0, - "fill-color", 0x000000FF, - NULL)) , _select_rect(NULL) , _zoom(1.0) , _font_size(0.0) @@ -246,8 +237,7 @@ struct GanvCanvasImpl { GanvPort* _connect_port; ///< Port for which a edge is being made GanvPort* _last_selected_port; - GanvItem* _base_rect; ///< Background - GanvBox* _select_rect; ///< Rectangle for drag selection + GanvBox* _select_rect; ///< Rectangle for drag selection double _zoom; ///< Current zoom level double _font_size; ///< Current font size in points @@ -373,7 +363,7 @@ void GanvCanvasImpl::add_item(GanvNode* n) { GanvItem* item = GANV_ITEM(n); - if (item != _base_rect && item->parent == GANV_ITEM(root())) { + if (item->parent == GANV_ITEM(root())) { _items.insert(n); } } @@ -827,7 +817,7 @@ GanvCanvasImpl::scroll_drag_handler(GdkEvent* event) if (event->type == GDK_BUTTON_PRESS && event->button.button == 2) { ganv_item_grab( - GANV_ITEM(_base_rect), + GANV_ITEM(root()), GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK, NULL, event->button.time); ganv_canvas_base_get_scroll_offsets(GANV_CANVAS_BASE(_gcanvas), &original_scroll_x, &original_scroll_y); @@ -857,7 +847,7 @@ GanvCanvasImpl::scroll_drag_handler(GdkEvent* event) last_x = x; last_y = y; } else if (event->type == GDK_BUTTON_RELEASE && _drag_state == SCROLL) { - ganv_item_ungrab(GANV_ITEM(_base_rect), event->button.time); + ganv_item_ungrab(GANV_ITEM(root()), event->button.time); _drag_state = NOT_DRAGGING; } else { handled = false; @@ -902,9 +892,8 @@ GanvCanvasImpl::select_drag_handler(GdkEvent* event) "border-color", SELECT_RECT_BORDER_COLOUR, NULL)); ganv_item_lower_to_bottom(GANV_ITEM(_select_rect)); - ganv_item_lower_to_bottom(GANV_ITEM(_base_rect)); ganv_item_grab( - GANV_ITEM(_base_rect), GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK, + GANV_ITEM(root()), GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK, NULL, event->button.time); return true; } else if (event->type == GDK_MOTION_NOTIFY && _drag_state == SELECT) { @@ -951,7 +940,7 @@ GanvCanvasImpl::select_drag_handler(GdkEvent* event) } } - ganv_item_ungrab(GANV_ITEM(_base_rect), event->button.time); + ganv_item_ungrab(GANV_ITEM(root()), event->button.time); gtk_object_destroy(GTK_OBJECT(_select_rect)); _select_rect = NULL; @@ -975,7 +964,6 @@ GanvCanvasImpl::connect_drag_handler(GdkEvent* event) if (event->type == GDK_MOTION_NOTIFY) { double x, y; get_motion_coords(&event->motion, &x, &y); - ganv_item_i2w(GANV_ITEM(_base_rect), &x, &y); if (!drag_edge) { // Create drag edge @@ -1023,11 +1011,10 @@ GanvCanvasImpl::connect_drag_handler(GdkEvent* event) return true; } else if (event->type == GDK_BUTTON_RELEASE) { - ganv_item_ungrab(GANV_ITEM(_base_rect), event->button.time); + ganv_item_ungrab(GANV_ITEM(root()), event->button.time); double x = event->button.x; double y = event->button.y; - ganv_item_i2w(GANV_ITEM(_base_rect), &x, &y); GanvNode* joinee = get_node_at(x, y); @@ -1175,7 +1162,7 @@ GanvCanvasImpl::port_event(GdkEvent* event, GanvPort* port) _connect_port = port; port_dragging = false; ganv_item_grab( - GANV_ITEM(_base_rect), + GANV_ITEM(root()), GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK, NULL, event->crossing.time); return true; @@ -1329,8 +1316,6 @@ void GanvCanvasImpl::resize(double width, double height) { if (width != _gcanvas->width || height != _gcanvas->height) { - ganv_box_set_width(GANV_BOX(_base_rect), width); - ganv_box_set_height(GANV_BOX(_base_rect), height); _gcanvas->width = width; _gcanvas->height = height; ganv_canvas_base_set_scroll_region(GANV_CANVAS_BASE(_gcanvas), @@ -1771,12 +1756,8 @@ ganv_canvas_set_property(GObject* object, case PROP_LOCKED: { const gboolean tmp = g_value_get_boolean(value); if (canvas->locked != tmp) { - GanvItem* base = GANV_ITEM(canvas->impl->_base_rect); - ganv_item_set(base, - "fill-color", tmp ? 0x131415FF : 0x000000FF, - NULL); + // TODO: change background color canvas->locked = tmp; - ganv_item_request_update(base); } break; } diff --git a/src/box.c b/src/box.c index 194a126..5d9a41a 100644 --- a/src/box.c +++ b/src/box.c @@ -236,8 +236,8 @@ ganv_box_draw(GanvItem* item, double degrees = G_PI / 180.0; for (int i = (impl->coords.stacked ? 1 : 0); i >= 0; --i) { - const int x = cx - (STACKED_OFFSET * i); - const int y = cy - (STACKED_OFFSET * i); + const double x = 0 - (STACKED_OFFSET * i); + const double y = 0 - (STACKED_OFFSET * i); if (impl->radius_tl == 0.0 && impl->radius_tr == 0.0 && impl->radius_br == 0.0 && impl->radius_bl == 0.0) { diff --git a/src/canvas-base.c b/src/canvas-base.c index 5b3a080..1383395 100644 --- a/src/canvas-base.c +++ b/src/canvas-base.c @@ -1024,11 +1024,7 @@ ganv_canvas_base_init(GanvCanvasBase* canvas) gtk_layout_set_hadjustment(GTK_LAYOUT(canvas), NULL); gtk_layout_set_vadjustment(GTK_LAYOUT(canvas), NULL); - /* Disable the gtk+ double buffering since the canvas uses it's own. */ - gtk_widget_set_double_buffered(GTK_WIDGET(canvas), FALSE); - /* Create the root item as a special case */ - canvas->root = GANV_ITEM(g_object_new(ganv_group_get_type(), NULL)); canvas->root->canvas = canvas; @@ -1848,15 +1844,12 @@ ganv_canvas_base_focus_out(GtkWidget* widget, GdkEventFocus* event) static void ganv_canvas_base_paint_rect(GanvCanvasBase* canvas, gint x0, gint y0, gint x1, gint y1) { - GtkWidget* widget; - gint draw_x1, draw_y1; - gint draw_x2, draw_y2; - gint draw_width, draw_height; + gint draw_x1, draw_y1; + gint draw_x2, draw_y2; + gint draw_width, draw_height; g_return_if_fail(!canvas->need_update); - widget = GTK_WIDGET(canvas); - draw_x1 = MAX(x0, canvas->layout.hadjustment->value - canvas->zoom_xofs); draw_y1 = MAX(y0, canvas->layout.vadjustment->value - canvas->zoom_yofs); draw_x2 = MIN(draw_x1 + GTK_WIDGET(canvas)->allocation.width, x1); @@ -1876,16 +1869,11 @@ ganv_canvas_base_paint_rect(GanvCanvasBase* canvas, gint x0, gint y0, gint x1, g canvas->draw_xofs = draw_x1; canvas->draw_yofs = draw_y1; - GdkPixmap* pixmap; - - pixmap = gdk_pixmap_new(canvas->layout.bin_window, - draw_width, draw_height, - gtk_widget_get_visual(widget)->depth); + cairo_t* cr = gdk_cairo_create(canvas->layout.bin_window); - g_signal_emit(G_OBJECT(canvas), canvas_signals[DRAW_BACKGROUND], 0, pixmap, - draw_x1, draw_y1, draw_width, draw_height); - - cairo_t* cr = gdk_cairo_create(pixmap); + double wx, wy; + ganv_canvas_base_window_to_world(canvas, 0, 0, &wx, &wy); + cairo_translate(cr, -wx, -wy); if (canvas->root->object.flags & GANV_ITEM_VISIBLE) { (*GANV_ITEM_GET_CLASS(canvas->root)->draw)( @@ -1895,18 +1883,6 @@ ganv_canvas_base_paint_rect(GanvCanvasBase* canvas, gint x0, gint y0, gint x1, g } cairo_destroy(cr); - - /* Copy the pixmap to the window and clean up */ - - gdk_draw_drawable(canvas->layout.bin_window, - canvas->pixmap_gc, - pixmap, - 0, 0, - draw_x1 + canvas->zoom_xofs, - draw_y1 + canvas->zoom_yofs, - draw_width, draw_height); - - g_object_unref(pixmap); } /* Expose handler for the canvas */ diff --git a/src/circle.c b/src/circle.c index cd4f09d..6010dc2 100644 --- a/src/circle.c +++ b/src/circle.c @@ -263,8 +263,8 @@ ganv_circle_draw(GanvItem* item, &circle->node, &dash_length, &border_color, &fill_color); cairo_arc(cr, - cx - x, - cy - y, + cx, + cy, impl->coords.radius, 0, 2 * G_PI); diff --git a/src/edge.c b/src/edge.c index 22a0ba9..8d43f46 100644 --- a/src/edge.c +++ b/src/edge.c @@ -300,10 +300,10 @@ ganv_edge_draw(GanvItem* item, GanvEdge* edge = GANV_EDGE(item); GanvEdgeImpl* impl = edge->impl; - double src_x = impl->coords.x1 - x; - double src_y = impl->coords.y1 - y; - double dst_x = impl->coords.x2 - x; - double dst_y = impl->coords.y2 - y; + double src_x = impl->coords.x1; + double src_y = impl->coords.y1; + double dst_x = impl->coords.x2; + double dst_y = impl->coords.y2; double dx = src_x - dst_x; double dy = src_y - dst_y; @@ -332,16 +332,16 @@ ganv_edge_draw(GanvItem* item, // Path 1 (src_x, src_y) -> (join_x, join_y) // Control point 1 - const double src_x1 = impl->coords.cx1 - x; - const double src_y1 = impl->coords.cy1 - y; + const double src_x1 = impl->coords.cx1; + const double src_y1 = impl->coords.cy1; // Control point 2 const double src_x2 = (join_x + src_x1) / 2.0; const double src_y2 = (join_y + src_y1) / 2.0; // Path 2, (join_x, join_y) -> (dst_x, dst_y) // Control point 1 - const double dst_x1 = impl->coords.cx2 - x; - const double dst_y1 = impl->coords.cy2 - y; + const double dst_x1 = impl->coords.cx2; + const double dst_y1 = impl->coords.cy2; // Control point 2 const double dst_x2 = (join_x + dst_x1) / 2.0; const double dst_y2 = (join_y + dst_y1) / 2.0; diff --git a/src/group.c b/src/group.c index 0e38396..160c755 100644 --- a/src/group.c +++ b/src/group.c @@ -205,6 +205,11 @@ ganv_group_draw(GanvItem* item, cairo_t* cr, group = GANV_GROUP(item); + // Draw background + cairo_set_source_rgba(cr, 0, 0, 0, 1.0); + cairo_rectangle(cr, x, y, width, height); + cairo_fill(cr); + for (list = group->item_list; list; list = list->next) { child = list->data; @@ -283,7 +288,12 @@ ganv_group_point(GanvItem* item, double x, double y, int cx, int cy, } } - return best; + if (*actual_item) { + return best; + } else { + *actual_item = item; + return 0.0; + } } static void diff --git a/src/module.c b/src/module.c index 7b7de6d..b82b5ee 100644 --- a/src/module.c +++ b/src/module.c @@ -513,16 +513,18 @@ ganv_module_update(GanvItem* item, int flags) GanvNode* node = GANV_NODE(item); GanvModule* module = GANV_MODULE(item); - FOREACH_PORT(module->impl->ports, p) { - ganv_item_invoke_update(GANV_ITEM(*p), flags); - } - if (module->impl->must_resize) { layout(node); } GanvItemClass* item_class = GANV_ITEM_CLASS(parent_class); item_class->update(item, flags); + + /* + FOREACH_PORT(module->impl->ports, p) { + ganv_item_invoke_update(GANV_ITEM(*p), flags); + } + */ } static void diff --git a/src/text.c b/src/text.c index a20dfa0..290eccc 100644 --- a/src/text.c +++ b/src/text.c @@ -299,8 +299,8 @@ ganv_text_draw(GanvItem* item, ganv_item_i2w(item, &wx, &wy); // Round to the nearest pixel so text isn't blurry - wx = lrint(wx - x); - wy = lrint(wy - y); + wx = lrint(wx); + wy = lrint(wy); cairo_set_source_surface(cr, impl->surface, wx, wy); cairo_paint(cr); -- cgit v1.2.1