summaryrefslogtreecommitdiff
path: root/frontends/cocoa/TreeView.m
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/cocoa/TreeView.m')
-rw-r--r--frontends/cocoa/TreeView.m247
1 files changed, 247 insertions, 0 deletions
diff --git a/frontends/cocoa/TreeView.m b/frontends/cocoa/TreeView.m
new file mode 100644
index 000000000..8fe3767fb
--- /dev/null
+++ b/frontends/cocoa/TreeView.m
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2011 Sven Weidauer <sven.weidauer@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf 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; version 2 of the License.
+ *
+ * NetSurf 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 "cocoa/TreeView.h"
+#import "cocoa/Tree.h"
+
+#import "utils/errors.h"
+
+#import "netsurf/plotters.h"
+#import "netsurf/keypress.h"
+#import "Tree.h"
+
+@interface TreeView () <TreeDelegate>
+
+@property (nonatomic) BOOL isDragging;
+@property (nonatomic) CGPoint dragStart;
+
+@end
+
+@implementation TreeView
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ [self.tree drawRect:dirtyRect inView:self];
+}
+
+- (BOOL)isFlipped
+{
+ return YES;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
+- (void)setTree:(Tree *)newTree
+{
+ if (_tree != newTree) {
+ _tree.redrawing = NO;
+ _tree.delegate = nil;
+
+ _tree = newTree;
+ _tree.delegate = self;
+ _tree.redrawing = YES;
+
+ [self setNeedsDisplay:YES];
+ }
+}
+
+//MARK: -
+//MARK: Event handlers
+
+- (void)mouseDown:(NSEvent *)event
+{
+ self.isDragging = NO;
+ self.dragStart = [self convertPoint:[event locationInWindow] fromView:nil];
+ [self.tree mouseAction:BROWSER_MOUSE_PRESS_1 atPoint:self.dragStart];
+}
+
+#define squared(x) ((x) * (x))
+#define MinDragDistance (5.0)
+
+- (void)mouseDragged:(NSEvent *)event
+{
+ const NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
+
+ if (!self.isDragging) {
+ const CGFloat distance = squared(self.dragStart.x - point.x) + squared(self.dragStart.y - point.y);
+ if (distance >= squared(MinDragDistance)) {
+ self.isDragging = YES;
+ }
+ }
+}
+
+- (void)mouseUp:(NSEvent *)event
+{
+ const NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
+
+ browser_mouse_state modifierFlags = 0;
+
+ if (self.isDragging) {
+ self.isDragging = NO;
+ [self.tree mouseDragEnd:modifierFlags fromPoint:self.dragStart toPoint:point];
+ } else {
+ modifierFlags |= BROWSER_MOUSE_CLICK_1;
+ if ([event clickCount] == 2) {
+ modifierFlags |= BROWSER_MOUSE_DOUBLE_CLICK;
+ }
+ [self.tree mouseAction:modifierFlags atPoint:point];
+ }
+}
+
+//MARK: Keyboard events
+
+- (void)keyDown:(NSEvent *)theEvent
+{
+ [self interpretKeyEvents:@[ theEvent ]];
+}
+
+- (void)insertText:(id)string
+{
+ for (NSUInteger i = 0, length = [string length]; i < length; i++) {
+ unichar ch = [string characterAtIndex:i];
+ [self.tree keyPress:ch];
+ }
+}
+
+- (void)moveLeft:(id)sender
+{
+ [self.tree keyPress:NS_KEY_LEFT];
+}
+
+- (void)moveRight:(id)sender
+{
+ [self.tree keyPress:NS_KEY_RIGHT];
+}
+
+- (void)moveUp:(id)sender
+{
+ [self.tree keyPress:NS_KEY_UP];
+}
+
+- (void)moveDown:(id)sender
+{
+ [self.tree keyPress:NS_KEY_DOWN];
+}
+
+- (void)deleteBackward:(id)sender
+{
+ [self.tree keyPress:NS_KEY_DELETE_LEFT];
+}
+
+- (void)deleteForward:(id)sender
+{
+ [self.tree keyPress:NS_KEY_DELETE_RIGHT];
+}
+
+- (void)cancelOperation:(id)sender
+{
+ [self.tree keyPress:NS_KEY_ESCAPE];
+}
+
+- (void)scrollPageUp:(id)sender
+{
+ [self.tree keyPress:NS_KEY_PAGE_UP];
+}
+
+- (void)scrollPageDown:(id)sender
+{
+ [self.tree keyPress:NS_KEY_PAGE_DOWN];
+}
+
+- (void)insertTab:(id)sender
+{
+ [self.tree keyPress:NS_KEY_TAB];
+}
+
+- (void)insertBacktab:(id)sender
+{
+ [self.tree keyPress:NS_KEY_SHIFT_TAB];
+}
+
+- (void)moveToBeginningOfLine:(id)sender
+{
+ [self.tree keyPress:NS_KEY_LINE_START];
+}
+
+- (void)moveToEndOfLine:(id)sender
+{
+ [self.tree keyPress:NS_KEY_LINE_END];
+}
+
+- (void)moveToBeginningOfDocument:(id)sender
+{
+ [self.tree keyPress:NS_KEY_TEXT_START];
+}
+
+- (void)moveToEndOfDocument:(id)sender
+{
+ [self.tree keyPress:NS_KEY_TEXT_END];
+}
+
+- (void)insertNewline:(id)sender
+{
+ [self.tree keyPress:NS_KEY_NL];
+}
+
+- (void)selectAll:(id)sender
+{
+ [self.tree keyPress:NS_KEY_SELECT_ALL];
+}
+
+- (void)copy:(id)sender
+{
+ [self.tree keyPress:NS_KEY_COPY_SELECTION];
+}
+
+- (void)cut:(id)sender
+{
+ [self.tree keyPress:NS_KEY_CUT_SELECTION];
+}
+
+- (void)paste:(id)sender
+{
+ [self.tree keyPress:NS_KEY_PASTE];
+}
+
+//MARK: -
+//MARK: Tree delegate methods
+
+- (void)tree:(Tree *)t requestedRedrawInRect:(NSRect)rect
+{
+ [self setNeedsDisplayInRect:rect];
+}
+
+- (void)tree:(Tree *)t resized:(NSSize)size
+{
+ self.minimumSize = size;
+}
+
+- (void)tree:(Tree *)t scrollPoint:(NSPoint)point
+{
+ [self scrollPoint:point];
+}
+
+- (NSSize)treeWindowSize:(Tree *)t
+{
+ return self.frame.size;
+}
+
+@end