diff options
Diffstat (limited to 'tikzit/src/gtk/PreviewWindow.m')
-rw-r--r-- | tikzit/src/gtk/PreviewWindow.m | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/tikzit/src/gtk/PreviewWindow.m b/tikzit/src/gtk/PreviewWindow.m new file mode 100644 index 0000000..418886e --- /dev/null +++ b/tikzit/src/gtk/PreviewWindow.m @@ -0,0 +1,191 @@ +/* + * 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 "PreviewWindow.h" + +#import "Preambles.h" +#import "PreviewRenderer.h" +#import "TikzDocument.h" +#import "WidgetSurface.h" + +#import "gtkhelpers.h" + +@interface PreviewWindow (Private) +- (BOOL) updateOrShowError; +@end + +// {{{ API +@implementation PreviewWindow + +- (id) init { + [self release]; + self = nil; + return nil; +} + +- (id) initWithPreambles:(Preambles*)p config:(Configuration*)c { + self = [super init]; + + if (self) { + parent = NULL; + previewer = [[PreviewRenderer alloc] initWithPreambles:p config:c]; + + window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL)); + gtk_window_set_title (window, "Preview"); + gtk_window_set_resizable (window, FALSE); + g_signal_connect (G_OBJECT (window), + "delete-event", + G_CALLBACK (gtk_widget_hide_on_delete), + NULL); + + GtkWidget *pdfArea = gtk_drawing_area_new (); + gtk_container_add (GTK_CONTAINER (window), pdfArea); + gtk_widget_set_size_request (pdfArea, 150.0, 150.0); + gtk_widget_show (pdfArea); + surface = [[WidgetSurface alloc] initWithWidget:pdfArea]; + [surface setRenderDelegate:previewer]; + Transformer *t = [surface transformer]; + [t setFlippedAboutXAxis:![t isFlippedAboutXAxis]]; + } + + return self; +} + +- (void) setParentWindow:(GtkWindow*)p { + parent = p; + gtk_window_set_transient_for (window, p); + if (p != NULL) { + gtk_window_set_position (window, GTK_WIN_POS_CENTER_ON_PARENT); + } +} + +- (TikzDocument*) document { + return [previewer document]; +} + +- (void) setDocument:(TikzDocument*)doc { + [previewer setDocument:doc]; +} + +- (void) updateSize { + double width = 150; + double height = 150; + if ([previewer isValid]) { + double pWidth = [previewer width]; + double pHeight = [previewer height]; + width = (width < pWidth + 4) ? pWidth + 4 : width; + height = (height < pHeight + 4) ? pHeight + 4 : height; + NSPoint offset; + offset.x = (width-pWidth)/2.0; + offset.y = (height-pHeight)/2.0; + [[surface transformer] setOrigin:offset]; + } + [surface setSizeRequestWidth:width height:height]; +} + +- (BOOL) update { + if ([self updateOrShowError]) { + [self updateSize]; + [surface invalidate]; + return YES; + } + + return NO; +} + +- (void) show { + if ([self updateOrShowError]) { + [self updateSize]; + gtk_widget_show (GTK_WIDGET (window)); + [surface invalidate]; + } +} + +- (void) hide { + gtk_widget_hide (GTK_WIDGET (window)); +} + +- (BOOL) isVisible { + gboolean visible; + g_object_get (G_OBJECT (window), "visible", &visible, NULL); + return visible ? YES : NO; +} + +- (void) setVisible:(BOOL)visible { + if (visible) { + [self show]; + } else { + [self hide]; + } +} + +- (void) dealloc { + [previewer release]; + [surface release]; + gtk_widget_destroy (GTK_WIDGET (window)); + + [super dealloc]; +} + +@end +// }}} + +@implementation PreviewWindow (Private) +- (BOOL) updateOrShowError { + NSError *error = nil; + if (![previewer updateWithError:&error]) { + GtkWindow *dparent = gtk_widget_get_visible (GTK_WIDGET (window)) + ? window + : parent; + GtkWidget *dialog = gtk_message_dialog_new (dparent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Failed to generate the preview: %s", + [[error localizedDescription] UTF8String]); +#if GTK_CHECK_VERSION(2,22,0) + if ([error code] == TZ_ERR_TOOL_FAILED) { + GtkBox *box = GTK_BOX (gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog))); + GtkWidget *label = gtk_label_new ("pdflatex said:"); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5f); + gtk_widget_show (label); + gtk_box_pack_start (box, label, FALSE, TRUE, 0); + + GtkWidget *view = gtk_text_view_new (); + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + gtk_text_buffer_set_text (buffer, [[error toolOutput] UTF8String], -1); + gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); + gtk_widget_show (view); + GtkWidget *scrolledView = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledView), + GTK_POLICY_NEVER, // horiz + GTK_POLICY_ALWAYS); // vert + gtk_widget_set_size_request (scrolledView, -1, 120); + gtk_container_add (GTK_CONTAINER (scrolledView), view); + gtk_widget_show (scrolledView); + gtk_box_pack_start (box, scrolledView, TRUE, TRUE, 0); + } +#endif // GTK+ 2.22.0 + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return NO; + } + return YES; +} +@end + +// vim:ft=objc:ts=8:et:sts=4:sw=4 |