summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Merry <alex.merry@cs.ox.ac.uk>2012-04-18 13:45:43 +0100
committerAlex Merry <alex.merry@cs.ox.ac.uk>2012-04-18 13:45:43 +0100
commit2f6a98730f6af18a71b31c72468042f3b5b81915 (patch)
tree63dc3ece2a7ca80be03f5c32add0edc3d9693ce0
parentb9c39efd55a5dd03a52e0ac3da191fed763f53db (diff)
Add edge colours
-rw-r--r--tikzit/NEWS1
-rw-r--r--tikzit/src/Makefile.am1
-rw-r--r--tikzit/src/common/EdgeStyle.h8
-rw-r--r--tikzit/src/common/EdgeStyle.m30
-rw-r--r--tikzit/src/common/NodeStyle.h4
-rw-r--r--tikzit/src/common/Preambles.m11
-rw-r--r--tikzit/src/gtk/Edge+Render.m10
-rw-r--r--tikzit/src/gtk/EdgeStyle+Gtk.h29
-rw-r--r--tikzit/src/gtk/EdgeStyle+Gtk.m33
-rw-r--r--tikzit/src/gtk/EdgeStyle+Storage.m6
-rw-r--r--tikzit/src/gtk/EdgeStyleEditor.h2
-rw-r--r--tikzit/src/gtk/EdgeStyleEditor.m89
-rw-r--r--tikzit/src/gtk/EdgeStyleSelector.m15
13 files changed, 232 insertions, 7 deletions
diff --git a/tikzit/NEWS b/tikzit/NEWS
index ff1de2d..fdac837 100644
--- a/tikzit/NEWS
+++ b/tikzit/NEWS
@@ -11,6 +11,7 @@ tikzit 0.8 (2012-01-??):
* Edges can now have arrow heads and arrow tails
* Nodes and edges have consistent ordering, and this can be
changed with Edge->Arrange
+ * Edges now have colours
tikzit 0.7 (2011-12-06):
* Add bounding box support
diff --git a/tikzit/src/Makefile.am b/tikzit/src/Makefile.am
index 31c7e8e..4a63760 100644
--- a/tikzit/src/Makefile.am
+++ b/tikzit/src/Makefile.am
@@ -23,6 +23,7 @@ tikzit_SOURCES = gtk/CairoRenderContext.m \
gtk/ColorRGB+Gtk.m \
gtk/Configuration.m \
gtk/Edge+Render.m \
+ gtk/EdgeStyle+Gtk.m \
gtk/EdgeStyle+Storage.m \
gtk/EdgeStyleEditor.m \
gtk/EdgeStyleSelector.m \
diff --git a/tikzit/src/common/EdgeStyle.h b/tikzit/src/common/EdgeStyle.h
index 248d8f4..83c3ecd 100644
--- a/tikzit/src/common/EdgeStyle.h
+++ b/tikzit/src/common/EdgeStyle.h
@@ -23,6 +23,7 @@
#import <Foundation/Foundation.h>
#import "PropertyHolder.h"
+#import "ColorRGB.h"
typedef enum {
AH_None = 0,
@@ -40,10 +41,17 @@ typedef enum {
ArrowHeadStyle headStyle, tailStyle;
EdgeDectorationStyle decorationStyle;
float thickness;
+ ColorRGB *colorRGB;
NSString *name;
NSString *category;
}
+/*!
+ @property colorRGB
+ @brief The color to render the line in
+ */
+@property (copy) ColorRGB *colorRGB;
+
@property (copy) NSString *name;
@property (copy) NSString *category;
@property (assign) ArrowHeadStyle headStyle;
diff --git a/tikzit/src/common/EdgeStyle.m b/tikzit/src/common/EdgeStyle.m
index da669e3..88b1f54 100644
--- a/tikzit/src/common/EdgeStyle.m
+++ b/tikzit/src/common/EdgeStyle.m
@@ -31,9 +31,16 @@
@"headStyle",
@"decorationStyle",
@"thickness",
+ @"colorRGB.red",
+ @"colorRGB.blue",
+ @"colorRGB.green",
@"name",
nil]
triggerChangeNotificationsForDependentKey:@"tikz"];
+ [self setKeys:[NSArray arrayWithObjects:
+ @"colorRGB.name",
+ nil]
+ triggerChangeNotificationsForDependentKey:@"colorIsKnown"];
}
- (id)initWithName:(NSString*)nm {
@@ -43,6 +50,7 @@
headStyle = AH_None;
tailStyle = AH_None;
decorationStyle = ED_None;
+ colorRGB = [[ColorRGB alloc] initWithRed:0 green:0 blue:0];
name = nm;
category = nil;
thickness = 1.0f;
@@ -64,12 +72,14 @@
[style setTailStyle:[self tailStyle]];
[style setDecorationStyle:[self decorationStyle]];
[style setThickness:[self thickness]];
+ [style setColorRGB:[self colorRGB]];
return style;
}
- (void)dealloc {
[name release];
[category release];
+ [colorRGB release];
[super dealloc];
}
@@ -127,9 +137,26 @@
}
}
+- (ColorRGB*)colorRGB {
+ return colorRGB;
+}
+
+- (void)setColorRGB:(ColorRGB*)c {
+ if (colorRGB != c) {
+ ColorRGB *oldValue = colorRGB;
+ colorRGB = [c copy];
+ [self postPropertyChanged:@"colorRGB" oldValue:oldValue];
+ [oldValue release];
+ }
+}
+
- (NSString*)tikz {
NSMutableString *buf = [NSMutableString stringWithFormat:@"\\tikzstyle{%@}=[", name];
+ NSString *colorName = [colorRGB name];
+ if (colorName == nil)
+ colorName = [colorRGB hexName];
+
if (tailStyle == AH_Plain)
[buf appendString:@"<"];
else if (tailStyle == AH_Latex)
@@ -142,6 +169,9 @@
else if (headStyle == AH_Latex)
[buf appendString:@"latex"];
+ [buf appendString:@",draw="];
+ [buf appendString:colorName];
+
if (decorationStyle != ED_None) {
[buf appendString:@",postaction={decorate},decoration={markings,mark="];
if (decorationStyle == ED_Arrow)
diff --git a/tikzit/src/common/NodeStyle.h b/tikzit/src/common/NodeStyle.h
index a78abaa..68aafad 100644
--- a/tikzit/src/common/NodeStyle.h
+++ b/tikzit/src/common/NodeStyle.h
@@ -59,13 +59,13 @@
/*!
@property strokeColorRGB
- @brief Stroke color.
+ @brief The stroke color used to render the node
*/
@property (copy) ColorRGB *strokeColorRGB;
/*!
@property fillColorRGB
- @brief Fill color.
+ @brief The fill color used to render the node
*/
@property (copy) ColorRGB *fillColorRGB;
diff --git a/tikzit/src/common/Preambles.m b/tikzit/src/common/Preambles.m
index d41f9b0..e107d5e 100644
--- a/tikzit/src/common/Preambles.m
+++ b/tikzit/src/common/Preambles.m
@@ -23,6 +23,7 @@
#import "Preambles.h"
#import "NodeStyle.h"
+#import "EdgeStyle.h"
static NSString *PREAMBLE_HEAD =
@"\\documentclass{article}\n"
@@ -112,15 +113,21 @@ static NSString *POSTAMBLE =
[fill hexName], [fill redFloat], [fill greenFloat], [fill blueFloat]];
}
- if ([fill name] == nil && ![colors containsObject:fill]) {
+ if ([stroke name] == nil && ![colors containsObject:stroke]) {
[colors addObject:stroke];
[colbuf appendFormat:@"\\definecolor{%@}{rgb}{%.3f,%.3f,%.3f}\n",
- [fill hexName], [fill redFloat], [fill greenFloat], [fill blueFloat]];
+ [stroke hexName], [stroke redFloat], [stroke greenFloat], [stroke blueFloat]];
}
}
[buf appendString:@"\n"];
for (EdgeStyle *st in [styleManager edgeStyles]) {
[buf appendFormat:@"%@\n", [st tikz]];
+ ColorRGB *color = [st colorRGB];
+ if ([color name] == nil && ![colors containsObject:color]) {
+ [colors addObject:color];
+ [colbuf appendFormat:@"\\definecolor{%@}{rgb}{%.3f,%.3f,%.3f}\n",
+ [color hexName], [color redFloat], [color greenFloat], [color blueFloat]];
+ }
}
NSString *defs = [[NSString alloc] initWithFormat:@"%@\n%@", colbuf, buf];
diff --git a/tikzit/src/gtk/Edge+Render.m b/tikzit/src/gtk/Edge+Render.m
index 61a78d7..d69a9ad 100644
--- a/tikzit/src/gtk/Edge+Render.m
+++ b/tikzit/src/gtk/Edge+Render.m
@@ -195,13 +195,21 @@ static const float cpLineWidth = 1.0;
}
}
+- (RColor) color {
+ if (style) {
+ return [[style colorRGB] rColor];
+ } else {
+ return WhiteRColor;
+ }
+}
+
- (void) renderBasicEdgeInContext:(id<RenderContext>)context withTransformer:(Transformer*)t selected:(BOOL)selected {
[self updateControls];
[context saveState];
const CGFloat lineWidth = style ? [style thickness] : edgeWidth;
[context setLineWidth:lineWidth];
- RColor color = BlackRColor;
+ RColor color = [self color];
if (selected) {
color.alpha = 0.5;
}
diff --git a/tikzit/src/gtk/EdgeStyle+Gtk.h b/tikzit/src/gtk/EdgeStyle+Gtk.h
new file mode 100644
index 0000000..4323593
--- /dev/null
+++ b/tikzit/src/gtk/EdgeStyle+Gtk.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2011 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 "EdgeStyle.h"
+#import <gtk/gtk.h>
+
+@interface EdgeStyle (Gtk)
+
+- (GdkColor) color;
+- (void) setColor:(GdkColor)color;
+
+@end
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4
diff --git a/tikzit/src/gtk/EdgeStyle+Gtk.m b/tikzit/src/gtk/EdgeStyle+Gtk.m
new file mode 100644
index 0000000..886329e
--- /dev/null
+++ b/tikzit/src/gtk/EdgeStyle+Gtk.m
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 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 "EdgeStyle+Gtk.h"
+#import "ColorRGB+Gtk.h"
+
+@implementation EdgeStyle (Gtk)
+
+- (GdkColor) color {
+ return [[self colorRGB] gdkColor];
+}
+
+- (void) setColor:(GdkColor)color {
+ [self setColorRGB:[ColorRGB colorWithGdkColor:color]];
+}
+
+@end
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4
diff --git a/tikzit/src/gtk/EdgeStyle+Storage.m b/tikzit/src/gtk/EdgeStyle+Storage.m
index 0904e1c..45e2a20 100644
--- a/tikzit/src/gtk/EdgeStyle+Storage.m
+++ b/tikzit/src/gtk/EdgeStyle+Storage.m
@@ -30,6 +30,11 @@
tailStyle = [configFile integerEntry:@"TailStyle" inGroup:groupName withDefault:tailStyle];
decorationStyle = [configFile integerEntry:@"DecorationStyle" inGroup:groupName withDefault:decorationStyle];
thickness = [configFile doubleEntry:@"Thickness" inGroup:groupName withDefault:thickness];
+ [self setColorRGB:
+ [ColorRGB colorFromValueList:
+ [configFile integerListEntry:@"Color"
+ inGroup:groupName
+ withDefault:[colorRGB valueList]]]];
}
return self;
@@ -42,6 +47,7 @@
[configFile setIntegerEntry:@"TailStyle" inGroup:groupName value:tailStyle];
[configFile setIntegerEntry:@"DecorationStyle" inGroup:groupName value:decorationStyle];
[configFile setDoubleEntry:@"Thickness" inGroup:groupName value:thickness];
+ [configFile setIntegerListEntry:@"Color" inGroup:groupName value:[[self colorRGB] valueList]];
}
@end
diff --git a/tikzit/src/gtk/EdgeStyleEditor.h b/tikzit/src/gtk/EdgeStyleEditor.h
index 6e55592..3d7d839 100644
--- a/tikzit/src/gtk/EdgeStyleEditor.h
+++ b/tikzit/src/gtk/EdgeStyleEditor.h
@@ -27,6 +27,8 @@
GtkComboBox *decorationCombo;
GtkComboBox *headArrowCombo;
GtkComboBox *tailArrowCombo;
+ GtkColorButton *colorButton;
+ GtkWidget *makeColorTexSafeButton;
GtkAdjustment *thicknessAdj;
BOOL blockSignals;
}
diff --git a/tikzit/src/gtk/EdgeStyleEditor.m b/tikzit/src/gtk/EdgeStyleEditor.m
index 0474259..32fa51e 100644
--- a/tikzit/src/gtk/EdgeStyleEditor.m
+++ b/tikzit/src/gtk/EdgeStyleEditor.m
@@ -18,6 +18,7 @@
#import "EdgeStyleEditor.h"
#import "EdgeStyle.h"
+#import "EdgeStyle+Gtk.h"
#import "Shape.h"
#include <gdk-pixbuf/gdk-pixdata.h>
@@ -59,7 +60,7 @@ static struct dec_info ah_tail_entries[] = {
};
static guint n_ah_tail_entries = G_N_ELEMENTS (ah_tail_entries);
-static const guint row_count = 5;
+static const guint row_count = 6;
// }}}
// {{{ Internal interfaces
@@ -69,6 +70,8 @@ static void decoration_combo_changed_cb (GtkComboBox *widget, EdgeStyleEditor *e
static void head_arrow_combo_changed_cb (GtkComboBox *widget, EdgeStyleEditor *editor);
static void tail_arrow_combo_changed_cb (GtkComboBox *widget, EdgeStyleEditor *editor);
static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEditor *editor);
+static void color_changed_cb (GtkColorButton *widget, EdgeStyleEditor *editor);
+static void make_color_safe_button_clicked_cb (GtkButton *widget, EdgeStyleEditor *editor);
// }}}
// {{{ Notifications
@@ -78,6 +81,8 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
- (void) headArrowChangedTo:(ArrowHeadStyle)value;
- (void) tailArrowChangedTo:(ArrowHeadStyle)value;
- (void) thicknessChangedTo:(double)value;
+- (void) makeColorTexSafe;
+- (void) colorChangedTo:(GdkColor)value;
@end
// }}}
@@ -134,6 +139,16 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
return combo;
}
+- (GtkWidget*) _createMakeColorTexSafeButton {
+ 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 = @"The colour is not a predefined TeX colour.\nClick here to choose the nearest TeX-safe colour.";
+ gtk_widget_set_tooltip_text (b, [ttip UTF8String]);
+ return b;
+}
+
- (id) init {
self = [super init];
@@ -199,6 +214,32 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
/**
+ * Colour
+ */
+ GtkWidget *colorBox = gtk_hbox_new (FALSE, 0);
+ [self _addWidget:colorBox
+ withLabel:"Colour"
+ atRow:4];
+ colorButton = GTK_COLOR_BUTTON (gtk_color_button_new ());
+ g_object_ref_sink (colorButton);
+ gtk_widget_show (GTK_WIDGET (colorButton));
+ gtk_box_pack_start (GTK_BOX (colorBox), GTK_WIDGET (colorButton),
+ FALSE, FALSE, 0);
+ makeColorTexSafeButton = [self _createMakeColorTexSafeButton];
+ g_object_ref_sink (makeColorTexSafeButton);
+ gtk_box_pack_start (GTK_BOX (colorBox), makeColorTexSafeButton,
+ FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (colorButton),
+ "color-set",
+ G_CALLBACK (color_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (makeColorTexSafeButton),
+ "clicked",
+ G_CALLBACK (make_color_safe_button_clicked_cb),
+ self);
+
+
+ /**
* Thickness
*/
thicknessAdj = GTK_ADJUSTMENT (gtk_adjustment_new (
@@ -212,7 +253,7 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
GtkWidget *scaleSpin = gtk_spin_button_new (thicknessAdj, 0.0, 2);
[self _addWidget:scaleSpin
withLabel:"Thickness"
- atRow:4];
+ atRow:5];
g_signal_connect (G_OBJECT (thicknessAdj),
"value-changed",
G_CALLBACK (thickness_adjustment_changed_cb),
@@ -227,6 +268,8 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
g_object_unref (nameEdit);
g_object_unref (decorationCombo);
+ g_object_unref (colorButton);
+ g_object_unref (makeColorTexSafeButton);
g_object_unref (thicknessAdj);
g_object_unref (table);
[style release];
@@ -252,12 +295,17 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
[self setDecCombo:headArrowCombo toValue:[style headStyle]];
[self setDecCombo:tailArrowCombo toValue:[style tailStyle]];
+ GdkColor c = [style color];
+ gtk_color_button_set_color(colorButton, &c);
+ gtk_widget_set_visible (makeColorTexSafeButton, ([[style colorRGB] name] == nil));
+
gtk_adjustment_set_value(thicknessAdj, [style thickness]);
} else {
gtk_entry_set_text(nameEdit, "");
[self clearDecCombo:decorationCombo];
[self clearDecCombo:headArrowCombo];
[self clearDecCombo:tailArrowCombo];
+ gtk_widget_set_visible (makeColorTexSafeButton, FALSE);
gtk_adjustment_set_value(thicknessAdj, 1.0);
gtk_widget_set_sensitive (GTK_WIDGET (table), FALSE);
}
@@ -295,6 +343,21 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi
- (void) thicknessChangedTo:(double)value {
[style setThickness:(float)value];
}
+
+- (void) colorChangedTo:(GdkColor)value {
+ [style setColor:value];
+ gtk_widget_set_visible (makeColorTexSafeButton,
+ [[style colorRGB] name] == nil);
+}
+
+- (void) makeColorTexSafe {
+ if (style != nil) {
+ [[style colorRGB] setToClosestHashed];
+ GdkColor color = [style color];
+ gtk_color_button_set_color(colorButton, &color);
+ gtk_widget_set_visible (makeColorTexSafeButton, FALSE);
+ }
+}
@end
// }}}
@@ -404,6 +467,28 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *adj, EdgeStyleEditor
[pool drain];
}
+static void color_changed_cb (GtkColorButton *widget, EdgeStyleEditor *editor) {
+ if ([editor signalsBlocked])
+ return;
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ GdkColor color;
+ gtk_color_button_get_color (widget, &color);
+ [editor colorChangedTo:color];
+
+ [pool drain];
+}
+
+static void make_color_safe_button_clicked_cb (GtkButton *widget, EdgeStyleEditor *editor) {
+ if ([editor signalsBlocked])
+ return;
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [editor makeColorTexSafe];
+ [pool drain];
+}
+
// }}}
// vim:ft=objc:ts=4:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/gtk/EdgeStyleSelector.m b/tikzit/src/gtk/EdgeStyleSelector.m
index b6139b8..544ed98 100644
--- a/tikzit/src/gtk/EdgeStyleSelector.m
+++ b/tikzit/src/gtk/EdgeStyleSelector.m
@@ -446,6 +446,18 @@ enum {
forKeyPath:@"decorationStyle"
options:0
context:NULL];
+ [style addObserver:self
+ forKeyPath:@"colorRGB.red"
+ options:0
+ context:NULL];
+ [style addObserver:self
+ forKeyPath:@"colorRGB.green"
+ options:0
+ context:NULL];
+ [style addObserver:self
+ forKeyPath:@"colorRGB.blue"
+ options:0
+ context:NULL];
}
- (void) stopObservingStyle:(EdgeStyle*)style {
@@ -454,6 +466,9 @@ enum {
[style removeObserver:self forKeyPath:@"headStyle"];
[style removeObserver:self forKeyPath:@"tailStyle"];
[style removeObserver:self forKeyPath:@"decorationStyle"];
+ [style removeObserver:self forKeyPath:@"colorRGB.red"];
+ [style removeObserver:self forKeyPath:@"colorRGB.green"];
+ [style removeObserver:self forKeyPath:@"colorRGB.blue"];
}
- (void) reloadStyles {