1 /*
2 * $Id: toolPalette.c,v 1.4 2005/01/01 15:27:54 baum Exp $
3 *
4 * This file implements the toolPalette widget which is a combination of the
5 * gtk toolPalette widget (TODO? and the gtk frame widget?)
6 *
7 * Copyright (c) 2001 - 2005 Peter G. Baum http://www.dr-baum.net
8 *
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 *
12 */
13
14 /*
15 History:
16 2013-07: added commands, options, commands
17 2011-04: Begin of developement
18 */
19
20 /**
21 \page page_toolPalette gnocl::toolPalette
22 \htmlinclude toolPalette.html
23 **/
24
25 #include "gnocl.h"
26
27 int gnoclOptDragDest ( Tcl_Interp *interp, GnoclOption *opt, GObject *obj, Tcl_Obj **ret );
28
29 static const int orientationIdx = 0;
30
31 static GnoclOption options[] =
32 {
33 /* widget specific options */
34 {"-orientation", GNOCL_OBJ, NULL},
35 {"-dragDest", GNOCL_OBJ, "", gnoclOptDragDest },
36
37 { "-iconSize", GNOCL_OBJ, NULL },
38 { "-iconSizeSet", GNOCL_OBJ, NULL },
39
40
41 /* widget signals */
42 { "-onSetScrollAdjustments", GNOCL_OBJ, "", gnoclOptOnScrollAdjustments}, /* taken from text.c, perhaps custom handler needed, see layout.c */
43
44 /* drag and drop */
45 { "-dropTargets", GNOCL_LIST, "t", gnoclOptDnDTargets },
46 { "-dragTargets", GNOCL_LIST, "s", gnoclOptDnDTargets },
47 { "-onDropData", GNOCL_OBJ, "", gnoclOptOnDropData },
48 { "-onDragData", GNOCL_OBJ, "", gnoclOptOnDragData },
49
50 /* general options */
51 { "-name", GNOCL_STRING, "name" },
52 { "-visible", GNOCL_BOOL, "visible" },
53 { "-sensitive", GNOCL_BOOL, "sensitive" },
54 { "-data", GNOCL_OBJ, "", gnoclOptData },
55 { "-tooltip", GNOCL_OBJ, "", gnoclOptTooltip },
56 { NULL },
57 };
58
59 /**
60 **/
dragDest_data_received(GtkWidget * toolbar,GdkDragContext * context,gint x,gint y,GtkSelectionData * selection,guint info,guint time,gpointer data)61 static void dragDest_data_received ( GtkWidget *toolbar,
62 GdkDragContext *context,
63 gint x,
64 gint y,
65 GtkSelectionData *selection,
66 guint info,
67 guint time,
68 gpointer data )
69 {
70 /* find the tool button, which is the source of this DnD operation */
71
72 GtkWidget *palette = gtk_drag_get_source_widget ( context );
73 //CanvasItem *canvas_item = NULL;
74
75 GtkToolbar *toolBar = NULL;
76 GtkWidget *tool_item = NULL;
77
78 while ( palette && !GTK_IS_TOOL_PALETTE ( palette ) )
79 {
80 palette = gtk_widget_get_parent ( palette );
81 }
82
83 if ( palette )
84 {
85 tool_item = gtk_tool_palette_get_drag_item ( GTK_TOOL_PALETTE ( palette ), selection );
86 }
87
88
89 /* append a new toolbar item when a tool button was found */
90
91 if ( GTK_IS_TOOL_ITEM ( tool_item ) )
92 {
93
94 gtk_toolbar_insert ( toolbar, tool_item, -1 );
95 }
96
97 }
98
99
100 /**
101 \brief
102 \note This command will configure 'dnd' communications between palette and toolbar.
103 **/
gnoclOptDragDest(Tcl_Interp * interp,GnoclOption * opt,GObject * obj,Tcl_Obj ** ret)104 int gnoclOptDragDest ( Tcl_Interp *interp, GnoclOption *opt, GObject *obj, Tcl_Obj **ret )
105 {
106 GtkFrame *frame;
107 GtkWidget *label_widget;
108 const char *txt;
109
110 GtkWidget *toolPalette = gtk_bin_get_child ( GTK_BIN ( obj ) );
111
112 GtkWidget *dragDest = gnoclGetWidgetFromName ( Tcl_GetString ( opt->val.obj ), interp );
113
114 /* Step 1) Configure DnD for the palette */
115
116 gtk_tool_palette_add_drag_dest ( GTK_TOOL_PALETTE ( toolPalette ),
117 GTK_WIDGET ( dragDest ),
118 GTK_DEST_DEFAULT_ALL,
119 GTK_TOOL_PALETTE_DRAG_ITEMS |
120 GTK_TOOL_PALETTE_DRAG_GROUPS,
121 GDK_ACTION_MOVE );
122
123
124 /* Step 2) Configure DnD for the toolbar */
125
126 g_object_connect ( dragDest, "signal::drag-data-received", dragDest_data_received, NULL, NULL );
127
128 return TCL_OK;
129 }
130
131
132 /**
133 \brief
134 **/
configure(Tcl_Interp * interp,GtkWidget * palette_scroller,GnoclOption options[])135 static int configure ( Tcl_Interp *interp, GtkWidget *palette_scroller, GnoclOption options[] )
136 {
137 debugStep ( __FUNCTION__, 1 );
138
139 GtkWidget *toolPalette = gtk_bin_get_child ( GTK_BIN ( palette_scroller ) );
140
141 /* set orientation of the toolpalette */
142 if ( options[orientationIdx].status == GNOCL_STATUS_CHANGED )
143 {
144
145 if ( strcmp ( Tcl_GetString ( options[orientationIdx].val.obj ), "horizontal" ) == 0 )
146 {
147 gtk_orientable_set_orientation ( GTK_ORIENTABLE ( toolPalette ), GTK_ORIENTATION_HORIZONTAL );
148
149 }
150
151 else if ( strcmp ( Tcl_GetString ( options[orientationIdx].val.obj ), "vertical" ) == 0 )
152 {
153
154 gtk_orientable_set_orientation ( GTK_ORIENTABLE ( toolPalette ), GTK_ORIENTATION_VERTICAL );
155 }
156
157 else
158 {
159 return TCL_ERROR;
160 }
161
162 }
163
164 return TCL_OK;
165 }
166
167 static const char *cmds[] =
168 {
169 "addGroup",
170 "delete", "configure", "class", "parent",
171 NULL
172 };
173 /**
174 \brief
175 **/
toolPaletteFunc(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * const objv[])176 int toolPaletteFunc ( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[] )
177 {
178
179 debugStep ( __FUNCTION__, 1 );
180
181
182
183 enum cmdIdx
184 {
185 AddGroupIdx,
186 DeleteIdx, ConfigureIdx, ClassIdx, ParentIdx
187 };
188
189 GtkWidget *palette_scroller = GTK_WIDGET ( data );
190
191 GtkWidget *toolPalette = gtk_bin_get_child ( GTK_BIN ( palette_scroller ) );
192
193 int idx;
194
195 if ( Tcl_GetIndexFromObj ( interp, objv[1], cmds, "command", TCL_EXACT, &idx ) != TCL_OK )
196 return TCL_ERROR;
197
198 switch ( idx )
199 {
200
201 case AddGroupIdx:
202 {
203
204 return addGroup ( toolPalette, interp, objc, objv );
205 }
206 break;
207 case ClassIdx:
208 {
209 Tcl_SetObjResult ( interp, Tcl_NewStringObj ( "toolPalette", -1 ) );
210 }
211 break;
212 case DeleteIdx:
213 {
214 return gnoclDelete ( interp, GTK_WIDGET ( palette_scroller ), objc, objv );
215 }
216
217 case ConfigureIdx:
218 {
219 int ret = TCL_ERROR;
220
221 if ( gnoclParseAndSetOptions ( interp, objc - 1, objv + 1,
222 options, G_OBJECT ( palette_scroller ) ) == TCL_OK )
223 {
224 ret = configure ( interp, palette_scroller, options );
225 }
226
227 gnoclClearOptions ( options );
228
229 return ret;
230 }
231 case ParentIdx:
232 {
233 return TCL_OK;
234 }
235
236 break;
237 }
238
239 return TCL_OK;
240 }
241
242 /**
243 \brief
244 **/
gnoclToolPaletteCmd(ClientData data,Tcl_Interp * interp,int objc,Tcl_Obj * const objv[])245 int gnoclToolPaletteCmd ( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[] )
246 {
247 if ( gnoclGetCmdsAndOpts ( interp, cmds, options, objv, objc ) == TCL_OK )
248 {
249 return TCL_OK;
250 }
251
252 int ret;
253 GtkWidget *group;
254
255 GtkToolItem *item;
256
257
258 GtkWidget *palette = NULL;
259 GtkWidget *palette_scroller = NULL;
260 GtkWidget *notebook = NULL;
261 GtkWidget *contents = NULL;
262 GtkWidget *contents_scroller = NULL;
263
264
265 if ( gnoclParseOptions ( interp, objc, objv, options ) != TCL_OK )
266 {
267 gnoclClearOptions ( options );
268 return TCL_ERROR;
269 }
270
271 palette = gtk_tool_palette_new ();
272
273 palette_scroller = gtk_scrolled_window_new ( NULL, NULL );
274 gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( palette_scroller ),
275 GTK_POLICY_AUTOMATIC,
276 GTK_POLICY_AUTOMATIC );
277
278 gtk_container_add ( GTK_CONTAINER ( palette_scroller ), palette );
279
280
281 ret = gnoclSetOptions ( interp, options, G_OBJECT ( palette ), -1 );
282
283 if ( ret == TCL_OK )
284 {
285 ret = configure ( interp, palette_scroller, options );
286 }
287
288 gnoclClearOptions ( options );
289
290 if ( ret != TCL_OK )
291 {
292 gtk_widget_destroy ( GTK_WIDGET ( palette_scroller ) );
293 return TCL_ERROR;
294 }
295
296 /* TODO: if not -visible == 0 */
297 gtk_widget_show_all ( GTK_WIDGET ( palette_scroller ) );
298
299
300 return gnoclRegisterWidget ( interp, GTK_WIDGET ( palette_scroller ), toolPaletteFunc );
301 }
302