|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* Copyright (C) 2003, 2004 Joaquin Cuenca Abela
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Authors:
|
|
Packit |
1e8aac |
* Joaquin Cuenca Abela <e98cuenc@yahoo.com>
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
1e8aac |
* it under the terms of the GNU General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
1e8aac |
* License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
1e8aac |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
1e8aac |
* GNU General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU General Public License
|
|
Packit |
1e8aac |
* along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "config.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* SECTION:glade-placeholder
|
|
Packit |
1e8aac |
* @Short_Description: A #GtkWidget to fill empty places.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Generally in Glade, container widgets are implemented with #GladePlaceholder
|
|
Packit |
1e8aac |
* children to allow users to 'click' and add thier widgets to a container.
|
|
Packit |
1e8aac |
* It is the responsability of the plugin writer to create placeholders for
|
|
Packit |
1e8aac |
* container widgets where appropriate; usually in #GladePostCreateFunc
|
|
Packit |
1e8aac |
* when the #GladeCreateReason is %GLADE_CREATE_USER.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <gtk/gtk.h>
|
|
Packit |
1e8aac |
#include "glade-marshallers.h"
|
|
Packit |
1e8aac |
#include "glade.h"
|
|
Packit |
1e8aac |
#include "glade-placeholder.h"
|
|
Packit |
1e8aac |
#include "glade-xml-utils.h"
|
|
Packit |
1e8aac |
#include "glade-project.h"
|
|
Packit |
1e8aac |
#include "glade-command.h"
|
|
Packit |
1e8aac |
#include "glade-palette.h"
|
|
Packit |
1e8aac |
#include "glade-popup.h"
|
|
Packit |
1e8aac |
#include "glade-cursor.h"
|
|
Packit |
1e8aac |
#include "glade-widget.h"
|
|
Packit |
1e8aac |
#include "glade-app.h"
|
|
Packit |
1e8aac |
#include "glade-adaptor-chooser-widget.h"
|
|
Packit |
1e8aac |
#include <math.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "glade-dnd.h"
|
|
Packit |
1e8aac |
#include "glade-drag.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define WIDTH_REQUISITION 20
|
|
Packit |
1e8aac |
#define HEIGHT_REQUISITION 20
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static cairo_pattern_t *placeholder_pattern = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
struct _GladePlaceholderPrivate
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *packing_actions;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GdkWindow *event_window;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean drag_highlight;
|
|
Packit |
1e8aac |
};
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
enum
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
PROP_0,
|
|
Packit |
1e8aac |
PROP_HADJUSTMENT,
|
|
Packit |
1e8aac |
PROP_VADJUSTMENT,
|
|
Packit |
1e8aac |
PROP_HSCROLL_POLICY,
|
|
Packit |
1e8aac |
PROP_VSCROLL_POLICY
|
|
Packit |
1e8aac |
};
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define GLADE_PLACEHOLDER_PRIVATE(object) (((GladePlaceholder*)object)->priv)
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void glade_placeholder_drag_init (_GladeDragInterface *iface);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_DEFINE_TYPE_WITH_CODE (GladePlaceholder, glade_placeholder, GTK_TYPE_WIDGET,
|
|
Packit |
1e8aac |
G_ADD_PRIVATE (GladePlaceholder)
|
|
Packit |
1e8aac |
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)
|
|
Packit |
1e8aac |
G_IMPLEMENT_INTERFACE (GLADE_TYPE_DRAG,
|
|
Packit |
1e8aac |
glade_placeholder_drag_init))
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_notify_parent (GObject *gobject,
|
|
Packit |
1e8aac |
GParamSpec *arg1,
|
|
Packit |
1e8aac |
gpointer user_data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder = GLADE_PLACEHOLDER (gobject);
|
|
Packit |
1e8aac |
GladeWidgetAdaptor *parent_adaptor = NULL;
|
|
Packit |
1e8aac |
GladeWidget *parent = glade_placeholder_get_parent (placeholder);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder->priv->packing_actions)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_list_foreach (placeholder->priv->packing_actions, (GFunc) g_object_unref,
|
|
Packit |
1e8aac |
NULL);
|
|
Packit |
1e8aac |
g_list_free (placeholder->priv->packing_actions);
|
|
Packit |
1e8aac |
placeholder->priv->packing_actions = NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (parent)
|
|
Packit |
1e8aac |
parent_adaptor = glade_widget_get_adaptor (parent);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (parent_adaptor)
|
|
Packit |
1e8aac |
placeholder->priv->packing_actions =
|
|
Packit |
1e8aac |
glade_widget_adaptor_pack_actions_new (parent_adaptor);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_init (GladePlaceholder *placeholder)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
placeholder->priv = glade_placeholder_get_instance_private (placeholder);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder->priv->packing_actions = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_set_can_focus (GTK_WIDGET (placeholder), TRUE);
|
|
Packit |
1e8aac |
gtk_widget_set_has_window (GTK_WIDGET (placeholder), FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_set_size_request (GTK_WIDGET (placeholder),
|
|
Packit |
1e8aac |
WIDTH_REQUISITION, HEIGHT_REQUISITION);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
_glade_dnd_dest_set (GTK_WIDGET (placeholder));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_signal_connect (placeholder, "notify::parent",
|
|
Packit |
1e8aac |
G_CALLBACK (glade_placeholder_notify_parent), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_set_hexpand (GTK_WIDGET (placeholder), TRUE);
|
|
Packit |
1e8aac |
gtk_widget_set_vexpand (GTK_WIDGET (placeholder), TRUE);
|
|
Packit |
1e8aac |
gtk_widget_show (GTK_WIDGET (placeholder));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_finalize (GObject *object)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_if_fail (GLADE_IS_PLACEHOLDER (object));
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder->priv->packing_actions)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_list_foreach (placeholder->priv->packing_actions, (GFunc) g_object_unref, NULL);
|
|
Packit |
1e8aac |
g_list_free (placeholder->priv->packing_actions);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_OBJECT_CLASS (glade_placeholder_parent_class)->finalize (object);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_set_property (GObject *object,
|
|
Packit |
1e8aac |
guint prop_id,
|
|
Packit |
1e8aac |
const GValue *value,
|
|
Packit |
1e8aac |
GParamSpec *pspec)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
switch (prop_id)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case PROP_HADJUSTMENT:
|
|
Packit |
1e8aac |
case PROP_VADJUSTMENT:
|
|
Packit |
1e8aac |
case PROP_HSCROLL_POLICY:
|
|
Packit |
1e8aac |
case PROP_VSCROLL_POLICY:
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_get_property (GObject *object,
|
|
Packit |
1e8aac |
guint prop_id,
|
|
Packit |
1e8aac |
GValue *value,
|
|
Packit |
1e8aac |
GParamSpec *pspec)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
switch (prop_id)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case PROP_HADJUSTMENT:
|
|
Packit |
1e8aac |
case PROP_VADJUSTMENT:
|
|
Packit |
1e8aac |
g_value_set_object (value, NULL);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case PROP_HSCROLL_POLICY:
|
|
Packit |
1e8aac |
case PROP_VSCROLL_POLICY:
|
|
Packit |
1e8aac |
g_value_set_enum (value, GTK_SCROLL_MINIMUM);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_realize (GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
GtkAllocation allocation;
|
|
Packit |
1e8aac |
GdkWindow *window;
|
|
Packit |
1e8aac |
GdkWindowAttr attributes;
|
|
Packit |
1e8aac |
gint attributes_mask;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_set_realized (widget, TRUE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_get_allocation (widget, &allocation);
|
|
Packit |
1e8aac |
attributes.x = allocation.x;
|
|
Packit |
1e8aac |
attributes.y = allocation.y;
|
|
Packit |
1e8aac |
attributes.width = allocation.width;
|
|
Packit |
1e8aac |
attributes.height = allocation.height;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
attributes.window_type = GDK_WINDOW_CHILD;
|
|
Packit |
1e8aac |
attributes.wclass = GDK_INPUT_ONLY;
|
|
Packit |
1e8aac |
attributes.event_mask =
|
|
Packit |
1e8aac |
gtk_widget_get_events (widget) |
|
|
Packit |
1e8aac |
GDK_POINTER_MOTION_MASK |
|
|
Packit |
1e8aac |
GDK_POINTER_MOTION_HINT_MASK |
|
|
Packit |
1e8aac |
GDK_BUTTON_PRESS_MASK |
|
|
Packit |
1e8aac |
GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
|
|
Packit |
1e8aac |
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
window = gtk_widget_get_parent_window (widget);
|
|
Packit |
1e8aac |
gtk_widget_set_window (widget, g_object_ref (window));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder->priv->event_window =
|
|
Packit |
1e8aac |
gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
|
|
Packit |
1e8aac |
attributes_mask);
|
|
Packit |
1e8aac |
gdk_window_set_user_data (placeholder->priv->event_window, widget);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_unrealize (GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder->priv->event_window)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gdk_window_set_user_data (placeholder->priv->event_window, NULL);
|
|
Packit |
1e8aac |
gdk_window_destroy (placeholder->priv->event_window);
|
|
Packit |
1e8aac |
placeholder->priv->event_window = NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GTK_WIDGET_CLASS (glade_placeholder_parent_class)->unrealize (widget);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_map (GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder->priv->event_window)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gdk_window_show (placeholder->priv->event_window);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GTK_WIDGET_CLASS (glade_placeholder_parent_class)->map (widget);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_unmap (GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder->priv->event_window)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gdk_window_hide (placeholder->priv->event_window);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GTK_WIDGET_CLASS (glade_placeholder_parent_class)->unmap (widget);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_set_allocation (widget, allocation);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (gtk_widget_get_realized (widget))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gdk_window_move_resize (placeholder->priv->event_window,
|
|
Packit |
1e8aac |
allocation->x, allocation->y,
|
|
Packit |
1e8aac |
allocation->width, allocation->height);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_draw (GtkWidget *widget, cairo_t *cr)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
gint h = gtk_widget_get_allocated_height (widget) - 1;
|
|
Packit |
1e8aac |
gint w = gtk_widget_get_allocated_width (widget) - 1;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder_pattern)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_save (cr);
|
|
Packit |
1e8aac |
cairo_rectangle (cr, 0, 0, w, h);
|
|
Packit |
1e8aac |
cairo_set_source (cr, placeholder_pattern);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
cairo_restore (cr);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_translate (cr, .5, .5);
|
|
Packit |
1e8aac |
cairo_set_line_width (cr, 1.0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* We hardcode colors here since we are already using an image as bg pattern */
|
|
Packit |
1e8aac |
cairo_set_source_rgb (cr, .9, .9, .9);
|
|
Packit |
1e8aac |
cairo_move_to (cr, w, 0);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 0, 0);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 0, h);
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_set_source_rgb (cr, .64, .64, .64);
|
|
Packit |
1e8aac |
cairo_move_to (cr, w, 0);
|
|
Packit |
1e8aac |
cairo_line_to (cr, w, h);
|
|
Packit |
1e8aac |
cairo_line_to (cr, 0, h);
|
|
Packit |
1e8aac |
cairo_stroke (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (placeholder->priv->drag_highlight)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
cairo_pattern_t *gradient;
|
|
Packit |
1e8aac |
GtkStyleContext *context;
|
|
Packit |
1e8aac |
gdouble ww, hh;
|
|
Packit |
1e8aac |
GdkRGBA c;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
context = gtk_widget_get_style_context (widget);
|
|
Packit |
1e8aac |
gtk_style_context_save (context);
|
|
Packit |
1e8aac |
gtk_style_context_get_background_color (context,
|
|
Packit |
1e8aac |
gtk_style_context_get_state (context) |
|
|
Packit |
1e8aac |
GTK_STATE_FLAG_SELECTED |
|
|
Packit |
1e8aac |
GTK_STATE_FLAG_FOCUSED, &c);
|
|
Packit |
1e8aac |
gtk_style_context_restore (context);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
ww = w/2.0;
|
|
Packit |
1e8aac |
hh = h/2.0;
|
|
Packit |
1e8aac |
gradient = cairo_pattern_create_radial (ww, hh, MIN (w, h)/6,
|
|
Packit |
1e8aac |
ww, hh, MAX (ww, hh));
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, 0, c.red, c.green, c.blue, .08);
|
|
Packit |
1e8aac |
cairo_pattern_add_color_stop_rgba (gradient, 1, c.red, c.green, c.blue, .28);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_set_source (cr, gradient);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_rectangle (cr, 0, 0, w, h);
|
|
Packit |
1e8aac |
cairo_fill (cr);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
cairo_pattern_destroy (gradient);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_update_cursor (GladePlaceholder *placeholder, GdkWindow *win)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeProject *project = glade_placeholder_get_project (placeholder);
|
|
Packit |
1e8aac |
GladePointerMode pointer_mode = glade_project_get_pointer_mode (project);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (pointer_mode == GLADE_POINTER_SELECT)
|
|
Packit |
1e8aac |
glade_cursor_set (project, win, GLADE_CURSOR_SELECTOR);
|
|
Packit |
1e8aac |
else if (pointer_mode == GLADE_POINTER_ADD_WIDGET)
|
|
Packit |
1e8aac |
glade_cursor_set (project, win, GLADE_CURSOR_ADD_WIDGET);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_enter_notify_event (GtkWidget *widget,
|
|
Packit |
1e8aac |
GdkEventCrossing *event)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_placeholder_update_cursor (GLADE_PLACEHOLDER (widget), event->window);
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_placeholder_update_cursor (GLADE_PLACEHOLDER (widget), event->window);
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
on_chooser_adaptor_widget_selected (_GladeAdaptorChooserWidget *chooser,
|
|
Packit |
1e8aac |
GladeWidgetAdaptor *adaptor,
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder)
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_create (adaptor, glade_placeholder_get_parent (placeholder),
|
|
Packit |
1e8aac |
placeholder, glade_placeholder_get_project (placeholder));
|
|
Packit |
1e8aac |
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (chooser), GTK_TYPE_POPOVER));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static GtkWidget *
|
|
Packit |
1e8aac |
glade_placeholder_popover_new (GladePlaceholder *placeholder, GtkWidget *relative_to)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *pop = gtk_popover_new (relative_to);
|
|
Packit |
1e8aac |
GtkWidget *chooser;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
chooser = _glade_adaptor_chooser_widget_new (GLADE_ADAPTOR_CHOOSER_WIDGET_WIDGET |
|
|
Packit |
1e8aac |
GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_TOPLEVEL |
|
|
Packit |
1e8aac |
GLADE_ADAPTOR_CHOOSER_WIDGET_SKIP_DEPRECATED,
|
|
Packit |
1e8aac |
glade_placeholder_get_project (placeholder));
|
|
Packit |
1e8aac |
_glade_adaptor_chooser_widget_populate (GLADE_ADAPTOR_CHOOSER_WIDGET (chooser));
|
|
Packit |
1e8aac |
g_signal_connect (chooser, "adaptor-selected",
|
|
Packit |
1e8aac |
G_CALLBACK (on_chooser_adaptor_widget_selected),
|
|
Packit |
1e8aac |
placeholder);
|
|
Packit |
1e8aac |
gtk_popover_set_position (GTK_POPOVER (pop), GTK_POS_BOTTOM);
|
|
Packit |
1e8aac |
gtk_container_add (GTK_CONTAINER (pop), chooser);
|
|
Packit |
1e8aac |
gtk_widget_show (chooser);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return pop;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_button_press (GtkWidget *widget, GdkEventButton *event)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder;
|
|
Packit |
1e8aac |
GladeProject *project;
|
|
Packit |
1e8aac |
GladeWidgetAdaptor *adaptor;
|
|
Packit |
1e8aac |
gboolean handled = FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_PLACEHOLDER (widget), FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
placeholder = GLADE_PLACEHOLDER (widget);
|
|
Packit |
1e8aac |
project = glade_placeholder_get_project (placeholder);
|
|
Packit |
1e8aac |
adaptor = glade_project_get_add_item (project);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!gtk_widget_has_focus (widget))
|
|
Packit |
1e8aac |
gtk_widget_grab_focus (widget);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((event->button == 1 || event->button == 2) &&
|
|
Packit |
1e8aac |
event->type == GDK_BUTTON_PRESS && adaptor != NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent = glade_placeholder_get_parent (placeholder);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* A widget type is selected in the palette.
|
|
Packit |
1e8aac |
* Add a new widget of that type.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
glade_command_create (adaptor, parent, placeholder, project);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Let the user use the middle button to create more than one widget */
|
|
Packit |
1e8aac |
if (event->button != 2)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_project_set_add_item (project, NULL);
|
|
Packit |
1e8aac |
/* reset the cursor */
|
|
Packit |
1e8aac |
glade_project_set_pointer_mode (project, GLADE_POINTER_SELECT);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
handled = TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (event->button == 1 &&
|
|
Packit |
1e8aac |
event->type == GDK_2BUTTON_PRESS &&
|
|
Packit |
1e8aac |
adaptor == NULL)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *event_widget = gtk_get_event_widget ((GdkEvent*) event);
|
|
Packit |
1e8aac |
GladeWidget *toplevel = glade_widget_get_toplevel (glade_placeholder_get_parent (placeholder));
|
|
Packit |
1e8aac |
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (glade_widget_get_object (toplevel)));
|
|
Packit |
1e8aac |
GtkWidget *pop = glade_placeholder_popover_new (placeholder, parent);
|
|
Packit |
1e8aac |
GdkRectangle rect = {0, 0, 8, 8};
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_widget_translate_coordinates (event_widget, parent,
|
|
Packit |
1e8aac |
event->x, event->y,
|
|
Packit |
1e8aac |
&rect.x, &rect.y);
|
|
Packit |
1e8aac |
gtk_popover_set_pointing_to (GTK_POPOVER (pop), &rect);
|
|
Packit |
1e8aac |
gtk_popover_popup (GTK_POPOVER (pop));
|
|
Packit |
1e8aac |
handled = TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!handled && glade_popup_is_popup_event (event))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_popup_placeholder_pop (placeholder, event);
|
|
Packit |
1e8aac |
handled = TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return handled;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_popup_menu (GtkWidget *widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_PLACEHOLDER (widget), FALSE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_popup_placeholder_pop (GLADE_PLACEHOLDER (widget), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_drag_can_drag (_GladeDrag *source)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent = glade_placeholder_get_parent (GLADE_PLACEHOLDER (source));
|
|
Packit |
1e8aac |
return (parent) ? _glade_drag_can_drag (GLADE_DRAG (parent)) : FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_drag_can_drop (_GladeDrag *dest, gint x, gint y, GObject *data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (GLADE_IS_WIDGET_ADAPTOR (data))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GType otype = glade_widget_adaptor_get_object_type (GLADE_WIDGET_ADAPTOR (data));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (g_type_is_a (otype, GTK_TYPE_WIDGET) && !GWA_IS_TOPLEVEL (data))
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (GTK_IS_WIDGET (data))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent, *new_child;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Avoid recursion */
|
|
Packit |
1e8aac |
if (gtk_widget_is_ancestor (GTK_WIDGET (dest), GTK_WIDGET (data)))
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
parent = glade_placeholder_get_parent (GLADE_PLACEHOLDER (dest));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if ((new_child = glade_widget_get_from_gobject (data)) &&
|
|
Packit |
1e8aac |
!glade_widget_add_verify (parent, new_child, FALSE))
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_placeholder_drag_drop (_GladeDrag *dest, gint x, gint y, GObject *data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholder *placeholder = GLADE_PLACEHOLDER (dest);
|
|
Packit |
1e8aac |
GladeWidget *gsource;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!data)
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (GLADE_IS_WIDGET_ADAPTOR (data))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent = glade_placeholder_get_parent (placeholder);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_command_create (GLADE_WIDGET_ADAPTOR (data), parent, placeholder,
|
|
Packit |
1e8aac |
glade_widget_get_project (parent));
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if ((gsource = glade_widget_get_from_gobject (data)))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent = glade_placeholder_get_parent (placeholder);
|
|
Packit |
1e8aac |
GList widgets = {gsource, NULL, NULL};
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Check for recursive paste */
|
|
Packit |
1e8aac |
if (parent != gsource)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_dnd (&widgets, parent, placeholder);
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_drag_highlight (_GladeDrag *dest, gint x, gint y)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladePlaceholderPrivate *priv = GLADE_PLACEHOLDER (dest)->priv;
|
|
Packit |
1e8aac |
gboolean highlight = !(x < 0 || y < 0);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (priv->drag_highlight == highlight)
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
priv->drag_highlight = highlight;
|
|
Packit |
1e8aac |
gtk_widget_queue_draw (GTK_WIDGET (dest));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_drag_init (_GladeDragInterface *iface)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
iface->can_drag = glade_placeholder_drag_can_drag;
|
|
Packit |
1e8aac |
iface->can_drop = glade_placeholder_drag_can_drop;
|
|
Packit |
1e8aac |
iface->drop = glade_placeholder_drag_drop;
|
|
Packit |
1e8aac |
iface->highlight = glade_placeholder_drag_highlight;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_placeholder_class_init (GladePlaceholderClass *klass)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
Packit |
1e8aac |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
1e8aac |
gchar *path;
|
|
Packit |
1e8aac |
cairo_surface_t *surface;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
object_class->finalize = glade_placeholder_finalize;
|
|
Packit |
1e8aac |
object_class->set_property = glade_placeholder_set_property;
|
|
Packit |
1e8aac |
object_class->get_property = glade_placeholder_get_property;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
widget_class->realize = glade_placeholder_realize;
|
|
Packit |
1e8aac |
widget_class->unrealize = glade_placeholder_unrealize;
|
|
Packit |
1e8aac |
widget_class->map = glade_placeholder_map;
|
|
Packit |
1e8aac |
widget_class->unmap = glade_placeholder_unmap;
|
|
Packit |
1e8aac |
widget_class->size_allocate = glade_placeholder_size_allocate;
|
|
Packit |
1e8aac |
widget_class->draw = glade_placeholder_draw;
|
|
Packit |
1e8aac |
widget_class->enter_notify_event = glade_placeholder_enter_notify_event;
|
|
Packit |
1e8aac |
widget_class->motion_notify_event = glade_placeholder_motion_notify_event;
|
|
Packit |
1e8aac |
widget_class->button_press_event = glade_placeholder_button_press;
|
|
Packit |
1e8aac |
widget_class->popup_menu = glade_placeholder_popup_menu;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* GtkScrollable implementation */
|
|
Packit |
1e8aac |
g_object_class_override_property (object_class, PROP_HADJUSTMENT,
|
|
Packit |
1e8aac |
"hadjustment");
|
|
Packit |
1e8aac |
g_object_class_override_property (object_class, PROP_VADJUSTMENT,
|
|
Packit |
1e8aac |
"vadjustment");
|
|
Packit |
1e8aac |
g_object_class_override_property (object_class, PROP_HSCROLL_POLICY,
|
|
Packit |
1e8aac |
"hscroll-policy");
|
|
Packit |
1e8aac |
g_object_class_override_property (object_class, PROP_VSCROLL_POLICY,
|
|
Packit |
1e8aac |
"vscroll-policy");
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Create our tiled background pattern */
|
|
Packit |
1e8aac |
path = g_build_filename (glade_app_get_pixmaps_dir (), "placeholder.png", NULL);
|
|
Packit |
1e8aac |
surface = cairo_image_surface_create_from_png (path);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (!surface)
|
|
Packit |
1e8aac |
g_warning ("Failed to create surface for %s\n", path);
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
placeholder_pattern = cairo_pattern_create_for_surface (surface);
|
|
Packit |
1e8aac |
cairo_pattern_set_extend (placeholder_pattern, CAIRO_EXTEND_REPEAT);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
g_free (path);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/**
|
|
Packit |
1e8aac |
* glade_placeholder_new:
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Returns: a new #GladePlaceholder cast as a #GtkWidget
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
GtkWidget *
|
|
Packit |
1e8aac |
glade_placeholder_new (void)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
return g_object_new (GLADE_TYPE_PLACEHOLDER, NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GladeProject *
|
|
Packit |
1e8aac |
glade_placeholder_get_project (GladePlaceholder *placeholder)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent;
|
|
Packit |
1e8aac |
parent = glade_placeholder_get_parent (placeholder);
|
|
Packit |
1e8aac |
return parent ? glade_widget_get_project (parent) : NULL;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GladeWidget *
|
|
Packit |
1e8aac |
glade_placeholder_get_parent (GladePlaceholder *placeholder)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkWidget *widget;
|
|
Packit |
1e8aac |
GladeWidget *parent = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_PLACEHOLDER (placeholder), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (widget = gtk_widget_get_parent (GTK_WIDGET (placeholder));
|
|
Packit |
1e8aac |
widget != NULL; widget = gtk_widget_get_parent (widget))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if ((parent = glade_widget_get_from_gobject (widget)) != NULL)
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
return parent;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GList *
|
|
Packit |
1e8aac |
glade_placeholder_packing_actions (GladePlaceholder *placeholder)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_PLACEHOLDER (placeholder), NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return placeholder->priv->packing_actions;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|