Compare commits

..

No commits in common. "5357aff1b8163fdef743fdd07f4368df78e7d0af" and "587b79dc31748bf27f645990f846fb53f69863b3" have entirely different histories.

8 changed files with 217 additions and 302 deletions

View File

@ -21,7 +21,7 @@ aux_source_directory("latex-output" LATEX_SOURCES)
aux_source_directory("cairo-output" CAIRO_SOURCES) aux_source_directory("cairo-output" CAIRO_SOURCES)
aux_source_directory("trigonometric" TRIG_SOURCES) aux_source_directory("trigonometric" TRIG_SOURCES)
aux_source_directory("layer" LAYER_SELECTOR_SOURCES) aux_source_directory("layer" LAYER_SELECTOR_SOURCES)
set(SOURCE "main.c" "mapping-parser.c" "command-line.c" "gds-render-gui.c" "external-renderer.c") set(SOURCE "main.c" "mapping-parser.c" "command-line.c" "main-window.c" "external-renderer.c")
set(SOURCE set(SOURCE
${SOURCE} ${SOURCE}

View File

@ -0,0 +1,31 @@
/*
* GDSII-Converter
* Copyright (C) 2019 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file layer-selector-dnd.h
* @brief Header for drag and drop of layer selector
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef _LAYER_SELECTOR_DND_H_
#define _LAYER_SELECTOR_DND_H_
#include <gtk/gtk.h>
#endif /* _LAYER_SELECTOR_DND_H_ */

View File

@ -29,6 +29,7 @@
*/ */
#include "layer-selector.h" #include "layer-selector.h"
#include "layer-selector-dnd.h"
#include "layer-info.h" #include "layer-info.h"
#include "../gds-parser/gds-parser.h" #include "../gds-parser/gds-parser.h"
#include "../widgets/layer-element.h" #include "../widgets/layer-element.h"
@ -48,8 +49,6 @@ struct _LayerSelector {
GtkWindow *save_parent_window; GtkWindow *save_parent_window;
GtkListBox *list_box; GtkListBox *list_box;
GtkTargetEntry dnd_target;
gpointer dummy[4]; gpointer dummy[4];
}; };
@ -57,62 +56,9 @@ G_DEFINE_TYPE(LayerSelector, layer_selector, G_TYPE_OBJECT)
/* Drag and drop code */ /* Drag and drop code */
static GtkTargetEntry entries[] = {
static void sel_layer_element_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) { "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 }
{ };
GtkWidget *row;
GtkAllocation alloc;
cairo_surface_t *surface;
cairo_t *cr;
int x, y;
(void)data;
row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
gtk_widget_get_allocation(row, &alloc);
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
cr = cairo_create(surface);
gtk_style_context_add_class (gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_draw (row, cr);
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
cairo_surface_set_device_offset (surface, -x, -y);
gtk_drag_set_icon_surface (context, surface);
cairo_destroy (cr);
cairo_surface_destroy (surface);
g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)), "drag-row", row);
gtk_style_context_add_class(gtk_widget_get_style_context(row), "drag-row");
}
static void sel_layer_element_drag_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
{
GtkWidget *row;
(void)context;
(void)data;
row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)), "drag-row", NULL);
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-row");
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-hover");
}
static void sel_layer_element_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
guint info, guint time, gpointer data)
{
(void)context;
(void)info;
(void)time;
(void)data;
GdkAtom atom;
atom = gdk_atom_intern_static_string("GTK_LIST_BOX_ROW");
gtk_selection_data_set(selection_data, atom,
32, (const guchar *)&widget, sizeof(gpointer));
}
static GtkListBoxRow *layer_selector_get_last_row (GtkListBox *list) static GtkListBoxRow *layer_selector_get_last_row (GtkListBox *list)
{ {
@ -304,11 +250,6 @@ static void layer_selector_dispose(GObject *self)
g_clear_object(&sel->associated_load_button); g_clear_object(&sel->associated_load_button);
g_clear_object(&sel->associated_save_button); g_clear_object(&sel->associated_save_button);
if (sel->dnd_target.target) {
g_free(sel->dnd_target.target);
sel->dnd_target.target = NULL;
}
/* Chain up to parent's dispose function */ /* Chain up to parent's dispose function */
G_OBJECT_CLASS(layer_selector_parent_class)->dispose(self); G_OBJECT_CLASS(layer_selector_parent_class)->dispose(self);
} }
@ -329,26 +270,23 @@ static void layer_selector_class_init(LayerSelectorClass *klass)
g_object_unref(provider); g_object_unref(provider);
} }
static void layer_selector_setup_dnd(LayerSelector *self) static void layer_selector_setup_dnd(GtkListBox *box)
{ {
gtk_drag_dest_set(GTK_WIDGET(self->list_box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &self->dnd_target, 1, GDK_ACTION_MOVE); gtk_drag_dest_set(GTK_WIDGET(box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, entries, 1, GDK_ACTION_MOVE);
g_signal_connect(self->list_box, "drag-data-received", G_CALLBACK(layer_selector_drag_data_received), NULL); g_signal_connect(box, "drag-data-received", G_CALLBACK(layer_selector_drag_data_received), NULL);
g_signal_connect(self->list_box, "drag-motion", G_CALLBACK(layer_selector_drag_motion), NULL); g_signal_connect(box, "drag-motion", G_CALLBACK(layer_selector_drag_motion), NULL);
g_signal_connect(self->list_box, "drag-leave", G_CALLBACK(layer_selector_drag_leave), NULL); g_signal_connect(box, "drag-leave", G_CALLBACK(layer_selector_drag_leave), NULL);
} }
/* Drag and drop end */ /* Drag and drop end */
static void layer_selector_init(LayerSelector *self) static void layer_selector_init(LayerSelector *self)
{ {
/* Setup drag and drop for associated list box */
self->load_parent_window = NULL; self->load_parent_window = NULL;
self->save_parent_window = NULL; self->save_parent_window = NULL;
self->associated_load_button = NULL; self->associated_load_button = NULL;
self->associated_save_button = NULL; self->associated_save_button = NULL;
self->dnd_target.target = g_strdup_printf("LAYER_SELECTOR_DND_%p", self);
self->dnd_target.info = 0;
self->dnd_target.flags = GTK_TARGET_SAME_APP;
} }
LayerSelector *layer_selector_new(GtkListBox *list_box) LayerSelector *layer_selector_new(GtkListBox *list_box)
@ -360,7 +298,7 @@ LayerSelector *layer_selector_new(GtkListBox *list_box)
selector = LAYER_SELECTOR(g_object_new(TYPE_LAYER_SELECTOR, NULL)); selector = LAYER_SELECTOR(g_object_new(TYPE_LAYER_SELECTOR, NULL));
selector->list_box = list_box; selector->list_box = list_box;
layer_selector_setup_dnd(selector); layer_selector_setup_dnd(list_box);
g_object_ref(G_OBJECT(list_box)); g_object_ref(G_OBJECT(list_box));
return selector; return selector;
@ -447,14 +385,6 @@ static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self,
return ret; return ret;
} }
static void sel_layer_element_setup_dnd_callbacks(LayerSelector *self, LayerElement *element)
{
layer_element_set_dnd_callbacks(element, &self->dnd_target, 1,
sel_layer_element_drag_begin,
sel_layer_element_drag_data_get,
sel_layer_element_drag_end);
}
/** /**
* @brief Analyze \p cell and append used layers to list box * @brief Analyze \p cell and append used layers to list box
* @param listbox listbox to add layer * @param listbox listbox to add layer
@ -472,7 +402,6 @@ static void layer_selector_analyze_cell_layers(LayerSelector *self, struct gds_c
layer = (int)gfx->layer; layer = (int)gfx->layer;
if (layer_selector_check_if_layer_widget_exists(self, layer) == FALSE) { if (layer_selector_check_if_layer_widget_exists(self, layer) == FALSE) {
le = layer_element_new(); le = layer_element_new();
sel_layer_element_setup_dnd_callbacks(self, LAYER_ELEMENT(le));
layer_element_set_layer(LAYER_ELEMENT(le), layer); layer_element_set_layer(LAYER_ELEMENT(le), layer);
gtk_list_box_insert(self->list_box, le, -1); gtk_list_box_insert(self->list_box, le, -1);
gtk_widget_show(le); gtk_widget_show(le);
@ -749,7 +678,7 @@ void layer_selector_force_sort(LayerSelector *selector, enum layer_selector_sort
if (!box) if (!box)
return; return;
/* Set sorting function, sort, and disable sorting function */ /* Set dorting function, sort, and disable sorting function */
gtk_list_box_set_sort_func(box, layer_selector_sort_func, (gpointer)&sort_function, NULL); gtk_list_box_set_sort_func(box, layer_selector_sort_func, (gpointer)&sort_function, NULL);
gtk_list_box_invalidate_sort(box); gtk_list_box_invalidate_sort(box);
gtk_list_box_set_sort_func(box, NULL, NULL, NULL); gtk_list_box_set_sort_func(box, NULL, NULL, NULL);

View File

@ -18,7 +18,7 @@
*/ */
/** /**
* @file gds-render-gui.c * @file main-window.c
* @brief Handling of GUI * @brief Handling of GUI
* @author Mario Hüttel <mario.huettel@gmx.net> * @author Mario Hüttel <mario.huettel@gmx.net>
*/ */
@ -27,11 +27,12 @@
* @{ * @{
*/ */
#include "gds-render-gui.h" #include "main-window.h"
#include <stdio.h> #include <stdio.h>
#include "gds-parser/gds-parser.h" #include "gds-parser/gds-parser.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "layer/layer-selector.h" #include "layer/layer-selector.h"
#include "layer/layer-selector-dnd.h"
#include "tree-renderer/tree-store.h" #include "tree-renderer/tree-store.h"
#include "latex-output/latex-output.h" #include "latex-output/latex-output.h"
#include "widgets/conv-settings-dialog.h" #include "widgets/conv-settings-dialog.h"
@ -40,22 +41,25 @@
#include "version/version.h" #include "version/version.h"
#include "tree-renderer/lib-cell-renderer.h" #include "tree-renderer/lib-cell-renderer.h"
#include "gds-parser/gds-tree-checker.h" #include "gds-parser/gds-tree-checker.h"
/**
struct _GdsRenderGui { * @brief User data supplied to callback function of the open button
/* Parent GObject */ */
GObject parent; struct open_button_data {
/* Custom fields */
GtkWindow *main_window; GtkWindow *main_window;
GtkWidget *convert_button; GList **list_ptr;
GtkTreeStore *cell_tree_store; GtkTreeStore *cell_store;
GtkWidget *cell_search_entry; GtkSearchEntry *search_entry;
LayerSelector *layer_selector; LayerSelector *layer_selector;
GtkTreeView *cell_tree_view;
GList *gds_libraries;
}; };
G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT) /**
* @brief User data supplied to callback function of the convert button
*/
struct convert_button_data {
GtkTreeView *tree_view;
GtkWindow *main_window;
LayerSelector *layer_selector;
};
/** /**
* @brief Window close event of main window * @brief Window close event of main window
@ -67,17 +71,11 @@ G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT)
*/ */
static gboolean on_window_close(gpointer window, GdkEvent *event, gpointer user) static gboolean on_window_close(gpointer window, GdkEvent *event, gpointer user)
{ {
GdsRenderGui *self; /* Destroy all objects helb by this module, that are not part of the GUI itself */
g_object_unref(LAYER_SELECTOR(user));
self = RENDERER_GUI(user); /* Close Window. Leads to termination of the program */
/* Don't close window in case of error */
if (!self)
return TRUE;
/* Close Window. Leads to termination of the program/the current instance */
g_clear_object(&self->main_window);
gtk_widget_destroy(GTK_WIDGET(window)); gtk_widget_destroy(GTK_WIDGET(window));
return TRUE; return TRUE;
} }
@ -113,7 +111,8 @@ static void on_load_gds(gpointer button, gpointer user)
GList *lib; GList *lib;
struct gds_library *gds_lib; struct gds_library *gds_lib;
struct gds_cell *gds_c; struct gds_cell *gds_c;
GdsRenderGui *self; struct open_button_data *ptr = (struct open_button_data *)user;
GtkTreeStore *store = ptr->cell_store;
GtkWidget *open_dialog; GtkWidget *open_dialog;
GtkFileChooser *file_chooser; GtkFileChooser *file_chooser;
GtkFileFilter *filter; GtkFileFilter *filter;
@ -125,11 +124,7 @@ static void on_load_gds(gpointer button, gpointer user)
GString *acc_date; GString *acc_date;
unsigned int cell_error_level; unsigned int cell_error_level;
self = RENDERER_GUI(user); open_dialog = gtk_file_chooser_dialog_new("Open GDSII File", ptr->main_window,
if (!self)
return;
open_dialog = gtk_file_chooser_dialog_new("Open GDSII File", self->main_window,
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL, "Cancel", GTK_RESPONSE_CANCEL,
"Open GDSII", GTK_RESPONSE_ACCEPT, "Open GDSII", GTK_RESPONSE_ACCEPT,
@ -148,11 +143,11 @@ static void on_load_gds(gpointer button, gpointer user)
/* Get File name */ /* Get File name */
filename = gtk_file_chooser_get_filename(file_chooser); filename = gtk_file_chooser_get_filename(file_chooser);
gtk_tree_store_clear(self->cell_tree_store); gtk_tree_store_clear(store);
clear_lib_list(&self->gds_libraries); clear_lib_list(ptr->list_ptr);
/* Parse new GDSII file */ /* Parse new GDSII file */
gds_result = parse_gds_from_file(filename, &self->gds_libraries); gds_result = parse_gds_from_file(filename, ptr->list_ptr);
/* Delete file name afterwards */ /* Delete file name afterwards */
g_free(filename); g_free(filename);
@ -163,16 +158,16 @@ static void on_load_gds(gpointer button, gpointer user)
button_style = gtk_widget_get_style_context(GTK_WIDGET(button)); button_style = gtk_widget_get_style_context(GTK_WIDGET(button));
gtk_style_context_remove_class(button_style, "suggested-action"); gtk_style_context_remove_class(button_style, "suggested-action");
for (lib = self->gds_libraries; lib != NULL; lib = lib->next) { for (lib = *(ptr->list_ptr); lib != NULL; lib = lib->next) {
gds_lib = (struct gds_library *)lib->data; gds_lib = (struct gds_library *)lib->data;
/* Create top level iter */ /* Create top level iter */
gtk_tree_store_append(self->cell_tree_store, &libiter, NULL); gtk_tree_store_append(store, &libiter, NULL);
/* Convert dates to String */ /* Convert dates to String */
mod_date = generate_string_from_date(&gds_lib->mod_time); mod_date = generate_string_from_date(&gds_lib->mod_time);
acc_date = generate_string_from_date(&gds_lib->access_time); acc_date = generate_string_from_date(&gds_lib->access_time);
gtk_tree_store_set(self->cell_tree_store, &libiter, gtk_tree_store_set(store, &libiter,
CELL_SEL_LIBRARY, gds_lib, CELL_SEL_LIBRARY, gds_lib,
CELL_SEL_MODDATE, mod_date->str, CELL_SEL_MODDATE, mod_date->str,
CELL_SEL_ACCESSDATE, acc_date->str, CELL_SEL_ACCESSDATE, acc_date->str,
@ -189,7 +184,7 @@ static void on_load_gds(gpointer button, gpointer user)
for (cell = gds_lib->cells; cell != NULL; cell = cell->next) { for (cell = gds_lib->cells; cell != NULL; cell = cell->next) {
gds_c = (struct gds_cell *)cell->data; gds_c = (struct gds_cell *)cell->data;
gtk_tree_store_append(self->cell_tree_store, &celliter, &libiter); gtk_tree_store_append(store, &celliter, &libiter);
/* Convert dates to String */ /* Convert dates to String */
mod_date = generate_string_from_date(&gds_c->mod_time); mod_date = generate_string_from_date(&gds_c->mod_time);
@ -205,7 +200,7 @@ static void on_load_gds(gpointer button, gpointer user)
cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR; cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR;
/* Add cell to tree store model */ /* Add cell to tree store model */
gtk_tree_store_set(self->cell_tree_store, &celliter, gtk_tree_store_set(store, &celliter,
CELL_SEL_CELL, gds_c, CELL_SEL_CELL, gds_c,
CELL_SEL_MODDATE, mod_date->str, CELL_SEL_MODDATE, mod_date->str,
CELL_SEL_ACCESSDATE, acc_date->str, CELL_SEL_ACCESSDATE, acc_date->str,
@ -220,7 +215,7 @@ static void on_load_gds(gpointer button, gpointer user)
} }
/* Create Layers in Layer Box */ /* Create Layers in Layer Box */
layer_selector_generate_layer_widgets(self->layer_selector, self->gds_libraries); layer_selector_generate_layer_widgets(ptr->layer_selector, *(ptr->list_ptr));
} }
end_destroy: end_destroy:
@ -240,7 +235,7 @@ static void on_convert_clicked(gpointer button, gpointer user)
.scale = 1000.0, .scale = 1000.0,
.renderer = RENDERER_LATEX_TIKZ, .renderer = RENDERER_LATEX_TIKZ,
}; };
GdsRenderGui *self; struct convert_button_data *data = (struct convert_button_data *)user;
GtkTreeSelection *selection; GtkTreeSelection *selection;
GtkTreeIter iter; GtkTreeIter iter;
GtkTreeModel *model; GtkTreeModel *model;
@ -255,13 +250,11 @@ static void on_convert_clicked(gpointer button, gpointer user)
union bounding_box cell_box; union bounding_box cell_box;
unsigned int height, width; unsigned int height, width;
self = RENDERER_GUI(user); if (!data)
if (!self)
return; return;
/* Get selected cell */ /* Get selected cell */
selection = gtk_tree_view_get_selection(self->cell_tree_view); selection = gtk_tree_view_get_selection(data->tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
return; return;
@ -271,7 +264,7 @@ static void on_convert_clicked(gpointer button, gpointer user)
return; return;
/* Get layers that are rendered */ /* Get layers that are rendered */
layer_list = layer_selector_export_rendered_layer_info(self->layer_selector); layer_list = layer_selector_export_rendered_layer_info(data->layer_selector);
/* Calculate cell size in DB units */ /* Calculate cell size in DB units */
bounding_box_prepare_empty(&cell_box); bounding_box_prepare_empty(&cell_box);
@ -285,7 +278,7 @@ static void on_convert_clicked(gpointer button, gpointer user)
width = (unsigned int)(cell_box.vectors.upper_right.x - cell_box.vectors.lower_left.x); width = (unsigned int)(cell_box.vectors.upper_right.x - cell_box.vectors.lower_left.x);
/* Show settings dialog */ /* Show settings dialog */
settings = renderer_settings_dialog_new(GTK_WINDOW(self->main_window)); settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window));
renderer_settings_dialog_set_settings(settings, &sett); renderer_settings_dialog_set_settings(settings, &sett);
renderer_settings_dialog_set_database_unit_scale(settings, cell_to_render->parent_library->unit_in_meters); renderer_settings_dialog_set_database_unit_scale(settings, cell_to_render->parent_library->unit_in_meters);
renderer_settings_dialog_set_cell_height(settings, height); renderer_settings_dialog_set_cell_height(settings, height);
@ -303,7 +296,7 @@ static void on_convert_clicked(gpointer button, gpointer user)
/* save file dialog */ /* save file dialog */
dialog = gtk_file_chooser_dialog_new((sett.renderer == RENDERER_LATEX_TIKZ dialog = gtk_file_chooser_dialog_new((sett.renderer == RENDERER_LATEX_TIKZ
? "Save LaTeX File" : "Save PDF"), ? "Save LaTeX File" : "Save PDF"),
GTK_WINDOW(self->main_window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_WINDOW(data->main_window), GTK_FILE_CHOOSER_ACTION_SAVE,
"Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL); "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL);
/* Set file filter according to settings */ /* Set file filter according to settings */
filter = gtk_file_filter_new(); filter = gtk_file_filter_new();
@ -381,83 +374,55 @@ static void cell_tree_view_activated(gpointer tree_view, GtkTreePath *path,
* This function activates/deactivates the convert button depending on whether * This function activates/deactivates the convert button depending on whether
* a cell is selected for conversion or not * a cell is selected for conversion or not
* @param sel * @param sel
* @param self * @param convert_button
*/ */
static void cell_selection_changed(GtkTreeSelection *sel, GdsRenderGui *self) static void cell_selection_changed(GtkTreeSelection *sel, GtkWidget *convert_button)
{ {
GtkTreeModel *model = NULL; GtkTreeModel *model = NULL;
GtkTreeIter iter; GtkTreeIter iter;
if (gtk_tree_selection_get_selected(sel, &model, &iter)) { if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
/* Node selected. Show button */ /* Node selected. Show button */
gtk_widget_set_sensitive(self->convert_button, TRUE); gtk_widget_set_sensitive(convert_button, TRUE);
} else { } else {
gtk_widget_set_sensitive(self->convert_button, FALSE); gtk_widget_set_sensitive(convert_button, FALSE);
} }
} }
static void sort_up_callback(GtkWidget *widget, gpointer user) static void sort_up_callback(GtkWidget *widget, gpointer user)
{ {
(void)widget; (void)widget;
GdsRenderGui *self; LayerSelector *sel;
self = RENDERER_GUI(user); sel = LAYER_SELECTOR(user);
if (!self) if (!sel)
return; return;
layer_selector_force_sort(self->layer_selector, LAYER_SELECTOR_SORT_UP); layer_selector_force_sort(sel, LAYER_SELECTOR_SORT_UP);
} }
static void sort_down_callback(GtkWidget *widget, gpointer user) static void sort_down_callback(GtkWidget *widget, gpointer user)
{ {
(void)widget; (void)widget;
GdsRenderGui *self; LayerSelector *sel;
self = RENDERER_GUI(user); sel = LAYER_SELECTOR(user);
if (!self) if (!sel)
return; return;
layer_selector_force_sort(self->layer_selector, LAYER_SELECTOR_SORT_DOWN); layer_selector_force_sort(sel, LAYER_SELECTOR_SORT_DOWN);
} }
static void gds_render_gui_dispose(GObject *gobject) GtkWindow *create_main_window()
{
GdsRenderGui *self;
self = RENDERER_GUI(gobject);
g_clear_object(&self->cell_tree_view);
g_clear_object(&self->convert_button);
g_clear_object(&self->layer_selector);
g_clear_object(&self->cell_tree_store);
g_clear_object(&self->cell_search_entry);
if (self->main_window) {
g_signal_handlers_destroy(self->main_window);
gtk_widget_destroy(GTK_WIDGET(self->main_window));
self->main_window = NULL;
}
/* Chain up */
G_OBJECT_CLASS(gds_render_gui_parent_class)->dispose(gobject);
}
static void gds_render_gui_class_init(GdsRenderGuiClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = gds_render_gui_dispose;
}
GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui)
{
return gui->main_window;
}
static void gds_render_gui_init(GdsRenderGui *self)
{ {
GtkBuilder *main_builder; GtkBuilder *main_builder;
GtkTreeView *cell_tree;
GtkWidget *listbox; GtkWidget *listbox;
GtkWidget *conv_button;
GtkWidget *search_entry;
GtkHeaderBar *header_bar; GtkHeaderBar *header_bar;
LayerSelector *layer_selector;
static GList *gds_libs;
static struct open_button_data open_data;
static struct convert_button_data conv_data;
struct tree_stores *cell_selector_stores; struct tree_stores *cell_selector_stores;
GtkWidget *sort_up_button; GtkWidget *sort_up_button;
GtkWidget *sort_down_button; GtkWidget *sort_down_button;
@ -465,29 +430,34 @@ static void gds_render_gui_init(GdsRenderGui *self)
main_builder = gtk_builder_new_from_resource("/main.glade"); main_builder = gtk_builder_new_from_resource("/main.glade");
gtk_builder_connect_signals(main_builder, NULL); gtk_builder_connect_signals(main_builder, NULL);
self->cell_tree_view = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree")); cell_tree = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree"));
self->cell_search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search")); search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search"));
open_data.search_entry = GTK_SEARCH_ENTRY(search_entry);
cell_selector_stores = setup_cell_selector(cell_tree, GTK_ENTRY(search_entry));
cell_selector_stores = setup_cell_selector(self->cell_tree_view, GTK_ENTRY(self->cell_search_entry)); open_data.cell_store = cell_selector_stores->base_store;
open_data.list_ptr = &gds_libs;
self->cell_tree_store = cell_selector_stores->base_store; open_data.main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
self->main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
g_signal_connect(GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds")), g_signal_connect(GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds")),
"clicked", G_CALLBACK(on_load_gds), (gpointer)self); "clicked", G_CALLBACK(on_load_gds), (gpointer)&open_data);
self->convert_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button")); /* Connect Convert button */
g_signal_connect(self->convert_button, "clicked", G_CALLBACK(on_convert_clicked), (gpointer)self); conv_data.tree_view = cell_tree;
conv_data.main_window = open_data.main_window;
conv_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button"));
g_signal_connect(conv_button, "clicked", G_CALLBACK(on_convert_clicked), &conv_data);
listbox = GTK_WIDGET(gtk_builder_get_object(main_builder, "layer-list")); listbox = GTK_WIDGET(gtk_builder_get_object(main_builder, "layer-list"));
/* Create layer selector */ /* Create layer selector */
self->layer_selector = layer_selector_new(GTK_LIST_BOX(listbox)); layer_selector = layer_selector_new(GTK_LIST_BOX(listbox));
conv_data.layer_selector = layer_selector;
open_data.layer_selector = layer_selector;
/* Callback for selection change of cell selector */ /* Callback for selection change of cell selector */
g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(self->cell_tree_view)), "changed", g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(cell_tree)), "changed",
G_CALLBACK(cell_selection_changed), self); G_CALLBACK(cell_selection_changed), conv_button);
g_signal_connect(self->cell_tree_view, "row-activated", G_CALLBACK(cell_tree_view_activated), self); g_signal_connect(cell_tree, "row-activated", G_CALLBACK(cell_tree_view_activated), &conv_data);
/* Set version in main window subtitle */ /* Set version in main window subtitle */
header_bar = GTK_HEADER_BAR(gtk_builder_get_object(main_builder, "header-bar")); header_bar = GTK_HEADER_BAR(gtk_builder_get_object(main_builder, "header-bar"));
@ -497,34 +467,25 @@ static void gds_render_gui_init(GdsRenderGui *self)
sort_up_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-up-sort")); sort_up_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-up-sort"));
sort_down_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-down-sort")); sort_down_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-down-sort"));
g_signal_connect(sort_up_button, "clicked", G_CALLBACK(sort_up_callback), self); g_signal_connect(sort_up_button, "clicked", G_CALLBACK(sort_up_callback), layer_selector);
g_signal_connect(sort_down_button, "clicked", G_CALLBACK(sort_down_callback), self); g_signal_connect(sort_down_button, "clicked", G_CALLBACK(sort_down_callback), layer_selector);
/* Set buttons for loading and saving */ /* Set buttons for loading and saving */
layer_selector_set_load_mapping_button(self->layer_selector, layer_selector_set_load_mapping_button(layer_selector,
GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping")), GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping")),
self->main_window); conv_data.main_window);
layer_selector_set_save_mapping_button(self->layer_selector, GTK_WIDGET(gtk_builder_get_object(main_builder, "button-save-mapping")), layer_selector_set_save_mapping_button(layer_selector, GTK_WIDGET(gtk_builder_get_object(main_builder, "button-save-mapping")),
self->main_window); conv_data.main_window);
/* Connect delete-event */ /* Connect delete-event */
g_signal_connect(GTK_WIDGET(self->main_window), "delete-event", g_signal_connect(GTK_WIDGET(open_data.main_window), "delete-event",
G_CALLBACK(on_window_close), self); G_CALLBACK(on_window_close), layer_selector);
g_object_unref(main_builder); g_object_unref(main_builder);
/* Reference all objects referenced by this object */ return conv_data.main_window;
g_object_ref(self->main_window);
g_object_ref(self->cell_tree_view);
g_object_ref(self->convert_button);
g_object_ref(self->layer_selector);
g_object_ref(self->cell_tree_store);
g_object_ref(self->cell_search_entry);
}
GdsRenderGui *gds_render_gui_new()
{
return RENDERER_GUI(g_object_new(RENDERER_TYPE_GUI, NULL));
} }
/** @} */ /** @} */

View File

@ -18,13 +18,13 @@
*/ */
/** /**
* @file gds-render-gui.h * @file main-window.h
* @brief Header for GdsRenderGui Object * @brief Header for main-window
* @author Mario Hüttel <mario.huettel@gmx.net> * @author Mario Hüttel <mario.huettel@gmx.net>
*/ */
#ifndef _GDS_RENDER_GUI_ #ifndef _MAIN_WINDOW_H_
#define _GDS_RENDER_GUI_ #define _MAIN_WINDOW_H_
/** /**
* @addtogroup MainApplication * @addtogroup MainApplication
@ -33,29 +33,14 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(GdsRenderGui, gds_render_gui, RENDERER, GUI, GObject);
#define RENDERER_TYPE_GUI (gds_render_gui_get_type())
/** /**
* @brief Create new GdsRenderGui Object * @brief Create main window
* @return
*/
GdsRenderGui *gds_render_gui_new();
/**
* @brief Get main window
* *
* This function returns the main window of the GUI, which can later be displayed. * This function creates the main window and sets the necessary callback routines.
* All handling of hte GUI is taken care of inside the GdsRenderGui Object
* @return * @return
*/ */
GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui); GtkWindow *create_main_window();
G_END_DECLS
/** @} */ /** @} */
#endif /* _GDS_RENDER_GUI_ */ #endif /* _MAIN_WINDOW_H_ */

48
main.c
View File

@ -20,32 +20,23 @@
#include <stdio.h> #include <stdio.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib.h> #include <glib.h>
#include "gds-render-gui.h" #include "main-window.h"
#include "command-line.h" #include "command-line.h"
#include "external-renderer.h" #include "external-renderer.h"
#include "version/version.h" #include "version/version.h"
struct application_data { struct application_data {
GtkApplication *app; GtkApplication *app;
GList *gui_list; GtkWindow *main_window;
}; };
static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data) static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{ {
struct application_data * const appdata = (struct application_data *)user_data; const struct application_data * const appdata = (const struct application_data *)user_data;
(void)action; (void)action;
(void)parameter; (void)parameter;
GList *list_iter;
GdsRenderGui *gui;
/* Dispose all GUIs */ gtk_widget_destroy(GTK_WIDGET(appdata->main_window));
for (list_iter = appdata->gui_list; list_iter != NULL; list_iter = g_list_next(list_iter)) {
gui = RENDERER_GUI(list_iter->data);
g_object_unref(gui);
}
g_list_free(appdata->gui_list);
appdata->gui_list = NULL;
} }
static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_data) static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_data)
@ -58,7 +49,7 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
builder = gtk_builder_new_from_resource("/about.glade"); builder = gtk_builder_new_from_resource("/about.glade");
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog")); dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog"));
gtk_window_set_transient_for(GTK_WINDOW(dialog), NULL); gtk_window_set_transient_for(GTK_WINDOW(dialog), appdata->main_window);
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string);
gtk_dialog_run(dialog); gtk_dialog_run(dialog);
@ -74,15 +65,10 @@ const static GActionEntry app_actions[] = {
static void gapp_activate(GApplication *app, gpointer user_data) static void gapp_activate(GApplication *app, gpointer user_data)
{ {
GtkWindow *main_window; GtkWindow *main_window;
GdsRenderGui *gui;
struct application_data * const appdata = (struct application_data *)user_data; struct application_data * const appdata = (struct application_data *)user_data;
gui = gds_render_gui_new(); main_window = create_main_window();
appdata->gui_list = g_list_append(appdata->gui_list, gui); appdata->main_window = main_window;
main_window = gds_render_gui_get_main_window(gui);
gtk_application_add_window(GTK_APPLICATION(app), main_window); gtk_application_add_window(GTK_APPLICATION(app), main_window);
gtk_widget_show(GTK_WIDGET(main_window)); gtk_widget_show(GTK_WIDGET(main_window));
} }
@ -92,23 +78,15 @@ static int start_gui(int argc, char **argv)
GtkApplication *gapp; GtkApplication *gapp;
int app_status; int app_status;
static struct application_data appdata = {.gui_list = NULL}; static struct application_data appdata;
GMenu *menu; GMenu *menu;
GMenu *m_quit; GMenu *m_quit;
GMenu *m_about; GMenu *m_about;
GList *list_iter;
GdsRenderGui *gui;
gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_FLAGS_NONE); gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_NON_UNIQUE);
g_application_register(G_APPLICATION(gapp), NULL, NULL); g_application_register(G_APPLICATION(gapp), NULL, NULL);
g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata); g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) {
g_application_activate(G_APPLICATION(gapp));
printf("There is already an open instance. Will open second window in said instance.\n");
return 0;
}
menu = g_menu_new(); menu = g_menu_new();
m_quit = g_menu_new(); m_quit = g_menu_new();
m_about = g_menu_new(); m_about = g_menu_new();
@ -127,14 +105,6 @@ static int start_gui(int argc, char **argv)
app_status = g_application_run(G_APPLICATION(gapp), argc, argv); app_status = g_application_run(G_APPLICATION(gapp), argc, argv);
g_object_unref(gapp); g_object_unref(gapp);
/* Destroy gui_list */
for (list_iter = appdata.gui_list; list_iter != NULL; list_iter = g_list_next(list_iter)) {
gui = RENDERER_GUI(list_iter->data);
g_object_unref(gui);
}
g_list_free(appdata.gui_list);
return app_status; return app_status;
} }

View File

@ -57,6 +57,65 @@ static void layer_element_class_init(LayerElementClass *klass)
oclass->constructed = layer_element_constructed; oclass->constructed = layer_element_constructed;
} }
static GtkTargetEntry entries[] = {
{ "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 }
};
static void layer_element_drag_begin(GtkWidget *widget,
GdkDragContext *context,
gpointer data)
{
GtkWidget *row;
GtkAllocation alloc;
cairo_surface_t *surface;
cairo_t *cr;
int x, y;
(void)data;
row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
gtk_widget_get_allocation(row, &alloc);
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
cr = cairo_create(surface);
gtk_style_context_add_class (gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_draw (row, cr);
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
cairo_surface_set_device_offset (surface, -x, -y);
gtk_drag_set_icon_surface (context, surface);
cairo_destroy (cr);
cairo_surface_destroy (surface);
g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)), "drag-row", row);
gtk_style_context_add_class(gtk_widget_get_style_context(row), "drag-row");
}
static void layer_element_drag_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
{
GtkWidget *row;
(void)context;
(void)data;
row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)), "drag-row", NULL);
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-row");
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-hover");
}
static void layer_element_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
guint info, guint time, gpointer data)
{
(void)context;
(void)info;
(void)time;
(void)data;
gtk_selection_data_set(selection_data, gdk_atom_intern_static_string("GTK_LIST_BOX_ROW"),
32, (const guchar *)&widget, sizeof(gpointer));
}
static void layer_element_init(LayerElement *self) static void layer_element_init(LayerElement *self)
{ {
GtkBuilder *builder; GtkBuilder *builder;
@ -72,6 +131,13 @@ static void layer_element_init(LayerElement *self)
self->priv.name = GTK_ENTRY(gtk_builder_get_object(builder, "entry")); self->priv.name = GTK_ENTRY(gtk_builder_get_object(builder, "entry"));
self->priv.event_handle = GTK_EVENT_BOX(gtk_builder_get_object(builder, "event-box")); self->priv.event_handle = GTK_EVENT_BOX(gtk_builder_get_object(builder, "event-box"));
/* Setup drag and drop */
gtk_style_context_add_class (gtk_widget_get_style_context(GTK_WIDGET(self)), "row");
gtk_drag_source_set(GTK_WIDGET(self->priv.event_handle), GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);
g_signal_connect(self->priv.event_handle, "drag-begin", G_CALLBACK(layer_element_drag_begin), NULL);
g_signal_connect(self->priv.event_handle, "drag-data-get", G_CALLBACK(layer_element_drag_data_get), NULL);
g_signal_connect(self->priv.event_handle, "drag-end", G_CALLBACK(layer_element_drag_end), NULL);
g_object_unref(builder); g_object_unref(builder);
} }
@ -128,19 +194,4 @@ void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba)
gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba); gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba);
} }
void layer_element_set_dnd_callbacks(LayerElement *elem, GtkTargetEntry *entries, int entry_count,
void (*drag_begin)(GtkWidget *, GdkDragContext *, gpointer),
void (*drag_data_get)(GtkWidget *, GdkDragContext *,
GtkSelectionData *, guint , guint, gpointer),
void (*drag_end)(GtkWidget *, GdkDragContext *, gpointer))
{
/* Setup drag and drop */
gtk_style_context_add_class (gtk_widget_get_style_context(GTK_WIDGET(elem)), "row");
gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK, entries, entry_count, GDK_ACTION_MOVE);
g_signal_connect(elem->priv.event_handle, "drag-begin", G_CALLBACK(drag_begin), NULL);
g_signal_connect(elem->priv.event_handle, "drag-data-get", G_CALLBACK(drag_data_get), NULL);
g_signal_connect(elem->priv.event_handle, "drag-end", G_CALLBACK(drag_end), NULL);
}
/** @} */ /** @} */

View File

@ -118,18 +118,6 @@ void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba);
*/ */
void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba); void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba);
/**
* @brief layer_element_set_dnd_callbacks
* @param elem
* @param entries
* @param entry_count
*/
void layer_element_set_dnd_callbacks(LayerElement *elem, GtkTargetEntry *entries, int entry_count,
void (*drag_begin)(GtkWidget *, GdkDragContext *, gpointer),
void (*drag_data_get)(GtkWidget *, GdkDragContext *,
GtkSelectionData *, guint , guint, gpointer),
void (*drag_end)(GtkWidget *, GdkDragContext *, gpointer));
G_END_DECLS G_END_DECLS
#endif /* __LAYER_ELEMENT_H__ */ #endif /* __LAYER_ELEMENT_H__ */