From 2f6a98730f6af18a71b31c72468042f3b5b81915 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Wed, 18 Apr 2012 13:45:43 +0100 Subject: Add edge colours --- tikzit/src/Makefile.am | 1 + tikzit/src/common/EdgeStyle.h | 8 ++++ tikzit/src/common/EdgeStyle.m | 30 +++++++++++++ tikzit/src/common/NodeStyle.h | 4 +- tikzit/src/common/Preambles.m | 11 ++++- tikzit/src/gtk/Edge+Render.m | 10 ++++- tikzit/src/gtk/EdgeStyle+Gtk.h | 29 +++++++++++++ tikzit/src/gtk/EdgeStyle+Gtk.m | 33 ++++++++++++++ tikzit/src/gtk/EdgeStyle+Storage.m | 6 +++ tikzit/src/gtk/EdgeStyleEditor.h | 2 + tikzit/src/gtk/EdgeStyleEditor.m | 89 +++++++++++++++++++++++++++++++++++++- tikzit/src/gtk/EdgeStyleSelector.m | 15 +++++++ 12 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 tikzit/src/gtk/EdgeStyle+Gtk.h create mode 100644 tikzit/src/gtk/EdgeStyle+Gtk.m (limited to 'tikzit/src') 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 #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)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 + * + * 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 . + */ + +#import "TZFoundation.h" +#import "EdgeStyle.h" +#import + +@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 + * + * 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 . + */ + +#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 @@ -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]; @@ -198,6 +213,32 @@ static void thickness_adjustment_changed_cb (GtkAdjustment *widget, EdgeStyleEdi self); + /** + * 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 */ @@ -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 { -- cgit v1.2.3