55G_DEFINE_TYPE(LayerSelector, layer_selector, G_TYPE_OBJECT)
66 cairo_surface_t *surface;
71 row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
72 gtk_widget_get_allocation(row, &alloc);
73 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
74 cr = cairo_create(surface);
76 gtk_style_context_add_class(gtk_widget_get_style_context(row),
"drag-icon");
77 gtk_widget_draw(row, cr);
78 gtk_style_context_remove_class(gtk_widget_get_style_context(row),
"drag-icon");
80 gtk_widget_translate_coordinates(widget, row, 0, 0, &x, &y);
81 cairo_surface_set_device_offset(surface, -x, -y);
82 gtk_drag_set_icon_surface(context, surface);
85 cairo_surface_destroy(surface);
87 g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)),
"drag-row", row);
88 gtk_style_context_add_class(gtk_widget_get_style_context(row),
"drag-row");
97 row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
98 g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)),
"drag-row", NULL);
99 gtk_style_context_remove_class(gtk_widget_get_style_context(row),
"drag-row");
100 gtk_style_context_remove_class(gtk_widget_get_style_context(row),
"drag-hover");
104 GtkSelectionData *selection_data,
105 guint info, guint time, gpointer data)
113 atom = gdk_atom_intern_static_string(
"GTK_LIST_BOX_ROW");
115 gtk_selection_data_set(selection_data, atom,
116 32, (
const guchar *)&widget,
sizeof(gpointer));
127 tmp = gtk_list_box_get_row_at_index(list, i);
140 pos = gtk_list_box_row_get_index(row);
141 return gtk_list_box_get_row_at_index(list, pos - 1);
148 pos = gtk_list_box_row_get_index(row);
149 return gtk_list_box_get_row_at_index(list, pos + 1);
153 GtkSelectionData *selection_data, guint info, guint32 time,
156 GtkWidget *row_before, *row_after;
169 row_before = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"row-before"));
170 row_after = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"row-after"));
172 g_object_set_data(G_OBJECT(widget),
"row-before", NULL);
173 g_object_set_data(G_OBJECT(widget),
"row-after", NULL);
176 gtk_style_context_remove_class(gtk_widget_get_style_context(row_before),
"drag-hover-bottom");
178 gtk_style_context_remove_class(gtk_widget_get_style_context(row_after),
"drag-hover-top");
180 row = (gpointer) *((gpointer *)gtk_selection_data_get_data(selection_data));
181 source = gtk_widget_get_ancestor(row, GTK_TYPE_LIST_BOX_ROW);
183 if (source == row_after)
186 g_object_ref(source);
187 gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(source)), source);
190 pos = gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(row_after));
192 pos = gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(row_before)) + 1;
194 gtk_list_box_insert(GTK_LIST_BOX(widget), source, pos);
195 g_object_unref(source);
203 int hover_row_height;
205 GtkWidget *row_before;
206 GtkWidget *row_after;
212 row = GTK_WIDGET(gtk_list_box_get_row_at_y(GTK_LIST_BOX(widget), y));
214 drag_row = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"drag-row"));
215 row_after = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"row-after"));
216 row_before = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"row-before"));
218 gtk_style_context_remove_class(gtk_widget_get_style_context(drag_row),
"drag-hover");
220 gtk_style_context_remove_class(gtk_widget_get_style_context(row_before),
"drag-hover-bottom");
222 gtk_style_context_remove_class(gtk_widget_get_style_context(row_after),
"drag-hover-top");
225 gtk_widget_get_allocation(row, &alloc);
226 hover_row_y = alloc.y;
227 hover_row_height = alloc.height;
229 if (y < hover_row_y + hover_row_height/2) {
232 GTK_LIST_BOX_ROW(row)));
236 GTK_LIST_BOX_ROW(row)));
243 g_object_set_data(G_OBJECT(widget),
"row-before", row_before);
244 g_object_set_data(G_OBJECT(widget),
"row-after", row_after);
246 if (drag_row == row_before || drag_row == row_after) {
247 gtk_style_context_add_class(gtk_widget_get_style_context(drag_row),
"drag-hover");
252 gtk_style_context_add_class(gtk_widget_get_style_context(row_before),
"drag-hover-bottom");
254 gtk_style_context_add_class(gtk_widget_get_style_context(row_after),
"drag-hover-top");
262 GtkWidget *row_before;
263 GtkWidget *row_after;
267 drag_row = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"drag-row"));
268 row_before = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"row-before"));
269 row_after = GTK_WIDGET(g_object_get_data(G_OBJECT(widget),
"row-after"));
271 gtk_style_context_remove_class(gtk_widget_get_style_context(drag_row),
"drag-hover");
273 gtk_style_context_remove_class(gtk_widget_get_style_context(row_before),
"drag-hover-bottom");
275 gtk_style_context_remove_class(gtk_widget_get_style_context(row_after),
"drag-hover-top");
280 ".row:not(:first-child) { "
281 " border-top: 1px solid alpha(gray,0.5); "
282 " border-bottom: 1px solid transparent; "
284 ".row:first-child { "
285 " border-top: 1px solid transparent; "
286 " border-bottom: 1px solid transparent; "
289 " border-top: 1px solid alpha(gray,0.5); "
290 " border-bottom: 1px solid alpha(gray,0.5); "
293 " background: #282828; "
294 " border: 1px solid blue; "
298 " background: alpha(gray,0.2); "
300 ".row.drag-row.drag-hover { "
301 " border-top: 1px solid #4e9a06; "
302 " border-bottom: 1px solid #4e9a06; "
304 ".row.drag-hover image, "
305 ".row.drag-hover label { "
308 ".row.drag-hover-top {"
309 " border-top: 1px solid #4e9a06; "
311 ".row.drag-hover-bottom {"
312 " border-bottom: 1px solid #4e9a06; "
317 LayerSelector *sel = LAYER_SELECTOR(self);
319 g_clear_object(&sel->list_box);
320 g_clear_object(&sel->load_parent_window);
321 g_clear_object(&sel->save_parent_window);
322 g_clear_object(&sel->associated_load_button);
323 g_clear_object(&sel->associated_save_button);
325 if (sel->dnd_target.target) {
326 g_free(sel->dnd_target.target);
327 sel->dnd_target.target = NULL;
331 G_OBJECT_CLASS(layer_selector_parent_class)->dispose(self);
336 GObjectClass *object_class = G_OBJECT_CLASS(klass);
337 GtkCssProvider *provider;
343 provider = gtk_css_provider_new();
345 gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(provider), 800);
347 g_object_unref(provider);
352 gtk_drag_dest_set(GTK_WIDGET(self->list_box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
353 &self->dnd_target, 1, GDK_ACTION_MOVE);
363 self->load_parent_window = NULL;
364 self->save_parent_window = NULL;
365 self->associated_load_button = NULL;
366 self->associated_save_button = NULL;
368 self->dnd_target.target = g_strdup_printf(
"LAYER_SELECTOR_DND_%p", self);
369 self->dnd_target.info = 0;
370 self->dnd_target.flags = GTK_TARGET_SAME_APP;
375 LayerSelector *selector;
377 if (GTK_IS_LIST_BOX(list_box) == FALSE)
381 selector->list_box = list_box;
383 g_object_ref(G_OBJECT(list_box));
390 LayerSettings *layer_settings;
401 row_list = gtk_container_get_children(GTK_CONTAINER(selector->list_box));
403 for (i = 0, iterator = row_list; iterator != NULL; iterator = g_list_next(iterator), i++) {
404 le = LAYER_ELEMENT(iterator->data);
420 return layer_settings;
428 list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
429 for (temp = list; temp != NULL; temp = temp->next)
430 gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(temp->data));
437 if (self->associated_load_button)
438 gtk_widget_set_sensitive(self->associated_load_button, FALSE);
439 if (self->associated_save_button)
440 gtk_widget_set_sensitive(self->associated_save_button, FALSE);
453 LayerElement *widget;
454 gboolean ret = FALSE;
456 list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
458 for (temp = list; temp != NULL; temp = temp->next) {
459 widget = LAYER_ELEMENT(temp->data);
480 if (!self || !element)
483 dnd_data.
entries = &self->dnd_target;
504 for (graphics = cell->
graphic_objs; graphics != NULL; graphics = graphics->next) {
511 gtk_list_box_insert(self->list_box, le, -1);
527 LayerElement *le1, *le2;
535 algo = &default_sort;
537 le1 = LAYER_ELEMENT(row1);
538 le2 = LAYER_ELEMENT(row2);
551 GList *cell_list = NULL;
556 for (; libs != NULL; libs = libs->next) {
558 for (cell_list = lib->
cells; cell_list != NULL; cell_list = cell_list->next)
566 if (selector->associated_load_button)
567 gtk_widget_set_sensitive(selector->associated_load_button, TRUE);
568 if (selector->associated_save_button)
569 gtk_widget_set_sensitive(selector->associated_save_button, TRUE);
580 LayerElement *ret = NULL;
582 for (; el_list != NULL; el_list = el_list->next) {
584 ret = LAYER_ELEMENT(el_list->data);
605 GFileInputStream *stream;
606 GDataInputStream *dstream;
612 LayerSettings *layer_settings;
615 file = g_file_new_for_path(file_name);
616 stream = g_file_read(file, NULL, NULL);
621 dstream = g_data_input_stream_new(G_INPUT_STREAM(stream));
623 rows = gtk_container_get_children(GTK_CONTAINER(self->list_box));
626 for (temp = rows; temp != NULL; temp = temp->next) {
627 le = LAYER_ELEMENT(temp->data);
629 g_object_ref(G_OBJECT(le));
630 gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
638 goto abort_layer_settings;
642 goto abort_layer_settings;
645 for (; layer_infos; layer_infos = g_list_next(layer_infos)) {
646 linfo = (
struct layer_info *)layer_infos->data;
654 gtk_container_add(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
655 rows = g_list_remove(rows, le);
660 g_object_unref(layer_settings);
663 for (temp = rows; temp != NULL; temp = temp->next) {
664 le = LAYER_ELEMENT(temp->data);
666 gtk_list_box_insert(self->list_box, GTK_WIDGET(le), -1);
667 g_object_unref(G_OBJECT(le));
674 g_object_unref(dstream);
675 g_object_unref(stream);
677 g_object_unref(file);
693 sel = LAYER_SELECTOR(user_data);
695 dialog = gtk_file_chooser_dialog_new(
"Load Mapping File", GTK_WINDOW(sel->load_parent_window),
696 GTK_FILE_CHOOSER_ACTION_OPEN,
697 "Cancel", GTK_RESPONSE_CANCEL,
"Load Mapping", GTK_RESPONSE_ACCEPT, NULL);
698 res = gtk_dialog_run(GTK_DIALOG(dialog));
699 if (res == GTK_RESPONSE_ACCEPT) {
700 file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
704 gtk_widget_destroy(dialog);
716 LayerSettings *layer_settings;
718 g_return_if_fail(LAYER_IS_SELECTOR(self));
719 g_return_if_fail(file_name);
739 sel = LAYER_SELECTOR(user_data);
741 dialog = gtk_file_chooser_dialog_new(
"Save Mapping File", GTK_WINDOW(sel->save_parent_window),
742 GTK_FILE_CHOOSER_ACTION_SAVE,
743 "Cancel", GTK_RESPONSE_CANCEL,
"Save Mapping", GTK_RESPONSE_ACCEPT, NULL);
744 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
746 res = gtk_dialog_run(GTK_DIALOG(dialog));
747 if (res == GTK_RESPONSE_ACCEPT) {
748 file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
752 gtk_widget_destroy(dialog);
757 g_clear_object(&selector->load_parent_window);
758 g_clear_object(&selector->associated_load_button);
760 g_object_ref(G_OBJECT(button));
761 g_object_ref(G_OBJECT(main_window));
762 selector->associated_load_button = button;
763 selector->load_parent_window = main_window;
769 g_clear_object(&selector->save_parent_window);
770 g_clear_object(&selector->associated_save_button);
772 g_object_ref(G_OBJECT(button));
773 g_object_ref(G_OBJECT(main_window));
774 selector->associated_save_button = button;
775 selector->save_parent_window = main_window;
786 box = selector->list_box;
792 gtk_list_box_invalidate_sort(box);
793 gtk_list_box_set_sort_func(box, NULL, NULL, NULL);
802 g_return_if_fail(LAYER_IS_SELECTOR(layer_selector));
803 g_return_if_fail(GTK_IS_LIST_BOX(layer_selector->list_box));
805 le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
807 for (iter = le_list; iter != NULL; iter = g_list_next(iter)) {
808 le = LAYER_ELEMENT(iter->data);
809 if (LAYER_IS_ELEMENT(le))
813 g_list_free(le_list);
821 unsigned int color_index = 0;
822 unsigned int color_count;
825 g_return_if_fail(GDS_RENDER_IS_COLOR_PALETTE(palette));
826 g_return_if_fail(LAYER_IS_SELECTOR(layer_selector));
827 g_return_if_fail(global_alpha > 0);
828 g_return_if_fail(GTK_IS_LIST_BOX(layer_selector->list_box));
830 le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
835 if (color_count == 0)
836 goto ret_free_le_list;
838 for (le_list_ptr = le_list; le_list_ptr != NULL; le_list_ptr = le_list_ptr->next) {
839 le = LAYER_ELEMENT(le_list_ptr->data);
842 color.alpha *= global_alpha;
845 if (color_index >= color_count)
851 g_list_free(le_list);
859 const char *old_layer_name;
860 GString *new_layer_name;
862 g_return_if_fail(LAYER_IS_SELECTOR(layer_selector));
864 new_layer_name = g_string_new_len(NULL, 10);
865 le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
867 for (le_list_ptr = le_list; le_list_ptr != NULL; le_list_ptr = g_list_next(le_list_ptr)) {
868 le = LAYER_ELEMENT(le_list_ptr->data);
874 if (!old_layer_name || *old_layer_name ==
'\0' || overwrite) {
880 g_string_free(new_layer_name, TRUE);
881 g_list_free(le_list);
886 GList *layer_element_list;
889 g_return_val_if_fail(LAYER_IS_SELECTOR(layer_selector), FALSE);
890 g_return_val_if_fail(GTK_IS_LIST_BOX(layer_selector->list_box), FALSE);
893 layer_element_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
896 return (layer_element_list ? TRUE : FALSE);
904 const char *layer_name;
907 g_return_val_if_fail(LAYER_IS_SELECTOR(layer_selector), 0U);
909 le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
911 for (le_list_ptr = le_list; le_list_ptr != NULL; le_list_ptr = g_list_next(le_list_ptr)) {
912 le = LAYER_ELEMENT(le_list_ptr->data);
917 if (layer_name && *layer_name) {
unsigned int color_palette_get_color_count(ColorPalette *palette)
Return amount of stored colors in palette.
GdkRGBA * color_palette_get_color(ColorPalette *palette, GdkRGBA *color, unsigned int index)
Get the n-th color in the palette identified by the index.
Header file for the GDS-Parser.
const char * layer_element_get_name(LayerElement *elem)
get name of the layer
void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba)
Set color of layer.
int layer_element_get_layer(LayerElement *elem)
Get layer number.
void layer_element_set_layer(LayerElement *elem, int layer)
Set layer number for this layer.
void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba)
Get color of layer.
void layer_element_set_name(LayerElement *elem, const char *name)
layer_element_set_name
void layer_element_set_dnd_callbacks(LayerElement *elem, struct layer_element_dnd_data *data)
Setup drag and drop of elem for use in the LayerSelector.
void layer_element_set_export(LayerElement *elem, gboolean export)
Set export flag for this layer.
gboolean layer_element_get_export(LayerElement *elem)
Get export flag of layer.
GtkWidget * layer_element_new(void)
Create new layer element object.
static void layer_selector_dispose(GObject *self)
static const char * dnd_additional_css
static void layer_selector_load_mapping_clicked(GtkWidget *button, gpointer user_data)
Callback for Load Mapping Button.
static void layer_selector_analyze_cell_layers(LayerSelector *self, struct gds_cell *cell)
Analyze cell layers and append detected layers to layer selector self.
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.
static gint layer_selector_sort_func(GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer unused)
sort_func Sort callback for list box
void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs)
Generate layer widgets in in the LayerSelector instance.
static void sel_layer_element_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer data)
#define TYPE_LAYER_SELECTOR
static gboolean layer_selector_drag_motion(GtkWidget *widget, GdkDragContext *context, int x, int y, guint time)
static void layer_selector_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint32 time, gpointer data)
static void layer_selector_drag_leave(GtkWidget *widget, GdkDragContext *context, guint time)
static void sel_layer_element_drag_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
static void layer_selector_init(LayerSelector *self)
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.
static void layer_selector_clear_widgets(LayerSelector *self)
void layer_selector_auto_name_layers(LayerSelector *layer_selector, gboolean overwrite)
Auto name all layers in the layer selector.
static GtkListBoxRow * layer_selector_get_row_before(GtkListBox *list, GtkListBoxRow *row)
static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, const gchar *file_name)
Load the layer mapping from a CSV formatted file.
static void layer_selector_setup_dnd(LayerSelector *self)
layer_selector_sort_algo
Defines how to sort the layer selector list box.
static void layer_selector_save_mapping_clicked(GtkWidget *button, gpointer user_data)
Callback for Save Layer Mapping Button.
static GtkListBoxRow * layer_selector_get_last_row(GtkListBox *list)
static void sel_layer_element_setup_dnd_callbacks(LayerSelector *self, LayerElement *element)
Setup the necessary drag and drop callbacks of layer elements.
void layer_selector_set_save_mapping_button(LayerSelector *selector, GtkWidget *button, GtkWindow *main_window)
Supply button for saving the layer mapping.
static void layer_selector_save_layer_mapping_data(LayerSelector *self, const gchar *file_name)
Save layer mapping of selector self to a file.
static void layer_selector_class_init(LayerSelectorClass *klass)
static LayerElement * layer_selector_find_layer_element_in_list(GList *el_list, int layer)
Find LayerElement in list with specified layer number.
static GtkListBoxRow * layer_selector_get_row_after(GtkListBox *list, GtkListBoxRow *row)
LayerSelector * layer_selector_new(GtkListBox *list_box)
layer_selector_new
static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, int layer)
Check if a specific layer element with the given layer number is present in the layer selector.
static void sel_layer_element_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, gpointer data)
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
Implementation of the layer element used for configuring layer colors etc.
Implementation of the Layer selection list.
int layer_settings_to_csv(LayerSettings *settings, const char *path)
Write layer settings to a CSV file.
LayerSettings * layer_settings_new()
New LayerSettings object.
GList * layer_settings_get_layer_info_list(LayerSettings *settings)
Get a GList with layer_info structs.
int layer_settings_load_from_csv(LayerSettings *settings, const char *path)
Load new layer Settings from CSV.
int layer_settings_append_layer_info(LayerSettings *settings, struct layer_info *info)
layer_settings_append_layer_info
GtkWidget * associated_save_button
GtkWidget * associated_load_button
GtkTargetEntry dnd_target
GtkWindow * load_parent_window
GtkWindow * save_parent_window
A Cell inside a gds_library.
GList * graphic_objs
List of gds_graphics.
int16_t layer
Layer the graphic object is on.
This structure holds the necessary data to set up a LayerElement for Drag'n'Drop.
void(* drag_data_get)(GtkWidget *, GdkDragContext *, GtkSelectionData *, guint, guint, gpointer)
Callback fucktion for data_get event.
GtkTargetEntry * entries
Array of target entries for the DnD operation.
void(* drag_begin)(GtkWidget *, GdkDragContext *, gpointer)
Callback function for drag_begin event.
void(* drag_end)(GtkWidget *, GdkDragContext *, gpointer)
Callback function for drag_end event.
int entry_count
Count of elements in layer_element_dnd_data::entries array.
int render
true: Render to output
int stacked_position
Position of layer in output.
GdkRGBA color
RGBA color used to render this layer.