⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkhandlebox.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1998 Elliot Lee * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS * file for a list of people on the GTK+ Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/.  */#include <stdlib.h>#include "gdk/gdkx.h"#include "gtkhandlebox.h"#include "gtkmain.h"#include "gtksignal.h"#include "gtkwindow.h"enum {  ARG_0,  ARG_SHADOW,  ARG_HANDLE_POSITION,  ARG_SNAP_EDGE};#define DRAG_HANDLE_SIZE 10#define CHILDLESS_SIZE	25#define GHOST_HEIGHT 3#define TOLERANCE 5enum {  SIGNAL_CHILD_ATTACHED,  SIGNAL_CHILD_DETACHED,  SIGNAL_LAST};/* The algorithm for docking and redocking implemented here * has a couple of nice properties: * * 1) During a single drag, docking always occurs at the *    the same cursor position. This means that the users *    motions are reversible, and that you won't *    undock/dock oscillations. * * 2) Docking generally occurs at user-visible features. *    The user, once they figure out to redock, will *    have useful information about doing it again in *    the future. * * Please try to preserve these properties if you * change the algorithm. (And the current algorithm * is far from ideal). Briefly, the current algorithm * for deciding whether the handlebox is docked or not: * * 1) The decision is done by comparing two rectangles - the *    allocation if the widget at the start of the drag, *    and the boundary of hb->bin_window at the start of *    of the drag offset by the distance that the cursor *    has moved. * * 2) These rectangles must have one edge, the "snap_edge" *    of the handlebox, aligned within TOLERANCE. *  * 3) On the other dimension, the extents of one rectangle *    must be contained in the extents of the other, *    extended by tolerance. That is, either we can have: * * <-TOLERANCE-|--------bin_window--------------|-TOLERANCE-> *         <--------float_window--------------------> * * or we can have: * * <-TOLERANCE-|------float_window--------------|-TOLERANCE-> *          <--------bin_window--------------------> */static void gtk_handle_box_class_init     (GtkHandleBoxClass *klass);static void gtk_handle_box_init           (GtkHandleBox      *handle_box);static void gtk_handle_box_set_arg        (GtkObject         *object,					   GtkArg            *arg,					   guint              arg_id);static void gtk_handle_box_get_arg        (GtkObject         *object,					   GtkArg            *arg,					   guint              arg_id);static void gtk_handle_box_destroy        (GtkObject         *object);static void gtk_handle_box_map            (GtkWidget         *widget);static void gtk_handle_box_unmap          (GtkWidget         *widget);static void gtk_handle_box_realize        (GtkWidget         *widget);static void gtk_handle_box_unrealize      (GtkWidget         *widget);static void gtk_handle_box_style_set      (GtkWidget         *widget,					   GtkStyle          *previous_style);static void gtk_handle_box_size_request   (GtkWidget         *widget,					   GtkRequisition    *requisition);static void gtk_handle_box_size_allocate  (GtkWidget         *widget,					   GtkAllocation     *real_allocation);static void gtk_handle_box_add            (GtkContainer      *container,					   GtkWidget         *widget);static void gtk_handle_box_remove         (GtkContainer      *container,					   GtkWidget         *widget);static void gtk_handle_box_draw_ghost     (GtkHandleBox      *hb);static void gtk_handle_box_paint          (GtkWidget         *widget,					   GdkEventExpose    *event,					   GdkRectangle      *area);static void gtk_handle_box_draw           (GtkWidget         *widget,					   GdkRectangle      *area);static gint gtk_handle_box_expose         (GtkWidget         *widget,					   GdkEventExpose    *event);static gint gtk_handle_box_button_changed (GtkWidget         *widget,					   GdkEventButton    *event);static gint gtk_handle_box_motion         (GtkWidget         *widget,					   GdkEventMotion    *event);static gint gtk_handle_box_delete_event   (GtkWidget         *widget,					   GdkEventAny       *event);static void gtk_handle_box_reattach       (GtkHandleBox      *hb);static GtkBinClass *parent_class;static guint        handle_box_signals[SIGNAL_LAST] = { 0 };GtkTypegtk_handle_box_get_type (void){  static GtkType handle_box_type = 0;  if (!handle_box_type)    {      static const GtkTypeInfo handle_box_info =      {	"GtkHandleBox",	sizeof (GtkHandleBox),	sizeof (GtkHandleBoxClass),	(GtkClassInitFunc) gtk_handle_box_class_init,	(GtkObjectInitFunc) gtk_handle_box_init,	/* reserved_1 */ NULL,        /* reserved_2 */ NULL,        (GtkClassInitFunc) NULL,      };      handle_box_type = gtk_type_unique (GTK_TYPE_BIN, &handle_box_info);    }  return handle_box_type;}static voidgtk_handle_box_class_init (GtkHandleBoxClass *class){  GtkObjectClass *object_class;  GtkWidgetClass *widget_class;  GtkContainerClass *container_class;  object_class = (GtkObjectClass *) class;  widget_class = (GtkWidgetClass *) class;  container_class = (GtkContainerClass *) class;  parent_class = gtk_type_class (GTK_TYPE_BIN);    gtk_object_add_arg_type ("GtkHandleBox::shadow", GTK_TYPE_SHADOW_TYPE, GTK_ARG_READWRITE, ARG_SHADOW);  gtk_object_add_arg_type ("GtkHandleBox::handle_position", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_HANDLE_POSITION);  gtk_object_add_arg_type ("GtkHandleBox::snap_edge", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_SNAP_EDGE);  object_class->set_arg = gtk_handle_box_set_arg;  object_class->get_arg = gtk_handle_box_get_arg;    handle_box_signals[SIGNAL_CHILD_ATTACHED] =    gtk_signal_new ("child_attached",		    GTK_RUN_FIRST,		    object_class->type,		    GTK_SIGNAL_OFFSET (GtkHandleBoxClass, child_attached),		    gtk_marshal_NONE__POINTER,		    GTK_TYPE_NONE, 1,		    GTK_TYPE_WIDGET);  handle_box_signals[SIGNAL_CHILD_DETACHED] =    gtk_signal_new ("child_detached",		    GTK_RUN_FIRST,		    object_class->type,		    GTK_SIGNAL_OFFSET (GtkHandleBoxClass, child_detached),		    gtk_marshal_NONE__POINTER,		    GTK_TYPE_NONE, 1,		    GTK_TYPE_WIDGET);  gtk_object_class_add_signals (object_class, handle_box_signals, SIGNAL_LAST);    object_class->destroy = gtk_handle_box_destroy;  widget_class->map = gtk_handle_box_map;  widget_class->unmap = gtk_handle_box_unmap;  widget_class->realize = gtk_handle_box_realize;  widget_class->unrealize = gtk_handle_box_unrealize;  widget_class->style_set = gtk_handle_box_style_set;  widget_class->size_request = gtk_handle_box_size_request;  widget_class->size_allocate = gtk_handle_box_size_allocate;  widget_class->draw = gtk_handle_box_draw;  widget_class->expose_event = gtk_handle_box_expose;  widget_class->button_press_event = gtk_handle_box_button_changed;  widget_class->button_release_event = gtk_handle_box_button_changed;  widget_class->motion_notify_event = gtk_handle_box_motion;  widget_class->delete_event = gtk_handle_box_delete_event;  container_class->add = gtk_handle_box_add;  container_class->remove = gtk_handle_box_remove;  class->child_attached = NULL;  class->child_detached = NULL;}static voidgtk_handle_box_init (GtkHandleBox *handle_box){  GTK_WIDGET_UNSET_FLAGS (handle_box, GTK_NO_WINDOW);  handle_box->bin_window = NULL;  handle_box->float_window = NULL;  handle_box->shadow_type = GTK_SHADOW_OUT;  handle_box->handle_position = GTK_POS_LEFT;  handle_box->float_window_mapped = FALSE;  handle_box->child_detached = FALSE;  handle_box->in_drag = FALSE;  handle_box->shrink_on_detach = TRUE;  handle_box->snap_edge = -1;}static voidgtk_handle_box_set_arg (GtkObject *object,			GtkArg    *arg,			guint      arg_id){  GtkHandleBox *handle_box = GTK_HANDLE_BOX (object);  switch (arg_id)    {    case ARG_SHADOW:      gtk_handle_box_set_shadow_type (handle_box, GTK_VALUE_ENUM (*arg));      break;    case ARG_HANDLE_POSITION:      gtk_handle_box_set_handle_position (handle_box, GTK_VALUE_ENUM (*arg));      break;    case ARG_SNAP_EDGE:      gtk_handle_box_set_snap_edge (handle_box, GTK_VALUE_ENUM (*arg));      break;    }}static voidgtk_handle_box_get_arg (GtkObject *object,			GtkArg    *arg,			guint      arg_id){  GtkHandleBox *handle_box = GTK_HANDLE_BOX (object);    switch (arg_id)    {    case ARG_SHADOW:      GTK_VALUE_ENUM (*arg) = handle_box->shadow_type;      break;    case ARG_HANDLE_POSITION:      GTK_VALUE_ENUM (*arg) = handle_box->handle_position;      break;    case ARG_SNAP_EDGE:      GTK_VALUE_ENUM (*arg) = handle_box->snap_edge;      break;    default:      arg->type = GTK_TYPE_INVALID;      break;    }} GtkWidget*gtk_handle_box_new (void){  return GTK_WIDGET (gtk_type_new (gtk_handle_box_get_type ()));}static voidgtk_handle_box_destroy (GtkObject *object){  GtkHandleBox *hb;  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_HANDLE_BOX (object));  hb = GTK_HANDLE_BOX (object);  if (GTK_OBJECT_CLASS (parent_class)->destroy)    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);}static voidgtk_handle_box_map (GtkWidget *widget){  GtkBin *bin;  GtkHandleBox *hb;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_HANDLE_BOX (widget));  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);  bin = GTK_BIN (widget);  hb = GTK_HANDLE_BOX (widget);  if (bin->child &&      GTK_WIDGET_VISIBLE (bin->child) &&      !GTK_WIDGET_MAPPED (bin->child))    gtk_widget_map (bin->child);  if (hb->child_detached && !hb->float_window_mapped)    {      gdk_window_show (hb->float_window);      hb->float_window_mapped = TRUE;    }  gdk_window_show (hb->bin_window);  gdk_window_show (widget->window);}static voidgtk_handle_box_unmap (GtkWidget *widget){  GtkHandleBox *hb;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_HANDLE_BOX (widget));  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);  hb = GTK_HANDLE_BOX (widget);  gdk_window_hide (widget->window);  if (hb->float_window_mapped)    {      gdk_window_hide (hb->float_window);      hb->float_window_mapped = FALSE;    }}static voidgtk_handle_box_realize (GtkWidget *widget){  GdkWindowAttr attributes;  gint attributes_mask;  GtkHandleBox *hb;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_HANDLE_BOX (widget));  hb = GTK_HANDLE_BOX (widget);  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);  attributes.x = widget->allocation.x;  attributes.y = widget->allocation.y;  attributes.width = widget->allocation.width;  attributes.height = widget->allocation.height;  attributes.window_type = GDK_WINDOW_CHILD;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes.event_mask = (gtk_widget_get_events (widget)			   | GDK_EXPOSURE_MASK);  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);  gdk_window_set_user_data (widget->window, widget);  attributes.x = 0;  attributes.y = 0;  attributes.width = widget->allocation.width;  attributes.height = widget->allocation.height;  attributes.window_type = GDK_WINDOW_CHILD;  attributes.event_mask |= (gtk_widget_get_events (widget) |			    GDK_EXPOSURE_MASK |			    GDK_BUTTON1_MOTION_MASK |			    GDK_POINTER_MOTION_HINT_MASK |			    GDK_BUTTON_PRESS_MASK |			    GDK_BUTTON_RELEASE_MASK);  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  hb->bin_window = gdk_window_new (widget->window, &attributes, attributes_mask);  gdk_window_set_user_data (hb->bin_window, widget);  if (GTK_BIN (hb)->child)    gtk_widget_set_parent_window (GTK_BIN (hb)->child, hb->bin_window);    attributes.x = 0;  attributes.y = 0;  attributes.width = widget->requisition.width;  attributes.height = widget->requisition.height;  attributes.window_type = GDK_WINDOW_TOPLEVEL;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes.event_mask = (gtk_widget_get_events (widget) |			   GDK_KEY_PRESS_MASK |			   GDK_ENTER_NOTIFY_MASK |			   GDK_LEAVE_NOTIFY_MASK |			   GDK_FOCUS_CHANGE_MASK |			   GDK_STRUCTURE_MASK);  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  hb->float_window = gdk_window_new (NULL, &attributes, attributes_mask);  gdk_window_set_user_data (hb->float_window, widget);  gdk_window_set_decorations (hb->float_window, 0);    widget->style = gtk_style_attach (widget->style, widget->window);  gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (hb));  gtk_style_set_background (widget->style, hb->bin_window, GTK_WIDGET_STATE (hb));  gtk_style_set_background (widget->style, hb->float_window, GTK_WIDGET_STATE (hb));  gdk_window_set_back_pixmap (widget->window, NULL, TRUE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -