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