summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tikzit/NEWS3
-rw-r--r--tikzit/src/Makefile.am17
-rw-r--r--tikzit/src/common/Graph.m19
-rw-r--r--tikzit/src/common/GraphChange.h27
-rw-r--r--tikzit/src/common/GraphChange.m34
-rw-r--r--tikzit/src/linux/Edge+Render.m27
-rw-r--r--tikzit/src/linux/EdgeStyleEditor.h39
-rw-r--r--tikzit/src/linux/EdgeStyleEditor.m322
-rw-r--r--tikzit/src/linux/EdgeStyleSelector.h69
-rw-r--r--tikzit/src/linux/EdgeStyleSelector.m454
-rw-r--r--tikzit/src/linux/EdgeStylesPalette.h46
-rw-r--r--tikzit/src/linux/EdgeStylesPalette.m283
-rw-r--r--tikzit/src/linux/MainWindow.h14
-rw-r--r--tikzit/src/linux/MainWindow.m82
-rw-r--r--tikzit/src/linux/NodeStyleEditor.h10
-rw-r--r--tikzit/src/linux/NodeStyleEditor.m414
-rw-r--r--tikzit/src/linux/NodeStyleSelector.h12
-rw-r--r--tikzit/src/linux/NodeStyleSelector.m48
-rw-r--r--tikzit/src/linux/NodeStylesPalette.h8
-rw-r--r--tikzit/src/linux/NodeStylesPalette.m54
-rw-r--r--tikzit/src/linux/PropertyPane.h10
-rw-r--r--tikzit/src/linux/PropertyPane.m1
-rw-r--r--tikzit/src/linux/StylesPane.h49
-rw-r--r--tikzit/src/linux/StylesPane.m143
-rw-r--r--tikzit/src/linux/TikzDocument.h7
-rw-r--r--tikzit/src/linux/TikzDocument.m34
26 files changed, 1876 insertions, 350 deletions
diff --git a/tikzit/NEWS b/tikzit/NEWS
index 801889a..c348ea2 100644
--- a/tikzit/NEWS
+++ b/tikzit/NEWS
@@ -2,6 +2,9 @@ tikzit 0.8 (2012-01-??):
* Compilers without basic Objective C 2 support cannot be
used to compile TikZiT any more
* Add support for scale to node styles
+ * Add support for editing edge styles
+ * Add support for multiple custom preambles
+ * Make everything look a bit better
tikzit 0.7 (2011-12-06):
* Add bounding box support
diff --git a/tikzit/src/Makefile.am b/tikzit/src/Makefile.am
index 15bc5d9..cbd9cfc 100644
--- a/tikzit/src/Makefile.am
+++ b/tikzit/src/Makefile.am
@@ -28,6 +28,9 @@ tikzit_SOURCES = linux/CairoRenderContext.m \
linux/Configuration.m \
linux/Edge+Render.m \
linux/EdgeStyle+Storage.m \
+ linux/EdgeStyleEditor.m \
+ linux/EdgeStyleSelector.m \
+ linux/EdgeStylesPalette.m \
linux/FileChooserDialog.m \
linux/GraphInputHandler.m \
linux/GraphRenderer.m \
@@ -47,6 +50,7 @@ tikzit_SOURCES = linux/CairoRenderContext.m \
linux/RecentManager.m \
linux/Shape+Render.m \
linux/StyleManager+Storage.m \
+ linux/StylesPane.m \
linux/TikzDocument.m \
linux/WidgetSurface.m \
linux/cairo_helpers.m \
@@ -129,8 +133,21 @@ linux/logodata.m: ../share/icons/hicolor/*/apps/tikzit.png
logo128 ../share/icons/hicolor/128x128/apps/tikzit.png \
> $@
+linux/edgedecdata.m: ../AH_*.png ../ED_*.png
+ $(AM_V_GEN)gdk-pixbuf-csource --struct --static --raw --build-list \
+ AH_none_pixdata ../AH_none.png \
+ AH_latex_head_pixdata ../AH_latex_head.png \
+ AH_latex_tail_pixdata ../AH_latex_tail.png \
+ AH_plain_head_pixdata ../AH_plain_head.png \
+ AH_plain_tail_pixdata ../AH_plain_tail.png \
+ ED_none_pixdata ../ED_none.png \
+ ED_arrow_pixdata ../ED_arrow.png \
+ ED_tick_pixdata ../ED_tick.png \
+ > $@
+
linux/Menu.m: linux/icondata.m
linux/logo.m: linux/logodata.m
+linux/EdgeStyleEditor.m: linux/edgedecdata.m
EXTRA_DIST = linux/*.h common/*.h $(PARSERFILES) common/tikzlexer.lm common/tikzparser.ym
MAINTAINERCLEANFILES = $(PARSERFILES) linux/icondata.m linux/logodata.m
diff --git a/tikzit/src/common/Graph.m b/tikzit/src/common/Graph.m
index 62774f5..4250f7f 100644
--- a/tikzit/src/common/Graph.m
+++ b/tikzit/src/common/Graph.m
@@ -425,15 +425,26 @@
[[ch nodeRef] setPropertiesFromNode:[ch nwNode]];
break;
case NodesPropertyChange:
- en = [[ch nwNodeTable] keyEnumerator];
- Node *key;
- while ((key = [en nextObject])) {
- [key setPropertiesFromNode:[[ch nwNodeTable] objectForKey:key]];
+ {
+ en = [[ch nwNodeTable] keyEnumerator];
+ Node *key;
+ while ((key = [en nextObject])) {
+ [key setPropertiesFromNode:[[ch nwNodeTable] objectForKey:key]];
+ }
}
break;
case EdgePropertyChange:
[[ch edgeRef] setPropertiesFromEdge:[ch nwEdge]];
break;
+ case EdgesPropertyChange:
+ {
+ en = [[ch nwEdgeTable] keyEnumerator];
+ Edge *key;
+ while ((key = [en nextObject])) {
+ [key setPropertiesFromEdge:[[ch nwEdgeTable] objectForKey:key]];
+ }
+ }
+ break;
case NodesShift:
en = [[ch affectedNodes] objectEnumerator];
NSPoint newLoc;
diff --git a/tikzit/src/common/GraphChange.h b/tikzit/src/common/GraphChange.h
index 0ad0c97..63bdfad 100644
--- a/tikzit/src/common/GraphChange.h
+++ b/tikzit/src/common/GraphChange.h
@@ -31,6 +31,7 @@ typedef enum {
NodePropertyChange,
EdgePropertyChange,
NodesPropertyChange,
+ EdgesPropertyChange,
NodesShift,
NodesFlip,
BoundingBoxChange,
@@ -63,6 +64,7 @@ typedef enum {
Node *oldNode, *nwNode;
Edge *oldEdge, *nwEdge;
BasicMapTable *oldNodeTable, *nwNodeTable;
+ BasicMapTable *oldEdgeTable, *nwEdgeTable;
NSRect oldBoundingBox, nwBoundingBox;
GraphElementData *oldGraphData, *nwGraphData;
}
@@ -146,6 +148,18 @@ typedef enum {
@property (retain) BasicMapTable *nwNodeTable;
/*!
+ @property oldEdgeTable
+ @brief A a table containing copies of a set of edges pre-change.
+ */
+@property (retain) BasicMapTable *oldEdgeTable;
+
+/*!
+ @property nwEdgeTable
+ @brief A a table containing copies of a set of edges post-change.
+ */
+@property (retain) BasicMapTable *nwEdgeTable;
+
+/*!
@property oldBoundingBox
@brief The old bounding box.
*/
@@ -227,6 +241,19 @@ typedef enum {
+ (GraphChange*)propertyChangeOfNodesFromOldCopies:(BasicMapTable*)oldC
toNewCopies:(BasicMapTable*)newC;
+/*!
+ @brief Construct a property change of set of edges.
+ @details Construct a property change of set of edges. oldC and newC should be
+ constructed using the class method [Graph edgeTableForEdges:] before
+ and after the property change, respectively. The affected edges are
+ keys(oldC) = keys(newC).
+ @param oldC a table of copies of edges pre-change
+ @param newC a table of copies of edges post-change
+ @result A property change of a set of edges.
+ */
++ (GraphChange*)propertyChangeOfEdgesFromOldCopies:(BasicMapTable*)oldC
+ toNewCopies:(BasicMapTable*)newC;
+
/*!
@brief Construct a shift of a set of nodes by a given point.
diff --git a/tikzit/src/common/GraphChange.m b/tikzit/src/common/GraphChange.m
index d09e732..3635383 100644
--- a/tikzit/src/common/GraphChange.m
+++ b/tikzit/src/common/GraphChange.m
@@ -142,6 +142,24 @@
}
}
+- (BasicMapTable*)oldEdgeTable { return oldEdgeTable; }
+
+- (void)setOldEdgeTable:(BasicMapTable*)tab {
+ if (oldEdgeTable != tab) {
+ [oldEdgeTable release];
+ oldEdgeTable = [tab retain];
+ }
+}
+
+- (BasicMapTable*)nwEdgeTable { return nwEdgeTable; }
+
+- (void)setNwEdgeTable:(BasicMapTable*)tab {
+ if (nwEdgeTable != tab) {
+ [nwEdgeTable release];
+ nwEdgeTable = [tab retain];
+ }
+}
+
- (NSRect)oldBoundingBox { return oldBoundingBox; }
- (void)setOldBoundingBox:(NSRect)bbox {
@@ -204,6 +222,11 @@
[inverse setOldEdge:[self nwEdge]];
[inverse setNwEdge:[self oldEdge]];
break;
+ case EdgesPropertyChange:
+ [inverse setChangeType:EdgesPropertyChange];
+ [inverse setOldEdgeTable:[self nwEdgeTable]];
+ [inverse setNwEdgeTable:[self oldEdgeTable]];
+ break;
case NodesShift:
[inverse setChangeType:NodesShift];
[inverse setAffectedNodes:[self affectedNodes]];
@@ -240,6 +263,8 @@
[oldEdge release];
[oldNodeTable release];
[nwNodeTable release];
+ [oldEdgeTable release];
+ [nwEdgeTable release];
[super dealloc];
}
@@ -287,6 +312,15 @@
return [gc autorelease];
}
++ (GraphChange*)propertyChangeOfEdgesFromOldCopies:(BasicMapTable*)oldC
+ toNewCopies:(BasicMapTable*)newC {
+ GraphChange *gc = [[GraphChange alloc] init];
+ [gc setChangeType:EdgesPropertyChange];
+ [gc setOldEdgeTable:oldC];
+ [gc setNwEdgeTable:newC];
+ return [gc autorelease];
+}
+
+ (GraphChange*)shiftNodes:(NSSet*)ns byPoint:(NSPoint)p {
GraphChange *gc = [[GraphChange alloc] init];
[gc setChangeType:NodesShift];
diff --git a/tikzit/src/linux/Edge+Render.m b/tikzit/src/linux/Edge+Render.m
index 2e5f127..a6738b7 100644
--- a/tikzit/src/linux/Edge+Render.m
+++ b/tikzit/src/linux/Edge+Render.m
@@ -134,19 +134,19 @@ static const float cpLineWidth = 1.0;
[context moveTo:c_source];
[context curveTo:c_target withCp1:c_cp1 andCp2:c_cp2];
- if ([self style] != nil) {
+ if ([self style] != nil) {
// draw edge decoration
switch ([[self style] decorationStyle]) {
case ED_None:
break;
case ED_Tick:
- [context moveTo:[transformer toScreen:[self leftNormal]]];
- [context lineTo:[transformer toScreen:[self rightNormal]]];
+ [context moveTo:[transformer toScreen:[self leftNormal]]];
+ [context lineTo:[transformer toScreen:[self rightNormal]]];
break;
case ED_Arrow:
- [context moveTo:[transformer toScreen:[self leftNormal]]];
- [context lineTo:[transformer toScreen:[self midTan]]];
- [context lineTo:[transformer toScreen:[self rightNormal]]];
+ [context moveTo:[transformer toScreen:[self leftNormal]]];
+ [context lineTo:[transformer toScreen:[self midTan]]];
+ [context lineTo:[transformer toScreen:[self rightNormal]]];
break;
}
}
@@ -157,7 +157,8 @@ static const float cpLineWidth = 1.0;
[self updateControls];
[context saveState];
- [context setLineWidth:edgeWidth];
+ const CGFloat lineWidth = style ? [style thickness] : edgeWidth;
+ [context setLineWidth:lineWidth];
[self createStrokePathInContext:context withTransformer:[surface transformer]];
RColor color = BlackRColor;
if (selected) {
@@ -170,11 +171,11 @@ static const float cpLineWidth = 1.0;
[self renderControlsToSurface:surface withContext:context];
}
- if ([self hasEdgeNode]) {
- NSPoint labelPt = [[surface transformer] toScreen:[self mid]];
- [[self edgeNode] renderLabelAt:labelPt
- withContext:context];
- }
+ if ([self hasEdgeNode]) {
+ NSPoint labelPt = [[surface transformer] toScreen:[self mid]];
+ [[self edgeNode] renderLabelAt:labelPt
+ withContext:context];
+ }
}
- (NSRect) renderedBoundsWithTransformer:(Transformer*)t whenSelected:(BOOL)selected {
@@ -205,4 +206,4 @@ static const float cpLineWidth = 1.0;
@end
-// vim:ft=objc:ts=4:noet:sts=4:sw=4
+// vim:ft=objc:ts=4:et:sts=4:sw=4
diff --git a/tikzit/src/linux/EdgeStyleEditor.h b/tikzit/src/linux/EdgeStyleEditor.h
new file mode 100644
index 0000000..70a8747
--- /dev/null
+++ b/tikzit/src/linux/EdgeStyleEditor.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "TZFoundation.h"
+#import <gtk/gtk.h>
+
+@class EdgeStyle;
+
+@interface EdgeStyleEditor: NSObject {
+ EdgeStyle *style;
+ GtkTable *table;
+ GtkEntry *nameEdit;
+ GtkComboBox *decorationCombo;
+ GtkAdjustment *thicknessAdj;
+ BOOL blockSignals;
+}
+
+@property (retain) EdgeStyle *style;
+@property (readonly) GtkWidget *widget;
+
+- (id) init;
+
+@end
+
+// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/EdgeStyleEditor.m b/tikzit/src/linux/EdgeStyleEditor.m
new file mode 100644
index 0000000..a0b3df2
--- /dev/null
+++ b/tikzit/src/linux/EdgeStyleEditor.m
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "EdgeStyleEditor.h"
+
+#import "EdgeStyle.h"
+#import "Shape.h"
+
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpointer-sign"
+#import "edgedecdata.m"
+#pragma GCC diagnostic pop
+
+enum {
+ ED_NAME_COL = 0,
+ ED_ICON_COL,
+ ED_VALUE_COL,
+ ED_N_COLS
+};
+
+static const guint row_count = 5;
+
+// {{{ Internal interfaces
+// {{{ GTK+ Callbacks
+static void style_name_edit_changed_cb (GtkEditable *widget, EdgeStyleEditor *editor);
+static void decoration_combo_changed_cb (GtkComboBox *widget, EdgeStyleEditor *editor);
+static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEditor *editor);
+// }}}
+// {{{ Notifications
+
+@interface EdgeStyleEditor (Notifications)
+- (void) nameChangedTo:(NSString*)value;
+- (void) edgeDecorationChangedTo:(EdgeDectorationStyle)value;
+- (void) thicknessChangedTo:(double)value;
+@end
+
+// }}}
+// {{{ Private
+
+@interface EdgeStyleEditor (Private)
+- (void) loadDecorationStylesInto:(GtkListStore*)list;
+- (void) clearEdgeDecorationStyle;
+- (void) setEdgeDecorationStyle:(EdgeDectorationStyle)value;
+@end
+
+// }}}
+// }}}
+// {{{ API
+
+@implementation EdgeStyleEditor
+
+- (void) _addWidget:(GtkWidget*)w withLabel:(gchar *)label atRow:(guint)row {
+ NSAssert(row < row_count, @"row_count is wrong!");
+
+ GtkWidget *l = gtk_label_new (label);
+ gtk_misc_set_alignment (GTK_MISC (l), 0, 0.5);
+ gtk_widget_show (l);
+ gtk_widget_show (w);
+
+ gtk_table_attach (table, l,
+ 0, 1, row, row+1, // l, r, t, b
+ GTK_FILL, // x opts
+ GTK_FILL | GTK_EXPAND, // y opts
+ 5, // x padding
+ 0); // y padding
+
+ gtk_table_attach (table, w,
+ 1, 2, row, row+1, // l, r, t, b
+ GTK_FILL | GTK_EXPAND, // x opts
+ GTK_FILL | GTK_EXPAND, // y opts
+ 0, // x padding
+ 0); // y padding
+}
+
+- (id) init {
+ self = [super init];
+
+ if (self != nil) {
+ style = nil;
+ table = GTK_TABLE (gtk_table_new (row_count, 2, FALSE));
+ gtk_table_set_col_spacings (table, 6);
+ gtk_table_set_row_spacings (table, 6);
+ gtk_widget_set_sensitive (GTK_WIDGET (table), FALSE);
+ blockSignals = NO;
+
+ /**
+ * Name
+ */
+ nameEdit = GTK_ENTRY (gtk_entry_new ());
+ g_object_ref_sink (nameEdit);
+ [self _addWidget:GTK_WIDGET (nameEdit)
+ withLabel:"Name"
+ atRow:0];
+ g_signal_connect (G_OBJECT (nameEdit),
+ "changed",
+ G_CALLBACK (style_name_edit_changed_cb),
+ self);
+
+
+ /**
+ * Edge decoration style
+ */
+ GtkListStore *store = gtk_list_store_new (ED_N_COLS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT);
+ [self loadDecorationStylesInto:store];
+
+ decorationCombo = GTK_COMBO_BOX (gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)));
+ g_object_unref (store);
+ GtkCellRenderer *cellRend = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (decorationCombo),
+ cellRend,
+ TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (decorationCombo), cellRend, "pixbuf", ED_ICON_COL);
+ g_object_ref_sink (decorationCombo);
+
+ [self _addWidget:GTK_WIDGET (decorationCombo)
+ withLabel:"Decoration"
+ atRow:1];
+ g_signal_connect (G_OBJECT (decorationCombo),
+ "changed",
+ G_CALLBACK (decoration_combo_changed_cb),
+ self);
+
+
+ /**
+ * Thickness
+ */
+ thicknessAdj = GTK_ADJUSTMENT (gtk_adjustment_new (
+ 1.0, // value
+ 0.0, // lower
+ 50.0, // upper
+ 0.20, // step
+ 1.0, // page
+ 0.0)); // (irrelevant)
+ g_object_ref_sink (thicknessAdj);
+ GtkWidget *scaleSpin = gtk_spin_button_new (thicknessAdj, 0.0, 2);
+ [self _addWidget:scaleSpin
+ withLabel:"Thickness"
+ atRow:4];
+ g_signal_connect (G_OBJECT (thicknessAdj),
+ "value-changed",
+ G_CALLBACK (thickness_adjustment_changed_cb),
+ self);
+ }
+
+ return self;
+}
+
+- (void) dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ g_object_unref (nameEdit);
+ g_object_unref (decorationCombo);
+ g_object_unref (thicknessAdj);
+ g_object_unref (table);
+ [style release];
+
+ [super dealloc];
+}
+
+- (EdgeStyle*) style {
+ return style;
+}
+
+- (void) setStyle:(EdgeStyle*)s {
+ blockSignals = YES;
+ EdgeStyle *oldStyle = style;
+ style = [s retain];
+
+ if (style != nil) {
+ gtk_widget_set_sensitive (GTK_WIDGET (table), TRUE);
+
+ gtk_entry_set_text(nameEdit, [[style name] UTF8String]);
+
+ [self setEdgeDecorationStyle:[style decorationStyle]];
+
+ gtk_adjustment_set_value(thicknessAdj, [style thickness]);
+ } else {
+ gtk_entry_set_text(nameEdit, "");
+ [self clearEdgeDecorationStyle];
+ gtk_adjustment_set_value(thicknessAdj, 1.0);
+ gtk_widget_set_sensitive (GTK_WIDGET (table), FALSE);
+ }
+
+ [oldStyle release];
+ blockSignals = NO;
+}
+
+- (GtkWidget*) widget {
+ return GTK_WIDGET (table);
+}
+
+@end
+
+// }}}
+// {{{ Notifications
+
+@implementation EdgeStyleEditor (Notifications)
+- (void) nameChangedTo:(NSString*)value {
+ [style setName:value];
+}
+
+- (void) edgeDecorationChangedTo:(EdgeDectorationStyle)value {
+ [style setDecorationStyle:value];
+}
+
+- (void) thicknessChangedTo:(double)value {
+ [style setThickness:(float)value];
+}
+@end
+
+// }}}
+// {{{ Private
+
+@implementation EdgeStyleEditor (Private)
+- (BOOL) signalsBlocked { return blockSignals; }
+
+- (void) loadDecorationStylesInto:(GtkListStore*)list {
+ GtkTreeIter iter;
+
+ GdkPixbuf *buf = gdk_pixbuf_from_pixdata (&ED_none_pixdata, FALSE, NULL);
+ gtk_list_store_append (list, &iter);
+ gtk_list_store_set (list, &iter,
+ ED_NAME_COL, "None",
+ ED_ICON_COL, buf,
+ ED_VALUE_COL, ED_None,
+ -1);
+ g_object_unref (buf);
+
+ buf = gdk_pixbuf_from_pixdata (&ED_arrow_pixdata, FALSE, NULL);
+ gtk_list_store_append (list, &iter);
+ gtk_list_store_set (list, &iter,
+ ED_NAME_COL, "Arrow",
+ ED_ICON_COL, buf,
+ ED_VALUE_COL, ED_Arrow,
+ -1);
+ g_object_unref (buf);
+
+ buf = gdk_pixbuf_from_pixdata (&ED_tick_pixdata, FALSE, NULL);
+ gtk_list_store_append (list, &iter);
+ gtk_list_store_set (list, &iter,
+ ED_NAME_COL, "Tick",
+ ED_ICON_COL, buf,
+ ED_VALUE_COL, ED_Tick,
+ -1);
+ g_object_unref (buf);
+}
+
+- (void) clearEdgeDecorationStyle {
+ gtk_combo_box_set_active (decorationCombo, -1);
+}
+
+- (void) setEdgeDecorationStyle:(EdgeDectorationStyle)value {
+ GtkTreeModel *model = gtk_combo_box_get_model (decorationCombo);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ EdgeDectorationStyle ed_style;
+ gtk_tree_model_get (model, &iter, ED_VALUE_COL, &ed_style, -1);
+ if (ed_style == value) {
+ gtk_combo_box_set_active_iter (decorationCombo, &iter);
+ return;
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+}
+@end
+
+// }}}
+// {{{ GTK+ callbacks
+
+static void style_name_edit_changed_cb (GtkEditable *widget, EdgeStyleEditor *editor) {
+ if ([editor signalsBlocked])
+ return;
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ const gchar *contents = gtk_entry_get_text (GTK_ENTRY (widget));
+ [editor nameChangedTo:[NSString stringWithUTF8String:contents]];
+
+ [pool drain];
+}
+
+static void decoration_combo_changed_cb (GtkComboBox *widget, EdgeStyleEditor *editor) {
+ if ([editor signalsBlocked])
+ return;
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ GtkTreeIter iter;
+ gtk_combo_box_get_active_iter (widget, &iter);
+ EdgeDectorationStyle dec = ED_None;
+ gtk_tree_model_get (gtk_combo_box_get_model (widget), &iter, ED_VALUE_COL, &dec, -1);
+ [editor edgeDecorationChangedTo:dec];
+
+ [pool drain];
+}
+
+static void thickness_adjustment_changed_cb (GtkAdjustment *adj, EdgeStyleEditor *editor) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [editor thicknessChangedTo:gtk_adjustment_get_value (adj)];
+ [pool drain];
+}
+
+// }}}
+
+// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/EdgeStyleSelector.h b/tikzit/src/linux/EdgeStyleSelector.h
new file mode 100644
index 0000000..935c9b7
--- /dev/null
+++ b/tikzit/src/linux/EdgeStyleSelector.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "TZFoundation.h"
+#import <gtk/gtk.h>
+#import "StyleManager.h"
+
+@interface EdgeStyleSelector: NSObject {
+ GtkListStore *store;
+ GtkTreeView *view;
+ StyleManager *styleManager;
+ BOOL linkedToActiveStyle;
+ BOOL suppressSetActiveStyle;
+}
+
+/*!
+ @property widget
+ @brief The GTK widget
+ */
+@property (readonly) GtkWidget *widget;
+
+/*!
+ @property manager
+ @brief The StyleManager to use. Default is [StyleManager manager]
+ */
+@property (retain) StyleManager *styleManager;
+
+/*!
+ @property linkedToActiveStyles
+ @brief Whether the current selection should be the same as the
+ style manager's active style
+ */
+@property (getter=isLinkedToActiveStyle) BOOL linkedToActiveStyle;
+
+/*!
+ @property selectedStyle
+ @brief The selected style. If linkedToActiveStyle is YES, this
+ will be the same as [manager activeStyle].
+
+ When this changes, a SelectedStyleChanged notification will be posted
+ */
+@property (assign) EdgeStyle *selectedStyle;
+
+/*!
+ * Initialise with the default style manager
+ */
+- (id) init;
+/*!
+ * Initialise with the given style manager
+ */
+- (id) initWithStyleManager:(StyleManager*)m;
+
+@end
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/EdgeStyleSelector.m b/tikzit/src/linux/EdgeStyleSelector.m
new file mode 100644
index 0000000..243d176
--- /dev/null
+++ b/tikzit/src/linux/EdgeStyleSelector.m
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "EdgeStyleSelector.h"
+
+#import "CairoRenderContext.h"
+#import "Shape.h"
+#import "Shape+Render.h"
+#import "ShapeNames.h"
+#import "StyleManager.h"
+
+#import <gdk-pixbuf/gdk-pixbuf.h>
+
+// {{{ Internal interfaces
+// {{{ Signals
+static void selection_changed_cb (GtkTreeSelection *sel, EdgeStyleSelector *mgr);
+// }}}
+
+enum {
+ STYLES_NAME_COL = 0,
+ STYLES_ICON_COL,
+ STYLES_PTR_COL,
+ STYLES_N_COLS
+};
+
+@interface EdgeStyleSelector (Notifications)
+- (void) stylesReplaced:(NSNotification*)notification;
+- (void) styleAdded:(NSNotification*)notification;
+- (void) styleRemoved:(NSNotification*)notification;
+- (void) activeStyleChanged:(NSNotification*)notification;
+- (void) stylePropertyChanged:(NSNotification*)notification;
+- (void) shapeDictionaryReplaced:(NSNotification*)n;
+- (void) selectionChanged;
+@end
+
+@interface EdgeStyleSelector (Private)
+- (void) clearModel;
+- (cairo_surface_t*) createEdgeIconSurface;
+- (GdkPixbuf*) pixbufOfEdgeInStyle:(EdgeStyle*)style;
+- (GdkPixbuf*) pixbufFromSurface:(cairo_surface_t*)surface;
+- (GdkPixbuf*) pixbufOfEdgeInStyle:(EdgeStyle*)style usingSurface:(cairo_surface_t*)surface;
+- (void) addStyle:(EdgeStyle*)style;
+- (void) postSelectedStyleChanged;
+- (void) reloadStyles;
+@end
+
+// }}}
+// {{{ API
+
+@implementation EdgeStyleSelector
+
+- (id) init {
+ self = [self initWithStyleManager:[StyleManager manager]];
+ return self;
+}
+
+- (id) initWithStyleManager:(StyleManager*)m {
+ self = [super init];
+
+ if (self) {
+ styleManager = nil;
+ linkedToActiveStyle = YES;
+
+ store = gtk_list_store_new (STYLES_N_COLS,
+ G_TYPE_STRING,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_POINTER);
+ g_object_ref (store);
+
+ view = GTK_TREE_VIEW (gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)));
+ gtk_tree_view_set_headers_visible (view, FALSE);
+ g_object_ref (view);
+
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Preview",
+ renderer,
+ "pixbuf", STYLES_ICON_COL,
+ NULL);
+ gtk_tree_view_append_column (view, column);
+ gtk_tree_view_set_tooltip_column (view, STYLES_NAME_COL);
+
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
+
+ g_signal_connect (G_OBJECT (sel),
+ "changed",
+ G_CALLBACK (selection_changed_cb),
+ self);
+
+ [self setStyleManager:m];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(stylePropertyChanged:)
+ name:@"EdgeStylePropertyChanged"
+ object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(shapeDictionaryReplaced:)
+ name:@"ShapeDictionaryReplaced"
+ object:[Shape class]];
+ }
+
+ return self;
+}
+
+- (void) dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ g_object_unref (view);
+ [self clearModel];
+ g_object_unref (store);
+ [styleManager release];
+
+ [super dealloc];
+}
+
+- (StyleManager*) styleManager {
+ return styleManager;
+}
+
+- (void) setStyleManager:(StyleManager*)m {
+ if (m == nil) {
+ [NSException raise:NSInvalidArgumentException format:@"Style manager cannot be nil"];
+ }
+ [m retain];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:styleManager];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(stylesReplaced:)
+ name:@"EdgeStylesReplaced"
+ object:m];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(styleAdded:)
+ name:@"EdgeStyleAdded"
+ object:m];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(styleRemoved:)
+ name:@"EdgeStyleRemoved"
+ object:m];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(activeStyleChanged:)
+ name:@"ActiveEdgeStyleChanged"
+ object:m];
+
+ [styleManager release];
+ styleManager = m;
+
+ [self reloadStyles];
+}
+
+- (GtkWidget*) widget {
+ return GTK_WIDGET (view);
+}
+
+- (BOOL) isLinkedToActiveStyle {
+ return linkedToActiveStyle;
+}
+
+- (void) setLinkedToActiveStyle:(BOOL)linked {
+ linkedToActiveStyle = linked;
+ if (linkedToActiveStyle) {
+ EdgeStyle *style = [self selectedStyle];
+ if ([styleManager activeEdgeStyle] != style) {
+ [self setSelectedStyle:[styleManager activeEdgeStyle]];
+ }
+ }
+}
+
+- (EdgeStyle*) selectedStyle {
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (view);
+ GtkTreeIter iter;
+
+ if (!gtk_tree_selection_get_selected (sel, NULL, &iter)) {
+ return nil;
+ }
+
+ EdgeStyle *style = nil;
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, STYLES_PTR_COL, &style, -1);
+
+ return style;
+}
+
+- (void) setSelectedStyle:(EdgeStyle*)style {
+ GtkTreeSelection *sel = gtk_tree_view_get_selection (view);
+
+ if (style == nil) {
+ gtk_tree_selection_unselect_all (sel);
+ return;
+ }
+
+ GtkTreeModel *m = GTK_TREE_MODEL (store);
+ GtkTreeIter row;
+ if (gtk_tree_model_get_iter_first (m, &row)) {
+ do {
+ EdgeStyle *rowStyle;
+ gtk_tree_model_get (m, &row, STYLES_PTR_COL, &rowStyle, -1);
+ if (style == rowStyle) {
+ gtk_tree_selection_unselect_all (sel);
+ GtkTreePath *path = gtk_tree_model_get_path (m, &row);
+ gtk_tree_selection_select_path (sel, path);
+ gtk_tree_path_free (path);
+ // styleManager.activeStyle will be updated by the GTK+ callback
+ return;
+ }
+ } while (gtk_tree_model_iter_next (m, &row));
+ }
+}
+
+@end
+
+// }}}
+// {{{ Notifications
+
+@implementation EdgeStyleSelector (Notifications)
+
+- (void) stylesReplaced:(NSNotification*)notification {
+ [self reloadStyles];
+}
+
+- (void) styleAdded:(NSNotification*)notification {
+ [self addStyle:[[notification userInfo] objectForKey:@"style"]];
+}
+
+- (void) styleRemoved:(NSNotification*)notification {
+ EdgeStyle *style = [[notification userInfo] objectForKey:@"style"];
+
+ GtkTreeModel *model = GTK_TREE_MODEL (store);
+ GtkTreeIter row;
+ if (gtk_tree_model_get_iter_first (model, &row)) {
+ do {
+ EdgeStyle *rowStyle;
+ gtk_tree_model_get (model, &row, STYLES_PTR_COL, &rowStyle, -1);
+ if (style == rowStyle) {
+ gtk_list_store_remove (store, &row);
+ [rowStyle release];
+ return;
+ }
+ } while (gtk_tree_model_iter_next (model, &row));
+ }
+}
+
+- (void) activeStyleChanged:(NSNotification*)notification {
+ if (linkedToActiveStyle) {
+ EdgeStyle *style = [self selectedStyle];
+ if ([styleManager activeEdgeStyle] != style) {
+ [self setSelectedStyle:[styleManager activeEdgeStyle]];
+ }
+ }
+}
+
+- (void) stylePropertyChanged:(NSNotification*)notification {
+ EdgeStyle *style = [notification object];
+
+ GtkTreeModel *model = GTK_TREE_MODEL (store);
+ GtkTreeIter row;
+ if (gtk_tree_model_get_iter_first (model, &row)) {
+ do {
+ EdgeStyle *rowStyle;
+ gtk_tree_model_get (model, &row, STYLES_PTR_COL, &rowStyle, -1);
+ if (style == rowStyle) {
+ if ([@"name" isEqual:[[notification userInfo] objectForKey:@"propertyName"]]) {
+ gtk_list_store_set (store, &row, STYLES_NAME_COL, [[style name] UTF8String], -1);
+ } else if (![@"scale" isEqual:[[notification userInfo] objectForKey:@"propertyName"]]) {
+ GdkPixbuf *pixbuf = [self pixbufOfEdgeInStyle:style];
+ gtk_list_store_set (store, &row, STYLES_ICON_COL, pixbuf, -1);
+ gdk_pixbuf_unref (pixbuf);
+ }
+ }
+ } while (gtk_tree_model_iter_next (model, &row));
+ }
+}
+
+- (void) shapeDictionaryReplaced:(NSNotification*)n {
+ [self reloadStyles];
+}
+
+- (void) selectionChanged {
+ if (linkedToActiveStyle) {
+ EdgeStyle *style = [self selectedStyle];
+ if ([styleManager activeEdgeStyle] != style) {
+ [styleManager setActiveEdgeStyle:style];
+ }
+ }
+ [self postSelectedStyleChanged];
+}
+@end
+
+// }}}
+// {{{ Private
+
+@implementation EdgeStyleSelector (Private)
+- (void) clearModel {
+ [self setSelectedStyle:nil];
+ GtkTreeModel *model = GTK_TREE_MODEL (store);
+ GtkTreeIter row;
+ if (gtk_tree_model_get_iter_first (model, &row)) {
+ do {
+ EdgeStyle *rowStyle;
+ gtk_tree_model_get (model, &row, STYLES_PTR_COL, &rowStyle, -1);
+ [rowStyle release];
+ } while (gtk_tree_model_iter_next (model, &row));
+ }
+ gtk_list_store_clear (store);
+}
+
+- (cairo_surface_t*) createEdgeIconSurface {
+ return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 48, 18);
+}
+
+- (GdkPixbuf*) pixbufOfEdgeInStyle:(EdgeStyle*)style {
+ cairo_surface_t *surface = [self createEdgeIconSurface];
+ GdkPixbuf *pixbuf = [self pixbufOfEdgeInStyle:style usingSurface:surface];
+ cairo_surface_destroy (surface);
+ return pixbuf;
+}
+
+// Bring on GTK+3 and gdk_pixbuf_get_from_surface()
+- (GdkPixbuf*) pixbufFromSurface:(cairo_surface_t*)surface {
+ cairo_surface_flush (surface);
+
+ int width = cairo_image_surface_get_width (surface);
+ int height = cairo_image_surface_get_height (surface);
+ int stride = cairo_image_surface_get_stride (surface);
+ unsigned char *data = cairo_image_surface_get_data (surface);
+
+ GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ width,
+ height);
+ unsigned char *pbdata = gdk_pixbuf_get_pixels (pixbuf);
+ int pbstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ for (int y = 0; y < height; ++y) {
+ uint32_t *line = (uint32_t*)(data + y*stride);
+ unsigned char *pbline = pbdata + (y*pbstride);
+ for (int x = 0; x < width; ++x) {
+ uint32_t pixel = *(line + x);
+ unsigned char *pbpixel = pbline + (x*4);
+ // NB: We should un-pre-mult the alpha here.
+ // However, in our world, alpha is always
+ // on or off, so it doesn't really matter
+ pbpixel[3] = ((pixel & 0xff000000) >> 24);
+ pbpixel[0] = ((pixel & 0x00ff0000) >> 16);
+ pbpixel[1] = ((pixel & 0x0000ff00) >> 8);
+ pbpixel[2] = (pixel & 0x000000ff);
+ }
+ }
+
+ return pixbuf;
+}
+
+- (GdkPixbuf*) pixbufOfEdgeInStyle:(EdgeStyle*)style usingSurface:(cairo_surface_t*)surface {
+ Transformer *transformer = [Transformer defaultTransformer];
+ [transformer setFlippedAboutXAxis:YES];
+
+ int width = cairo_image_surface_get_width (surface);
+ int height = cairo_image_surface_get_height (surface);
+ NSRect pixbufBounds = NSMakeRect(0.0, 0.0, width, height);
+ NSRect graphBounds = [transformer rectFromScreen:pixbufBounds];
+
+ NSPoint mid = NSMakePoint (NSMidX (graphBounds), NSMidY (graphBounds));
+ NSPoint start = NSMakePoint (NSMinX (graphBounds) + 0.1f, mid.y);
+ NSPoint end = NSMakePoint (NSMaxX (graphBounds) - 0.1f, mid.y);
+ NSPoint midTan = NSMakePoint (mid.x + 0.1f, mid.y);
+ NSPoint leftNormal = NSMakePoint (mid.x, mid.y - 0.1f);
+ NSPoint rightNormal = NSMakePoint (mid.x, mid.y + 0.1f);
+
+ CairoRenderContext *context = [[CairoRenderContext alloc] initForSurface:surface];
+ [context clearSurface];
+
+ [context startPath];
+ [context moveTo:[transformer toScreen:start]];
+ [context lineTo:[transformer toScreen:end]];
+
+ switch ([style decorationStyle]) {
+ case ED_None:
+ break;
+ case ED_Tick:
+ [context moveTo:[transformer toScreen:leftNormal]];
+ [context lineTo:[transformer toScreen:rightNormal]];
+ break;
+ case ED_Arrow:
+ [context moveTo:[transformer toScreen:leftNormal]];
+ [context lineTo:[transformer toScreen:midTan]];
+ [context lineTo:[transformer toScreen:rightNormal]];
+ break;
+ }
+
+ [context setLineWidth:[style thickness]];
+ [context strokePathWithColor:BlackRColor];
+
+ [context release];
+
+ return [self pixbufFromSurface:surface];
+}
+
+- (void) addStyle:(EdgeStyle*)style usingSurface:(cairo_surface_t*)surface {
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+
+ GdkPixbuf *pixbuf = [self pixbufOfEdgeInStyle:style usingSurface:surface];
+ gtk_list_store_set (store, &iter,
+ STYLES_NAME_COL, [[style name] UTF8String],
+ STYLES_ICON_COL, pixbuf,
+ STYLES_PTR_COL, (gpointer)[style retain],
+ -1);
+ gdk_pixbuf_unref (pixbuf);
+}
+
+- (void) addStyle:(EdgeStyle*)style {
+ cairo_surface_t *surface = [self createEdgeIconSurface];
+ [self addStyle:style usingSurface:surface];
+ cairo_surface_destroy (surface);
+}
+
+- (void) postSelectedStyleChanged {
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"SelectedStyleChanged" object:self];
+}
+
+- (void) reloadStyles {
+ [self clearModel];
+ for (EdgeStyle *style in [styleManager edgeStyles]) {
+ [self addStyle:style];
+ }
+}
+@end
+
+// }}}
+// {{{ GTK+ callbacks
+
+static void selection_changed_cb (GtkTreeSelection *sel, EdgeStyleSelector *mgr) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [mgr selectionChanged];
+ [pool drain];
+}
+// }}}
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
+
diff --git a/tikzit/src/linux/EdgeStylesPalette.h b/tikzit/src/linux/EdgeStylesPalette.h
new file mode 100644
index 0000000..a7d715b
--- /dev/null
+++ b/tikzit/src/linux/EdgeStylesPalette.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "TZFoundation.h"
+#import <gtk/gtk.h>
+
+@class StyleManager;
+@class EdgeStyleSelector;
+@class EdgeStyleEditor;
+@class TikzDocument;
+
+@interface EdgeStylesPalette: NSObject {
+ TikzDocument *document;
+ EdgeStyleSelector *selector;
+ EdgeStyleEditor *editor;
+
+ GtkWidget *palette;
+
+ GtkWidget *removeStyleButton;
+ GtkWidget *applyStyleButton;
+ GtkWidget *clearStyleButton;
+}
+
+@property (retain) StyleManager *styleManager;
+@property (retain) TikzDocument *document;
+@property (readonly) GtkWidget *widget;
+
+- (id) initWithManager:(StyleManager*)m;
+
+@end
+
+// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/EdgeStylesPalette.m b/tikzit/src/linux/EdgeStylesPalette.m
new file mode 100644
index 0000000..bcb631e
--- /dev/null
+++ b/tikzit/src/linux/EdgeStylesPalette.m
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "EdgeStylesPalette.h"
+
+#import "EdgeStyleSelector.h"
+#import "EdgeStyleEditor.h"
+#import "StyleManager.h"
+#import "TikzDocument.h"
+
+// {{{ Internal interfaces
+// {{{ GTK+ Callbacks
+static void add_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette);
+static void remove_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette);
+static void apply_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette);
+static void clear_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette);
+// }}}
+// {{{ Notifications
+
+@interface EdgeStylesPalette (Notifications)
+- (void) selectedStyleChanged:(NSNotification*)notification;
+- (void) edgeSelectionChanged:(NSNotification*)n;
+@end
+
+// }}}
+// {{{ Private
+
+@interface EdgeStylesPalette (Private)
+- (void) updateButtonState;
+- (void) removeSelectedStyle;
+- (void) applySelectedStyle;
+- (void) clearSelectedStyle;
+@end
+
+// }}}
+// }}}
+// {{{ API
+
+@implementation EdgeStylesPalette
+
+@synthesize widget=palette;
+
+- (id) init {
+ [self release];
+ self = nil;
+ return nil;
+}
+
+- (id) initWithManager:(StyleManager*)m {
+ self = [super init];
+
+ if (self) {
+ document = nil;
+ selector = [[EdgeStyleSelector alloc] initWithStyleManager:m];
+ editor = [[EdgeStyleEditor alloc] init];
+
+ palette = gtk_vbox_new (FALSE, 0);
+ // FIXME: remove this line when we add edge styles
+ gtk_container_set_border_width (GTK_CONTAINER (palette), 6);
+ gtk_box_set_spacing (GTK_BOX (palette), 6);
+ g_object_ref_sink (palette);
+
+ gtk_box_pack_start (GTK_BOX (palette), [editor widget], FALSE, FALSE, 0);
+ gtk_widget_show ([editor widget]);
+ GtkWidget *selectorFrame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (selectorFrame), [selector widget]);
+ gtk_box_pack_start (GTK_BOX (palette), selectorFrame, TRUE, TRUE, 0);
+ gtk_widget_show (selectorFrame);
+ gtk_widget_show ([selector widget]);
+
+ GtkBox *buttonBox = GTK_BOX (gtk_hbox_new(FALSE, 5));
+ gtk_box_pack_start (GTK_BOX (palette), GTK_WIDGET (buttonBox), FALSE, FALSE, 0);
+
+ GtkBox *bbox1 = GTK_BOX (gtk_hbox_new(FALSE, 0));
+ gtk_box_pack_start (buttonBox, GTK_WIDGET (bbox1), FALSE, FALSE, 0);
+
+ GtkWidget *addStyleButton = gtk_button_new ();
+ gtk_widget_set_tooltip_text (addStyleButton, "Add a new style");
+ GtkWidget *addIcon = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
+ gtk_container_add (GTK_CONTAINER (addStyleButton), addIcon);
+ gtk_box_pack_start (bbox1, addStyleButton, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (addStyleButton),
+ "clicked",
+ G_CALLBACK (add_style_button_cb),
+ self);
+
+ removeStyleButton = gtk_button_new ();
+ g_object_ref_sink (removeStyleButton);
+ gtk_widget_set_tooltip_text (removeStyleButton, "Delete selected style");
+ GtkWidget *removeIcon = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON);
+ gtk_container_add (GTK_CONTAINER (removeStyleButton), removeIcon);
+ gtk_box_pack_start (bbox1, removeStyleButton, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (removeStyleButton),
+ "clicked",
+ G_CALLBACK (remove_style_button_cb),
+ self);
+
+ GtkBox *bbox2 = GTK_BOX (gtk_hbox_new(FALSE, 0));
+ gtk_box_pack_start (buttonBox, GTK_WIDGET (bbox2), FALSE, FALSE, 0);
+
+ applyStyleButton = gtk_button_new_with_label ("Apply");
+ g_object_ref_sink (applyStyleButton);
+ gtk_widget_set_tooltip_text (applyStyleButton, "Apply style to selected edges");
+ gtk_box_pack_start (bbox2, applyStyleButton, FALSE, FALSE, 5);
+ g_signal_connect (G_OBJECT (applyStyleButton),
+ "clicked",
+ G_CALLBACK (apply_style_button_cb),
+ self);
+
+ clearStyleButton = gtk_button_new_with_label ("Clear");
+ g_object_ref_sink (clearStyleButton);
+ gtk_widget_set_tooltip_text (clearStyleButton, "Clear style from selected edges");
+ gtk_box_pack_start (bbox2, clearStyleButton, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (clearStyleButton),
+ "clicked",
+ G_CALLBACK (clear_style_button_cb),
+ self);
+
+ gtk_widget_show_all (GTK_WIDGET (buttonBox));
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(selectedStyleChanged:)
+ name:@"SelectedStyleChanged"
+ object:selector];
+
+ [self updateButtonState];
+ }
+
+ return self;
+}
+
+- (StyleManager*) styleManager {
+ return [selector styleManager];
+}
+
+- (void) setStyleManager:(StyleManager*)m {
+ [selector setStyleManager:m];
+}
+
+- (TikzDocument*) document {
+ return document;
+}
+
+- (void) setDocument:(TikzDocument*)doc {
+ if (document != nil) {
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:nil
+ object:[document pickSupport]];
+ }
+
+ [doc retain];
+ [document release];
+ document = doc;
+
+ if (document != nil) {
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(edgeSelectionChanged:)
+ name:@"EdgeSelectionChanged"
+ object:[document pickSupport]];
+ }
+}
+
+- (void) dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [editor release];
+ [selector release];
+ [document release];
+
+ g_object_unref (palette);
+ g_object_unref (removeStyleButton);
+ g_object_unref (applyStyleButton);
+ g_object_unref (clearStyleButton);
+
+ [super dealloc];
+}
+
+@end
+
+// }}}
+// {{{ Notifications
+
+@implementation EdgeStylesPalette (Notifications)
+- (void) selectedStyleChanged:(NSNotification*)notification {
+ [editor setStyle:[selector selectedStyle]];
+ [self updateButtonState];
+}
+
+- (void) edgeSelectionChanged:(NSNotification*)n {
+ [self updateButtonState];
+}
+@end
+
+// }}}
+// {{{ Private
+
+@implementation EdgeStylesPalette (Private)
+- (void) updateButtonState {
+ gboolean hasEdgeSelection = [[[document pickSupport] selectedEdges] count] > 0;
+ gboolean hasStyleSelection = [selector selectedStyle] != nil;
+
+ gtk_widget_set_sensitive (applyStyleButton, hasEdgeSelection && hasStyleSelection);
+ gtk_widget_set_sensitive (clearStyleButton, hasEdgeSelection);
+ gtk_widget_set_sensitive (removeStyleButton, hasStyleSelection);
+}
+
+- (void) removeSelectedStyle {
+ EdgeStyle *style = [selector selectedStyle];
+ if (style)
+ [[selector styleManager] removeEdgeStyle:style];
+}
+
+- (void) applySelectedStyle {
+ [document startModifyEdges:[[document pickSupport] selectedEdges]];
+
+ EdgeStyle *style = [selector selectedStyle];
+ for (Edge *edge in [[document pickSupport] selectedEdges]) {
+ [edge setStyle:style];
+ }
+
+ [document endModifyEdges];
+}
+
+- (void) clearSelectedStyle {
+ [document startModifyEdges:[[document pickSupport] selectedEdges]];
+
+ for (Edge *edge in [[document pickSupport] selectedEdges]) {
+ [edge setStyle:nil];
+ }
+
+ [document endModifyEdges];
+}
+
+@end
+
+// }}}
+// {{{ GTK+ callbacks
+
+static void add_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ EdgeStyle *newStyle = [EdgeStyle defaultEdgeStyleWithName:@"newstyle"];
+ [[palette styleManager] addEdgeStyle:newStyle];
+ [[palette styleManager] setActiveEdgeStyle:newStyle];
+
+ [pool drain];
+}
+
+static void remove_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [palette removeSelectedStyle];
+ [pool drain];
+}
+
+static void apply_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [palette applySelectedStyle];
+ [pool drain];
+}
+
+static void clear_style_button_cb (GtkButton *widget, EdgeStylesPalette *palette) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [palette clearSelectedStyle];
+ [pool drain];
+}
+
+// }}}
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/MainWindow.h b/tikzit/src/linux/MainWindow.h
index 8d3c583..09e531e 100644
--- a/tikzit/src/linux/MainWindow.h
+++ b/tikzit/src/linux/MainWindow.h
@@ -23,12 +23,12 @@
@class GraphRenderer;
@class GraphInputHandler;
@class Menu;
-@class StylesPalette;
-@class StyleManager;
@class PropertyPane;
@class Preambles;
@class PreambleEditor;
@class PreviewWindow;
+@class StyleManager;
+@class StylesPane;
@class TikzDocument;
/**
@@ -46,17 +46,17 @@
GtkWindow *mainWindow;
GtkTextBuffer *tikzBuffer;
GtkStatusbar *statusBar;
- GtkPaned *propsPane;
- GtkPaned *stylesPane;
- GtkPaned *graphPane;
- GtkWidget *tikzDisp;
+ GtkPaned *propertyPaneSplitter;
+ GtkPaned *stylesPaneSplitter;
+ GtkPaned *tikzPaneSplitter;
+ GtkWidget *tikzPane;
// Classes that manage parts of the window
// (or other windows)
Menu *menu;
GraphRenderer *renderer;
GraphInputHandler *inputHandler;
- StylesPalette *stylesPalette;
+ StylesPane *stylesPane;
PropertyPane *propertyPane;
PreambleEditor *preambleWindow;
PreviewWindow *previewWindow;
diff --git a/tikzit/src/linux/MainWindow.m b/tikzit/src/linux/MainWindow.m
index 5e5a81a..1feb922 100644
--- a/tikzit/src/linux/MainWindow.m
+++ b/tikzit/src/linux/MainWindow.m
@@ -37,7 +37,7 @@
#import "StyleManager.h"
#import "Shape.h"
#import "StyleManager+Storage.h"
-#import "NodeStylesPalette.h"
+#import "StylesPane.h"
#import "SupportDir.h"
#import "TikzDocument.h"
#import "WidgetSurface.h"
@@ -152,7 +152,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
[menu release];
[renderer release];
[inputHandler release];
- [stylesPalette release];
+ [stylesPane release];
[propertyPane release];
[preambleWindow release];
[previewWindow release];
@@ -163,10 +163,10 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
g_object_unref (mainWindow);
g_object_unref (tikzBuffer);
g_object_unref (statusBar);
- g_object_unref (propsPane);
- g_object_unref (stylesPane);
- g_object_unref (graphPane);
- g_object_unref (tikzDisp);
+ g_object_unref (propertyPaneSplitter);
+ g_object_unref (stylesPaneSplitter);
+ g_object_unref (tikzPaneSplitter);
+ g_object_unref (tikzPane);
[super dealloc];
}
@@ -455,6 +455,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
[styleManager saveStylesUsingConfigurationName:@"styles"];
[propertyPane saveUiStateToConfig:configFile group:@"PropertyPane"];
+ [stylesPane saveUiStateToConfig:configFile group:@"StylesPane"];
if (lastFolder != nil) {
[configFile setStringEntry:@"lastFolder" inGroup:@"Paths" value:lastFolder];
@@ -592,41 +593,41 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
gtk_container_add (GTK_CONTAINER (toolbarBox), [menu toolbar]);
gtk_widget_show ([menu toolbar]);
- propsPane = GTK_PANED (gtk_hpaned_new ());
- g_object_ref_sink (propsPane);
- gtk_widget_show (GTK_WIDGET (propsPane));
- gtk_box_pack_start (mainLayout, GTK_WIDGET (propsPane), TRUE, TRUE, 0);
+ propertyPaneSplitter = GTK_PANED (gtk_hpaned_new ());
+ g_object_ref_sink (propertyPaneSplitter);
+ gtk_widget_show (GTK_WIDGET (propertyPaneSplitter));
+ gtk_box_pack_start (mainLayout, GTK_WIDGET (propertyPaneSplitter), TRUE, TRUE, 0);
propertyPane = [[PropertyPane alloc] init];
GtkWidget *propFrame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (propFrame), [propertyPane widget]);
- gtk_paned_pack1 (propsPane, propFrame, FALSE, TRUE);
+ gtk_paned_pack1 (propertyPaneSplitter, propFrame, FALSE, TRUE);
gtk_widget_show (propFrame);
gtk_widget_show ([propertyPane widget]);
- stylesPane = GTK_PANED (gtk_hpaned_new ());
- g_object_ref_sink (stylesPane);
- gtk_widget_show (GTK_WIDGET (stylesPane));
- gtk_paned_pack2 (propsPane, GTK_WIDGET (stylesPane), TRUE, TRUE);
+ stylesPaneSplitter = GTK_PANED (gtk_hpaned_new ());
+ g_object_ref_sink (stylesPaneSplitter);
+ gtk_widget_show (GTK_WIDGET (stylesPaneSplitter));
+ gtk_paned_pack2 (propertyPaneSplitter, GTK_WIDGET (stylesPaneSplitter), TRUE, TRUE);
- stylesPalette = [[NodeStylesPalette alloc] initWithManager:styleManager];
+ stylesPane = [[StylesPane alloc] initWithManager:styleManager];
GtkWidget *stylesFrame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (stylesFrame), [stylesPalette widget]);
- gtk_paned_pack2 (stylesPane, stylesFrame, FALSE, TRUE);
+ gtk_container_add (GTK_CONTAINER (stylesFrame), [stylesPane widget]);
+ gtk_paned_pack2 (stylesPaneSplitter, stylesFrame, FALSE, TRUE);
gtk_widget_show (stylesFrame);
- gtk_widget_show ([stylesPalette widget]);
+ gtk_widget_show ([stylesPane widget]);
- graphPane = GTK_PANED (gtk_vpaned_new ());
- g_object_ref_sink (graphPane);
- gtk_widget_show (GTK_WIDGET (graphPane));
- gtk_paned_pack1 (stylesPane, GTK_WIDGET (graphPane), TRUE, TRUE);
+ tikzPaneSplitter = GTK_PANED (gtk_vpaned_new ());
+ g_object_ref_sink (tikzPaneSplitter);
+ gtk_widget_show (GTK_WIDGET (tikzPaneSplitter));
+ gtk_paned_pack1 (stylesPaneSplitter, GTK_WIDGET (tikzPaneSplitter), TRUE, TRUE);
surface = [[WidgetSurface alloc] init];
gtk_widget_show ([surface widget]);
GtkWidget *graphFrame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (graphFrame), [surface widget]);
gtk_widget_show (graphFrame);
- gtk_paned_pack1 (graphPane, graphFrame, TRUE, TRUE);
+ gtk_paned_pack1 (tikzPaneSplitter, graphFrame, TRUE, TRUE);
[surface setDefaultScale:50.0f];
[surface setKeepCentered:YES];
[surface setGrabsFocusOnClick:YES];
@@ -640,16 +641,16 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
GtkWidget *tikzScroller = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (tikzScroller);
- tikzDisp = gtk_text_view_new_with_buffer (tikzBuffer);
- gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tikzDisp), 3);
- gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tikzDisp), 3);
- g_object_ref_sink (tikzDisp);
- gtk_widget_show (tikzDisp);
- gtk_container_add (GTK_CONTAINER (tikzScroller), tikzDisp);
+ tikzPane = gtk_text_view_new_with_buffer (tikzBuffer);
+ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tikzPane), 3);
+ gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tikzPane), 3);
+ g_object_ref_sink (tikzPane);
+ gtk_widget_show (tikzPane);
+ gtk_container_add (GTK_CONTAINER (tikzScroller), tikzPane);
GtkWidget *tikzFrame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (tikzFrame), tikzScroller);
gtk_widget_show (tikzFrame);
- gtk_paned_pack2 (graphPane, tikzFrame, FALSE, TRUE);
+ gtk_paned_pack2 (tikzPaneSplitter, tikzFrame, FALSE, TRUE);
statusBar = GTK_STATUSBAR (gtk_statusbar_new ());
gtk_widget_show (GTK_WIDGET (statusBar));
@@ -670,17 +671,18 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
}
int panePos = [configFile integerEntry:@"toolboxWidth" inGroup:@"mainWindow"];
if (panePos > 0) {
- gtk_paned_set_position (propsPane, panePos);
+ gtk_paned_set_position (propertyPaneSplitter, panePos);
}
panePos = [configFile integerEntry:@"styleboxWidth" inGroup:@"mainWindow"];
if (panePos > 0) {
- gtk_paned_set_position (stylesPane, panePos);
+ gtk_paned_set_position (stylesPaneSplitter, panePos);
}
panePos = [configFile integerEntry:@"graphHeight" inGroup:@"mainWindow"];
if (panePos > 0) {
- gtk_paned_set_position (graphPane, panePos);
+ gtk_paned_set_position (tikzPaneSplitter, panePos);
}
[propertyPane restoreUiStateFromConfig:configFile group:@"PropertyPane"];
+ [stylesPane restoreUiStateFromConfig:configFile group:@"StylesPane"];
}
- (void) _connectSignals {
@@ -693,15 +695,15 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
"key-press-event",
G_CALLBACK (tz_hijack_key_press),
NULL);
- g_signal_connect (G_OBJECT (propsPane),
+ g_signal_connect (G_OBJECT (propertyPaneSplitter),
"notify::position",
G_CALLBACK (toolbox_divider_position_changed_cb),
self);
- g_signal_connect (G_OBJECT (stylesPane),
+ g_signal_connect (G_OBJECT (stylesPaneSplitter),
"notify::position",
G_CALLBACK (stylebox_divider_position_changed_cb),
self);
- g_signal_connect (G_OBJECT (graphPane),
+ g_signal_connect (G_OBJECT (tikzPaneSplitter),
"notify::position",
G_CALLBACK (graph_divider_position_changed_cb),
self);
@@ -775,10 +777,10 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
if (hasError && !hasParseError) {
gtk_statusbar_push (statusBar, 1, "Parse error");
GdkColor color = {0, 65535, 61184, 61184};
- gtk_widget_modify_base (tikzDisp, GTK_STATE_NORMAL, &color);
+ gtk_widget_modify_base (tikzPane, GTK_STATE_NORMAL, &color);
} else if (!hasError && hasParseError) {
gtk_statusbar_pop (statusBar, 1);
- gtk_widget_modify_base (tikzDisp, GTK_STATE_NORMAL, NULL);
+ gtk_widget_modify_base (tikzPane, GTK_STATE_NORMAL, NULL);
}
hasParseError = hasError;
}
@@ -866,7 +868,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
document = newDoc;
[renderer setDocument:document];
- [stylesPalette setDocument:document];
+ [stylesPane setDocument:document];
[propertyPane setDocument:document];
#ifdef HAVE_POPPLER
[previewWindow setDocument:document];
diff --git a/tikzit/src/linux/NodeStyleEditor.h b/tikzit/src/linux/NodeStyleEditor.h
index 67219e8..9bde203 100644
--- a/tikzit/src/linux/NodeStyleEditor.h
+++ b/tikzit/src/linux/NodeStyleEditor.h
@@ -22,22 +22,22 @@
@interface NodeStyleEditor: NSObject {
NodeStyle *style;
- GtkTable *table;
+ GtkTable *table;
GtkEntry *nameEdit;
GtkComboBox *shapeNameCombo;
GtkColorButton *strokeColorButton;
GtkWidget *makeStrokeTexSafeButton;
GtkColorButton *fillColorButton;
GtkWidget *makeFillTexSafeButton;
- GtkAdjustment *scaleAdj;
- BOOL blockSignals;
+ GtkAdjustment *scaleAdj;
+ BOOL blockSignals;
}
-@property (retain) NodeStyle *style;
+@property (retain) NodeStyle *style;
@property (readonly) GtkWidget *widget;
- (id) init;
@end
-// vim:ft=objc:ts=4:noet:sts=4:sw=4
+// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/NodeStyleEditor.m b/tikzit/src/linux/NodeStyleEditor.m
index 32416be..febbf3c 100644
--- a/tikzit/src/linux/NodeStyleEditor.m
+++ b/tikzit/src/linux/NodeStyleEditor.m
@@ -60,189 +60,189 @@ static void scale_adjustment_changed_cb (GtkAdjustment *widget, NodeStyleEditor
@implementation NodeStyleEditor
- (void) _addWidget:(GtkWidget*)w withLabel:(gchar *)label atRow:(guint)row {
- NSAssert(row < row_count, @"row_count is wrong!");
-
- GtkWidget *l = gtk_label_new (label);
- gtk_misc_set_alignment (GTK_MISC (l), 0, 0.5);
- gtk_widget_show (l);
- gtk_widget_show (w);
-
- gtk_table_attach (table, l,
- 0, 1, row, row+1, // l, r, t, b
- GTK_FILL, // x opts
- GTK_FILL | GTK_EXPAND, // y opts
- 5, // x padding
- 0); // y padding
-
- gtk_table_attach (table, w,
- 1, 2, row, row+1, // l, r, t, b
- GTK_FILL | GTK_EXPAND, // x opts
- GTK_FILL | GTK_EXPAND, // y opts
- 0, // x padding
- 0); // y padding
+ NSAssert(row < row_count, @"row_count is wrong!");
+
+ GtkWidget *l = gtk_label_new (label);
+ gtk_misc_set_alignment (GTK_MISC (l), 0, 0.5);
+ gtk_widget_show (l);
+ gtk_widget_show (w);
+
+ gtk_table_attach (table, l,
+ 0, 1, row, row+1, // l, r, t, b
+ GTK_FILL, // x opts
+ GTK_FILL | GTK_EXPAND, // y opts
+ 5, // x padding
+ 0); // y padding
+
+ gtk_table_attach (table, w,
+ 1, 2, row, row+1, // l, r, t, b
+ GTK_FILL | GTK_EXPAND, // x opts
+ GTK_FILL | GTK_EXPAND, // y opts
+ 0, // x padding
+ 0); // y padding
}
- (GtkWidget*) _createMakeColorTexSafeButton:(NSString*)type {
- GtkWidget *b = gtk_button_new ();
- GtkWidget *icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON);
- gtk_widget_show (icon);
- gtk_container_add (GTK_CONTAINER (b), icon);
- NSString *ttip = [NSString stringWithFormat:@"The %@ colour is not a predefined TeX colour.\nClick here to choose the nearest TeX-safe colour.", type];
- gtk_widget_set_tooltip_text (b, [ttip UTF8String]);
- return b;
+ GtkWidget *b = gtk_button_new ();
+ GtkWidget *icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON);
+ gtk_widget_show (icon);
+ gtk_container_add (GTK_CONTAINER (b), icon);
+ NSString *ttip = [NSString stringWithFormat:@"The %@ colour is not a predefined TeX colour.\nClick here to choose the nearest TeX-safe colour.", type];
+ gtk_widget_set_tooltip_text (b, [ttip UTF8String]);
+ return b;
}
- (id) init {
- self = [super init];
-
- if (self != nil) {
- style = nil;
- table = GTK_TABLE (gtk_table_new (row_count, 2, FALSE));
- gtk_table_set_col_spacings (table, 6);
- gtk_table_set_row_spacings (table, 6);
- gtk_widget_set_sensitive (GTK_WIDGET (table), FALSE);
- blockSignals = NO;
-
- /**
- * Name
- */
- nameEdit = GTK_ENTRY (gtk_entry_new ());
- g_object_ref_sink (nameEdit);
- [self _addWidget:GTK_WIDGET (nameEdit)
- withLabel:"Name"
- atRow:0];
- g_signal_connect (G_OBJECT (nameEdit),
- "changed",
- G_CALLBACK (style_name_edit_changed_cb),
- self);
-
-
- /**
- * Shape
- */
- GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
- shapeNameCombo = GTK_COMBO_BOX (gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)));
- GtkCellRenderer *cellRend = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (shapeNameCombo),
- cellRend,
- TRUE);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (shapeNameCombo), cellRend, "text", 0);
- g_object_ref_sink (shapeNameCombo);
- [self _addWidget:GTK_WIDGET (shapeNameCombo)
- withLabel:"Shape"
- atRow:1];
- g_signal_connect (G_OBJECT (shapeNameCombo),
- "changed",
- G_CALLBACK (style_shape_combo_changed_cb),
- self);
-
-
- /**
- * Stroke colour
- */
- GtkWidget *strokeBox = gtk_hbox_new (FALSE, 0);
- [self _addWidget:strokeBox
- withLabel:"Stroke colour"
- atRow:2];
- strokeColorButton = GTK_COLOR_BUTTON (gtk_color_button_new ());
- g_object_ref_sink (strokeColorButton);
- gtk_widget_show (GTK_WIDGET (strokeColorButton));
- gtk_box_pack_start (GTK_BOX (strokeBox), GTK_WIDGET (strokeColorButton),
- FALSE, FALSE, 0);
- makeStrokeTexSafeButton = [self _createMakeColorTexSafeButton:@"stroke"];
- g_object_ref_sink (makeStrokeTexSafeButton);
- gtk_box_pack_start (GTK_BOX (strokeBox), makeStrokeTexSafeButton,
- FALSE, FALSE, 0);
- g_signal_connect (G_OBJECT (strokeColorButton),
- "color-set",
- G_CALLBACK (stroke_color_changed_cb),
- self);
- g_signal_connect (G_OBJECT (makeStrokeTexSafeButton),
- "clicked",
- G_CALLBACK (make_stroke_safe_button_clicked_cb),
- self);
-
-
- /**
- * Fill colour
- */
- GtkWidget *fillBox = gtk_hbox_new (FALSE, 0);
- [self _addWidget:fillBox
- withLabel:"Fill colour"
- atRow:3];
- fillColorButton = GTK_COLOR_BUTTON (gtk_color_button_new ());
- g_object_ref_sink (fillColorButton);
- gtk_widget_show (GTK_WIDGET (fillColorButton));
- gtk_box_pack_start (GTK_BOX (fillBox), GTK_WIDGET (fillColorButton),
- FALSE, FALSE, 0);
- makeFillTexSafeButton = [self _createMakeColorTexSafeButton:@"fill"];
- g_object_ref_sink (makeFillTexSafeButton);
- gtk_box_pack_start (GTK_BOX (fillBox), makeFillTexSafeButton,
- FALSE, FALSE, 0);
- g_signal_connect (G_OBJECT (fillColorButton),
- "color-set",
- G_CALLBACK (fill_color_changed_cb),
- self);
- g_signal_connect (G_OBJECT (makeFillTexSafeButton),
- "clicked",
- G_CALLBACK (make_fill_safe_button_clicked_cb),
- self);
-
-
- /**
- * Scale
- */
- scaleAdj = GTK_ADJUSTMENT (gtk_adjustment_new (
- 1.0, // value
- 0.0, // lower
- 50.0, // upper
- 0.20, // step
- 1.0, // page
- 0.0)); // (irrelevant)
- g_object_ref_sink (scaleAdj);
- GtkWidget *scaleSpin = gtk_spin_button_new (scaleAdj, 0.0, 2);
- [self _addWidget:scaleSpin
- withLabel:"Scale"
- atRow:4];
- g_signal_connect (G_OBJECT (scaleAdj),
- "value-changed",
- G_CALLBACK (scale_adjustment_changed_cb),
- self);
-
- [self loadShapeNames];
+ self = [super init];
+
+ if (self != nil) {
+ style = nil;
+ table = GTK_TABLE (gtk_table_new (row_count, 2, FALSE));
+ gtk_table_set_col_spacings (table, 6);
+ gtk_table_set_row_spacings (table, 6);
+ gtk_widget_set_sensitive (GTK_WIDGET (table), FALSE);
+ blockSignals = NO;
+
+ /**
+ * Name
+ */
+ nameEdit = GTK_ENTRY (gtk_entry_new ());
+ g_object_ref_sink (nameEdit);
+ [self _addWidget:GTK_WIDGET (nameEdit)
+ withLabel:"Name"
+ atRow:0];
+ g_signal_connect (G_OBJECT (nameEdit),
+ "changed",
+ G_CALLBACK (style_name_edit_changed_cb),
+ self);
+
+
+ /**
+ * Shape
+ */
+ GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
+ shapeNameCombo = GTK_COMBO_BOX (gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)));
+ GtkCellRenderer *cellRend = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (shapeNameCombo),
+ cellRend,
+ TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (shapeNameCombo), cellRend, "text", 0);
+ g_object_ref_sink (shapeNameCombo);
+ [self _addWidget:GTK_WIDGET (shapeNameCombo)
+ withLabel:"Shape"
+ atRow:1];
+ g_signal_connect (G_OBJECT (shapeNameCombo),
+ "changed",
+ G_CALLBACK (style_shape_combo_changed_cb),
+ self);
+
+
+ /**
+ * Stroke colour
+ */
+ GtkWidget *strokeBox = gtk_hbox_new (FALSE, 0);
+ [self _addWidget:strokeBox
+ withLabel:"Stroke colour"
+ atRow:2];
+ strokeColorButton = GTK_COLOR_BUTTON (gtk_color_button_new ());
+ g_object_ref_sink (strokeColorButton);
+ gtk_widget_show (GTK_WIDGET (strokeColorButton));
+ gtk_box_pack_start (GTK_BOX (strokeBox), GTK_WIDGET (strokeColorButton),
+ FALSE, FALSE, 0);
+ makeStrokeTexSafeButton = [self _createMakeColorTexSafeButton:@"stroke"];
+ g_object_ref_sink (makeStrokeTexSafeButton);
+ gtk_box_pack_start (GTK_BOX (strokeBox), makeStrokeTexSafeButton,
+ FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (strokeColorButton),
+ "color-set",
+ G_CALLBACK (stroke_color_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (makeStrokeTexSafeButton),
+ "clicked",
+ G_CALLBACK (make_stroke_safe_button_clicked_cb),
+ self);
+
+
+ /**
+ * Fill colour
+ */
+ GtkWidget *fillBox = gtk_hbox_new (FALSE, 0);
+ [self _addWidget:fillBox
+ withLabel:"Fill colour"
+ atRow:3];
+ fillColorButton = GTK_COLOR_BUTTON (gtk_color_button_new ());
+ g_object_ref_sink (fillColorButton);
+ gtk_widget_show (GTK_WIDGET (fillColorButton));
+ gtk_box_pack_start (GTK_BOX (fillBox), GTK_WIDGET (fillColorButton),
+ FALSE, FALSE, 0);
+ makeFillTexSafeButton = [self _createMakeColorTexSafeButton:@"fill"];
+ g_object_ref_sink (makeFillTexSafeButton);
+ gtk_box_pack_start (GTK_BOX (fillBox), makeFillTexSafeButton,
+ FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (fillColorButton),
+ "color-set",
+ G_CALLBACK (fill_color_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (makeFillTexSafeButton),
+ "clicked",
+ G_CALLBACK (make_fill_safe_button_clicked_cb),
+ self);
+
+
+ /**
+ * Scale
+ */
+ scaleAdj = GTK_ADJUSTMENT (gtk_adjustment_new (
+ 1.0, // value
+ 0.0, // lower
+ 50.0, // upper
+ 0.20, // step
+ 1.0, // page
+ 0.0)); // (irrelevant)
+ g_object_ref_sink (scaleAdj);
+ GtkWidget *scaleSpin = gtk_spin_button_new (scaleAdj, 0.0, 2);
+ [self _addWidget:scaleSpin
+ withLabel:"Scale"
+ atRow:4];
+ g_signal_connect (G_OBJECT (scaleAdj),
+ "value-changed",
+ G_CALLBACK (scale_adjustment_changed_cb),
+ self);
+
+ [self loadShapeNames];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(shapeDictionaryReplaced:)
name:@"ShapeDictionaryReplaced"
object:[Shape class]];
- }
+ }
- return self;
+ return self;
}
- (void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
- g_object_unref (nameEdit);
- g_object_unref (shapeNameCombo);
+ g_object_unref (nameEdit);
+ g_object_unref (shapeNameCombo);
g_object_unref (strokeColorButton);
g_object_unref (makeStrokeTexSafeButton);
g_object_unref (fillColorButton);
g_object_unref (makeFillTexSafeButton);
- g_object_unref (scaleAdj);
- g_object_unref (table);
- [style release];
+ g_object_unref (scaleAdj);
+ g_object_unref (table);
+ [style release];
- [super dealloc];
+ [super dealloc];
}
- (NodeStyle*) style {
- return style;
+ return style;
}
- (void) setStyle:(NodeStyle*)s {
- blockSignals = YES;
- NodeStyle *oldStyle = style;
- style = [s retain];
+ blockSignals = YES;
+ NodeStyle *oldStyle = style;
+ style = [s retain];
if (style != nil) {
gtk_widget_set_sensitive (GTK_WIDGET (table), TRUE);
@@ -256,7 +256,7 @@ static void scale_adjustment_changed_cb (GtkAdjustment *widget, NodeStyleEditor
gtk_widget_set_visible (makeStrokeTexSafeButton, ([[style strokeColorRGB] name] == nil));
- c = [style fillColor];
+ c = [style fillColor];
gtk_color_button_set_color(fillColorButton, &c);
gtk_widget_set_visible (makeFillTexSafeButton, ([[style fillColorRGB] name] == nil));
@@ -271,12 +271,12 @@ static void scale_adjustment_changed_cb (GtkAdjustment *widget, NodeStyleEditor
gtk_widget_set_sensitive (GTK_WIDGET (table), FALSE);
}
- [oldStyle release];
- blockSignals = NO;
+ [oldStyle release];
+ blockSignals = NO;
}
- (GtkWidget*) widget {
- return GTK_WIDGET (table);
+ return GTK_WIDGET (table);
}
@end
@@ -286,54 +286,54 @@ static void scale_adjustment_changed_cb (GtkAdjustment *widget, NodeStyleEditor
@implementation NodeStyleEditor (Notifications)
- (void) shapeDictionaryReplaced:(NSNotification*)n {
- blockSignals = YES;
+ blockSignals = YES;
[self loadShapeNames];
[self setActiveShapeName:[style shapeName]];
- blockSignals = NO;
+ blockSignals = NO;
}
- (void) nameChangedTo:(NSString*)value {
- [style setName:value];
+ [style setName:value];
}
- (void) shapeNameChangedTo:(NSString*)value {
- [style setShapeName:value];
+ [style setShapeName:value];
}
- (void) strokeColorChangedTo:(GdkColor)value {
- [style setStrokeColor:value];
- gtk_widget_set_visible (makeStrokeTexSafeButton,
- [[style strokeColorRGB] name] == nil);
+ [style setStrokeColor:value];
+ gtk_widget_set_visible (makeStrokeTexSafeButton,
+ [[style strokeColorRGB] name] == nil);
}
- (void) makeStrokeColorTexSafe {
- if (style != nil) {
- [[style strokeColorRGB] setToClosestHashed];
- GdkColor color = [style strokeColor];
- gtk_color_button_set_color(strokeColorButton, &color);
- gtk_widget_set_visible (makeStrokeTexSafeButton, FALSE);
- }
+ if (style != nil) {
+ [[style strokeColorRGB] setToClosestHashed];
+ GdkColor color = [style strokeColor];
+ gtk_color_button_set_color(strokeColorButton, &color);
+ gtk_widget_set_visible (makeStrokeTexSafeButton, FALSE);
+ }
}
- (void) fillColorChangedTo:(GdkColor)value {
- [style setFillColor:value];
- gtk_widget_set_visible (makeFillTexSafeButton,
- [[style fillColorRGB] name] == nil);
+ [style setFillColor:value];
+ gtk_widget_set_visible (makeFillTexSafeButton,
+ [[style fillColorRGB] name] == nil);
}
- (void) makeFillColorTexSafe {
- if (style != nil) {
- [[style fillColorRGB] setToClosestHashed];
- GdkColor color = [style fillColor];
- gtk_color_button_set_color(fillColorButton, &color);
- gtk_widget_set_visible (makeFillTexSafeButton, FALSE);
- }
+ if (style != nil) {
+ [[style fillColorRGB] setToClosestHashed];
+ GdkColor color = [style fillColor];
+ gtk_color_button_set_color(fillColorButton, &color);
+ gtk_widget_set_visible (makeFillTexSafeButton, FALSE);
+ }
}
- (void) scaleChangedTo:(double)value {
- [style setScale:value];
+ [style setScale:value];
}
@end
@@ -390,62 +390,62 @@ static void scale_adjustment_changed_cb (GtkAdjustment *widget, NodeStyleEditor
// {{{ GTK+ callbacks
static void style_name_edit_changed_cb (GtkEditable *widget, NodeStyleEditor *editor) {
- if ([editor signalsBlocked])
- return;
+ if ([editor signalsBlocked])
+ return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- const gchar *contents = gtk_entry_get_text (GTK_ENTRY (widget));
- [editor nameChangedTo:[NSString stringWithUTF8String:contents]];
+ const gchar *contents = gtk_entry_get_text (GTK_ENTRY (widget));
+ [editor nameChangedTo:[NSString stringWithUTF8String:contents]];
[pool drain];
}
static void style_shape_combo_changed_cb (GtkComboBox *widget, NodeStyleEditor *editor) {
- if ([editor signalsBlocked])
- return;
+ if ([editor signalsBlocked])
+ return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GtkTreeIter iter;
- gtk_combo_box_get_active_iter (widget, &iter);
- gchar *shapeName = NULL;
- gtk_tree_model_get (gtk_combo_box_get_model (widget), &iter, 0, &shapeName, -1);
- [editor shapeNameChangedTo:[NSString stringWithUTF8String:shapeName]];
- g_free (shapeName);
+ GtkTreeIter iter;
+ gtk_combo_box_get_active_iter (widget, &iter);
+ gchar *shapeName = NULL;
+ gtk_tree_model_get (gtk_combo_box_get_model (widget), &iter, 0, &shapeName, -1);
+ [editor shapeNameChangedTo:[NSString stringWithUTF8String:shapeName]];
+ g_free (shapeName);
[pool drain];
}
static void stroke_color_changed_cb (GtkColorButton *widget, NodeStyleEditor *editor) {
- if ([editor signalsBlocked])
- return;
+ if ([editor signalsBlocked])
+ return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GdkColor color;
gtk_color_button_get_color (widget, &color);
- [editor strokeColorChangedTo:color];
+ [editor strokeColorChangedTo:color];
[pool drain];
}
static void fill_color_changed_cb (GtkColorButton *widget, NodeStyleEditor *editor) {
- if ([editor signalsBlocked])
- return;
+ if ([editor signalsBlocked])
+ return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GdkColor color;
gtk_color_button_get_color (widget, &color);
- [editor fillColorChangedTo:color];
+ [editor fillColorChangedTo:color];
[pool drain];
}
static void make_stroke_safe_button_clicked_cb (GtkButton *widget, NodeStyleEditor *editor) {
- if ([editor signalsBlocked])
- return;
+ if ([editor signalsBlocked])
+ return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[editor makeStrokeColorTexSafe];
@@ -453,8 +453,8 @@ static void make_stroke_safe_button_clicked_cb (GtkButton *widget, NodeStyleEdit
}
static void make_fill_safe_button_clicked_cb (GtkButton *widget, NodeStyleEditor *editor) {
- if ([editor signalsBlocked])
- return;
+ if ([editor signalsBlocked])
+ return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[editor makeFillColorTexSafe];
@@ -463,10 +463,10 @@ static void make_fill_safe_button_clicked_cb (GtkButton *widget, NodeStyleEditor
static void scale_adjustment_changed_cb (GtkAdjustment *adj, NodeStyleEditor *editor) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [editor scaleChangedTo:gtk_adjustment_get_value (adj)];
+ [editor scaleChangedTo:gtk_adjustment_get_value (adj)];
[pool drain];
}
// }}}
-// vim:ft=objc:ts=4:noet:sts=4:sw=4:foldmethod=marker
+// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/NodeStyleSelector.h b/tikzit/src/linux/NodeStyleSelector.h
index c6c8833..894d71e 100644
--- a/tikzit/src/linux/NodeStyleSelector.h
+++ b/tikzit/src/linux/NodeStyleSelector.h
@@ -56,21 +56,13 @@
@property (assign) NodeStyle *selectedStyle;
/*!
- * Initialise with the default style manager and a new icon view widget
+ * Initialise with the default style manager
*/
- (id) init;
/*!
- * Initialise with the default style manager and the given icon view widget
- */
-- (id) initWithIconView:(GtkIconView*)view;
-/*!
- * Initialise with the given style manager and a new icon view widget
+ * Initialise with the given style manager
*/
- (id) initWithStyleManager:(StyleManager*)m;
-/*!
- * Initialise with the given style manager and icon view widget
- */
-- (id) initWithIconView:(GtkIconView*)view andStyleManager:(StyleManager*)m;
@end
diff --git a/tikzit/src/linux/NodeStyleSelector.m b/tikzit/src/linux/NodeStyleSelector.m
index 5539b93..395d9ca 100644
--- a/tikzit/src/linux/NodeStyleSelector.m
+++ b/tikzit/src/linux/NodeStyleSelector.m
@@ -23,8 +23,9 @@
#import "ShapeNames.h"
#import "StyleManager.h"
-#import "gdk-pixbuf/gdk-pixbuf.h"
+#import <gdk-pixbuf/gdk-pixbuf.h>
+// {{{ Internal interfaces
// {{{ Signals
static void selection_changed_cb (GtkIconView *widget, NodeStyleSelector *mgr);
// }}}
@@ -56,7 +57,9 @@ enum {
- (void) reloadStyles;
@end
+// }}}
// {{{ API
+
@implementation NodeStyleSelector
- (id) init {
@@ -64,17 +67,7 @@ enum {
return self;
}
-- (id) initWithIconView:(GtkIconView*)view {
- self = [self initWithIconView:GTK_ICON_VIEW (gtk_icon_view_new ()) andStyleManager:[StyleManager manager]];
- return self;
-}
-
- (id) initWithStyleManager:(StyleManager*)m {
- self = [self initWithIconView:GTK_ICON_VIEW (gtk_icon_view_new ()) andStyleManager:m];
- return self;
-}
-
-- (id) initWithIconView:(GtkIconView*)v andStyleManager:(StyleManager*)m {
self = [super init];
if (self) {
@@ -87,7 +80,7 @@ enum {
G_TYPE_POINTER);
g_object_ref (store);
- view = v;
+ view = GTK_ICON_VIEW (gtk_icon_view_new ());
g_object_ref (view);
gtk_icon_view_set_model (view, GTK_TREE_MODEL (store));
@@ -115,6 +108,16 @@ enum {
return self;
}
+- (void) dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ g_object_unref (view);
+ [self clearModel];
+ g_object_unref (store);
+ [styleManager release];
+
+ [super dealloc];
+}
+
- (void) clearModel {
[self setSelectedStyle:nil];
GtkTreeModel *model = GTK_TREE_MODEL (store);
@@ -226,20 +229,11 @@ enum {
}
}
-- (void) dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- g_object_unref (view);
- [self clearModel];
- g_object_unref (store);
- [styleManager release];
-
- [super dealloc];
-}
-
@end
-// }}}
+// }}}
// {{{ Notifications
+
@implementation NodeStyleSelector (Notifications)
- (void) stylesReplaced:(NSNotification*)notification {
@@ -313,9 +307,10 @@ enum {
[self postSelectedStyleChanged];
}
@end
-// }}}
+// }}}
// {{{ Private
+
@implementation NodeStyleSelector (Private)
- (cairo_surface_t*) createNodeIconSurface {
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 24, 24);
@@ -416,9 +411,10 @@ enum {
}
}
@end
-// }}}
+// }}}
// {{{ GTK+ callbacks
+
static void selection_changed_cb (GtkIconView *view, NodeStyleSelector *mgr) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[mgr selectionChanged];
@@ -426,4 +422,4 @@ static void selection_changed_cb (GtkIconView *view, NodeStyleSelector *mgr) {
}
// }}}
-// vim:ft=objc:ts=8:et:sts=4:sw=4
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/NodeStylesPalette.h b/tikzit/src/linux/NodeStylesPalette.h
index dfecc17..0185857 100644
--- a/tikzit/src/linux/NodeStylesPalette.h
+++ b/tikzit/src/linux/NodeStylesPalette.h
@@ -35,12 +35,12 @@
GtkWidget *clearStyleButton;
}
-@property (retain) StyleManager *styleManager;
-@property (retain) TikzDocument *document;
-@property (readonly) GtkWidget *widget;
+@property (retain) StyleManager *styleManager;
+@property (retain) TikzDocument *document;
+@property (readonly) GtkWidget *widget;
- (id) initWithManager:(StyleManager*)m;
@end
-// vim:ft=objc:ts=4:noet:sts=4:sw=4
+// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/NodeStylesPalette.m b/tikzit/src/linux/NodeStylesPalette.m
index 24a5729..d5ac2e1 100644
--- a/tikzit/src/linux/NodeStylesPalette.m
+++ b/tikzit/src/linux/NodeStylesPalette.m
@@ -66,27 +66,25 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
if (self) {
document = nil;
selector = [[NodeStyleSelector alloc] initWithStyleManager:m];
- editor = [[NodeStyleEditor alloc] init];
+ editor = [[NodeStyleEditor alloc] init];
palette = gtk_vbox_new (FALSE, 0);
- // FIXME: remove this line when we add edge styles
- gtk_container_set_border_width (GTK_CONTAINER (palette), 6);
- gtk_box_set_spacing (GTK_BOX (palette), 6);
- g_object_ref_sink (palette);
-
- gtk_box_pack_start (GTK_BOX (palette), [editor widget], FALSE, FALSE, 0);
- gtk_widget_show ([editor widget]);
- GtkWidget *selectorFrame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (selectorFrame), [selector widget]);
- gtk_box_pack_start (GTK_BOX (palette), selectorFrame, TRUE, TRUE, 0);
- gtk_widget_show (selectorFrame);
- gtk_widget_show ([selector widget]);
+ gtk_box_set_spacing (GTK_BOX (palette), 6);
+ g_object_ref_sink (palette);
+
+ gtk_box_pack_start (GTK_BOX (palette), [editor widget], FALSE, FALSE, 0);
+ gtk_widget_show ([editor widget]);
+ GtkWidget *selectorFrame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (selectorFrame), [selector widget]);
+ gtk_box_pack_start (GTK_BOX (palette), selectorFrame, TRUE, TRUE, 0);
+ gtk_widget_show (selectorFrame);
+ gtk_widget_show ([selector widget]);
GtkBox *buttonBox = GTK_BOX (gtk_hbox_new(FALSE, 5));
- gtk_box_pack_start (GTK_BOX (palette), GTK_WIDGET (buttonBox), FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (palette), GTK_WIDGET (buttonBox), FALSE, FALSE, 0);
GtkBox *bbox1 = GTK_BOX (gtk_hbox_new(FALSE, 0));
- gtk_box_pack_start (buttonBox, GTK_WIDGET (bbox1), FALSE, FALSE, 0);
+ gtk_box_pack_start (buttonBox, GTK_WIDGET (bbox1), FALSE, FALSE, 0);
GtkWidget *addStyleButton = gtk_button_new ();
gtk_widget_set_tooltip_text (addStyleButton, "Add a new style");
@@ -99,7 +97,7 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
self);
removeStyleButton = gtk_button_new ();
- g_object_ref_sink (removeStyleButton);
+ g_object_ref_sink (removeStyleButton);
gtk_widget_set_tooltip_text (removeStyleButton, "Delete selected style");
GtkWidget *removeIcon = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (removeStyleButton), removeIcon);
@@ -110,10 +108,10 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
self);
GtkBox *bbox2 = GTK_BOX (gtk_hbox_new(FALSE, 0));
- gtk_box_pack_start (buttonBox, GTK_WIDGET (bbox2), FALSE, FALSE, 0);
+ gtk_box_pack_start (buttonBox, GTK_WIDGET (bbox2), FALSE, FALSE, 0);
applyStyleButton = gtk_button_new_with_label ("Apply");
- g_object_ref_sink (applyStyleButton);
+ g_object_ref_sink (applyStyleButton);
gtk_widget_set_tooltip_text (applyStyleButton, "Apply style to selected nodes");
gtk_box_pack_start (bbox2, applyStyleButton, FALSE, FALSE, 5);
g_signal_connect (G_OBJECT (applyStyleButton),
@@ -122,7 +120,7 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
self);
clearStyleButton = gtk_button_new_with_label ("Clear");
- g_object_ref_sink (clearStyleButton);
+ g_object_ref_sink (clearStyleButton);
gtk_widget_set_tooltip_text (clearStyleButton, "Clear style from selected nodes");
gtk_box_pack_start (bbox2, clearStyleButton, FALSE, FALSE, 0);
g_signal_connect (G_OBJECT (clearStyleButton),
@@ -130,14 +128,14 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
G_CALLBACK (clear_style_button_cb),
self);
- gtk_widget_show_all (GTK_WIDGET (buttonBox));
+ gtk_widget_show_all (GTK_WIDGET (buttonBox));
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(selectedStyleChanged:)
name:@"SelectedStyleChanged"
object:selector];
- [self updateButtonState];
+ [self updateButtonState];
}
return self;
@@ -179,10 +177,10 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
[editor release];
[selector release];
[document release];
- g_object_unref (palette);
- g_object_unref (removeStyleButton);
- g_object_unref (applyStyleButton);
- g_object_unref (clearStyleButton);
+ g_object_unref (palette);
+ g_object_unref (removeStyleButton);
+ g_object_unref (applyStyleButton);
+ g_object_unref (clearStyleButton);
[super dealloc];
}
@@ -194,7 +192,7 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
@implementation NodeStylesPalette (Notifications)
- (void) selectedStyleChanged:(NSNotification*)notification {
- [editor setStyle:[selector selectedStyle]];
+ [editor setStyle:[selector selectedStyle]];
[self updateButtonState];
}
@@ -213,7 +211,7 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
gtk_widget_set_sensitive (applyStyleButton, hasNodeSelection && hasStyleSelection);
gtk_widget_set_sensitive (clearStyleButton, hasNodeSelection);
- gtk_widget_set_sensitive (removeStyleButton, hasStyleSelection);
+ gtk_widget_set_sensitive (removeStyleButton, hasStyleSelection);
}
- (void) removeSelectedStyle {
@@ -278,4 +276,4 @@ static void clear_style_button_cb (GtkButton *widget, NodeStylesPalette *palette
// }}}
-// vim:ft=objc:ts=4:noet:sts=4:sw=4:foldmethod=marker
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/PropertyPane.h b/tikzit/src/linux/PropertyPane.h
index 5b6ef1b..30f8e5a 100644
--- a/tikzit/src/linux/PropertyPane.h
+++ b/tikzit/src/linux/PropertyPane.h
@@ -19,8 +19,8 @@
#import <gtk/gtk.h>
#import "Configuration.h"
#import "TikzDocument.h"
-#import "PropertyListEditor.h"
+@class PropertyListEditor;
@class GraphPropertyDelegate;
@class NodePropertyDelegate;
@class EdgePropertyDelegate;
@@ -52,16 +52,14 @@
GtkEntry *edgeNodeLabelEntry;
}
-@property (readonly) GtkWidget *widget;
+@property (readonly) GtkWidget *widget;
+@property (retain) TikzDocument *document;
- (id) init;
-- (TikzDocument*) document;
-- (void) setDocument:(TikzDocument*)doc;
-
- (void) restoreUiStateFromConfig:(Configuration*)file group:(NSString*)group;
- (void) saveUiStateToConfig:(Configuration*)file group:(NSString*)group;
@end
-// vim:ft=objc:ts=8:et:sts=4:sw=4
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/PropertyPane.m b/tikzit/src/linux/PropertyPane.m
index 33ed29d..35910f7 100644
--- a/tikzit/src/linux/PropertyPane.m
+++ b/tikzit/src/linux/PropertyPane.m
@@ -16,6 +16,7 @@
*/
#import "PropertyPane.h"
+#import "PropertyListEditor.h"
#import "GraphElementProperty.h"
#import "gtkhelpers.h"
diff --git a/tikzit/src/linux/StylesPane.h b/tikzit/src/linux/StylesPane.h
new file mode 100644
index 0000000..c1a603d
--- /dev/null
+++ b/tikzit/src/linux/StylesPane.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "TZFoundation.h"
+#import <gtk/gtk.h>
+
+@class Configuration;
+@class EdgeStylesPalette;
+@class NodeStylesPalette;
+@class StyleManager;
+@class TikzDocument;
+
+@interface StylesPane: NSObject {
+ NodeStylesPalette *nodeStyles;
+ EdgeStylesPalette *edgeStyles;
+
+ GtkWidget *stylesPane;
+
+ GtkExpander *nodeStylesExpander;
+ GtkExpander *edgeStylesExpander;
+}
+
+@property (readonly) GtkWidget *widget;
+@property (retain) TikzDocument *document;
+@property (retain) StyleManager *styleManager;
+
+- (id) initWithManager:(StyleManager*)m;
+
+- (void) restoreUiStateFromConfig:(Configuration*)file group:(NSString*)group;
+- (void) saveUiStateToConfig:(Configuration*)file group:(NSString*)group;
+
+@end
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
+
diff --git a/tikzit/src/linux/StylesPane.m b/tikzit/src/linux/StylesPane.m
new file mode 100644
index 0000000..0f6adef
--- /dev/null
+++ b/tikzit/src/linux/StylesPane.m
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "StylesPane.h"
+
+#import "Configuration.h"
+#import "NodeStylesPalette.h"
+#import "EdgeStylesPalette.h"
+
+@interface StylesPane (Private)
+- (void) _addSplitter;
+- (GtkExpander*) _addExpanderWithName:(const gchar*)name contents:(GtkWidget*)contents;
+@end
+
+@implementation StylesPane
+
+@synthesize widget=stylesPane;
+
+- (id) init {
+ [self dealloc];
+ self = nil;
+ return nil;
+}
+
+- (id) initWithManager:(StyleManager*)m {
+ self = [super init];
+
+ if (self) {
+ nodeStyles = [[NodeStylesPalette alloc] initWithManager:m];
+ edgeStyles = [[EdgeStylesPalette alloc] initWithManager:m];
+
+ stylesPane = gtk_vbox_new (FALSE, 0);
+ g_object_ref_sink (stylesPane);
+
+ nodeStylesExpander = [self _addExpanderWithName:"Node styles"
+ contents:[nodeStyles widget]];
+ g_object_ref_sink (nodeStylesExpander);
+ [self _addSplitter];
+
+ edgeStylesExpander = [self _addExpanderWithName:"Edge styles"
+ contents:[edgeStyles widget]];
+ g_object_ref_sink (edgeStylesExpander);
+ [self _addSplitter];
+ }
+
+ return self;
+}
+
+- (void) dealloc {
+ g_object_unref (stylesPane);
+
+ [nodeStyles release];
+ [edgeStyles release];
+
+ [super dealloc];
+}
+
+- (TikzDocument*) document {
+ return [nodeStyles document];
+}
+
+- (void) setDocument:(TikzDocument*)doc {
+ [nodeStyles setDocument:doc];
+ [edgeStyles setDocument:doc];
+}
+
+- (StyleManager*) styleManager {
+ return [nodeStyles styleManager];
+}
+
+- (void) setStyleManager:(StyleManager*)m {
+ [nodeStyles setStyleManager:m];
+ [edgeStyles setStyleManager:m];
+}
+
+- (void) restoreUiStateFromConfig:(Configuration*)file group:(NSString*)group {
+ gtk_expander_set_expanded (nodeStylesExpander,
+ [file booleanEntry:@"node-styles-expanded"
+ inGroup:group
+ withDefault:YES]);
+ gtk_expander_set_expanded (edgeStylesExpander,
+ [file booleanEntry:@"edge-styles-expanded"
+ inGroup:group
+ withDefault:NO]);
+}
+
+- (void) saveUiStateToConfig:(Configuration*)file group:(NSString*)group {
+ [file setBooleanEntry:@"node-styles-expanded"
+ inGroup:group
+ value:gtk_expander_get_expanded (nodeStylesExpander)];
+ [file setBooleanEntry:@"edge-styles-expanded"
+ inGroup:group
+ value:gtk_expander_get_expanded (edgeStylesExpander)];
+}
+
+@end
+
+// }}}
+// {{{ Private
+
+@implementation StylesPane (Private)
+- (void) _addSplitter {
+ GtkWidget *split = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (stylesPane),
+ split,
+ FALSE, // expand
+ FALSE, // fill
+ 0); // padding
+ gtk_widget_show (split);
+}
+
+- (GtkExpander*) _addExpanderWithName:(const gchar*)name contents:(GtkWidget*)contents {
+ GtkWidget *exp = gtk_expander_new (name);
+ gtk_box_pack_start (GTK_BOX (stylesPane),
+ exp,
+ FALSE, // expand
+ TRUE, // fill
+ 0); // padding
+ gtk_widget_show (exp);
+ gtk_container_set_border_width (GTK_CONTAINER (contents), 6);
+ gtk_container_add (GTK_CONTAINER (exp), contents);
+ gtk_widget_show (contents);
+ return GTK_EXPANDER (exp);
+}
+@end
+
+// }}}
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/linux/TikzDocument.h b/tikzit/src/linux/TikzDocument.h
index 5ab5f30..11f754b 100644
--- a/tikzit/src/linux/TikzDocument.h
+++ b/tikzit/src/linux/TikzDocument.h
@@ -35,6 +35,8 @@
NSString *path;
NSSet *nodesetBeingModified;
BasicMapTable *nodesetBeingModifiedOldCopy;
+ NSSet *edgesetBeingModified;
+ BasicMapTable *edgesetBeingModifiedOldCopy;
NSPoint currentNodeShift;
Node *nodeBeingModified;
Node *nodeBeingModifiedOldCopy;
@@ -110,6 +112,11 @@
- (void) endModifyEdge;
- (void) cancelModifyEdge;
+- (void) startModifyEdges:(NSSet*)edges;
+- (void) modifyEdgesCheckPoint;
+- (void) endModifyEdges;
+- (void) cancelModifyEdges;
+
- (void) startChangeBoundingBox;
- (void) changeBoundingBoxCheckPoint;
- (void) endChangeBoundingBox;
diff --git a/tikzit/src/linux/TikzDocument.m b/tikzit/src/linux/TikzDocument.m
index 43001cc..5556654 100644
--- a/tikzit/src/linux/TikzDocument.m
+++ b/tikzit/src/linux/TikzDocument.m
@@ -523,6 +523,40 @@
- (void) endModifyEdge { [self _finishModifyEdgeCancelled:NO]; }
- (void) cancelModifyEdge { [self _finishModifyEdgeCancelled:YES]; }
+- (void) startModifyEdges:(NSSet*)edges {
+ if (edgesetBeingModified != nil) {
+ [NSException raise:@"NSInternalInconsistencyException" format:@"Already modifying an edge set"];
+ }
+
+ edgesetBeingModified = [edges copy];
+ edgesetBeingModifiedOldCopy = [[Graph edgeTableForEdges:edges] retain];
+}
+
+- (void) modifyEdgesCheckPoint {
+ [self regenerateTikz];
+ GraphChange *change = [GraphChange propertyChangeOfEdgesFromOldCopies:edgesetBeingModifiedOldCopy
+ toNewCopies:[Graph edgeTableForEdges:edgesetBeingModified]];
+ [self postIncompleteGraphChange:change];
+}
+
+- (void) _finishModifyEdgesCancelled:(BOOL)cancelled {
+ if (edgesetBeingModified == nil) {
+ [NSException raise:@"NSInternalInconsistencyException" format:@"Not modifying an edge"];
+ }
+
+ GraphChange *change = [GraphChange propertyChangeOfEdgesFromOldCopies:edgesetBeingModifiedOldCopy
+ toNewCopies:[Graph edgeTableForEdges:edgesetBeingModified]];
+ [self _finishModifySequence:change withName:@"Modify edges" cancelled:cancelled];
+
+ [edgesetBeingModified release];
+ edgesetBeingModified = nil;
+ [edgesetBeingModifiedOldCopy release];
+ edgesetBeingModifiedOldCopy = nil;
+}
+
+- (void) endModifyEdges { [self _finishModifyEdgesCancelled:NO]; }
+- (void) cancelModifyEdges { [self _finishModifyEdgesCancelled:YES]; }
+
- (void) startChangeBoundingBox {
oldGraphBounds = [graph boundingBox];
}