Implemente layer box

* Layers can be added dynamically
* Layers are sorted

TODO:
- implement load and save functions
This commit is contained in:
Mario Hüttel 2018-05-16 16:20:09 +02:00
parent 43b208a467
commit 781c2a603a
8 changed files with 400 additions and 19 deletions

View File

@ -7,9 +7,9 @@ pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS}) include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS})
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS}) link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS})
configure_file(glade/main.glade glade/main.glade COPYONLY) configure_file(glade/main.glade glade/main.glade COPYONLY)
configure_file(glade/layer-widget.glade glade/layer-widget.glade COPYONLY)
project(gds-render) project(gds-render)
add_executable(${PROJECT_NAME} "main.c" "gdsparse.c" "layer-element.c") add_executable(${PROJECT_NAME} "main.c" "gdsparse.c" "layer-element.c" "layer-selector.c")
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} m) target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} m)

83
glade/layer-widget.glade Normal file
View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="value">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkBox" id="box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">3</property>
<child>
<object class="GtkLabel" id="layer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkColorButton" id="color">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScale" id="opacity">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment1</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">100</property>
<property name="round_digits">0</property>
<property name="digits">0</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="export">
<property name="label" translatable="yes">Export Layer</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</interface>

View File

@ -14,6 +14,10 @@
<property name="title" translatable="yes">GDS Renderer</property> <property name="title" translatable="yes">GDS Renderer</property>
<property name="subtitle" translatable="yes">GDSII to PDF Converter</property> <property name="subtitle" translatable="yes">GDSII to PDF Converter</property>
<property name="show_close_button">True</property> <property name="show_close_button">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child> <child>
<object class="GtkButton" id="button-load-gds"> <object class="GtkButton" id="button-load-gds">
<property name="label">gtk-open</property> <property name="label">gtk-open</property>
@ -26,6 +30,41 @@
<class name="suggested-action"/> <class name="suggested-action"/>
</style> </style>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-load-mapping">
<property name="label" translatable="yes">Load Mapping</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-save-mapping">
<property name="label" translatable="yes">Save Mapping</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child> </child>
</object> </object>
</child> </child>
@ -48,10 +87,10 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkListBox"> <object class="GtkListBox" id="layer-list">
<property name="name">layer-list</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="selection_mode">none</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>

View File

@ -19,21 +19,104 @@
#include "layer-element.h" #include "layer-element.h"
G_DEFINE_TYPE (LayerElement, layer_element, GTK_TYPE_BOX) G_DEFINE_TYPE(LayerElement, layer_element, GTK_TYPE_BOX)
static void layer_element_dispose(GObject *obj)
{
/* destroy parent container. This destroys all widgets inside */
G_OBJECT_CLASS(layer_element_parent_class)->dispose(obj);
}
static void layer_element_class_init(LayerElementClass *klass) static void layer_element_class_init(LayerElementClass *klass)
{ {
GObjectClass *oclass = G_OBJECT_CLASS(klass);
oclass->dispose = layer_element_dispose;
return; return;
} }
static void layer_element_init(LayerElement *self) static void layer_element_init(LayerElement *self)
{ {
self->button = gtk_button_new(); GtkBuilder *builder;
gtk_box_pack_start(GTK_BOX(self), self->button, TRUE, TRUE, 0); GtkWidget *glade_box;
gtk_widget_show(self->button); builder = gtk_builder_new_from_file("glade/layer-widget.glade");
glade_box = GTK_WIDGET(gtk_builder_get_object(builder, "box"));
gtk_box_pack_start(GTK_BOX(self), glade_box, TRUE, TRUE, 0);
/* Get Elements */
self->priv.color = GTK_COLOR_BUTTON(gtk_builder_get_object(builder, "color"));
self->priv.export = GTK_CHECK_BUTTON(gtk_builder_get_object(builder, "export"));
self->priv.layer = GTK_LABEL(gtk_builder_get_object(builder, "layer"));
self->priv.name = GTK_ENTRY(gtk_builder_get_object(builder, "entry"));
self->priv.opacity = GTK_SCALE(gtk_builder_get_object(builder, "opacity"));
/* Connect signals */
/* None */
g_object_unref(builder);
} }
GtkWidget *layer_element_new(void) GtkWidget *layer_element_new(void)
{ {
return GTK_WIDGET(g_object_new(layer_element_get_type(), NULL)); return GTK_WIDGET(g_object_new(layer_element_get_type(), NULL));
} }
const char *layer_element_get_name(LayerElement *elem)
{
return gtk_entry_get_text(elem->priv.name);
}
void layer_element_set_name(LayerElement *elem, const char* name)
{
gtk_entry_set_text(elem->priv.name, name);
}
void layer_element_set_layer(LayerElement *elem, int layer)
{
GString *string;
string = g_string_new_len(NULL, 100);
g_string_printf(string, "Layer: %d", layer);
gtk_label_set_text(elem->priv.layer, (const gchar *)string->str);
elem->priv.layer_num = layer;
g_string_free(string, TRUE);
}
int layer_element_get_layer(LayerElement *elem)
{
return elem->priv.layer_num;
}
void layer_element_set_opacity(LayerElement *elem, int opacity)
{
if (opacity > 100 || opacity < 0)
return;
gtk_range_set_value(GTK_RANGE(elem->priv.opacity), (gdouble)opacity);
}
int layer_element_get_opacity(LayerElement *elem)
{
return (int)gtk_range_get_value(GTK_RANGE(elem->priv.opacity));
}
void layer_element_set_export(LayerElement *elem, gboolean export)
{
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(elem->priv.export), export);
}
gboolean layer_element_get_export(LayerElement *elem)
{
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(elem->priv.export));
}
void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba)
{
if (!rgba)
return;
gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba);
}
void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba)
{
gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba);
}

View File

@ -27,11 +27,20 @@
#define LAYER_ELEMENT_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, layer_element_get_type(), LayerElementClass) #define LAYER_ELEMENT_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, layer_element_get_type(), LayerElementClass)
#define IS_LAYE_RELEMENT(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, layer_element_get_type()) #define IS_LAYE_RELEMENT(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, layer_element_get_type())
typedef struct _LayerElementPriv {
GtkEntry *name;
GtkLabel *layer;
int layer_num;
GtkColorButton *color;
GtkScale *opacity;
GtkCheckButton *export;
} LayerElementPriv;
typedef struct _LayerElement { typedef struct _LayerElement {
/* Inheritance */ /* Inheritance */
GtkBox hbox; GtkBox hbox;
/* Custom Elements */ /* Custom Elements */
GtkWidget *button; LayerElementPriv priv;
} LayerElement; } LayerElement;
typedef struct _LayerElementClass { typedef struct _LayerElementClass {
@ -42,4 +51,15 @@ typedef struct _LayerElementClass {
GType layer_element_get_type(void); GType layer_element_get_type(void);
GtkWidget *layer_element_new(void); GtkWidget *layer_element_new(void);
const char *layer_element_get_name(LayerElement *elem);
void layer_element_set_name(LayerElement *elem, const char* name);
void layer_element_set_layer(LayerElement *elem, int layer);
int layer_element_get_layer(LayerElement *elem);
void layer_element_set_opacity(LayerElement *elem, int opacity);
int layer_element_get_opacity(LayerElement *elem);
void layer_element_set_export(LayerElement *elem, gboolean export);
gboolean layer_element_get_export(LayerElement *elem);
void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba);
void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba);
#endif /* __LAYER_ELEMENT_H__ */ #endif /* __LAYER_ELEMENT_H__ */

122
layer-selector.c Normal file
View File

@ -0,0 +1,122 @@
#include "layer-selector.h"
#include "gdsparse.h"
static void layer_list_remove_element(struct layer_info *inf)
{
if (inf)
free(inf);
}
void get_layer_info(GList **info_list, GtkListBox *box)
{
GList *local_list = NULL;
/* Clear info Glist */
if (*info_list != NULL) {
g_list_free_full(*info_list, (GDestroyNotify)layer_list_remove_element);
*info_list = NULL;
}
*info_list = local_list;
}
static GList *layer_widgets = NULL;
static void delete_layer_widget(GtkWidget *widget)
{
gtk_widget_destroy(widget);
}
void clear_list_box_widgets(GtkListBox *box)
{
GList *list;
list = gtk_container_get_children(GTK_CONTAINER(box));
for (;list != NULL; list = list->next) {
gtk_container_remove(GTK_CONTAINER(box), GTK_WIDGET(list->data));
}
/* Widgets are already destroyed when removed from box */
g_list_free(layer_widgets);
layer_widgets = NULL;
}
static gboolean check_if_layer_widget_exists(int layer) {
GList *list;
LayerElement *widget;
gboolean ret = FALSE;
for (list = layer_widgets; list != NULL; list = list->next) {
widget = (LayerElement *)list->data;
if (layer_element_get_layer(widget) == layer) {
ret = TRUE;
break;
}
}
return ret;
}
static void analyze_cell_layers(GtkListBox *listbox, struct gds_cell *cell)
{
GList *graphics;
struct gds_graphics *gfx;
int layer;
GtkWidget *le;
for (graphics = cell->graphic_objs; graphics != NULL; graphics = graphics->next) {
gfx = (struct gds_graphics *)graphics->data;
layer = (int)gfx->layer;
if (check_if_layer_widget_exists(layer) == FALSE) {
le = layer_element_new();
layer_element_set_layer(LAYER_ELEMENT(le), layer);
gtk_list_box_insert(listbox, le, -1);
gtk_widget_show(le);
layer_widgets = g_list_append(layer_widgets, le);
printf("added new layer\n");
}
}
}
gint sort_func(GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer unused)
{
GList *children1, *children2;
LayerElement *le1, *le2;
gint ret;
children1 = gtk_container_get_children(GTK_CONTAINER(row1));
children2 = gtk_container_get_children(GTK_CONTAINER(row2));
le1 = LAYER_ELEMENT(children1->data);
le2 = LAYER_ELEMENT(children2->data);
ret = layer_element_get_layer(le1) - layer_element_get_layer(le2);
g_list_free(children1);
g_list_free(children2);
return ret;
}
void generate_layer_widgets(GtkListBox *listbox, GList *libs)
{
GList *cell_list = NULL;
struct gds_library *lib;
printf("foo?\n");
clear_list_box_widgets(listbox);
gtk_list_box_set_sort_func(listbox, sort_func, NULL, NULL);
printf("layers deleted\n");
for (; libs != NULL; libs = libs->next) {
lib = (struct gds_library *)libs->data;
for (cell_list = lib->cells; cell_list != NULL; cell_list = cell_list->next) {
analyze_cell_layers(listbox, (struct gds_cell *)cell_list->data);
} /* For Cell List */
} /* For libs */
/* Force sort */
gtk_list_box_invalidate_sort(listbox);
}

23
layer-selector.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __LAYER_SELECTOR_H__
#define __LAYER_SELECTOR_H__
#include <gtk/gtk.h>
#include <glib.h>
#include "layer-element.h"
struct layer_info {
int id;
/* This contains both: opacity and Color */
GdkRGBA color;
};
void generate_layer_widgets(GtkListBox *listbox, GList *libs);
void clear_list_box_widgets();
void setup_load_mapping_callback(GtkWidget *button);
void setup_save_mapping_callback(GtkWidget *button);
void get_layer_info(GList **info_list, GtkListBox *box);
#endif /* __LAYER_SELECTOR_H__ */

13
main.c
View File

@ -21,6 +21,7 @@
#include "gdsparse.h" #include "gdsparse.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "layer-element.h" #include "layer-element.h"
#include "layer-selector.h"
enum cell_store_columns { enum cell_store_columns {
@ -34,6 +35,7 @@ struct open_button_data {
GtkWindow *main_window; GtkWindow *main_window;
GList **list_ptr; GList **list_ptr;
GtkTreeStore *cell_store; GtkTreeStore *cell_store;
GtkListBox *layer_box;
}; };
@ -108,6 +110,9 @@ void on_load_gds(gpointer button, gpointer user)
gtk_tree_store_set (store, &celliter, CELL, gds_c->name, -1); gtk_tree_store_set (store, &celliter, CELL, gds_c->name, -1);
} }
} }
/* Create Layers in Layer Box */
generate_layer_widgets(ptr->layer_box, *(ptr->list_ptr));
} }
end_destroy: end_destroy:
@ -146,6 +151,8 @@ int main(int argc, char **argv)
GtkTreeView *cell_tree; GtkTreeView *cell_tree;
GtkTreeStore *cell_store; GtkTreeStore *cell_store;
GtkWidget *widget_generic; GtkWidget *widget_generic;
GtkWidget *layer;
GtkWidget *listbox;
struct open_button_data open_data; struct open_button_data open_data;
@ -166,10 +173,14 @@ int main(int argc, char **argv)
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)&open_data); "clicked", G_CALLBACK(on_load_gds), (gpointer)&open_data);
/* Connect Convert button */ /* Connect Convert button */
widget_generic = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button")); widget_generic = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button"));
g_signal_connect(widget_generic, "clicked", G_CALLBACK(on_convert_clicked), NULL); g_signal_connect(widget_generic, "clicked", G_CALLBACK(on_convert_clicked), layer);
/* test widget list */
listbox = GTK_WIDGET(gtk_builder_get_object(main_builder, "layer-list"));
open_data.layer_box = GTK_LIST_BOX(listbox);
gtk_main(); gtk_main();