fix rules for optional plugins.
[galan.git] / src / shcomp.c
blobcf04a8e2af94982960e6393c27f239a65deaa044
1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * this is gencomp.c from tony. I modifie it to be shcomp.c
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
30 #include <gdk/gdk.h>
31 #include <gtk/gtk.h>
33 #include "global.h"
34 #include "generator.h"
35 #include "comp.h"
36 #include "sheet.h"
37 #include "msgbox.h"
38 #include "control.h"
39 #include "gencomp.h"
40 #include "shcomp.h"
41 #include "iscomp.h"
42 #include "gui.h"
44 /* %%% Win32: dirent.h seems to conflict with glib-1.3, so ignore dirent.h */
45 #ifndef G_PLATFORM_WIN32
46 #include <dirent.h>
47 #endif
49 /* On Win32, these headers seem to need to follow glib.h */
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <unistd.h>
54 #define SHCOMP_ICONLENGTH 48
55 #define SHCOMP_TITLEHEIGHT 15
56 #define SHCOMP_CONNECTOR_SPACE 5
57 #define SHCOMP_CONNECTOR_WIDTH 10
58 #define SHCOMP_BORDER_WIDTH (SHCOMP_CONNECTOR_WIDTH + SHCOMP_CONNECTOR_SPACE)
61 //PRIVATE int next_component_number = 1;
62 //PRIVATE ComponentClass InterSheetComponentClass; /* forward reference */
63 PRIVATE ComponentClass SheetComponentClass;
64 PRIVATE void do_control(Component *c, guint action, GtkWidget *widget);
66 PRIVATE void build_connectors(Component *c, int count, gboolean is_outbound, gboolean is_signal) {
67 int i;
69 for (i = 0; i < count; i++)
70 comp_new_connector(c, is_signal? COMP_SIGNAL_CONNECTOR : COMP_EVENT_CONNECTOR,
71 is_outbound, i,
72 0, 0);
75 PRIVATE void resize_connectors(Component *c, int count,
76 gboolean is_outbound, gboolean is_signal,
77 int hsize, int vsize) {
78 int spacing = (is_signal ? vsize : hsize) / (count + 1);
79 int startpos = is_outbound ? (SHCOMP_BORDER_WIDTH * 2
80 + (is_signal ? hsize : vsize)
81 - (SHCOMP_CONNECTOR_WIDTH >> 1))
82 : (SHCOMP_CONNECTOR_WIDTH >> 1);
83 int x = is_signal ? startpos : SHCOMP_BORDER_WIDTH + spacing;
84 int y = is_signal ? SHCOMP_BORDER_WIDTH + spacing : startpos;
85 int dx = is_signal ? 0 : spacing;
86 int dy = is_signal ? spacing : 0;
87 int i;
89 for (i = 0; i < count; i++, x += dx, y += dy) {
90 ConnectorReference ref = { c, is_signal ? COMP_SIGNAL_CONNECTOR : COMP_EVENT_CONNECTOR,
91 is_outbound, i };
92 Connector *con = comp_get_connector(&ref);
94 con->x = x;
95 con->y = y;
99 PUBLIC void shcomp_resize(Component *c) {
100 int body_vert, body_horiz;
101 ShCompData *data = c->data;
103 gboolean icon=FALSE;
106 body_vert =
107 SHCOMP_CONNECTOR_WIDTH
108 + MAX(MAX(data->isl.anzinputsignals, data->isl.anzoutputsignals) * SHCOMP_CONNECTOR_WIDTH,
109 SHCOMP_TITLEHEIGHT + (icon ? SHCOMP_ICONLENGTH : 0));
110 body_horiz =
111 SHCOMP_CONNECTOR_WIDTH
112 + MAX(2,
113 MAX(sheet_get_textwidth(c->sheet, data->sheet->name),
114 MAX(data->isl.anzinputevents * SHCOMP_CONNECTOR_WIDTH,
115 data->isl.anzoutputevents * SHCOMP_CONNECTOR_WIDTH)));
117 resize_connectors(c, data->isl.anzinputevents, 0, 0, body_horiz, body_vert);
118 resize_connectors(c, data->isl.anzinputsignals, 0, 1, body_horiz, body_vert);
119 resize_connectors(c, data->isl.anzoutputevents, 1, 0, body_horiz, body_vert);
120 resize_connectors(c, data->isl.anzoutputsignals, 1, 1, body_horiz, body_vert);
122 c->width = body_horiz + 2 * SHCOMP_BORDER_WIDTH + 1;
123 c->height = body_vert + 2 * SHCOMP_BORDER_WIDTH + 1;
127 * make InterSheetLinks -> list<list< Components >>.
128 * but why ?
129 * what are the components for ?
132 PRIVATE InterSheetLinks *find_intersheet_links( Sheet *sheet ) {
134 gboolean warned = FALSE;
135 GList *lst = sheet->components;
136 InterSheetLinks *isl = safe_malloc( sizeof(InterSheetLinks) );
137 isl->inputevents = NULL;
138 isl->outputevents = NULL;
139 isl->inputsignals = NULL;
140 isl->outputsignals = NULL;
142 isl->anzinputevents = 0;
143 isl->anzoutputevents = 0;
144 isl->anzinputsignals = 0;
145 isl->anzoutputsignals = 0;
147 while (lst != NULL) {
148 Component *c = lst->data;
150 if ( ! strcmp( c->klass->class_tag, "iscomp" ) ) {
152 ISCompData *d=c->data;
153 if( d->ref != NULL )
155 switch( ((ISCompData *) c->data)->reftype ) {
156 case SIGIN:
157 isl->outputsignals = g_list_append(isl->outputsignals, c );
158 isl->anzoutputsignals++;
159 break;
160 case SIGOUT:
161 isl->inputsignals = g_list_append(isl->inputsignals, c );
162 isl->anzinputsignals++;
163 break;
164 case EVTIN:
165 isl->outputevents = g_list_append(isl->outputevents, c );
166 isl->anzoutputevents++;
167 break;
168 case EVTOUT:
169 isl->inputevents = g_list_append(isl->inputevents, c );
170 isl->anzinputevents++;
171 break;
173 } else {
174 if( !warned ) {
175 warned = TRUE;
176 popup_msgbox("Warning", MSGBOX_OK, 120000, MSGBOX_OK,
177 "Unconnected Intersheet Component on Sheet %s..", sheet->name );
181 lst = g_list_next(lst);
183 return isl;
189 * There must be a different init_data for the load from file
190 * library components...
192 * ansonsten ist das aber das selbe hier mit dem ganzen Kram...
193 * ich habe dann zwei component klassen, die sich nur durch
194 * den konstruktor unterscheiden... sp"ater aber auch durch
195 * das pickle unpickle geraffel... obwohl
196 * das probleme gibt, wegen den generator links :(
198 * erster Versuch ist
200 * konstruktor mit load file, register sheet, aufruf von shcomp_init
202 * ansonsten das selbe...
204 * TODO: shared component code in eigenes Teil packen...
208 PRIVATE int shcomp_initialize(Component *c, gpointer init_data) {
210 ShCompData *d = safe_malloc(sizeof(ShCompData));
211 ShCompInitData *id = (ShCompInitData *) init_data;
213 InterSheetLinks *isl = find_intersheet_links( id->sheet );
215 d->sheet = id->sheet;
217 sheet_register_ref( id->sheet, c );
219 d->isl = *isl;
221 //d->panel_control_active = FALSE;
223 build_connectors(c, d->isl.anzinputevents, 0, 0);
224 build_connectors(c, d->isl.anzinputsignals, 0, 1);
225 build_connectors(c, d->isl.anzoutputevents, 1, 0);
226 build_connectors(c, d->isl.anzoutputsignals, 1, 1);
228 c->x -= SHCOMP_BORDER_WIDTH;
229 c->y -= SHCOMP_BORDER_WIDTH;
230 c->width = c->height = 0;
231 c->data = d;
234 shcomp_resize(c);
236 return 1;
239 PRIVATE Component *shcomp_clone(Component *c, Sheet *sheet) {
240 ShCompData *d = c->data;
242 Sheet *newsheet = sheet_clone( d->sheet );
244 if( newsheet == NULL )
245 return NULL;
247 ShCompInitData id;
248 Component *retval;
250 id.sheet = newsheet;
251 retval = comp_new_component( &SheetComponentClass, &id, sheet, 0, 0 );
253 if( retval == NULL ) {
254 sheet_remove( newsheet );
255 return NULL;
258 if( d->sheet->panel_control_active ) {
260 do_control( retval, 0, NULL );
261 newsheet->panel_control->frame_visible = d->sheet->panel_control->frame_visible;
263 if( ! (newsheet->panel_control->frame_visible) ) {
264 gtk_frame_set_shadow_type (GTK_FRAME (newsheet->panel_control->title_frame) , GTK_SHADOW_NONE);
265 gtk_frame_set_label (GTK_FRAME (newsheet->panel_control->title_frame) , NULL);
266 gtk_label_set_text(GTK_LABEL(newsheet->panel_control->title_label)," ");
269 newsheet->panel_control->control_visible = d->sheet->panel_control->control_visible;
271 if( ! (newsheet->panel_control->control_visible) ) {
272 gtk_widget_hide( newsheet->panel_control->widget );
275 control_moveto( newsheet->panel_control, d->sheet->panel_control->x, d->sheet->panel_control->y );
277 //shcomp_resize( retval );
279 return retval;
282 PRIVATE int fileshcomp_initialize(Component *c, gpointer init_data) {
283 FileShCompInitData *id = (FileShCompInitData *) init_data;
284 int retval;
286 ShCompInitData *shcid = safe_malloc( sizeof( ShCompInitData ) );
287 //printf( "hi %s\n", id->filename );
288 FILE *f = fopen( id->filename, "rb" );
290 sheet_set_load_hidden( TRUE );
291 shcid->sheet = sheet_loadfrom( NULL, f );
292 sheet_set_load_hidden( FALSE );
293 fclose( f );
294 retval = shcomp_initialize( c, shcid );
295 free(shcid);
296 return retval;
299 PRIVATE void shcomp_destroy(Component *c) {
300 ShCompData *d = c->data;
302 sheet_unregister_ref( d->sheet, c );
304 if( !sheet_has_refs( d->sheet ) && d->sheet->panel_control_active )
305 control_kill_control( d->sheet->panel_control, FALSE );
307 if( !sheet_has_refs( d->sheet ) && ! d->sheet->visible )
308 sheet_remove( d->sheet );
310 //free(d->name);
311 //g_list_free( d->isl.inputevents );
312 //g_list_free( d->isl.outputevents );
313 //g_list_free( d->isl.inputsignals);
314 //g_list_free( d->isl.outputsignals );
317 safe_free(d);
320 PRIVATE void shcomp_unpickle(Component *c, ObjectStoreItem *item, ObjectStore *db) {
321 ShCompData *d = safe_malloc(sizeof(ShCompData));
323 d->sheet = sheet_unpickle( objectstore_item_get_object( item, "othersheet" ) );
325 sheet_register_ref( d->sheet, c );
326 //ShCompInitData *id;
328 //d->name = safe_string_dup( objectstore_item_get_string(item, "name", "was geht denn hier ???" ) );
329 //d->reftype = objectstore_item_get_integer(item, "reftype", SIGIN );
331 d->isl.anzinputevents = objectstore_item_get_integer(item, "isl_anzinputevents", 0 );
332 d->isl.anzoutputevents = objectstore_item_get_integer(item, "isl_anzoutputevents", 0 );
333 d->isl.anzinputsignals = objectstore_item_get_integer(item, "isl_anzinputsignals", 0 );
334 d->isl.anzoutputsignals = objectstore_item_get_integer(item, "isl_anzoutputsignals", 0 );
336 d->isl.inputevents = objectstore_extract_list_of_items( objectstore_item_get( item, "isl_inputevents"),
337 item->db, (objectstore_unpickler_t) comp_unpickle);
338 d->isl.outputevents = objectstore_extract_list_of_items( objectstore_item_get( item, "isl_outputevents"),
339 item->db, (objectstore_unpickler_t) comp_unpickle);
340 d->isl.inputsignals = objectstore_extract_list_of_items( objectstore_item_get( item, "isl_inputsignals"),
341 item->db, (objectstore_unpickler_t) comp_unpickle);
342 d->isl.outputsignals = objectstore_extract_list_of_items( objectstore_item_get( item, "isl_outputsignals"),
343 item->db, (objectstore_unpickler_t) comp_unpickle);
346 c->data = d;
347 //validate_connectors(c);
348 shcomp_resize(c); /* because things may be different if loading on a different
349 system from the one we saved with */
352 PRIVATE void shcomp_pickle(Component *c, ObjectStoreItem *item, ObjectStore *db) {
353 ShCompData *d = c->data;
355 objectstore_item_set_object(item, "othersheet", sheet_pickle(d->sheet, db) );
356 objectstore_item_set_integer(item, "isl_anzinputevents", d->isl.anzinputevents );
357 objectstore_item_set_integer(item, "isl_anzoutputevents", d->isl.anzoutputevents );
358 objectstore_item_set_integer(item, "isl_anzinputsignals", d->isl.anzinputsignals );
359 objectstore_item_set_integer(item, "isl_anzoutputsignals", d->isl.anzoutputsignals );
360 objectstore_item_set(item, "isl_inputevents", objectstore_create_list_of_items( d->isl.inputevents, db,
361 (objectstore_pickler_t) comp_pickle) );
362 objectstore_item_set(item, "isl_outputevents", objectstore_create_list_of_items( d->isl.outputevents, db,
363 (objectstore_pickler_t) comp_pickle) );
364 objectstore_item_set(item, "isl_inputsignals", objectstore_create_list_of_items( d->isl.inputsignals, db,
365 (objectstore_pickler_t) comp_pickle) );
366 objectstore_item_set(item, "isl_outputsignals", objectstore_create_list_of_items( d->isl.outputsignals, db,
367 (objectstore_pickler_t) comp_pickle) );
369 //objectstore_item_set_integer(item, "reftype", d->reftype);
373 /* %%% Is this due to GTK changing from 1.2.x to 1.3.x, or is it a bug? */
374 #ifdef NATIVE_WIN32
375 #define FULLCIRCLE_DEGREES_NUMBER 72000
376 #else
377 #define FULLCIRCLE_DEGREES_NUMBER 36000
378 #endif
380 PRIVATE Component *shcomp_get_linked_componenent( Component *c, ConnectorReference *ref ) {
382 Component *cc;
383 ShCompData *d = c->data;
384 GList *lst = (ref->kind == COMP_SIGNAL_CONNECTOR)
385 ? (ref->is_output
386 ? d->isl.outputsignals : d->isl.inputsignals )
387 : (ref->is_output
388 ? d->isl.outputevents : d->isl.inputevents );
390 cc = g_list_nth( lst, ref->queue_number )->data;
391 return cc;
395 PRIVATE void shcomp_paint(Component *c, GdkRectangle *area,
396 GdkDrawable *drawable, GtkStyle *style, GdkColor *colors) {
397 ShCompData *d = c->data;
398 GList *l = c->connectors;
399 GdkGC *gc = style->black_gc;
401 while (l != NULL) {
402 Connector *con = l->data;
403 Component *linked = shcomp_get_linked_componenent( c, &(con->ref) );
404 ISCompData *isdata = linked->data;
405 ConnectorReference *tref = isdata->ref;
407 int colidx;
408 int x, y;
410 if( !connectorreference_equal( &(con->ref), &(c->sheet->highlight_ref) ) )
411 colidx = COMP_COLOR_VIOLET;
412 else
413 if ((tref->kind == COMP_SIGNAL_CONNECTOR)
414 && ((tref->is_output
415 ? ((GenCompData *)tref->c->data)->g->klass->out_sigs[tref->queue_number].flags
416 : ((GenCompData *)tref->c->data)->g->klass->in_sigs[tref->queue_number].flags) & SIG_FLAG_RANDOMACCESS))
417 colidx = (con->refs == NULL) ? COMP_COLOR_RED : COMP_COLOR_YELLOW;
418 else
419 colidx = (con->refs == NULL) ? COMP_COLOR_BLUE : COMP_COLOR_GREEN;
422 gdk_gc_set_foreground(gc, &colors[colidx]);
423 gdk_draw_arc(drawable, gc, TRUE,
424 con->x + c->x - (SHCOMP_CONNECTOR_WIDTH>>1),
425 con->y + c->y - (SHCOMP_CONNECTOR_WIDTH>>1),
426 SHCOMP_CONNECTOR_WIDTH,
427 SHCOMP_CONNECTOR_WIDTH,
428 0, FULLCIRCLE_DEGREES_NUMBER);
429 gdk_gc_set_foreground(gc, &colors[COMP_COLOR_WHITE]);
430 gdk_draw_arc(drawable, gc, FALSE,
431 con->x + c->x - (SHCOMP_CONNECTOR_WIDTH>>1),
432 con->y + c->y - (SHCOMP_CONNECTOR_WIDTH>>1),
433 SHCOMP_CONNECTOR_WIDTH,
434 SHCOMP_CONNECTOR_WIDTH,
435 0, FULLCIRCLE_DEGREES_NUMBER);
437 x = ((con->ref.kind == COMP_SIGNAL_CONNECTOR)
438 ? (con->ref.is_output
439 ? con->x - (SHCOMP_CONNECTOR_SPACE + (SHCOMP_CONNECTOR_WIDTH>>1))
440 : con->x + (SHCOMP_CONNECTOR_WIDTH>>1))
441 : con->x) + c->x;
443 y = ((con->ref.kind == COMP_EVENT_CONNECTOR)
444 ? (con->ref.is_output
445 ? con->y - (SHCOMP_CONNECTOR_SPACE + (SHCOMP_CONNECTOR_WIDTH>>1))
446 : con->y + (SHCOMP_CONNECTOR_WIDTH>>1))
447 : con->y) + c->y;
449 gdk_draw_line(drawable, gc,
450 x, y,
451 (con->ref.kind == COMP_SIGNAL_CONNECTOR ? x + SHCOMP_CONNECTOR_SPACE : x),
452 (con->ref.kind == COMP_SIGNAL_CONNECTOR ? y : y + SHCOMP_CONNECTOR_SPACE));
454 l = g_list_next(l);
457 gdk_gc_set_foreground(gc, &style->black);
458 gdk_draw_rectangle(drawable, gc, TRUE,
459 c->x + SHCOMP_BORDER_WIDTH,
460 c->y + SHCOMP_BORDER_WIDTH,
461 c->width - 2 * SHCOMP_BORDER_WIDTH,
462 c->height - 2 * SHCOMP_BORDER_WIDTH);
463 gdk_gc_set_foreground(gc, &colors[2]);
464 gdk_draw_rectangle(drawable, gc, FALSE,
465 c->x + SHCOMP_BORDER_WIDTH,
466 c->y + SHCOMP_BORDER_WIDTH,
467 c->width - 2 * SHCOMP_BORDER_WIDTH - 1,
468 c->height - 2 * SHCOMP_BORDER_WIDTH - 1);
470 gdk_gc_set_foreground(gc, &colors[COMP_COLOR_WHITE]);
471 gdk_draw_text(drawable, gtk_style_get_font(style), gc,
472 c->x + SHCOMP_BORDER_WIDTH + (SHCOMP_CONNECTOR_WIDTH>>1),
473 c->y + SHCOMP_BORDER_WIDTH + SHCOMP_TITLEHEIGHT - 3,
474 d->sheet->name, strlen(d->sheet->name));
476 gdk_gc_set_foreground(gc, &style->black);
478 if (NULL != NULL)
479 gdk_draw_pixmap(drawable, gc, NULL, 0, 0,
480 c->x + (c->width>>1) - (SHCOMP_ICONLENGTH>>1),
481 c->y + ((c->height-SHCOMP_TITLEHEIGHT)>>1) - (SHCOMP_ICONLENGTH>>1)
482 + SHCOMP_TITLEHEIGHT,
483 SHCOMP_ICONLENGTH,
484 SHCOMP_ICONLENGTH);
487 PRIVATE int shcomp_find_connector_at(Component *c, gint x, gint y, ConnectorReference *ref) {
488 GList *l = c->connectors;
490 x -= c->x;
491 y -= c->y;
493 while (l != NULL) {
494 Connector *con = l->data;
496 if (ABS(x - con->x) < (SHCOMP_CONNECTOR_WIDTH>>1) &&
497 ABS(y - con->y) < (SHCOMP_CONNECTOR_WIDTH>>1)) {
498 if (ref != NULL)
499 *ref = con->ref;
500 return 1;
503 l = g_list_next(l);
506 return 0;
509 PRIVATE int shcomp_contains_point(Component *c, gint x, gint y) {
510 gint dx = x - c->x;
511 gint dy = y - c->y;
513 if (dx >= SHCOMP_BORDER_WIDTH &&
514 dy >= SHCOMP_BORDER_WIDTH &&
515 dx < (c->width - SHCOMP_BORDER_WIDTH) &&
516 dy < (c->height - SHCOMP_BORDER_WIDTH))
517 return 1;
519 return shcomp_find_connector_at(c, x, y, NULL);
523 PRIVATE gboolean shcomp_accept_outbound(Component *c, ConnectorReference *src,
524 ConnectorReference *dst) {
526 Component *linked = shcomp_get_linked_componenent( c, src );
527 ISCompData *isdata = linked->data;
528 ConnectorReference *tref = isdata->ref;
530 return tref->c->klass->accept_outbound( tref->c, tref, dst );
533 PRIVATE gboolean shcomp_accept_inbound(Component *c, ConnectorReference *src,
534 ConnectorReference *dst) {
536 Component *linked = shcomp_get_linked_componenent( c, dst );
537 ISCompData *isdata = linked->data;
538 ConnectorReference *tref = isdata->ref;
540 return src->c->klass->accept_outbound( src->c, src, tref );
543 PRIVATE gboolean shcomp_unlink_outbound(Component *c, ConnectorReference *src,
544 ConnectorReference *dst) {
546 Component *linked = shcomp_get_linked_componenent( c, src );
547 ISCompData *isdata = linked->data;
548 ConnectorReference *tref = isdata->ref;
550 return tref->c->klass->unlink_outbound( tref->c, tref, dst );
553 PRIVATE gboolean shcomp_unlink_inbound(Component *c, ConnectorReference *src,
554 ConnectorReference *dst) {
555 Component *linked = shcomp_get_linked_componenent( c, dst );
556 ISCompData *isdata = linked->data;
557 ConnectorReference *tref = isdata->ref;
559 return src->c->klass->unlink_outbound( src->c, src, tref );
562 PRIVATE char *shcomp_get_title(Component *c) {
564 ShCompData *d = c->data;
565 return safe_string_dup( d->sheet->name );
568 PRIVATE char *shcomp_get_connector_name(Component *c, ConnectorReference *ref) {
570 Component *cc;
571 ShCompData *d = c->data;
572 GList *lst = (ref->kind == COMP_SIGNAL_CONNECTOR)
573 ? (ref->is_output
574 ? d->isl.outputsignals : d->isl.inputsignals )
575 : (ref->is_output
576 ? d->isl.outputevents : d->isl.inputevents );
578 cc = g_list_nth( lst, ref->queue_number )->data;
579 return cc->klass->get_title( cc );
584 PRIVATE void do_rename(Component *c, guint action, GtkWidget *widget) {
585 ShCompData *d = c->data;
586 sheet_rename( d->sheet );
589 PRIVATE GtkWidget *panel_fixed = NULL;
591 PRIVATE void init_panel( Control *control ) {
592 control->widget = panel_fixed;
594 PRIVATE void done_panel( Control *control ) {
596 GtkWidget *viewport;
598 control->this_panel->sheet->panel_control_active = FALSE;
599 control->this_panel->sheet->panel_control = NULL;
601 control_panel_register_panel( control->this_panel, control->this_panel->name, FALSE );
603 viewport = gtk_viewport_new (gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(control->this_panel->scrollwin)),
604 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(control->this_panel->scrollwin)));
607 gtk_container_add (GTK_CONTAINER (control->this_panel->scrollwin), viewport);
608 gtk_widget_show( viewport );
609 gtk_widget_reparent( control->this_panel->fixedwidget, viewport );
612 PRIVATE ControlDescriptor desc =
613 { CONTROL_KIND_PANEL, "panel", 0,0,0,0, 0,FALSE, TRUE,0, init_panel, done_panel, NULL, NULL };
615 PRIVATE void do_control(Component *c, guint action, GtkWidget *widget) {
616 ShCompData *d = c->data;
618 //gtk_object_ref( GTK_OBJECT(d->sheet->control_panel->fixedwidget) );
619 desc.refresh_data = d->sheet->control_panel;
620 panel_fixed = d->sheet->control_panel->fixedwidget;
621 d->sheet->panel_control = control_new_control( &desc, NULL, c->sheet->control_panel );
622 d->sheet->panel_control_active = TRUE;
623 control_panel_unregister_panel( d->sheet->control_panel );
626 PUBLIC void shcomp_do_control( Component *c ) {
627 do_control( c, 0, NULL );
630 //PRIVATE void do_props(Component *c, guint action, GtkWidget *widget) {
631 // ShCompData *d = c->data;
632 // if (d->propgen)
633 // d->propgen(c, d->g);
638 PRIVATE void do_visible(Component *c, guint action, GtkWidget *widget) {
640 ShCompData *d = c->data;
641 GtkCheckMenuItem *check = GTK_CHECK_MENU_ITEM( widget );
642 gboolean visible = gtk_check_menu_item_get_active( check );
644 if( d->sheet->visible == visible )
645 return;
647 if( visible )
649 d->sheet->visible = TRUE;
650 gui_register_sheet( d->sheet );
652 else
654 d->sheet->visible = TRUE;
655 gui_unregister_sheet( d->sheet );
656 d->sheet->visible = FALSE;
661 PRIVATE void do_delete(Component *c, guint action, GtkWidget *widget) {
662 sheet_delete_component(c->sheet, c);
665 PRIVATE GtkItemFactoryEntry popup_items[] = {
666 { "/_Rename...", NULL, do_rename, 0, NULL },
667 { "/Add _Control", NULL, do_control, 0, NULL },
668 { "/Sheet visible", NULL, do_visible, 0, "<ToggleItem>" },
669 // { "/_Properties...", NULL, do_props, 0, NULL },
670 { "/sep1", NULL, NULL, 0, "<Separator>" },
671 { "/_Delete", NULL, do_delete, 0, NULL },
674 PRIVATE void kill_popup(GtkWidget *popup, GtkItemFactory *ifact) {
675 gtk_object_unref(GTK_OBJECT(ifact));
678 PRIVATE GtkWidget *shcomp_build_popup(Component *c) {
679 ShCompData *d = c->data;
680 GtkItemFactory *ifact;
681 int nitems = sizeof(popup_items) / sizeof(popup_items[0]);
682 GtkWidget *result;
684 ifact = gtk_item_factory_new(GTK_TYPE_MENU, "<shcomp-popup>", NULL);
685 gtk_item_factory_create_items(ifact, nitems, popup_items, c);
687 result = gtk_item_factory_get_widget(ifact, "<shcomp-popup>");
689 if( d->sheet->panel_control_active )
690 gtk_widget_set_state(gtk_item_factory_get_item(ifact, "<shcomp-popup>/Add Control"),
691 GTK_STATE_INSENSITIVE);
693 gtk_check_menu_item_set_active(
694 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item( ifact, "<shcomp-popup>/Sheet visible" )),
695 d->sheet->visible );
698 gtk_signal_connect(GTK_OBJECT(result), "destroy", GTK_SIGNAL_FUNC(kill_popup), ifact);
700 return result;
703 PRIVATE ComponentClass SheetComponentClass = {
704 "shcomp",
706 shcomp_initialize,
707 shcomp_destroy,
708 shcomp_clone,
710 shcomp_unpickle,
711 shcomp_pickle,
713 shcomp_paint,
715 shcomp_find_connector_at,
716 shcomp_contains_point,
718 shcomp_accept_outbound,
719 shcomp_accept_inbound,
720 shcomp_unlink_outbound,
721 shcomp_unlink_inbound,
723 shcomp_get_title,
724 shcomp_get_connector_name,
726 shcomp_build_popup
729 PRIVATE ComponentClass FileSheetComponentClass = {
730 "shcomp",
732 fileshcomp_initialize,
733 shcomp_destroy,
734 shcomp_clone,
736 shcomp_unpickle,
737 shcomp_pickle,
739 shcomp_paint,
741 shcomp_find_connector_at,
742 shcomp_contains_point,
744 shcomp_accept_outbound,
745 shcomp_accept_inbound,
746 shcomp_unlink_outbound,
747 shcomp_unlink_inbound,
749 shcomp_get_title,
750 shcomp_get_connector_name,
752 shcomp_build_popup
756 // Code for the Sheet Library
757 // nice and compact :)
759 PRIVATE void add_gsheet(char *plugin, char *leafname) {
761 FileShCompInitData *id = safe_malloc( sizeof( FileShCompInitData ) );
763 id->filename = g_strdup_printf( "%s", plugin );
765 comp_add_newmenu_item( leafname, &FileSheetComponentClass, id );
768 PRIVATE void load_all_gsheets(char *dir, char *menupos ); /* forward decl */
770 PRIVATE int check_gsheet_validity(char *name, char *menupos, const char *dirname ) {
771 struct stat sb;
773 if (stat(name, &sb) == -1)
774 return 0;
776 if (S_ISDIR(sb.st_mode)) {
777 // XXX: how do i get this name nicely ?
778 // dont care now works....
780 char *newmenupos = g_strdup_printf( "%s/%s", menupos, dirname );
781 load_all_gsheets(name, newmenupos );
782 free( newmenupos );
785 if( strlen(name) < 8 || strcmp(name+(strlen(name)-7), ".gsheet" ) )
786 return 0;
788 return S_ISREG(sb.st_mode);
791 PRIVATE void load_all_gsheets(char *dir, char *menupos) {
792 GDir *d = g_dir_open(dir, 0, NULL);
793 const char *filename;
795 if (d == NULL)
796 /* the plugin directory cannot be read */
797 return;
799 while ((filename = g_dir_read_name(d)) != NULL) {
800 char *fullname;
802 fullname = g_strdup_printf( "%s%s%s", dir, G_DIR_SEPARATOR_S, filename );
804 if (check_gsheet_validity(fullname, menupos, filename)) {
805 char *menuname = g_strdup_printf( "%s/%s", menupos, filename );
806 add_gsheet(fullname, menuname);
807 free( menuname );
810 free(fullname);
813 g_dir_close(d);
816 PRIVATE void scan_library_dir( void ) {
817 char *sheetdir = getenv("GALAN_SHEET_DIR");
819 if( sheetdir )
820 load_all_gsheets( sheetdir, "Lib" );
821 else
822 load_all_gsheets(SITE_PKGDATA_DIR G_DIR_SEPARATOR_S "sheets", "Lib" );
826 PUBLIC void shcomp_register_sheet( Sheet *sheet ) {
828 ShCompInitData *initdata = safe_malloc( sizeof( ShCompInitData ) );
830 gchar *str = g_strdup_printf( "Sheets/%s", sheet->name );
832 initdata->sheet = sheet;
833 comp_add_newmenu_item( str, &SheetComponentClass, initdata );
835 g_free( str );
838 PUBLIC void init_shcomp(void) {
839 comp_register_componentclass(&SheetComponentClass);
840 comp_register_componentclass(&FileSheetComponentClass);
842 scan_library_dir();
845 PUBLIC void done_shcomp(void) {