Compare commits
14 Commits
2a204640bd
...
v1.0-rc4
Author | SHA1 | Date | |
---|---|---|---|
33deba8ca4 | |||
b0c25a4bcf | |||
899c8daf81 | |||
a9c7b9f61f | |||
55fd080796 | |||
178ef2d5b2 | |||
6a78e0df15 | |||
1e6d0bd1b9 | |||
658e681c38 | |||
e24b4a8367 | |||
960a773ed1 | |||
ab23be1cfc | |||
72d5352b09 | |||
3f198f870a |
@@ -20,7 +20,8 @@ aux_source_directory("gds-parser" PARSER_SOURCES)
|
|||||||
aux_source_directory("latex-output" LATEX_SOURCES)
|
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)
|
||||||
set(SOURCE "main.c" "layer-selector.c" "mapping-parser.c" "command-line.c" "main-window.c" "external-renderer.c")
|
aux_source_directory("layer-selector" LAYER_SELECTOR_SOURCES)
|
||||||
|
set(SOURCE "main.c" "mapping-parser.c" "command-line.c" "main-window.c" "external-renderer.c")
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
${SOURCE}
|
${SOURCE}
|
||||||
@@ -30,6 +31,7 @@ set(SOURCE
|
|||||||
${LATEX_SOURCES}
|
${LATEX_SOURCES}
|
||||||
${CAIRO_SOURCES}
|
${CAIRO_SOURCES}
|
||||||
${TRIG_SOURCES}
|
${TRIG_SOURCES}
|
||||||
|
${LAYER_SELECTOR_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_compile_options(-Wall)
|
add_compile_options(-Wall)
|
||||||
@@ -41,3 +43,4 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPER
|
|||||||
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})
|
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})
|
||||||
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
|
|
||||||
|
add_custom_target(documentation DEPENDS doxygen)
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#ifndef __CAIRO_OUTPUT_H__
|
#ifndef __CAIRO_OUTPUT_H__
|
||||||
#define __CAIRO_OUTPUT_H__
|
#define __CAIRO_OUTPUT_H__
|
||||||
|
|
||||||
#include "../layer-selector.h"
|
#include "../layer-selector/layer-selector.h"
|
||||||
#include "../gds-parser/gds-types.h"
|
#include "../gds-parser/gds-types.h"
|
||||||
|
|
||||||
/** @addtogroup Cairo-Renderer
|
/** @addtogroup Cairo-Renderer
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
find_package(Doxygen)
|
find_package(Doxygen)
|
||||||
|
|
||||||
if (DOXYGEN_FOUND)
|
if (DOXYGEN_FOUND)
|
||||||
add_custom_target(doxygen
|
add_custom_target(doxygen
|
||||||
COMMAND ./build-doxygen.sh "${PROJECT_BINARY_DIR}"
|
COMMAND ./build-doxygen.sh "${PROJECT_BINARY_DIR}"
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMENT "Generating documentation with Doxygen")
|
COMMENT "Generating documentation with Doxygen")
|
||||||
|
|
||||||
else (DOXYGEN_FOUND)
|
else (DOXYGEN_FOUND)
|
||||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||||
endif (DOXYGEN_FOUND)
|
endif (DOXYGEN_FOUND)
|
||||||
|
@@ -2,6 +2,16 @@
|
|||||||
<!-- Generated with glade 3.22.1 -->
|
<!-- Generated with glade 3.22.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.20"/>
|
<requires lib="gtk+" version="3.20"/>
|
||||||
|
<object class="GtkImage" id="image1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-go-up</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-go-down</property>
|
||||||
|
</object>
|
||||||
<object class="GtkWindow" id="main-window">
|
<object class="GtkWindow" id="main-window">
|
||||||
<property name="height_request">250</property>
|
<property name="height_request">250</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
@@ -131,6 +141,50 @@
|
|||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button-up-sort">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="image">image1</property>
|
||||||
|
<property name="always_show_image">True</property>
|
||||||
|
</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-down-sort">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="image">image2</property>
|
||||||
|
<property name="always_show_image">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -158,6 +212,13 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
231
layer-selector/layer-selector-dnd.c
Normal file
231
layer-selector/layer-selector-dnd.c
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Original Drag and Drop Code taken from:
|
||||||
|
* https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-22/tests/testlist3.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file layer-selector-dnd.c
|
||||||
|
* @brief This file implements the drag and drop functions regarding the list box containing the layer elements
|
||||||
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "layer-selector-dnd.h"
|
||||||
|
|
||||||
|
static GtkTargetEntry entries[] = {
|
||||||
|
{ "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static GtkListBoxRow *layer_selector_get_last_row (GtkListBox *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
GtkListBoxRow *row;
|
||||||
|
|
||||||
|
row = NULL;
|
||||||
|
for (i = 0; ; i++) {
|
||||||
|
GtkListBoxRow *tmp;
|
||||||
|
tmp = gtk_list_box_get_row_at_index(list, i);
|
||||||
|
if (tmp == NULL)
|
||||||
|
break;
|
||||||
|
row = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GtkListBoxRow *layer_selector_get_row_before (GtkListBox *list, GtkListBoxRow *row)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
pos = gtk_list_box_row_get_index (row);
|
||||||
|
return gtk_list_box_get_row_at_index (list, pos - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkListBoxRow *layer_selector_get_row_after (GtkListBox *list, GtkListBoxRow *row)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
pos = gtk_list_box_row_get_index(row);
|
||||||
|
return gtk_list_box_get_row_at_index(list, pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void layer_selector_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||||
|
GtkSelectionData *selection_data, guint info, guint32 time,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget *row_before, *row_after;
|
||||||
|
GtkWidget *row;
|
||||||
|
GtkWidget *source;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
row_before = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "row-before"));
|
||||||
|
row_after = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "row-after"));
|
||||||
|
|
||||||
|
g_object_set_data(G_OBJECT(widget), "row-before", NULL);
|
||||||
|
g_object_set_data(G_OBJECT(widget), "row-after", NULL);
|
||||||
|
|
||||||
|
if (row_before)
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row_before), "drag-hover-bottom");
|
||||||
|
if (row_after)
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row_after), "drag-hover-top");
|
||||||
|
|
||||||
|
row = (gpointer) *((gpointer *)gtk_selection_data_get_data(selection_data));
|
||||||
|
source = gtk_widget_get_ancestor(row, GTK_TYPE_LIST_BOX_ROW);
|
||||||
|
|
||||||
|
if (source == row_after)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_ref(source);
|
||||||
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(source)), source);
|
||||||
|
|
||||||
|
if (row_after)
|
||||||
|
pos = gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(row_after));
|
||||||
|
else
|
||||||
|
pos = gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(row_before)) + 1;
|
||||||
|
|
||||||
|
gtk_list_box_insert(GTK_LIST_BOX(widget), source, pos);
|
||||||
|
g_object_unref(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean layer_selector_drag_motion(GtkWidget *widget, GdkDragContext *context, int x, int y, guint time)
|
||||||
|
{
|
||||||
|
GtkAllocation alloc;
|
||||||
|
GtkWidget *row;
|
||||||
|
int hover_row_y;
|
||||||
|
int hover_row_height;
|
||||||
|
GtkWidget *drag_row;
|
||||||
|
GtkWidget *row_before;
|
||||||
|
GtkWidget *row_after;
|
||||||
|
|
||||||
|
row = GTK_WIDGET(gtk_list_box_get_row_at_y(GTK_LIST_BOX(widget), y));
|
||||||
|
|
||||||
|
drag_row = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "drag-row"));
|
||||||
|
row_after = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "row-after"));
|
||||||
|
row_before = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "row-before"));
|
||||||
|
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(drag_row), "drag-hover");
|
||||||
|
if (row_before)
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row_before), "drag-hover-bottom");
|
||||||
|
if (row_after)
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row_after), "drag-hover-top");
|
||||||
|
|
||||||
|
if (row) {
|
||||||
|
gtk_widget_get_allocation(row, &alloc);
|
||||||
|
hover_row_y = alloc.y;
|
||||||
|
hover_row_height = alloc.height;
|
||||||
|
|
||||||
|
if (y < hover_row_y + hover_row_height/2) {
|
||||||
|
row_after = row;
|
||||||
|
row_before = GTK_WIDGET(layer_selector_get_row_before(GTK_LIST_BOX(widget), GTK_LIST_BOX_ROW(row)));
|
||||||
|
} else {
|
||||||
|
row_before = row;
|
||||||
|
row_after = GTK_WIDGET(layer_selector_get_row_after(GTK_LIST_BOX(widget), GTK_LIST_BOX_ROW(row)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
row_before = GTK_WIDGET(layer_selector_get_last_row(GTK_LIST_BOX(widget)));
|
||||||
|
row_after = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set_data(G_OBJECT(widget), "row-before", row_before);
|
||||||
|
g_object_set_data(G_OBJECT(widget), "row-after", row_after);
|
||||||
|
|
||||||
|
if (drag_row == row_before || drag_row == row_after) {
|
||||||
|
gtk_style_context_add_class(gtk_widget_get_style_context(drag_row), "drag-hover");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row_before)
|
||||||
|
gtk_style_context_add_class(gtk_widget_get_style_context(row_before), "drag-hover-bottom");
|
||||||
|
if (row_after)
|
||||||
|
gtk_style_context_add_class(gtk_widget_get_style_context(row_after), "drag-hover-top");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void layer_selector_drag_leave(GtkWidget *widget, GdkDragContext *context, guint time)
|
||||||
|
{
|
||||||
|
GtkWidget *drag_row;
|
||||||
|
GtkWidget *row_before;
|
||||||
|
GtkWidget *row_after;
|
||||||
|
|
||||||
|
drag_row = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "drag-row"));
|
||||||
|
row_before = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "row-before"));
|
||||||
|
row_after = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "row-after"));
|
||||||
|
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(drag_row), "drag-hover");
|
||||||
|
if (row_before)
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row_before), "drag-hover-bottom");
|
||||||
|
if (row_after)
|
||||||
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row_after), "drag-hover-top");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *dnd_additional_css =
|
||||||
|
".row:not(:first-child) { "
|
||||||
|
" border-top: 1px solid alpha(gray,0.5); "
|
||||||
|
" border-bottom: 1px solid transparent; "
|
||||||
|
"}"
|
||||||
|
".row:first-child { "
|
||||||
|
" border-top: 1px solid transparent; "
|
||||||
|
" border-bottom: 1px solid transparent; "
|
||||||
|
"}"
|
||||||
|
".row:last-child { "
|
||||||
|
" border-top: 1px solid alpha(gray,0.5); "
|
||||||
|
" border-bottom: 1px solid alpha(gray,0.5); "
|
||||||
|
"}"
|
||||||
|
".row.drag-icon { "
|
||||||
|
" background: #282828; "
|
||||||
|
" border: 1px solid blue; "
|
||||||
|
"}"
|
||||||
|
".row.drag-row { "
|
||||||
|
" color: gray; "
|
||||||
|
" background: alpha(gray,0.2); "
|
||||||
|
"}"
|
||||||
|
".row.drag-row.drag-hover { "
|
||||||
|
" border-top: 1px solid #4e9a06; "
|
||||||
|
" border-bottom: 1px solid #4e9a06; "
|
||||||
|
"}"
|
||||||
|
".row.drag-hover image, "
|
||||||
|
".row.drag-hover label { "
|
||||||
|
" color: #4e9a06; "
|
||||||
|
"}"
|
||||||
|
".row.drag-hover-top {"
|
||||||
|
" border-top: 1px solid #4e9a06; "
|
||||||
|
"}"
|
||||||
|
".row.drag-hover-bottom {"
|
||||||
|
" border-bottom: 1px solid #4e9a06; "
|
||||||
|
"}";
|
||||||
|
|
||||||
|
void layer_selector_list_box_setup_dnd(GtkListBox *box)
|
||||||
|
{
|
||||||
|
GtkCssProvider *provider;
|
||||||
|
|
||||||
|
provider = gtk_css_provider_new ();
|
||||||
|
gtk_css_provider_load_from_data (provider, dnd_additional_css, -1, NULL);
|
||||||
|
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (provider), 800);
|
||||||
|
|
||||||
|
gtk_drag_dest_set(GTK_WIDGET(box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, entries, 1, GDK_ACTION_MOVE);
|
||||||
|
g_signal_connect(box, "drag-data-received", G_CALLBACK(layer_selector_drag_data_received), NULL);
|
||||||
|
g_signal_connect(box, "drag-motion", G_CALLBACK(layer_selector_drag_motion), NULL);
|
||||||
|
g_signal_connect(box, "drag-leave", G_CALLBACK(layer_selector_drag_leave), NULL);
|
||||||
|
|
||||||
|
}
|
33
layer-selector/layer-selector-dnd.h
Normal file
33
layer-selector/layer-selector-dnd.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
void layer_selector_list_box_setup_dnd(GtkListBox *box);
|
||||||
|
|
||||||
|
#endif /* _LAYER_SELECTOR_DND_H_ */
|
@@ -29,8 +29,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "layer-selector.h"
|
#include "layer-selector.h"
|
||||||
#include "gds-parser/gds-parser.h"
|
#include "../gds-parser/gds-parser.h"
|
||||||
#include "widgets/layer-element.h"
|
#include "../widgets/layer-element.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -155,19 +155,30 @@ static void analyze_cell_layers(GtkListBox *listbox, struct gds_cell *cell)
|
|||||||
* @param row1
|
* @param row1
|
||||||
* @param row2
|
* @param row2
|
||||||
* @param unused
|
* @param unused
|
||||||
* @note Do not use this function
|
* @note Do not use this function. This is an internal callback
|
||||||
* @return
|
* @return See sort function documentation of GTK+
|
||||||
*/
|
*/
|
||||||
static gint sort_func(GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer unused)
|
static gint sort_func(GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer unused)
|
||||||
{
|
{
|
||||||
LayerElement *le1, *le2;
|
LayerElement *le1, *le2;
|
||||||
gint ret;
|
gint ret;
|
||||||
|
static const enum layer_selector_sort_algo default_sort = LAYER_SELECTOR_SORT_DOWN;
|
||||||
|
const enum layer_selector_sort_algo *algo = (const enum layer_selector_sort_algo *)unused;
|
||||||
|
|
||||||
|
/* Assume downward sorting */
|
||||||
|
/* TODO: This is nasty. Find a better way */
|
||||||
|
if (!algo)
|
||||||
|
algo = &default_sort;
|
||||||
|
|
||||||
le1 = LAYER_ELEMENT(row1);
|
le1 = LAYER_ELEMENT(row1);
|
||||||
le2 = LAYER_ELEMENT(row2);
|
le2 = LAYER_ELEMENT(row2);
|
||||||
|
|
||||||
|
/* Determine sort fow downward sort */
|
||||||
ret = layer_element_get_layer(le1) - layer_element_get_layer(le2);
|
ret = layer_element_get_layer(le1) - layer_element_get_layer(le2);
|
||||||
|
|
||||||
|
/* Change order if upward sort is requested */
|
||||||
|
ret *= (*algo == LAYER_SELECTOR_SORT_DOWN ? 1 : -1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +190,6 @@ void generate_layer_widgets(GtkListBox *listbox, GList *libs)
|
|||||||
global_list_box = listbox;
|
global_list_box = listbox;
|
||||||
|
|
||||||
clear_list_box_widgets(listbox);
|
clear_list_box_widgets(listbox);
|
||||||
gtk_list_box_set_sort_func(listbox, sort_func, NULL, NULL);
|
|
||||||
|
|
||||||
for (; libs != NULL; libs = libs->next) {
|
for (; libs != NULL; libs = libs->next) {
|
||||||
lib = (struct gds_library *)libs->data;
|
lib = (struct gds_library *)libs->data;
|
||||||
@@ -188,11 +198,8 @@ void generate_layer_widgets(GtkListBox *listbox, GList *libs)
|
|||||||
} /* For Cell List */
|
} /* For Cell List */
|
||||||
} /* For libs */
|
} /* For libs */
|
||||||
|
|
||||||
/* Force sort */
|
/* Sort the layers */
|
||||||
gtk_list_box_invalidate_sort(listbox);
|
layer_selector_force_sort(LAYER_SELECTOR_SORT_DOWN);
|
||||||
|
|
||||||
/* Disable sort, so user can sort layers */
|
|
||||||
gtk_list_box_set_sort_func(listbox, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
/* Activate Buttons */
|
/* Activate Buttons */
|
||||||
gtk_widget_set_sensitive(global_load_button, TRUE);
|
gtk_widget_set_sensitive(global_load_button, TRUE);
|
||||||
@@ -435,4 +442,15 @@ void setup_save_mapping_callback(GtkWidget *button, GtkWindow *main_window)
|
|||||||
g_signal_connect(button, "clicked", G_CALLBACK(save_mapping_clicked), main_window);
|
g_signal_connect(button, "clicked", G_CALLBACK(save_mapping_clicked), main_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void layer_selector_force_sort(enum layer_selector_sort_algo sort_function)
|
||||||
|
{
|
||||||
|
if (!global_list_box)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Set dorting function, sort, and disable sorting function */
|
||||||
|
gtk_list_box_set_sort_func(global_list_box, sort_func, (gpointer)&sort_function, NULL);
|
||||||
|
gtk_list_box_invalidate_sort(global_list_box);
|
||||||
|
gtk_list_box_set_sort_func(global_list_box, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
@@ -28,7 +28,12 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "mapping-parser.h"
|
#include "../mapping-parser.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines how to sort the layer selector list box.
|
||||||
|
*/
|
||||||
|
enum layer_selector_sort_algo {LAYER_SELECTOR_SORT_DOWN = 0, LAYER_SELECTOR_SORT_UP};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generate layer widgets in \p listbox
|
* @brief Generate layer widgets in \p listbox
|
||||||
@@ -64,4 +69,14 @@ GList *export_rendered_layer_info();
|
|||||||
* @note The layer_info::name Element has to be freed manually
|
* @note The layer_info::name Element has to be freed manually
|
||||||
*/
|
*/
|
||||||
void delete_layer_info_struct(struct layer_info *info);
|
void delete_layer_info_struct(struct layer_info *info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Force sorting of the layer selector in a specified way
|
||||||
|
*
|
||||||
|
* If the layer selector is not yet set up, this function has no effect.
|
||||||
|
*
|
||||||
|
* @param sort_function Sorting direction
|
||||||
|
*/
|
||||||
|
void layer_selector_force_sort(enum layer_selector_sort_algo sort_function);
|
||||||
|
|
||||||
#endif /* __LAYER_SELECTOR_H__ */
|
#endif /* __LAYER_SELECTOR_H__ */
|
@@ -31,7 +31,8 @@
|
|||||||
#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-selector.h"
|
#include "layer-selector/layer-selector.h"
|
||||||
|
#include "layer-selector/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,7 +41,6 @@
|
|||||||
#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"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief User data supplied to callback function of the open button
|
* @brief User data supplied to callback function of the open button
|
||||||
*/
|
*/
|
||||||
@@ -384,6 +384,22 @@ static void cell_selection_changed(GtkTreeSelection *sel, GtkWidget *convert_but
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sort_up_callback(GtkWidget *widget, gpointer user)
|
||||||
|
{
|
||||||
|
(void)widget;
|
||||||
|
(void)user;
|
||||||
|
|
||||||
|
layer_selector_force_sort(LAYER_SELECTOR_SORT_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort_down_callback(GtkWidget *widget, gpointer user)
|
||||||
|
{
|
||||||
|
(void)widget;
|
||||||
|
(void)user;
|
||||||
|
|
||||||
|
layer_selector_force_sort(LAYER_SELECTOR_SORT_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
GtkWindow *create_main_window()
|
GtkWindow *create_main_window()
|
||||||
{
|
{
|
||||||
GtkBuilder *main_builder;
|
GtkBuilder *main_builder;
|
||||||
@@ -396,6 +412,8 @@ GtkWindow *create_main_window()
|
|||||||
static struct open_button_data open_data;
|
static struct open_button_data open_data;
|
||||||
static struct convert_button_data conv_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_down_button;
|
||||||
|
|
||||||
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);
|
||||||
@@ -423,6 +441,9 @@ GtkWindow *create_main_window()
|
|||||||
g_signal_connect(conv_button, "clicked", G_CALLBACK(on_convert_clicked), &conv_data);
|
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"));
|
||||||
|
/* Set up the list box sided callbacks for drag and drop */
|
||||||
|
layer_selector_list_box_setup_dnd(GTK_LIST_BOX(listbox));
|
||||||
|
|
||||||
open_data.layer_box = GTK_LIST_BOX(listbox);
|
open_data.layer_box = GTK_LIST_BOX(listbox);
|
||||||
|
|
||||||
/* Set buttons fpr layer mapping GUI */
|
/* Set buttons fpr layer mapping GUI */
|
||||||
@@ -440,6 +461,13 @@ GtkWindow *create_main_window()
|
|||||||
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"));
|
||||||
gtk_header_bar_set_subtitle(header_bar, _app_version_string);
|
gtk_header_bar_set_subtitle(header_bar, _app_version_string);
|
||||||
|
|
||||||
|
/* Get layer sorting buttons and set callbacks */
|
||||||
|
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"));
|
||||||
|
|
||||||
|
g_signal_connect(sort_up_button, "clicked", G_CALLBACK(sort_up_callback), NULL);
|
||||||
|
g_signal_connect(sort_down_button, "clicked", G_CALLBACK(sort_down_callback), NULL);
|
||||||
|
|
||||||
g_object_unref(main_builder);
|
g_object_unref(main_builder);
|
||||||
|
|
||||||
return conv_data.main_window;
|
return conv_data.main_window;
|
||||||
|
11
main.c
11
main.c
@@ -50,6 +50,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), appdata->main_window);
|
gtk_window_set_transient_for(GTK_WINDOW(dialog), appdata->main_window);
|
||||||
|
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string);
|
||||||
gtk_dialog_run(dialog);
|
gtk_dialog_run(dialog);
|
||||||
|
|
||||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
gtk_widget_destroy(GTK_WIDGET(dialog));
|
||||||
@@ -57,8 +58,8 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
|
|||||||
}
|
}
|
||||||
|
|
||||||
const static GActionEntry app_actions[] = {
|
const static GActionEntry app_actions[] = {
|
||||||
{"quit", app_quit},
|
{"quit", app_quit, NULL, NULL, NULL, {0}},
|
||||||
{"about", app_about}
|
{"about", app_about, NULL, NULL, NULL, {0}}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gapp_activate(GApplication *app, gpointer user_data)
|
static void gapp_activate(GApplication *app, gpointer user_data)
|
||||||
@@ -82,7 +83,7 @@ static int start_gui(int argc, char **argv)
|
|||||||
GMenu *m_quit;
|
GMenu *m_quit;
|
||||||
GMenu *m_about;
|
GMenu *m_about;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -181,8 +182,8 @@ int main(int argc, char **argv)
|
|||||||
if (!pdfname)
|
if (!pdfname)
|
||||||
pdfname = g_strdup_printf("./%s.pdf", basename);
|
pdfname = g_strdup_printf("./%s.pdf", basename);
|
||||||
|
|
||||||
if (!pdfname)
|
if (!svgname)
|
||||||
pdfname = g_strdup_printf("./%s.svg", basename);
|
svgname = g_strdup_printf("./%s.svg", basename);
|
||||||
|
|
||||||
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz,
|
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz,
|
||||||
mappingname, cellname, (double)scale,
|
mappingname, cellname, (double)scale,
|
||||||
|
@@ -17,9 +17,16 @@
|
|||||||
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The drag and drop implementation is adapted from
|
||||||
|
* https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-22/tests/testlist3.c
|
||||||
|
*
|
||||||
|
* Thanks to the GTK3 people for creating these examples.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file layer-element.c
|
* @file layer-element.c
|
||||||
* @brief Omplementation of the layer element used for configuring layer colors etc.
|
* @brief Implementation of the layer element used for configuring layer colors etc.
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -65,14 +72,14 @@ static void layer_element_drag_begin(GtkWidget *widget,
|
|||||||
int x, y;
|
int x, y;
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
row = gtk_widget_get_ancestor (widget, GTK_TYPE_LIST_BOX_ROW);
|
row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
|
||||||
gtk_widget_get_allocation (row, &alloc);
|
gtk_widget_get_allocation(row, &alloc);
|
||||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
|
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create(surface);
|
||||||
|
|
||||||
gtk_style_context_add_class (gtk_widget_get_style_context (row), "drag-icon");
|
gtk_style_context_add_class (gtk_widget_get_style_context(row), "drag-icon");
|
||||||
gtk_widget_draw (row, cr);
|
gtk_widget_draw (row, cr);
|
||||||
gtk_style_context_remove_class (gtk_widget_get_style_context (row), "drag-icon");
|
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-icon");
|
||||||
|
|
||||||
gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
|
gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
|
||||||
cairo_surface_set_device_offset (surface, -x, -y);
|
cairo_surface_set_device_offset (surface, -x, -y);
|
||||||
@@ -80,6 +87,21 @@ static void layer_element_drag_begin(GtkWidget *widget,
|
|||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
cairo_surface_destroy (surface);
|
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,
|
static void layer_element_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
|
||||||
@@ -94,36 +116,6 @@ static void layer_element_drag_data_get(GtkWidget *widget, GdkDragContext *conte
|
|||||||
32, (const guchar *)&widget, sizeof(gpointer));
|
32, (const guchar *)&widget, sizeof(gpointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void layer_element_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
|
||||||
GtkSelectionData *selection_data, guint info, guint32 time,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget *target;
|
|
||||||
GtkWidget *row;
|
|
||||||
GtkWidget *source;
|
|
||||||
int pos;
|
|
||||||
(void)context;
|
|
||||||
(void)x;
|
|
||||||
(void)y;
|
|
||||||
(void)info;
|
|
||||||
(void)time;
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
target = widget;
|
|
||||||
|
|
||||||
pos = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (target));
|
|
||||||
row = (gpointer)(*(gpointer *)gtk_selection_data_get_data(selection_data));
|
|
||||||
source = gtk_widget_get_ancestor (row, GTK_TYPE_LIST_BOX_ROW);
|
|
||||||
|
|
||||||
if (source == target)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_object_ref (source);
|
|
||||||
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (source)), source);
|
|
||||||
gtk_list_box_insert (GTK_LIST_BOX (gtk_widget_get_parent (target)), source, pos);
|
|
||||||
g_object_unref (source);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void layer_element_init(LayerElement *self)
|
static void layer_element_init(LayerElement *self)
|
||||||
{
|
{
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
@@ -140,11 +132,11 @@ static void layer_element_init(LayerElement *self)
|
|||||||
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 */
|
/* 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);
|
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-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-data-get", G_CALLBACK(layer_element_drag_data_get), NULL);
|
||||||
gtk_drag_dest_set(GTK_WIDGET(self), GTK_DEST_DEFAULT_ALL, entries, 1, GDK_ACTION_MOVE);
|
g_signal_connect(self->priv.event_handle, "drag-end", G_CALLBACK(layer_element_drag_end), NULL);
|
||||||
g_signal_connect(GTK_WIDGET(self), "drag-data-received", G_CALLBACK(layer_element_drag_data_received), NULL);
|
|
||||||
|
|
||||||
g_object_unref(builder);
|
g_object_unref(builder);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user