Root/gui.c

Source at commit 1d7eccb06b61f239b9671617488f33910286f0f1 created 5 years 7 months ago.
By Werner Almesberger, dump.c: add dumping of %iprint
1/*
2 * gui.c - Editor GUI core
3 *
4 * Written 2009-2012 by Werner Almesberger
5 * Copyright 2009-2012 by Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <locale.h>
15#include <gtk/gtk.h>
16
17#include "inst.h"
18#include "file.h"
19#include "gui_util.h"
20#include "gui_style.h"
21#include "gui_status.h"
22#include "gui_canvas.h"
23#include "gui_tool.h"
24#include "gui_frame.h"
25#include "gui.h"
26#include "fped.h"
27
28#include "icons/stuff.xpm"
29#include "icons/stuff_off.xpm"
30#include "icons/meas.xpm"
31#include "icons/meas_off.xpm"
32#include "icons/all.xpm"
33#include "icons/all_off.xpm"
34#include "icons/bright.xpm"
35#include "icons/bright_off.xpm"
36
37
38GtkWidget *root;
39int show_all = 1;
40int show_stuff = 1;
41int show_meas = 1;
42int show_bright = 0;
43
44
45static GtkWidget *paned;
46static GtkWidget *frames_box;
47static GtkWidget *ev_stuff, *ev_meas, *ev_all, *ev_bright;
48static GtkWidget *stuff_image[2], *meas_image[2], *all_image[2];
49static GtkWidget *bright_image[2];
50
51static void do_build_frames(void);
52
53
54/* ----- save callbacks ---------------------------------------------------- */
55
56
57static void save_as_fpd(void)
58{
59    GtkWidget *dialog;
60
61    dialog = gtk_file_chooser_dialog_new("Save File",
62        NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
63        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
64        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
65    gtk_file_chooser_set_do_overwrite_confirmation(
66        GTK_FILE_CHOOSER(dialog), TRUE);
67    if (save_file_name)
68        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
69            save_file_name);
70    if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
71        save_file_name =
72            gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
73        save_fpd();
74        /* @@@ we may leak save_file_name */
75        no_save = 0;
76    }
77    gtk_widget_destroy(dialog);
78}
79
80
81/* ----- view callbacks ---------------------------------------------------- */
82
83
84static void swap_var_code(void)
85{
86    extern int show_vars;
87
88    show_vars = !show_vars;
89    change_world();
90}
91
92
93/* ----- menu bar ---------------------------------------------------------- */
94
95
96static GtkItemFactoryEntry menu_entries[] = {
97    { "/File", NULL, NULL, 0, "<Branch>" },
98    { "/File/Save", NULL, save_fpd, 0, "<Item>" },
99    { "/File/Save as", NULL, save_as_fpd, 0, "<Item>" },
100        { "/File/sep1", NULL, NULL, 0, "<Separator>" },
101        { "/File/Write KiCad", NULL, write_kicad, 0, "<Item>" },
102        { "/File/Write Postscript",
103                NULL, write_ps, 0, "<Item>" },
104        { "/File/sep2", NULL, NULL, 0, "<Separator>" },
105        { "/File/Reload", NULL, reload, 0, "<Item>" },
106        { "/File/sep3", NULL, NULL, 0, "<Separator>" },
107        { "/File/Quit", NULL, gtk_main_quit, 0, "<Item>" },
108    { "/View", NULL, NULL, 0, "<Branch>" },
109    { "/View/Zoom in", NULL, zoom_in_center, 0, "<Item>" },
110    { "/View/Zoom out", NULL, zoom_out_center,0, "<Item>" },
111    { "/View/Zoom all", NULL, zoom_to_extents,0, "<Item>" },
112    { "/View/Zoom frame", NULL, zoom_to_frame, 0, "<Item>" },
113    { "/View/sep1", NULL, NULL, 0, "<Separator>" },
114    { "/View/Swap var&code",NULL, swap_var_code, 0, "<Item>" },
115};
116
117
118static void make_menu_bar(GtkWidget *hbox)
119{
120    GtkItemFactory *factory;
121    GtkWidget *bar;
122
123    factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<FpedMenu>", NULL);
124        gtk_item_factory_create_items(factory,
125        sizeof(menu_entries)/sizeof(*menu_entries), menu_entries, NULL);
126
127    bar = gtk_item_factory_get_widget(factory, "<FpedMenu>");
128    gtk_box_pack_start(GTK_BOX(hbox), bar, TRUE, TRUE, 0);
129
130    gtk_widget_set_sensitive(
131        gtk_item_factory_get_item(factory, "/File/Save"), !no_save);
132    gtk_widget_set_sensitive(
133        gtk_item_factory_get_item(factory, "/File/Reload"),
134        no_save && !!save_file_name);
135}
136
137
138static gboolean toggle_all(GtkWidget *widget, GdkEventButton *event,
139    gpointer data)
140{
141    switch (event->button) {
142    case 1:
143        show_all = !show_all;
144        set_image(ev_all, all_image[show_all]);
145        inst_deselect();
146        redraw();
147        break;
148    }
149        return TRUE;
150}
151
152
153static gboolean toggle_stuff(GtkWidget *widget, GdkEventButton *event,
154    gpointer data)
155{
156    switch (event->button) {
157    case 1:
158        show_stuff = !show_stuff;
159        set_image(ev_stuff, stuff_image[show_stuff]);
160        inst_deselect();
161        redraw();
162        break;
163    }
164        return TRUE;
165}
166
167
168static gboolean toggle_meas(GtkWidget *widget, GdkEventButton *event,
169    gpointer data)
170{
171    switch (event->button) {
172    case 1:
173        show_meas = !show_meas;
174        set_image(ev_meas, meas_image[show_meas]);
175        inst_deselect();
176        redraw();
177        break;
178    }
179        return TRUE;
180}
181
182
183static gboolean toggle_bright(GtkWidget *widget, GdkEventButton *event,
184    gpointer data)
185{
186    switch (event->button) {
187    case 1:
188        show_bright = !show_bright;
189        set_image(ev_bright, bright_image[show_bright]);
190        inst_deselect();
191        redraw();
192        break;
193    }
194        return TRUE;
195}
196
197
198static void make_tool_bar(GtkWidget *hbox, GdkDrawable *drawable)
199{
200    GtkWidget *bar;
201
202    bar = gtk_toolbar_new();
203    gtk_box_pack_end(GTK_BOX(hbox), bar, TRUE, TRUE, 0);
204    //gtk_box_pack_end(GTK_BOX(hbox), bar, FALSE, FALSE, 0);
205    gtk_toolbar_set_style(GTK_TOOLBAR(bar), GTK_TOOLBAR_ICONS);
206
207    ev_all = tool_button(bar, drawable, NULL, NULL, toggle_all, NULL);
208    ev_stuff = tool_button(bar, drawable, NULL, NULL, toggle_stuff, NULL);
209    ev_meas = tool_button(bar, drawable, NULL, NULL, toggle_meas, NULL);
210    ev_bright = tool_button(bar, drawable, NULL, NULL, toggle_bright, NULL);
211
212    stuff_image[0] = gtk_widget_ref(make_image(drawable, xpm_stuff_off,
213        "Show vectors and frame references (disabled)"));
214    stuff_image[1] = gtk_widget_ref(make_image(drawable, xpm_stuff,
215        "Show vectors and frame references (enabled)"));
216    meas_image[0] = gtk_widget_ref(make_image(drawable, xpm_meas_off,
217        "Show measurements (disabled)"));
218    meas_image[1] = gtk_widget_ref(make_image(drawable, xpm_meas,
219        "Show measurements (enabled)"));
220    all_image[0] = gtk_widget_ref(make_image(drawable, xpm_all_off,
221        "Show all frames (currently showing only the active frame)"));
222    all_image[1] = gtk_widget_ref(make_image(drawable, xpm_all,
223        "Show all frames (enabled)"));
224    bright_image[0] = gtk_widget_ref(make_image(drawable, xpm_bright_off,
225        "Highlight elements (disabled)"));
226    bright_image[1] = gtk_widget_ref(make_image(drawable, xpm_bright,
227        "Highlight elements (enabled)"));
228
229    set_image(ev_stuff, stuff_image[show_stuff]);
230    set_image(ev_meas, meas_image[show_meas]);
231    set_image(ev_all, all_image[show_all]);
232    set_image(ev_bright, bright_image[show_bright]);
233}
234
235
236static void cleanup_tool_bar(void)
237{
238    g_object_unref(stuff_image[0]);
239    g_object_unref(stuff_image[1]);
240    g_object_unref(meas_image[0]);
241    g_object_unref(meas_image[1]);
242    g_object_unref(all_image[0]);
243    g_object_unref(all_image[1]);
244    g_object_unref(bright_image[0]);
245    g_object_unref(bright_image[1]);
246}
247
248
249static void make_top_bar(GtkWidget *vbox)
250{
251    GtkWidget *hbox;
252
253    hbox = gtk_hbox_new(FALSE, 0);
254    make_menu_bar(hbox);
255    make_tool_bar(hbox, root->window);
256    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
257}
258
259
260/* ----- central screen area ----------------------------------------------- */
261
262
263static void resize_frames_area(GtkWidget *widget, GtkAllocation *allocation,
264    gpointer user_data)
265{
266    static int width = 0;
267
268    if (allocation->width == width)
269        return;
270    width = allocation->width;
271    do_build_frames();
272}
273
274
275static void make_center_area(GtkWidget *vbox)
276{
277    GtkWidget *hbox, *frames_area;//, *paned;
278    GtkWidget *tools;
279
280    hbox = gtk_hbox_new(FALSE, 0);
281    gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
282
283    paned = gtk_hpaned_new();
284    gtk_box_pack_start(GTK_BOX(hbox), paned, TRUE, TRUE, 0);
285
286    /* Frames */
287
288    frames_area = gtk_scrolled_window_new(NULL, NULL);
289    gtk_paned_add1(GTK_PANED(paned), frames_area);
290    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(frames_area),
291        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
292    gtk_widget_set_size_request(frames_area,
293        DEFAULT_FRAME_AREA_WIDTH, DEFAULT_FRAME_AREA_HEIGHT);
294
295    frames_box = gtk_vbox_new(FALSE, 0);
296    build_frames(frames_box, DEFAULT_FRAME_AREA_WIDTH);
297
298    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(frames_area),
299        frames_box);
300
301    g_signal_connect(G_OBJECT(frames_area), "size-allocate",
302        G_CALLBACK(resize_frames_area), NULL);
303
304    /* Canvas */
305
306    gtk_paned_add2(GTK_PANED(paned), make_canvas());
307
308    /* Icon bar */
309
310    tools = gui_setup_tools(root->window);
311    gtk_box_pack_end(GTK_BOX(hbox), tools, FALSE, FALSE, 0);
312}
313
314
315/* ----- GUI construction -------------------------------------------------- */
316
317
318static void do_build_frames(void)
319{
320    int width;
321
322    width = gtk_paned_get_position(GTK_PANED(paned));
323    build_frames(frames_box, width > 0 ? width : DEFAULT_FRAME_AREA_WIDTH);
324}
325
326
327void change_world(void)
328{
329    struct bbox before, after;
330    int reachable_is_active;
331
332    inst_deselect();
333    status_begin_reporting();
334    before = inst_get_bbox(NULL);
335    reachable_is_active = reachable_pkg && reachable_pkg == active_pkg;
336    instantiate();
337    if (reachable_is_active && reachable_pkg &&
338         reachable_pkg != active_pkg) {
339        active_pkg = reachable_pkg;
340        instantiate();
341    }
342    after = inst_get_bbox(NULL);
343    label_in_box_bg(active_frame->label, COLOR_FRAME_SELECTED);
344    do_build_frames();
345    if (after.min.x < before.min.x || after.min.y < before.min.y ||
346        after.max.x > before.max.x || after.max.y > before.max.y)
347        zoom_to_extents();
348    else
349        redraw();
350}
351
352
353void change_world_reselect(void)
354{
355    struct obj *selected_obj;
356
357    /*
358     * We can edit an object even if it's not selected if it was picked
359     * via the item view. inst_select_obj tries to find an instance, but
360     * if there's never been a successful instantiation since creation of
361     * the object or if the object is unreachable for some other reason,
362     * then selected_inst will be NULL.
363     */
364    if (!selected_inst) {
365        change_world();
366        return;
367    }
368    selected_obj = selected_inst->obj;
369    change_world();
370    inst_select_obj(selected_obj);
371}
372
373
374static void make_screen(GtkWidget *window)
375{
376    GtkWidget *vbox;
377
378    vbox = gtk_vbox_new(FALSE, 0);
379    gtk_container_add(GTK_CONTAINER(window), vbox);
380
381    make_top_bar(vbox);
382    make_center_area(vbox);
383    make_status_area(vbox);
384}
385
386
387int gui_init(int *argc, char ***argv)
388{
389    gtk_init(argc, argv);
390    setlocale(LC_ALL, "C"); /* damage control */
391    return 0;
392}
393
394
395int gui_main(void)
396{
397    root = gtk_window_new(GTK_WINDOW_TOPLEVEL);
398    gtk_window_set_position(GTK_WINDOW(root), GTK_WIN_POS_CENTER);
399    gtk_window_set_default_size(GTK_WINDOW(root), 620, 460);
400    if (*VERSION)
401        gtk_window_set_title(GTK_WINDOW(root),
402            "fped (rev " VERSION ")");
403    else
404        gtk_window_set_title(GTK_WINDOW(root), "fped");
405
406    /* get root->window */
407    gtk_widget_show_all(root);
408
409    g_signal_connect(G_OBJECT(root), "destroy",
410        G_CALLBACK(gtk_main_quit), NULL);
411
412    make_screen(root);
413
414    gtk_widget_show_all(root);
415
416    gui_setup_style(root->window);
417    init_canvas();
418    edit_nothing();
419    select_frame(frames);
420    make_popups();
421
422    gtk_main();
423
424    gui_cleanup_style();
425    gui_cleanup_tools();
426    cleanup_tool_bar();
427    cleanup_status_area();
428
429    return 0;
430}
431

Archive Download this file

Branches:
master



interactive