]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/ui/backend/cocoa/views/views.factor
use radix literals
[factor.git] / basis / ui / backend / cocoa / views / views.factor
index 9fb83e48659d77c74f69587237da2c90b82bf89b..38dd21c10d4294d33ec85197cb076dd0ce74ac87 100644 (file)
@@ -1,15 +1,18 @@
-! Copyright (C) 2006, 2008 Slava Pestov
+! Copyright (C) 2006, 2010 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien alien.c-types arrays assocs cocoa kernel math
-cocoa.messages cocoa.subclassing cocoa.classes cocoa.views
-cocoa.application cocoa.pasteboard cocoa.types cocoa.windows sequences
-ui ui.private ui.gadgets ui.gadgets.private ui.gadgets.worlds
-ui.gestures core-foundation.strings core-graphics core-graphics.types
+USING: accessors alien alien.c-types alien.data alien.strings
+arrays assocs cocoa kernel math cocoa.messages cocoa.subclassing
+cocoa.classes cocoa.views cocoa.application cocoa.pasteboard
+cocoa.runtime cocoa.types cocoa.windows sequences
+io.encodings.utf8 locals ui ui.private ui.gadgets
+ui.gadgets.private ui.gadgets.worlds ui.gestures
+core-foundation.strings core-graphics core-graphics.types
 threads combinators math.rectangles ;
 IN: ui.backend.cocoa.views
 
 : send-mouse-moved ( view event -- )
-    [ mouse-location ] [ drop window ] 2bi move-hand fire-motion yield ;
+    [ mouse-location ] [ drop window ] 2bi
+    dup [ move-hand fire-motion yield ] [ 2drop ] if ;
 
 : button ( event -- n )
     #! Cocoa -> Factor UI button mapping
@@ -17,10 +20,10 @@ IN: ui.backend.cocoa.views
 
 CONSTANT: modifiers
     {
-        { S+ HEX: 20000 }
-        { C+ HEX: 40000 }
-        { A+ HEX: 100000 }
-        { M+ HEX: 80000 }
+        { S+ 0x20000 }
+        { C+ 0x40000 }
+        { A+ 0x100000 }
+        { M+ 0x80000 }
     }
 
 CONSTANT: key-codes
@@ -61,7 +64,7 @@ CONSTANT: key-codes
     [ event-modifiers ] [ key-code ] bi ;
 
 : send-key-event ( view gesture -- )
-    swap window propagate-key-gesture ;
+    swap window dup [ propagate-key-gesture ] [ 2drop ] if ;
 
 : interpret-key-event ( view event -- )
     NSArray swap -> arrayWithObject: -> interpretKeyEvents: ;
@@ -81,22 +84,25 @@ CONSTANT: key-codes
     [ nip mouse-event>gesture <button-down> ]
     [ mouse-location ]
     [ drop window ]
-    2tri send-button-down ;
+    2tri
+    dup [ send-button-down ] [ 3drop ] if ;
 
 : send-button-up$ ( view event -- )
     [ nip mouse-event>gesture <button-up> ]
     [ mouse-location ]
     [ drop window ]
-    2tri send-button-up ;
+    2tri
+    dup [ send-button-up ] [ 3drop ] if ;
 
-: send-wheel$ ( view event -- )
-    [ nip [ -> deltaX ] [ -> deltaY ] bi [ sgn neg ] bi@ 2array ]
+: send-scroll$ ( view event -- )
+    [ nip [ -> deltaX ] [ -> deltaY ] bi [ neg ] bi@ 2array ]
     [ mouse-location ]
     [ drop window ]
-    2tri send-wheel ;
+    2tri
+    dup [ send-scroll ] [ 3drop ] if ;
 
-: send-action$ ( view event gesture -- junk )
-    [ drop window ] dip send-action f ;
+: send-action$ ( view event gesture -- )
+    [ drop window ] dip over [ send-action ] [ 2drop ] if ;
 
 : add-resize-observer ( observer object -- )
     [
@@ -121,146 +127,109 @@ CONSTANT: key-codes
     [ drop dim>> first2 ]
     2bi <CGRect> ;
 
-CLASS: {
-    { +superclass+ "NSOpenGLView" }
-    { +name+ "FactorView" }
-    { +protocols+ { "NSTextInput" } }
+CONSTANT: selector>action H{
+    { "undo:" undo-action }
+    { "redo:" redo-action }
+    { "cut:" cut-action }
+    { "copy:" copy-action }
+    { "paste:" paste-action }
+    { "delete:" delete-action }
+    { "selectAll:" select-all-action }
+    { "newDocument:" new-action }
+    { "openDocument:" open-action }
+    { "saveDocument:" save-action }
+    { "saveDocumentAs:" save-as-action }
+    { "revertDocumentToSaved:" revert-action }
 }
 
-! Rendering
-{ "drawRect:" "void" { "id" "SEL" "NSRect" }
-    [ 2drop window relayout-1 ]
-}
+: validate-action ( world selector -- ? validated? )
+    selector>action at
+    [ swap world-focus parents-handle-gesture? t ] [ drop f f ] if* ;
 
-! Events
-{ "acceptsFirstMouse:" "char" { "id" "SEL" "id" }
-    [ 3drop 1 ]
-}
+CLASS: FactorView < NSOpenGLView NSTextInput
+[
+    ! Rendering
+    METHOD: void drawRect: NSRect rect [ self window [ draw-world ] when* ]
 
-{ "mouseEntered:" "void" { "id" "SEL" "id" }
-    [ nip send-mouse-moved ]
-}
+    ! Events
+    METHOD: char acceptsFirstMouse: id event [ 0 ]
 
-{ "mouseExited:" "void" { "id" "SEL" "id" }
-    [ 3drop forget-rollover ]
-}
+    METHOD: void mouseEntered: id event [ self event send-mouse-moved ]
 
-{ "mouseMoved:" "void" { "id" "SEL" "id" }
-    [ nip send-mouse-moved ]
-}
+    METHOD: void mouseExited: id event [ forget-rollover ]
 
-{ "mouseDragged:" "void" { "id" "SEL" "id" }
-    [ nip send-mouse-moved ]
-}
+    METHOD: void mouseMoved: id event [ self event send-mouse-moved ]
 
-{ "rightMouseDragged:" "void" { "id" "SEL" "id" }
-    [ nip send-mouse-moved ]
-}
+    METHOD: void mouseDragged: id event [ self event send-mouse-moved ]
 
-{ "otherMouseDragged:" "void" { "id" "SEL" "id" }
-    [ nip send-mouse-moved ]
-}
+    METHOD: void rightMouseDragged: id event [ self event send-mouse-moved ]
 
-{ "mouseDown:" "void" { "id" "SEL" "id" }
-    [ nip send-button-down$ ]
-}
+    METHOD: void otherMouseDragged: id event [ self event send-mouse-moved ]
 
-{ "mouseUp:" "void" { "id" "SEL" "id" }
-    [ nip send-button-up$ ]
-}
+    METHOD: void mouseDown: id event [ self event send-button-down$ ]
 
-{ "rightMouseDown:" "void" { "id" "SEL" "id" }
-    [ nip send-button-down$ ]
-}
+    METHOD: void mouseUp: id event [ self event send-button-up$ ]
 
-{ "rightMouseUp:" "void" { "id" "SEL" "id" }
-    [ nip send-button-up$ ]
-}
+    METHOD: void rightMouseDown: id event [ self event send-button-down$ ]
 
-{ "otherMouseDown:" "void" { "id" "SEL" "id" }
-    [ nip send-button-down$ ]
-}
+    METHOD: void rightMouseUp: id event [ self event send-button-up$ ]
 
-{ "otherMouseUp:" "void" { "id" "SEL" "id" }
-    [ nip send-button-up$ ]
-}
+    METHOD: void otherMouseDown: id event [ self event send-button-down$ ]
 
-{ "scrollWheel:" "void" { "id" "SEL" "id" }
-    [ nip send-wheel$ ]
-}
+    METHOD: void otherMouseUp: id event [ self event send-button-up$ ]
 
-{ "keyDown:" "void" { "id" "SEL" "id" }
-    [ nip send-key-down-event ]
-}
+    METHOD: void scrollWheel: id event [ self event send-scroll$ ]
 
-{ "keyUp:" "void" { "id" "SEL" "id" }
-    [ nip send-key-up-event ]
-}
+    METHOD: void keyDown: id event [ self event send-key-down-event ]
 
-{ "undo:" "id" { "id" "SEL" "id" }
-    [ nip undo-action send-action$ ]
-}
+    METHOD: void keyUp: id event [ self event send-key-up-event ]
 
-{ "redo:" "id" { "id" "SEL" "id" }
-    [ nip redo-action send-action$ ]
-}
+    METHOD: char validateUserInterfaceItem: id event
+    [
+        self window [
+            event -> action utf8 alien>string validate-action
+            [ >c-bool ] [ drop self event SUPER-> validateUserInterfaceItem: ] if
+        ] [ 0 ] if*
+    ]
 
-{ "cut:" "id" { "id" "SEL" "id" }
-    [ nip cut-action send-action$ ]
-}
+    METHOD: id undo: id event [ self event undo-action send-action$ f ]
 
-{ "copy:" "id" { "id" "SEL" "id" }
-    [ nip copy-action send-action$ ]
-}
+    METHOD: id redo: id event [ self event redo-action send-action$ f ]
 
-{ "paste:" "id" { "id" "SEL" "id" }
-    [ nip paste-action send-action$ ]
-}
+    METHOD: id cut: id event [ self event cut-action send-action$ f ]
 
-{ "delete:" "id" { "id" "SEL" "id" }
-    [ nip delete-action send-action$ ]
-}
+    METHOD: id copy: id event [ self event copy-action send-action$ f ]
 
-{ "selectAll:" "id" { "id" "SEL" "id" }
-    [ nip select-all-action send-action$ ]
-}
+    METHOD: id paste: id event [ self event paste-action send-action$ f ]
 
-{ "newDocument:" "id" { "id" "SEL" "id" }
-    [ nip new-action send-action$ ]
-}
+    METHOD: id delete: id event [ self event delete-action send-action$ f ]
 
-{ "openDocument:" "id" { "id" "SEL" "id" }
-    [ nip open-action send-action$ ]
-}
+    METHOD: id selectAll: id event [ self event select-all-action send-action$ f ]
 
-{ "saveDocument:" "id" { "id" "SEL" "id" }
-    [ nip save-action send-action$ ]
-}
+    METHOD: id newDocument: id event [ self event new-action send-action$ f ]
 
-{ "saveDocumentAs:" "id" { "id" "SEL" "id" }
-    [ nip save-as-action send-action$ ]
-}
+    METHOD: id openDocument: id event [ self event open-action send-action$ f ]
 
-{ "revertDocumentToSaved:" "id" { "id" "SEL" "id" }
-    [ nip revert-action send-action$ ]
-}
+    METHOD: id saveDocument: id event [ self event save-action send-action$ f ]
+
+    METHOD: id saveDocumentAs: id event [ self event save-as-action send-action$ f ]
 
-! Multi-touch gestures: this is undocumented.
-! http://cocoadex.com/2008/02/nsevent-modifications-swipe-ro.html
-{ "magnifyWithEvent:" "void" { "id" "SEL" "id" }
+    METHOD: id revertDocumentToSaved: id event [ self event revert-action send-action$ f ]
+
+    ! Multi-touch gestures
+    METHOD: void magnifyWithEvent: id event
     [
-        nip
+        self event
         dup -> deltaZ sgn {
             {  1 [ zoom-in-action send-action$ ] }
             { -1 [ zoom-out-action send-action$ ] }
             {  0 [ 2drop ] }
         } case
     ]
-}
 
-{ "swipeWithEvent:" "void" { "id" "SEL" "id" }
+    METHOD: void swipeWithEvent: id event
     [
-        nip
+        self event
         dup -> deltaX sgn {
             {  1 [ left-action send-action$ ] }
             { -1 [ right-action send-action$ ] }
@@ -275,114 +244,95 @@ CLASS: {
             }
         } case
     ]
-}
-
-! "rotateWithEvent:" "void" { "id" "SEL" "id" }}
 
-{ "acceptsFirstResponder" "char" { "id" "SEL" }
-    [ 2drop 1 ]
-}
+    METHOD: char acceptsFirstResponder [ 1 ]
 
-! Services
-{ "validRequestorForSendType:returnType:" "id" { "id" "SEL" "id" "id" }
+    ! Services
+    METHOD: id validRequestorForSendType: id sendType returnType: id returnType
     [
         ! We return either self or nil
-        [ over window-focus ] 2dip
-        valid-service? [ drop ] [ 2drop f ] if
+        self window [
+            world-focus sendType returnType
+            valid-service? [ self ] [ f ] if
+        ] [ f ] if*
     ]
-}
 
-{ "writeSelectionToPasteboard:types:" "char" { "id" "SEL" "id" "id" }
+    METHOD: char writeSelectionToPasteboard: id pboard types: id types
     [
-        CF>string-array NSStringPboardType swap member? [
-            [ drop window-focus gadget-selection ] dip over
-            [ set-pasteboard-string 1 ] [ 2drop 0 ] if
-        ] [ 3drop 0 ] if
+        NSStringPboardType types CF>string-array member? [
+            self window [
+                world-focus gadget-selection
+                [ pboard set-pasteboard-string 1 ] [ 0 ] if*
+            ] [ 0 ] if*
+        ] [ 0 ] if
     ]
-}
 
-{ "readSelectionFromPasteboard:" "char" { "id" "SEL" "id" }
+    METHOD: char readSelectionFromPasteboard: id pboard
     [
-        pasteboard-string dup [
-            [ drop window ] dip swap user-input 1
-        ] [ 3drop 0 ] if
+        self window :> window
+        window [
+            pboard pasteboard-string
+            [ window user-input 1 ] [ 0 ] if*
+        ] [ 0 ] if
     ]
-}
 
-! Text input
-{ "insertText:" "void" { "id" "SEL" "id" }
-    [ nip CF>string swap window user-input ]
-}
+    ! Text input
+    METHOD: void insertText: id text
+    [
+        self window :> window
+        window [
+            text CF>string window user-input
+        ] when
+    ]
 
-{ "hasMarkedText" "char" { "id" "SEL" }
-    [ 2drop 0 ]
-}
+    METHOD: char hasMarkedText [ 0 ]
 
-{ "markedRange" "NSRange" { "id" "SEL" }
-    [ 2drop 0 0 <NSRange> ]
-}
+    METHOD: NSRange markedRange [ 0 0 <NSRange> ]
 
-{ "selectedRange" "NSRange" { "id" "SEL" }
-    [ 2drop 0 0 <NSRange> ]
-}
+    METHOD: NSRange selectedRange [ 0 0 <NSRange> ]
 
-{ "setMarkedText:selectedRange:" "void" { "id" "SEL" "id" "NSRange" }
-    [ 2drop 2drop ]
-}
+    METHOD: void setMarkedText: id text selectedRange: NSRange range [ ]
 
-{ "unmarkText" "void" { "id" "SEL" }
-    [ 2drop ]
-}
+    METHOD: void unmarkText [ ]
 
-{ "validAttributesForMarkedText" "id" { "id" "SEL" }
-    [ 2drop NSArray -> array ]
-}
+    METHOD: id validAttributesForMarkedText [ NSArray -> array ]
 
-{ "attributedSubstringFromRange:" "id" { "id" "SEL" "NSRange" }
-    [ 3drop f ]
-}
+    METHOD: id attributedSubstringFromRange: NSRange range [ f ]
 
-{ "characterIndexForPoint:" "NSUInteger" { "id" "SEL" "NSPoint" }
-    [ 3drop 0 ]
-}
+    METHOD: NSUInteger characterIndexForPoint: NSPoint point [ 0 ]
 
-{ "firstRectForCharacterRange:" "NSRect" { "id" "SEL" "NSRange" }
-    [ 3drop 0 0 0 0 <CGRect> ]
-}
+    METHOD: NSRect firstRectForCharacterRange: NSRange range [ 0 0 0 0 <CGRect> ]
 
-{ "conversationIdentifier" "NSInteger" { "id" "SEL" }
-    [ drop alien-address ]
-}
+    METHOD: NSInteger conversationIdentifier [ self alien-address ]
 
-! Initialization
-{ "updateFactorGadgetSize:" "void" { "id" "SEL" "id" }
-    [ 2drop [ window ] [ view-dim ] bi >>dim drop yield ]
-}
+    ! Initialization
+    METHOD: void updateFactorGadgetSize: id notification
+    [
+        self window :> window
+        window [
+            self view-dim window dim<< yield
+        ] when
+    ]
 
-{ "doCommandBySelector:" "void" { "id" "SEL" "SEL" }
-    [ 3drop ]
-}
+    METHOD: void doCommandBySelector: SEL selector [ ]
 
-{ "initWithFrame:pixelFormat:" "id" { "id" "SEL" "NSRect" "id" }
+    METHOD: id initWithFrame: NSRect frame pixelFormat: id pixelFormat
     [
-        [ drop ] 2dip
-        SUPER-> initWithFrame:pixelFormat:
+        self frame pixelFormat SUPER-> initWithFrame:pixelFormat:
         dup dup add-resize-observer
     ]
-}
 
-{ "dealloc" "void" { "id" "SEL" }
+    METHOD: char isOpaque [ 0 ]
+
+    METHOD: void dealloc
     [
-        drop
-        [ unregister-window ]
-        [ remove-observer ]
-        [ SUPER-> dealloc ]
-        tri
+        self remove-observer
+        self SUPER-> dealloc
     ]
-} ;
+]
 
 : sync-refresh-to-screen ( GLView -- )
-    -> openGLContext -> CGLContextObj NSOpenGLCPSwapInterval 1 <int>
+    -> openGLContext -> CGLContextObj NSOpenGLCPSwapInterval 1 int <ref>
     CGLSetParameter drop ;
 
 : <FactorView> ( dim pixel-format -- view )
@@ -391,44 +341,39 @@ CLASS: {
 : save-position ( world window -- )
     -> frame CGRect-top-left 2array >>window-loc drop ;
 
-CLASS: {
-    { +superclass+ "NSObject" }
-    { +name+ "FactorWindowDelegate" }
-}
-
-{ "windowDidMove:" "void" { "id" "SEL" "id" }
+CLASS: FactorWindowDelegate < NSObject
+[
+    METHOD: void windowDidMove: id notification
     [
-        2nip -> object [ -> contentView window ] keep save-position
+        notification -> object -> contentView window
+        [ notification -> object save-position ] when*
     ]
-}
 
-{ "windowDidBecomeKey:" "void" { "id" "SEL" "id" }
+    METHOD: void windowDidBecomeKey: id notification
     [
-        2nip -> object -> contentView window focus-world
+        notification -> object -> contentView window
+        [ focus-world ] when*
     ]
-}
 
-{ "windowDidResignKey:" "void" { "id" "SEL" "id" }
+    METHOD: void windowDidResignKey: id notification
     [
         forget-rollover
-        2nip -> object -> contentView
-        dup -> isInFullScreenMode zero? 
-        [ window unfocus-world ]
-        [ drop ] if
+        notification -> object -> contentView :> view
+        view window :> window
+        window [
+            view -> isInFullScreenMode 0 =
+            [ window unfocus-world ] when
+        ] when
     ]
-}
 
-{ "windowShouldClose:" "char" { "id" "SEL" "id" }
-    [
-        3drop 1
-    ]
-}
+    METHOD: char windowShouldClose: id notification [ 1 ]
 
-{ "windowWillClose:" "void" { "id" "SEL" "id" }
+    METHOD: void windowWillClose: id notification
     [
-        2nip -> object -> contentView window ungraft
+        notification -> object -> contentView
+        [ window ungraft ] [ unregister-window ] bi
     ]
-} ;
+]
 
 : install-window-delegate ( window -- )
     FactorWindowDelegate install-delegate ;