GDS-Render v1.2.1
gds-render-gui.c
Go to the documentation of this file.
1/*
2 * GDSII-Converter
3 * Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
4 *
5 * This file is part of GDSII-Converter.
6 *
7 * GDSII-Converter is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * GDSII-Converter is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
18 */
19
30#include <stdio.h>
31#include <gtk/gtk.h>
32#include <glib/gi18n.h>
33
44#include <gds-render/version.h>
45
52};
53
55
57
61};
62
64 /* Parent GObject */
65 GObject parent;
66
67 /* Custom fields */
68 GtkWindow *main_window;
69 GtkWidget *convert_button;
70 GtkWidget *open_button;
74 GtkTreeStore *cell_tree_store;
75 GtkTreeModelFilter *cell_filter;
77 LayerSelector *layer_selector;
78 GtkTreeView *cell_tree_view;
80 ActivityBar *activity_status_bar;
82 ColorPalette *palette;
84};
85
86G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT)
87
88
95static gboolean on_window_close(gpointer window, GdkEvent *event, gpointer user)
96{
97 GdsRenderGui *self;
98 (void)event;
99
100 self = RENDERER_GUI(user);
101 /* Don't close window in case of error */
102 if (!self)
103 return TRUE;
104
105 /* Close Window. Leads to termination of the program/the current instance */
106 g_clear_object(&self->main_window);
107 gtk_widget_destroy(GTK_WIDGET(window));
108
109 /* Delete loaded library data */
110 clear_lib_list(&self->gds_libraries);
111
112 g_signal_emit(self, gds_render_gui_signals[SIGNAL_WINDOW_CLOSED], 0);
113
114 return TRUE;
115}
116
126static gboolean tree_sel_func(GtkTreeSelection *selection,
127 GtkTreeModel *model,
128 GtkTreePath *path,
129 gboolean path_currently_selected,
130 gpointer data)
131{
132 GtkTreeIter iter;
133 struct gds_cell *cell;
134 unsigned int error_level;
135 gboolean ret = FALSE;
136 (void)selection;
137 (void)path_currently_selected;
138 (void)data;
139
140 gtk_tree_model_get_iter(model, &iter, path);
141 gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1);
142
143 /* Allow only rows with _valid_ cell to be selected */
144 if (cell) {
145 /* Cell available. Check if it passed the critical checks */
146 if (!(error_level & LIB_CELL_RENDERER_ERROR_ERR))
147 ret = TRUE;
148 }
149
150 return ret;
151}
152
158static void cell_tree_view_change_filter(GtkWidget *entry, gpointer data)
159{
160 GdsRenderGui *self = RENDERER_GUI(data);
161 (void)entry;
162
163 gtk_tree_model_filter_refilter(self->cell_filter);
164}
165
174static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
175{
176 GdsRenderGui *self;
177 struct gds_cell *cell;
178 struct gds_library *lib;
179 gboolean result = FALSE;
180 const char *search_string;
181
182 self = RENDERER_GUI(data);
183 g_return_val_if_fail(RENDERER_IS_GUI(self), FALSE);
184
185 if (!model || !iter)
186 goto exit_filter;
187
188 gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
189
190 /* Show always, if this is a pure lib entry */
191 if (lib && !cell) {
192 result = TRUE;
193 goto exit_filter;
194 }
195
196 if (!cell)
197 goto exit_filter;
198
199 search_string = gtk_entry_get_text(GTK_ENTRY(self->cell_search_entry));
200
201 /* Show all, if field is empty */
202 if (!strlen(search_string))
203 result = TRUE;
204
205 if (strstr(cell->name, search_string))
206 result = TRUE;
207
208 gtk_tree_view_expand_all(self->cell_tree_view);
209
210exit_filter:
211 return result;
212}
213
219{
220 GtkCellRenderer *render_cell;
221 GtkCellRenderer *render_lib;
222 GtkTreeViewColumn *column;
223
224 self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER,
225 G_TYPE_POINTER, G_TYPE_UINT);
226
227 /* Searching */
228 self->cell_filter = GTK_TREE_MODEL_FILTER(
229 gtk_tree_model_filter_new(GTK_TREE_MODEL(self->cell_tree_store), NULL));
230
231 gtk_tree_model_filter_set_visible_func(self->cell_filter,
232 (GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
233 self, NULL);
234 g_signal_connect(GTK_SEARCH_ENTRY(self->cell_search_entry), "search-changed",
235 G_CALLBACK(cell_tree_view_change_filter), self);
236
237 gtk_tree_view_set_model(self->cell_tree_view, GTK_TREE_MODEL(self->cell_filter));
238
240 render_lib = lib_cell_renderer_new();
241
242 column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
243 gtk_tree_view_append_column(self->cell_tree_view, column);
244
245 column = gtk_tree_view_column_new_with_attributes(_("Cell"), render_cell, "gds-cell", CELL_SEL_CELL,
246 "error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
247 gtk_tree_view_append_column(self->cell_tree_view, column);
248
249 /* Callback for selection
250 * This prevents selecting a library
251 */
252 gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(self->cell_tree_view),
253 tree_sel_func, NULL, NULL);
254
255 return 0;
256}
257
263static void on_load_gds(gpointer button, gpointer user)
264{
265 GList *cell;
266 GtkTreeIter libiter;
267 GtkTreeIter celliter;
268 GList *lib;
269 struct gds_library *gds_lib;
270 struct gds_cell *gds_c;
271 GdsRenderGui *self;
272 GtkWidget *open_dialog;
273 GtkFileChooser *file_chooser;
274 GtkFileFilter *filter;
275 GtkStyleContext *button_style;
276 gint dialog_result;
277 int gds_result;
278 char *filename;
279 unsigned int cell_error_level;
280
281 self = RENDERER_GUI(user);
282 if (!self)
283 return;
284
285 open_dialog = gtk_file_chooser_dialog_new(_("Open GDSII File"), self->main_window,
286 GTK_FILE_CHOOSER_ACTION_OPEN,
287 _("Cancel"), GTK_RESPONSE_CANCEL,
288 _("Open GDSII"), GTK_RESPONSE_ACCEPT,
289 NULL);
290 file_chooser = GTK_FILE_CHOOSER(open_dialog);
291
292 /* Add GDS II Filter */
293 filter = gtk_file_filter_new();
294 gtk_file_filter_add_pattern(filter, "*.gds");
295 gtk_file_filter_set_name(filter, _("GDSII-Files"));
296 gtk_file_chooser_add_filter(file_chooser, filter);
297
298 dialog_result = gtk_dialog_run(GTK_DIALOG(open_dialog));
299
300 if (dialog_result != GTK_RESPONSE_ACCEPT)
301 goto end_destroy;
302
303 /* Get File name */
304 filename = gtk_file_chooser_get_filename(file_chooser);
305
306 gtk_tree_store_clear(self->cell_tree_store);
307 clear_lib_list(&self->gds_libraries);
308
309 /* Parse new GDSII file */
310 gds_result = parse_gds_from_file(filename, &self->gds_libraries);
311
312 /* Delete file name afterwards */
313 g_free(filename);
314 if (gds_result)
315 goto end_destroy;
316
317 /* remove suggested action from Open button */
318 button_style = gtk_widget_get_style_context(GTK_WIDGET(button));
319 gtk_style_context_remove_class(button_style, "suggested-action");
320
321 for (lib = self->gds_libraries; lib != NULL; lib = lib->next) {
322 gds_lib = (struct gds_library *)lib->data;
323 /* Create top level iter */
324 gtk_tree_store_append(self->cell_tree_store, &libiter, NULL);
325
326 gtk_tree_store_set(self->cell_tree_store, &libiter,
327 CELL_SEL_LIBRARY, gds_lib,
328 -1);
329
330 /* Check this library. This might take a while */
331 (void)gds_tree_check_cell_references(gds_lib);
332 (void)gds_tree_check_reference_loops(gds_lib);
333
334 for (cell = gds_lib->cells; cell != NULL; cell = cell->next) {
335 gds_c = (struct gds_cell *)cell->data;
336 gtk_tree_store_append(self->cell_tree_store, &celliter, &libiter);
337
338 /* Get the checking results for this cell */
339 cell_error_level = 0;
341 cell_error_level |= LIB_CELL_RENDERER_ERROR_WARN;
342
343 /* Check if it is completely b0rken */
345 cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR;
346
347 /* Add cell to tree store model */
348 gtk_tree_store_set(self->cell_tree_store, &celliter,
349 CELL_SEL_CELL, gds_c,
350 CELL_SEL_CELL_ERROR_STATE, cell_error_level,
352 -1);
353 } /* for cells */
354 } /* for libraries */
355
356 /* Create Layers in Layer Box */
357 layer_selector_generate_layer_widgets(self->layer_selector, self->gds_libraries);
358
359end_destroy:
360 /* Destroy dialog and filter */
361 gtk_widget_destroy(open_dialog);
362}
363
364static void process_button_state_changes(GdsRenderGui *self)
365{
366 gboolean convert_button_state = FALSE;
367 gboolean open_gds_button_state = FALSE;
368
369 /* Calculate states */
370 if (!self->button_state_data.rendering_active) {
371 open_gds_button_state = TRUE;
372 if (self->button_state_data.valid_cell_selected)
373 convert_button_state = TRUE;
374 }
375
376 /* Apply states */
377 gtk_widget_set_sensitive(self->convert_button, convert_button_state);
378 gtk_widget_set_sensitive(self->open_button, open_gds_button_state);
379}
380
386static void on_auto_color_clicked(gpointer button, gpointer user)
387{
388 GdsRenderGui *self;
389 (void)button;
390
391 self = RENDERER_GUI(user);
392 layer_selector_auto_color_layers(self->layer_selector, self->palette, 1.0);
393}
394
395static void async_rendering_finished_callback(GdsOutputRenderer *renderer, gpointer gui)
396{
397 GdsRenderGui *self;
398
399 self = RENDERER_GUI(gui);
400
401 self->button_state_data.rendering_active = FALSE;
403 activity_bar_set_ready(self->activity_status_bar);
404
405 g_object_unref(renderer);
406}
407
408static void async_rendering_status_update_callback(GdsOutputRenderer *renderer,
409 const char *status_message,
410 gpointer data)
411{
412 GdsRenderGui *gui;
413 (void)renderer;
414
415 gui = RENDERER_GUI(data);
416
417 activity_bar_set_busy(gui->activity_status_bar, status_message);
418}
419
425static void on_convert_clicked(gpointer button, gpointer user)
426{
427 (void)button;
428 GdsRenderGui *self;
429 GtkTreeSelection *selection;
430 GtkTreeIter iter;
431 GtkTreeModel *model;
432 struct gds_cell *cell_to_render;
433 GtkWidget *dialog;
434 RendererSettingsDialog *settings;
435 GtkFileFilter *filter;
436 gint res;
437 char *file_name;
438 union bounding_box cell_box;
439 unsigned int height, width;
440 struct render_settings *sett;
441 LayerSettings *layer_settings;
442 GdsOutputRenderer *render_engine;
443
444 self = RENDERER_GUI(user);
445
446 if (!self)
447 return;
448
449 /* Abort if rendering is already active */
450 if (self->button_state_data.rendering_active == TRUE)
451 return;
452
453 sett = &self->render_dialog_settings;
454
455 /* Get selected cell */
456 selection = gtk_tree_view_get_selection(self->cell_tree_view);
457 if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
458 return;
459
460 gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell_to_render, -1);
461
462 if (!cell_to_render)
463 return;
464
465 /* Get layers that are rendered */
466 layer_settings = layer_selector_export_rendered_layer_info(self->layer_selector);
467
468 /* Calculate cell size in DB units */
470 calculate_cell_bounding_box(&cell_box, cell_to_render);
471
472 /* Calculate size in database units
473 * Note that the results are bound to be positive,
474 * so casting them to unsigned int is absolutely valid
475 */
476 height = (unsigned int)(cell_box.vectors.upper_right.y - cell_box.vectors.lower_left.y);
477 width = (unsigned int)(cell_box.vectors.upper_right.x - cell_box.vectors.lower_left.x);
478
479 /* Show settings dialog */
480 settings = renderer_settings_dialog_new(GTK_WINDOW(self->main_window));
485 g_object_set(G_OBJECT(settings), "cell-name", cell_to_render->name, NULL);
486
487 res = gtk_dialog_run(GTK_DIALOG(settings));
488 if (res == GTK_RESPONSE_OK) {
490 gtk_widget_destroy(GTK_WIDGET(settings));
491 } else {
492 gtk_widget_destroy(GTK_WIDGET(settings));
493 goto ret_layer_destroy;
494 }
495
496 /* save file dialog */
497 dialog = gtk_file_chooser_dialog_new((sett->renderer == RENDERER_LATEX_TIKZ
498 ? "Save LaTeX File" : "Save PDF"),
499 GTK_WINDOW(self->main_window), GTK_FILE_CHOOSER_ACTION_SAVE,
500 "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL);
501 /* Set file filter according to settings */
502 filter = gtk_file_filter_new();
503 switch (sett->renderer) {
505 gtk_file_filter_add_pattern(filter, "*.tex");
506 gtk_file_filter_set_name(filter, "LaTeX-Files");
507 break;
509 gtk_file_filter_add_pattern(filter, "*.pdf");
510 gtk_file_filter_set_name(filter, "PDF-Files");
511 break;
513 gtk_file_filter_add_pattern(filter, "*.svg");
514 gtk_file_filter_set_name(filter, "SVG-Files");
515 break;
516 }
517
518 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
519
520 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
521
522 res = gtk_dialog_run(GTK_DIALOG(dialog));
523 if (res == GTK_RESPONSE_ACCEPT) {
524 file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
525 gtk_widget_destroy(dialog);
526
527 switch (sett->renderer) {
529 render_engine =
530 GDS_RENDER_OUTPUT_RENDERER(latex_renderer_new_with_options(sett->tex_pdf_layers,
531 sett->tex_standalone));
532 break;
534 render_engine = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_svg());
535 break;
537 render_engine = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_pdf());
538 break;
539 default:
540 /* Abort rendering */
541 render_engine = NULL;
542 break;
543 }
544
545 if (render_engine) {
546 gds_output_renderer_set_output_file(render_engine, file_name);
547 gds_output_renderer_set_layer_settings(render_engine, layer_settings);
548 /* Prevent user from overwriting library or triggering additional conversion */
549 self->button_state_data.rendering_active = TRUE;
551
552 g_signal_connect(render_engine, "async-finished", G_CALLBACK(async_rendering_finished_callback),
553 self);
554
555 activity_bar_set_busy(self->activity_status_bar, _("Rendering cell..."));
556
557 g_signal_connect(render_engine, "progress-changed",
559 gds_output_renderer_render_output_async(render_engine, cell_to_render, sett->scale);
560 }
561 g_free(file_name);
562 } else {
563 gtk_widget_destroy(dialog);
564 }
565ret_layer_destroy:
566 g_object_unref(layer_settings);
567}
568
576static void cell_tree_view_activated(gpointer tree_view, GtkTreePath *path,
577 GtkTreeViewColumn *column, gpointer user)
578{
579 (void)tree_view;
580 (void)path;
581 (void)column;
582
583 on_convert_clicked(NULL, user);
584}
585
594static void cell_selection_changed(GtkTreeSelection *sel, GdsRenderGui *self)
595{
596 GtkTreeModel *model = NULL;
597 GtkTreeIter iter;
598
599 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
600 /* Node selected. Show button */
601 self->button_state_data.valid_cell_selected = TRUE;
602 } else {
603 self->button_state_data.valid_cell_selected = FALSE;
604 }
605
607}
608
609static void sort_up_callback(GtkWidget *widget, gpointer user)
610{
611 (void)widget;
612 GdsRenderGui *self;
613
614 self = RENDERER_GUI(user);
615 if (!self)
616 return;
618}
619
620static void sort_down_callback(GtkWidget *widget, gpointer user)
621{
622 (void)widget;
623 GdsRenderGui *self;
624
625 self = RENDERER_GUI(user);
626 if (!self)
627 return;
629}
630
631static void gds_render_gui_dispose(GObject *gobject)
632{
633 GdsRenderGui *self;
634
635 self = RENDERER_GUI(gobject);
636
637 clear_lib_list(&self->gds_libraries);
638
639 g_clear_object(&self->cell_tree_view);
640 g_clear_object(&self->convert_button);
641 g_clear_object(&self->layer_selector);
642 g_clear_object(&self->cell_tree_store);
643 g_clear_object(&self->cell_filter);
644 g_clear_object(&self->cell_search_entry);
645 g_clear_object(&self->activity_status_bar);
646 g_clear_object(&self->palette);
647 g_clear_object(&self->load_layer_button);
648 g_clear_object(&self->save_layer_button);
649 g_clear_object(&self->open_button);
650 g_clear_object(&self->select_all_button);
651
652 if (self->main_window) {
653 g_signal_handlers_destroy(self->main_window);
654 gtk_widget_destroy(GTK_WIDGET(self->main_window));
655 self->main_window = NULL;
656 }
657
658 /* Chain up */
659 G_OBJECT_CLASS(gds_render_gui_parent_class)->dispose(gobject);
660}
661
662static void gds_render_gui_class_init(GdsRenderGuiClass *klass)
663{
664 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
665
667 g_signal_newv("window-closed", RENDERER_TYPE_GUI,
668 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
669 NULL,
670 NULL,
671 NULL,
672 NULL,
673 G_TYPE_NONE,
674 0,
675 NULL);
676
677 gobject_class->dispose = gds_render_gui_dispose;
678}
679
685static void on_select_all_layers_clicked(GtkWidget *button, gpointer user_data)
686{
687 GdsRenderGui *gui;
688 (void)button;
689
690 gui = RENDERER_GUI(user_data);
691 layer_selector_select_all_layers(gui->layer_selector, TRUE);
692}
693
694static gboolean auto_naming_ask_for_override(GdsRenderGui *gui)
695{
696 GtkDialog *dialog;
697 gint dialog_result;
698 gboolean overwrite = FALSE;
699
700 g_return_val_if_fail(RENDERER_IS_GUI(gui), FALSE);
701
702 /* Ask for overwrite */
703 dialog = GTK_DIALOG(gtk_message_dialog_new(gui->main_window, GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_QUESTION,
704 GTK_BUTTONS_YES_NO, "Overwrite existing layer names?"));
705 dialog_result = gtk_dialog_run(dialog);
706 switch (dialog_result) {
707 case GTK_RESPONSE_YES:
708 overwrite = TRUE;
709 break;
710 case GTK_RESPONSE_NO: /* Expected fallthrough */
711 default:
712 overwrite = FALSE;
713 break;
714 }
715 gtk_widget_destroy(GTK_WIDGET(dialog));
716
717 return overwrite;
718}
719
720static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
721{
722 GdsRenderGui *gui;
723 gboolean overwrite = FALSE;
724 (void)button;
725
726 gui = RENDERER_GUI(user_data);
727
728 /* Don't do anything if the selector is empty. */
729 if (!layer_selector_contains_elements(gui->layer_selector))
730 return;
731
732 /* Ask, if names shall be overwritten, if they are not empty */
733 if (layer_selector_num_of_named_elements(gui->layer_selector) > 0)
734 overwrite = auto_naming_ask_for_override(gui);
735
736 layer_selector_auto_name_layers(gui->layer_selector, overwrite);
737}
738
739GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui)
740{
741 return gui->main_window;
742}
743
744static void gds_render_gui_init(GdsRenderGui *self)
745{
746 GtkBuilder *main_builder;
747 GtkWidget *listbox;
748 GtkHeaderBar *header_bar;
749 GtkWidget *sort_up_button;
750 GtkWidget *sort_down_button;
751 GtkWidget *activity_bar_box;
752 GtkWidget *auto_color_button;
753 GtkWidget *auto_naming_button;
754
755 main_builder = gtk_builder_new_from_resource("/gui/main.glade");
756
757 self->cell_tree_view = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree"));
758 self->cell_search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search"));
759
761
762 self->main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
763 self->open_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds"));
764 g_signal_connect(self->open_button,
765 "clicked", G_CALLBACK(on_load_gds), (gpointer)self);
766
767 self->convert_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button"));
768 g_signal_connect(self->convert_button, "clicked", G_CALLBACK(on_convert_clicked), (gpointer)self);
769
770 listbox = GTK_WIDGET(gtk_builder_get_object(main_builder, "layer-list"));
771 /* Create layer selector */
772 self->layer_selector = layer_selector_new(GTK_LIST_BOX(listbox));
773
774 activity_bar_box = GTK_WIDGET(gtk_builder_get_object(main_builder, "activity-bar"));
775
776 /* Callback for selection change of cell selector */
777 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(self->cell_tree_view)), "changed",
778 G_CALLBACK(cell_selection_changed), self);
779 g_signal_connect(self->cell_tree_view, "row-activated", G_CALLBACK(cell_tree_view_activated), self);
780
781 /* Set version in main window subtitle */
782 header_bar = GTK_HEADER_BAR(gtk_builder_get_object(main_builder, "header-bar"));
783 gtk_header_bar_set_subtitle(header_bar, _app_version_string);
784
785 /* Get layer sorting buttons and set callbacks */
786 sort_up_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-up-sort"));
787 sort_down_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-down-sort"));
788
789 g_signal_connect(sort_up_button, "clicked", G_CALLBACK(sort_up_callback), self);
790 g_signal_connect(sort_down_button, "clicked", G_CALLBACK(sort_down_callback), self);
791
792 /* Set buttons for loading and saving */
793 self->load_layer_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping"));
794 self->save_layer_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-save-mapping"));
795 layer_selector_set_load_mapping_button(self->layer_selector, self->load_layer_button, self->main_window);
796 layer_selector_set_save_mapping_button(self->layer_selector, self->save_layer_button, self->main_window);
797
798 /* Connect delete-event */
799 g_signal_connect(GTK_WIDGET(self->main_window), "delete-event",
800 G_CALLBACK(on_window_close), self);
801
802 /* Create and apply ActivityBar */
803 self->activity_status_bar = activity_bar_new();
804 gtk_container_add(GTK_CONTAINER(activity_bar_box), GTK_WIDGET(self->activity_status_bar));
805 gtk_widget_show(GTK_WIDGET(self->activity_status_bar));
806
807 /* Create color palette */
808 self->palette = color_palette_new_from_resource("/data/color-palette.txt");
809 auto_color_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "auto-color-button"));
810 g_signal_connect(auto_color_button, "clicked", G_CALLBACK(on_auto_color_clicked), self);
811
812
813 /* Set default conversion/rendering settings */
814 self->render_dialog_settings.scale = 1000;
815 self->render_dialog_settings.renderer = RENDERER_LATEX_TIKZ;
816 self->render_dialog_settings.tex_pdf_layers = FALSE;
817 self->render_dialog_settings.tex_standalone = FALSE;
818
819 /* Get select all button and connect callback */
820 self->select_all_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-select-all"));
821 g_signal_connect(self->select_all_button, "clicked", G_CALLBACK(on_select_all_layers_clicked), self);
822
823 /* Setup auto naming button */
824 auto_naming_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-auto-name"));
825 g_signal_connect(auto_naming_button, "clicked", G_CALLBACK(auto_naming_clicked), self);
826
827 g_object_unref(main_builder);
828
829 /* Setup default button sensibility data */
830 self->button_state_data.rendering_active = FALSE;
831 self->button_state_data.valid_cell_selected = FALSE;
832
833 /* Reference all objects referenced by this object */
834 g_object_ref(self->activity_status_bar);
835 g_object_ref(self->main_window);
836 g_object_ref(self->cell_tree_view);
837 g_object_ref(self->convert_button);
838 /* g_object_ref(self->layer_selector); <= This is already referenced by the _new() function */
839 g_object_ref(self->cell_search_entry);
840 /* g_object_ref(self->palette); */
841 g_object_ref(self->open_button);
842 g_object_ref(self->load_layer_button);
843 g_object_ref(self->save_layer_button);
844 g_object_ref(self->select_all_button);
845}
846
847GdsRenderGui *gds_render_gui_new()
848{
849 return RENDERER_GUI(g_object_new(RENDERER_TYPE_GUI, NULL));
850}
851
Header file for activity bar widget.
Header File for Cairo output renderer.
Calculation of gds_cell geometrics.
ColorPalette * color_palette_new_from_resource(char *resource_name)
Create a new object with from a resource containing the html hex color scheme.
Header file for the Conversion Settings Dialog.
Header file for the GDS-Parser.
Header for GdsRenderGui Object.
Checking functions of a cell tree (Header)
void activity_bar_set_ready(ActivityBar *bar)
Deletes all applied tasks and sets bar to "Ready".
Definition: activity-bar.c:102
ActivityBar * activity_bar_new()
Create new Object ActivityBar.
Definition: activity-bar.c:91
void activity_bar_set_busy(ActivityBar *bar, const char *text)
Enable spinner and set text. If text is NULL, 'Working...' is displayed.
Definition: activity-bar.c:108
static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, double scale)
render_cell Render a cell with its sub-cells
CairoRenderer * cairo_renderer_new_pdf()
Create new CairoRenderer for PDF output.
CairoRenderer * cairo_renderer_new_svg()
Create new CairoRenderer for SVG output.
int gds_tree_check_reference_loops(struct gds_library *lib)
gds_tree_check_reference_loops checks if the given library contains reference loops
int gds_tree_check_cell_references(struct gds_library *lib)
gds_tree_check_cell_references checks if all child cell references can be resolved in the given libra...
int clear_lib_list(GList **library_list)
Deletes all libraries including cells, references etc.
Definition: gds-parser.c:1146
int parse_gds_from_file(const char *filename, GList **library_list)
Parse a GDS file.
Definition: gds-parser.c:620
static void process_button_state_changes(GdsRenderGui *self)
static guint gds_render_gui_signals[SIGNAL_COUNT]
static void gds_render_gui_init(GdsRenderGui *self)
static void gds_render_gui_class_init(GdsRenderGuiClass *klass)
cell_store_columns
Columns of selection tree view.
gds_render_gui_signal_sig_ids
static void async_rendering_finished_callback(GdsOutputRenderer *renderer, gpointer gui)
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer, const char *status_message, gpointer data)
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
cell_store_filter_visible_func Decides whether an element of the tree model model is visible.
static void cell_selection_changed(GtkTreeSelection *sel, GdsRenderGui *self)
Callback for cell-selection change event.
#define RENDERER_TYPE_GUI
static void sort_up_callback(GtkWidget *widget, gpointer user)
static void on_convert_clicked(gpointer button, gpointer user)
Convert button callback.
static gboolean auto_naming_ask_for_override(GdsRenderGui *gui)
static void cell_tree_view_activated(gpointer tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user)
cell_tree_view_activated Callback for 'double click' on cell selector element
GtkWindow * gds_render_gui_get_main_window(GdsRenderGui *gui)
Get main window.
static void gds_render_gui_dispose(GObject *gobject)
static void on_load_gds(gpointer button, gpointer user)
Callback function of Load GDS button.
static void on_auto_color_clicked(gpointer button, gpointer user)
Callback for auto coloring button.
static void on_select_all_layers_clicked(GtkWidget *button, gpointer user_data)
Callback for the 'select all layers'-button.
GdsRenderGui * gds_render_gui_new()
Create new GdsRenderGui Object.
static void cell_tree_view_change_filter(GtkWidget *entry, gpointer data)
Trigger refiltering of cell filter.
int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
Setup a GtkTreeView with the necessary columns.
static gboolean on_window_close(gpointer window, GdkEvent *event, gpointer user)
Main window close event.
static void sort_down_callback(GtkWidget *widget, gpointer user)
static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
static gboolean tree_sel_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data)
This function only allows valid cells to be selected.
@ CELL_SEL_CELL
@ CELL_SEL_CELL_ERROR_STATE
@ CELL_SEL_LIBRARY
@ CELL_SEL_COLUMN_COUNT
Not a column. Used to determine count of columns.
@ SIGNAL_COUNT
@ SIGNAL_WINDOW_CLOSED
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
Render output asynchronously.
void gds_output_renderer_set_output_file(GdsOutputRenderer *renderer, const gchar *file_name)
Convenience function for setting the "output-file" property.
void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSettings *settings)
Set layer settings.
LatexRenderer * latex_renderer_new_with_options(gboolean pdf_layers, gboolean standalone)
Create new LatexRenderer object.
GtkCellRenderer * lib_cell_renderer_new()
Create a new renderer for renderering gds_cell and gds_library elements.
#define LIB_CELL_RENDERER_ERROR_ERR
#define LIB_CELL_RENDERER_ERROR_WARN
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
Get the settings configured in the dialog.
void renderer_settings_dialog_set_cell_height(RendererSettingsDialog *dialog, unsigned int height)
renderer_settings_dialog_set_cell_height Set height for rendered cell
void renderer_settings_dialog_set_database_unit_scale(RendererSettingsDialog *dialog, double unit_in_meters)
renderer_settings_dialog_set_database_unit_scale Set database scale
G_END_DECLS void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
Apply settings to dialog.
void renderer_settings_dialog_set_cell_width(RendererSettingsDialog *dialog, unsigned int width)
renderer_settings_dialog_set_cell_width Set width for rendered cell
RendererSettingsDialog * renderer_settings_dialog_new(GtkWindow *parent)
Create a new RedererSettingsDialog GObject.
@ RENDERER_CAIROGRAPHICS_PDF
@ RENDERER_CAIROGRAPHICS_SVG
@ RENDERER_LATEX_TIKZ
void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell)
Calculate bounding box of a gds cell.
void bounding_box_prepare_empty(union bounding_box *box)
Prepare an empty bounding box.
Definition: bounding-box.c:86
void layer_selector_force_sort(LayerSelector *selector, enum layer_selector_sort_algo sort_function)
Force the layer selector list to be sorted according to sort_function.
void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs)
Generate layer widgets in in the LayerSelector instance.
void layer_selector_set_load_mapping_button(LayerSelector *selector, GtkWidget *button, GtkWindow *main_window)
Supply button for loading the layer mapping.
void layer_selector_select_all_layers(LayerSelector *layer_selector, gboolean select)
Set 'export' value of all layers in the LayerSelector to the supplied select value.
LayerSettings * layer_selector_export_rendered_layer_info(LayerSelector *selector)
Get a list of all layers that shall be exported when rendering the cells.
void layer_selector_auto_name_layers(LayerSelector *layer_selector, gboolean overwrite)
Auto name all layers in the layer selector.
void layer_selector_set_save_mapping_button(LayerSelector *selector, GtkWidget *button, GtkWindow *main_window)
Supply button for saving the layer mapping.
LayerSelector * layer_selector_new(GtkListBox *list_box)
layer_selector_new
gboolean layer_selector_contains_elements(LayerSelector *layer_selector)
Check if the given layer selector contains layer elements.
size_t layer_selector_num_of_named_elements(LayerSelector *layer_selector)
Get number of layer elements that are named.
void layer_selector_auto_color_layers(LayerSelector *layer_selector, ColorPalette *palette, double global_alpha)
Apply colors from palette to all layers. Aditionally set alpha.
@ LAYER_SELECTOR_SORT_DOWN
@ LAYER_SELECTOR_SORT_UP
const char * _app_version_string
This string holds the Git Based Version Number of the app.
Definition: version.c:32
LaTeX output renderer.
Implementation of the Layer selection list.
Header file for the LibCellRenderer GObject Class.
GtkTreeView * cell_tree_view
GtkWidget * cell_search_entry
GList * gds_libraries
ColorPalette * palette
struct gui_button_states button_state_data
struct render_settings render_dialog_settings
LayerSelector * layer_selector
ActivityBar * activity_status_bar
GtkWidget * select_all_button
GtkWidget * convert_button
GtkWidget * open_button
GtkTreeStore * cell_tree_store
GtkWidget * save_layer_button
GtkWindow * main_window
GtkTreeModelFilter * cell_filter
GtkWidget * load_layer_button
struct vector_2d upper_right
Upper right point of the bounding box.
Definition: bounding-box.h:64
struct vector_2d lower_left
Lower left point of the bounding box.
Definition: bounding-box.h:62
int unresolved_child_count
Number of unresolved cell instances inside this cell. Default: GDS_CELL_CHECK_NOT_RUN.
Definition: gds-types.h:72
int affected_by_reference_loop
1 if the cell is affected by a reference loop and therefore not renderable. Default: GDS_CELL_CHECK_N...
Definition: gds-types.h:73
A Cell inside a gds_library.
Definition: gds-types.h:122
struct gds_cell_checks checks
Checking results.
Definition: gds-types.h:129
char name[CELL_NAME_MAX]
Definition: gds-types.h:123
struct gds_library * parent_library
Pointer to parent library.
Definition: gds-types.h:128
GDS Toplevel library.
Definition: gds-types.h:135
double unit_in_meters
Definition: gds-types.h:139
GList * cells
Definition: gds-types.h:140
gboolean valid_cell_selected
gboolean rendering_active
This struct holds the renderer configuration.
double scale
Scale image down by this factor.
enum output_renderer renderer
Union describing a bounding box.
Definition: bounding-box.h:55
struct bounding_box::_vectors vectors