diff --git a/basis/cocoa/cocoa.factor b/basis/cocoa/cocoa.factor index b78bb020d0..ec5db31940 100644 --- a/basis/cocoa/cocoa.factor +++ b/basis/cocoa/cocoa.factor @@ -60,6 +60,7 @@ SYNTAX: IMPORT: scan [ ] import-objc-class ; "NSOpenGLPixelFormat" "NSOpenGLView" "NSOpenPanel" + "NSPanel" "NSPasteboard" "NSPropertyListSerialization" "NSResponder" diff --git a/basis/cocoa/windows/windows.factor b/basis/cocoa/windows/windows.factor index 4e0f768b96..ed2c2d51bd 100644 --- a/basis/cocoa/windows/windows.factor +++ b/basis/cocoa/windows/windows.factor @@ -4,36 +4,37 @@ USING: arrays kernel math cocoa cocoa.messages cocoa.classes sequences math.bitwise ; IN: cocoa.windows +! Window styles CONSTANT: NSBorderlessWindowMask 0 CONSTANT: NSTitledWindowMask 1 CONSTANT: NSClosableWindowMask 2 CONSTANT: NSMiniaturizableWindowMask 4 CONSTANT: NSResizableWindowMask 8 +! Additional panel-only styles +CONSTANT: NSUtilityWindowMask 16 +CONSTANT: NSDocModalWindowMask 64 +CONSTANT: NSNonactivatingPanelMask 128 +CONSTANT: NSHUDWindowMask HEX: 1000 + CONSTANT: NSBackingStoreRetained 0 CONSTANT: NSBackingStoreNonretained 1 CONSTANT: NSBackingStoreBuffered 2 -: standard-window-type ( -- n ) - { - NSTitledWindowMask - NSClosableWindowMask - NSMiniaturizableWindowMask - NSResizableWindowMask - } flags ; inline - -: ( rect -- window ) - NSWindow -> alloc swap - standard-window-type NSBackingStoreBuffered 1 +: ( rect style class -- window ) + [ -> alloc ] curry 2dip NSBackingStoreBuffered 1 -> initWithContentRect:styleMask:backing:defer: ; -: ( view rect -- window ) - [ swap -> setContentView: ] keep +: class-for-style ( style -- NSWindow/NSPanel ) + HEX: 1ff0 bitand zero? NSWindow NSPanel ? ; + +: ( view rect style -- window ) + dup class-for-style [ swap -> setContentView: ] keep dup dup -> contentView -> setInitialFirstResponder: dup 1 -> setAcceptsMouseMovedEvents: dup 0 -> setReleasedWhenClosed: ; : window-content-rect ( window -- rect ) - [ NSWindow ] dip + dup -> class swap [ -> frame ] [ -> styleMask ] bi -> contentRectForFrameRect:styleMask: ; diff --git a/basis/game-input/dinput/dinput.factor b/basis/game-input/dinput/dinput.factor index 0ecf543baa..6cd161bd28 100755 --- a/basis/game-input/dinput/dinput.factor +++ b/basis/game-input/dinput/dinput.factor @@ -190,7 +190,7 @@ TUPLE: window-rect < rect window-loc ; DBT_DEVTYP_DEVICEINTERFACE over set-DEV_BROADCAST_DEVICEW-dbcc_devicetype ; : create-device-change-window ( -- ) - create-window + WS_OVERLAPPEDWINDOW 0 create-window [ (device-notification-filter) DEVICE_NOTIFY_WINDOW_HANDLE DEVICE_NOTIFY_ALL_INTERFACE_CLASSES bitor diff --git a/basis/literals/literals.factor b/basis/literals/literals.factor index ba1da393b1..b954d561fa 100755 --- a/basis/literals/literals.factor +++ b/basis/literals/literals.factor @@ -19,3 +19,7 @@ PRIVATE> SYNTAX: $ scan-word expand-literal >vector ; SYNTAX: $[ parse-quotation with-datastack >vector ; SYNTAX: ${ \ } [ expand-literals ] parse-literal ; + +SYNTAX: $$ + scan-word execute( accum -- accum ) dup pop [ >quotation ] keep + [ output>sequence ] 2curry call( -- object ) parsed ; diff --git a/basis/math/bitwise/bitwise-docs.factor b/basis/math/bitwise/bitwise-docs.factor old mode 100644 new mode 100755 index fca06526e0..38bccd1dca --- a/basis/math/bitwise/bitwise-docs.factor +++ b/basis/math/bitwise/bitwise-docs.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: help.markup help.syntax math sequences ; +USING: assocs help.markup help.syntax math sequences ; IN: math.bitwise HELP: bitfield @@ -145,6 +145,25 @@ HELP: flags } } ; +HELP: symbols>flags +{ $values { "symbols" sequence } { "assoc" assoc } { "flag-bits" integer } } +{ $description "Constructs an integer value by mapping the values in the " { $snippet "symbols" } " sequence to integer values using " { $snippet "assoc" } " and " { $link bitor } "ing the values together." } +{ $examples + { $example "USING: math.bitwise prettyprint ui.gadgets.worlds ;" + "IN: scratchpad" + "CONSTANT: window-controls>flags H{" + " { close-button 1 }" + " { minimize-button 2 }" + " { maximize-button 4 }" + " { resize-handles 8 }" + " { small-title-bar 16 }" + " { normal-title-bar 32 }" + "}" + "{ resize-handles close-button small-title-bar } window-controls>flags symbols>flags ." + "25" + } +} ; + HELP: mask { $values { "x" integer } { "n" integer } diff --git a/basis/math/bitwise/bitwise.factor b/basis/math/bitwise/bitwise.factor index ff4806348b..cea944a6e8 100755 --- a/basis/math/bitwise/bitwise.factor +++ b/basis/math/bitwise/bitwise.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2007, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays kernel math sequences accessors math.bits -sequences.private words namespaces macros hints -combinators fry io.binary combinators.smart ; +USING: arrays assocs kernel math sequences accessors +math.bits sequences.private words namespaces macros +hints combinators fry io.binary combinators.smart ; IN: math.bitwise ! utilities @@ -44,6 +44,10 @@ IN: math.bitwise MACRO: flags ( values -- ) [ 0 ] [ [ ?execute bitor ] curry compose ] reduce ; +: symbols>flags ( symbols assoc -- flag-bits ) + [ at ] curry map + 0 [ bitor ] reduce ; + ! bitfield ( shaders frag-data-locations -- program ) + glCreateProgram + [ + [ swap [ glAttachShader ] with each ] + [ swap [ first2 swap glBindFragDataLocationEXT ] with each ] bi-curry bi* + ] + [ glLinkProgram ] + [ ] tri + gl-error ; + : ( shaders -- program ) - glCreateProgram swap - [ dupd glAttachShader ] each - [ glLinkProgram ] keep + glCreateProgram + [ swap [ glAttachShader ] with each ] + [ glLinkProgram ] + [ ] tri gl-error ; : (gl-program?) ( object -- ? ) diff --git a/basis/roman/roman.factor b/basis/roman/roman.factor index 92202da8ca..817b6637d6 100644 --- a/basis/roman/roman.factor +++ b/basis/roman/roman.factor @@ -1,10 +1,9 @@ ! Copyright (C) 2007 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays assocs fry generalizations grouping -kernel lexer macros make math math.order math.vectors +USING: accessors arrays assocs effects fry generalizations +grouping kernel lexer macros math math.order math.vectors namespaces parser quotations sequences sequences.private -splitting.monotonic stack-checker strings unicode.case -words effects ; +splitting.monotonic stack-checker strings unicode.case words ; IN: roman = ( ch1 ch2 -- ? ) [ roman-digit-index ] bi@ >= ; : roman>n ( ch -- n ) roman-digit-index roman-values nth ; -: (>roman) ( n -- ) - roman-values roman-digits [ - [ /mod swap ] dip concat % - ] 2each drop ; - : (roman>) ( seq -- n ) [ [ roman>n ] map ] [ all-eq? ] bi [ sum ] [ first2 swap - ] if ; @@ -41,12 +35,15 @@ ERROR: roman-range-error n ; PRIVATE> : >roman ( n -- str ) - dup roman-range-check [ (>roman) ] "" make ; + roman-range-check + roman-values roman-digits [ + [ /mod swap ] dip concat + ] 2map "" concat-as nip ; : >ROMAN ( n -- str ) >roman >upper ; : roman> ( str -- n ) - >lower [ roman<= ] monotonic-split [ (roman>) ] sigma ; + >lower [ roman>= ] monotonic-split [ (roman>) ] sigma ; << + SYNTAX: ROMAN-OP: scan-word [ name>> "roman" prepend create-in ] keep 1quotation '[ _ binary-roman-op ] dup infer [ in>> ] [ out>> ] bi [ "string" ] bi@ define-declared ; + >> ROMAN-OP: + diff --git a/basis/ui/backend/cocoa/cocoa.factor b/basis/ui/backend/cocoa/cocoa.factor index aa84ee43c5..e05704e623 100755 --- a/basis/ui/backend/cocoa/cocoa.factor +++ b/basis/ui/backend/cocoa/cocoa.factor @@ -6,7 +6,7 @@ cocoa.pasteboard cocoa.runtime cocoa.subclassing cocoa.types cocoa.views cocoa.windows combinators command-line core-foundation core-foundation.run-loop core-graphics core-graphics.types destructors fry generalizations io.thread -kernel libc literals locals math math.rectangles memory +kernel libc literals locals math math.bitwise math.rectangles memory namespaces sequences specialized-arrays.int threads ui ui.backend ui.backend.cocoa.views ui.clipboards ui.gadgets ui.gadgets.worlds ui.pixel-formats ui.pixel-formats.private @@ -109,10 +109,23 @@ M: cocoa-ui-backend (set-fullscreen) ( world ? -- ) M: cocoa-ui-backend (fullscreen?) ( world -- ? ) handle>> view>> -> isInFullScreenMode zero? not ; +CONSTANT: window-control>styleMask + H{ + { close-button $ NSClosableWindowMask } + { minimize-button $ NSMiniaturizableWindowMask } + { maximize-button 0 } + { resize-handles $ NSResizableWindowMask } + { small-title-bar $[ NSTitledWindowMask NSUtilityWindowMask bitor ] } + { normal-title-bar $ NSTitledWindowMask } + } + +: world>styleMask ( world -- n ) + window-controls>> window-control>styleMask symbols>flags ; + M:: cocoa-ui-backend (open-window) ( world -- ) world [ [ dim>> ] dip ] with-world-pixel-format :> view - view world world>NSRect :> window + view world [ world>NSRect ] [ world>styleMask ] bi :> window view -> release world view register-window window world window-loc>> auto-position @@ -145,7 +158,7 @@ M: cocoa-ui-backend (ungrab-input) ( handle -- ) M: cocoa-ui-backend close-window ( gadget -- ) find-world [ handle>> [ - window>> f -> performClose: + window>> -> close ] when* ] when* ; diff --git a/basis/ui/backend/windows/windows.factor b/basis/ui/backend/windows/windows.factor index 551d89b66c..03a86fe25f 100755 --- a/basis/ui/backend/windows/windows.factor +++ b/basis/ui/backend/windows/windows.factor @@ -9,7 +9,7 @@ windows.kernel32 windows.gdi32 windows.user32 windows.opengl32 windows.messages windows.types windows.offscreen windows.nt threads libc combinators fry combinators.short-circuit continuations command-line shuffle opengl ui.render math.bitwise locals -accessors math.rectangles math.order calendar ascii +accessors math.rectangles math.order calendar ascii sets io.encodings.utf16n windows.errors literals ui.pixel-formats ui.pixel-formats.private memoize classes struct-arrays ; IN: ui.backend.windows @@ -223,8 +223,40 @@ M: pasteboard set-clipboard-contents drop copy ; SYMBOLS: msg-obj class-name-ptr mouse-captured ; -: style ( -- n ) WS_OVERLAPPEDWINDOW ; inline -: ex-style ( -- n ) WS_EX_APPWINDOW WS_EX_WINDOWEDGE bitor ; inline +CONSTANT: window-control>style + H{ + { close-button 0 } + { minimize-button $ WS_MINIMIZEBOX } + { maximize-button $ WS_MAXIMIZEBOX } + { resize-handles $ WS_THICKFRAME } + { small-title-bar $ WS_CAPTION } + { normal-title-bar $ WS_CAPTION } + } + +CONSTANT: window-control>ex-style + H{ + { close-button 0 } + { minimize-button 0 } + { maximize-button 0 } + { resize-handles $ WS_EX_WINDOWEDGE } + { small-title-bar $ WS_EX_TOOLWINDOW } + { normal-title-bar $ WS_EX_APPWINDOW } + } + +: needs-sysmenu? ( controls -- ? ) + { close-button minimize-button maximize-button } intersects? ; + +: has-titlebar? ( controls -- ? ) + { small-title-bar normal-title-bar } intersects? ; + +: world>style ( world -- n ) + window-controls>> + [ window-control>style symbols>flags ] + [ needs-sysmenu? [ WS_SYSMENU bitor ] when ] + [ has-titlebar? [ WS_POPUP bitor ] unless ] tri ; + +: world>ex-style ( world -- n ) + window-controls>> window-control>ex-style symbols>flags ; : get-RECT-top-left ( RECT -- x y ) [ RECT-left ] keep RECT-top ; @@ -242,12 +274,12 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ; : handle-wm-size ( hWnd uMsg wParam lParam -- ) 2nip [ lo-word ] keep hi-word 2array - dup { 0 0 } = [ 2drop ] [ swap window (>>dim) ] if ; + dup { 0 0 } = [ 2drop ] [ swap window [ (>>dim) ] [ drop ] if* ] if ; : handle-wm-move ( hWnd uMsg wParam lParam -- ) 2nip [ lo-word ] keep hi-word 2array - swap window (>>window-loc) ; + swap window [ (>>window-loc) ] [ drop ] if* ; CONSTANT: wm-keydown-codes H{ @@ -571,8 +603,8 @@ M: windows-ui-backend do-events RegisterClassEx win32-error=0/f ] [ drop ] if ; -: adjust-RECT ( RECT -- ) - style 0 ex-style AdjustWindowRectEx win32-error=0/f ; +: adjust-RECT ( RECT style ex-style -- ) + [ 0 ] dip AdjustWindowRectEx win32-error=0/f ; : make-RECT ( world -- RECT ) [ window-loc>> ] [ dim>> ] bi ; @@ -584,10 +616,12 @@ M: windows-ui-backend do-events CW_USEDEFAULT over set-RECT-left CW_USEDEFAULT swap set-RECT-top ; -: make-adjusted-RECT ( rect -- RECT ) - make-RECT - dup get-RECT-top-left [ zero? ] both? swap - dup adjust-RECT +: make-adjusted-RECT ( rect style ex-style -- RECT ) + [ + make-RECT + dup get-RECT-top-left [ zero? ] both? swap + dup + ] 2dip adjust-RECT swap [ dup default-position-RECT ] when ; : get-window-class ( -- class-name ) @@ -597,12 +631,12 @@ M: windows-ui-backend do-events dup ] change-global ; -: create-window ( rect -- hwnd ) - make-adjusted-RECT +:: create-window ( rect style ex-style -- hwnd ) + rect style ex-style make-adjusted-RECT [ get-window-class f ] dip [ [ ex-style ] 2dip - { WS_CLIPSIBLINGS WS_CLIPCHILDREN style } flags + WS_CLIPSIBLINGS WS_CLIPCHILDREN bitor style bitor ] dip get-RECT-dimensions f f f GetModuleHandle f CreateWindowEx dup win32-error=0/f ; @@ -636,8 +670,21 @@ M: windows-ui-backend do-events [ swap [ handle>> hDC>> set-pixel-format ] [ get-rc ] bi ] with-world-pixel-format ; +: disable-close-button ( hwnd -- ) + 0 GetSystemMenu + SC_CLOSE MF_BYCOMMAND MF_GRAYED bitor EnableMenuItem drop ; + +: ?disable-close-button ( world hwnd -- ) + swap window-controls>> close-button swap member? not + [ disable-close-button ] [ drop ] if ; + M: windows-ui-backend (open-window) ( world -- ) - [ dup create-window [ f f ] dip f f >>handle setup-gl ] + [ + dup + [ ] [ world>style ] [ world>ex-style ] tri create-window + [ ?disable-close-button ] + [ [ f f ] dip f f >>handle setup-gl ] 2bi + ] [ dup handle>> hWnd>> register-window ] [ handle>> hWnd>> show-window ] tri ; @@ -743,13 +790,9 @@ M: windows-ui-backend (ungrab-input) ( handle -- ) } cleave ; : exit-fullscreen ( world -- ) - handle>> hWnd>> + dup handle>> hWnd>> { - [ - GWL_STYLE GetWindowLong - fullscreen-flags bitor - ] - [ GWL_STYLE rot SetWindowLong win32-error=0/f ] + [ GWL_STYLE rot world>style SetWindowLong win32-error=0/f ] [ f over hwnd>RECT get-RECT-dimensions diff --git a/basis/ui/gadgets/worlds/worlds-docs.factor b/basis/ui/gadgets/worlds/worlds-docs.factor index c12c6b93aa..d0fd169871 100755 --- a/basis/ui/gadgets/worlds/worlds-docs.factor +++ b/basis/ui/gadgets/worlds/worlds-docs.factor @@ -56,6 +56,7 @@ HELP: world { { $snippet "grab-input?" } " - if set to " { $link t } ", the world will hide the mouse cursor and disable normal mouse input while focused. Use " { $link grab-input } " and " { $link ungrab-input } " to change this setting." } { { $snippet "handle" } " - a backend-specific native handle representing the native window containing the world, or " { $link f } " if the world is not grafted." } { { $snippet "window-loc" } " - the on-screen location of the native window containing the world. The co-ordinate system here is backend-specific." } + { { $snippet "window-controls" } " - the set of " { $link "ui.gadgets.worlds-window-controls" } " with which the world window was created." } } } ; @@ -113,3 +114,4 @@ $nl { $subsection "ui.gadgets.worlds-subclassing" } { $subsection "gl-utilities" } { $subsection "text-rendering" } ; + diff --git a/basis/ui/gadgets/worlds/worlds.factor b/basis/ui/gadgets/worlds/worlds.factor index dfce3d3eee..82f3637b83 100755 --- a/basis/ui/gadgets/worlds/worlds.factor +++ b/basis/ui/gadgets/worlds/worlds.factor @@ -7,16 +7,34 @@ ui.gadgets ui.gestures ui.render ui.backend ui.gadgets.tracks ui.pixel-formats destructors literals strings ; IN: ui.gadgets.worlds +SYMBOLS: + close-button + minimize-button + maximize-button + resize-handles + small-title-bar + normal-title-bar ; + CONSTANT: default-world-pixel-format-attributes { windowed double-buffered T{ depth-bits { value 16 } } } +CONSTANT: default-world-window-controls + { + normal-title-bar + close-button + minimize-button + maximize-button + resize-handles + } + TUPLE: world < track active? focused? grab-input? layers title status status-owner text-handle handle images window-loc - pixel-format-attributes ; + pixel-format-attributes + window-controls ; TUPLE: world-attributes { world-class initial: world } @@ -24,7 +42,8 @@ TUPLE: world-attributes { title string initial: "Factor Window" } status gadgets - { pixel-format-attributes initial: $ default-world-pixel-format-attributes } ; + { pixel-format-attributes initial: $ default-world-pixel-format-attributes } + { window-controls initial: $ default-world-window-controls } ; : ( -- world-attributes ) world-attributes new ; inline @@ -86,6 +105,7 @@ M: world request-focus-on ( child gadget -- ) [ title>> >>title ] [ status>> >>status ] [ pixel-format-attributes>> >>pixel-format-attributes ] + [ window-controls>> >>window-controls ] [ grab-input?>> >>grab-input? ] [ gadgets>> [ 1 track-add ] each ] } cleave ; diff --git a/basis/ui/ui-docs.factor b/basis/ui/ui-docs.factor index 7e83265926..b381c4e677 100644 --- a/basis/ui/ui-docs.factor +++ b/basis/ui/ui-docs.factor @@ -14,6 +14,10 @@ HELP: open-window { $values { "gadget" gadget } { "title/attributes" { "a " { $link string } " or a " { $link world-attributes } " tuple" } } } { $description "Opens a native window containing " { $snippet "gadget" } " with the specified attributes. If a string is provided, it is used as the window title; otherwise, the window attributes are specified in a " { $link world-attributes } " tuple." } ; +HELP: close-window +{ $values { "gadget" gadget } } +{ $description "Close the native window containing " { $snippet "gadget" } "." } ; + HELP: world-attributes { $values { "world-class" class } { "title" string } { "status" gadget } { "gadgets" sequence } { "pixel-format-attributes" sequence } } { $class-description "Tuples of this class can be passed to " { $link open-window } " to control attributes of the window opened. The following attributes can be set:" } @@ -23,6 +27,7 @@ HELP: world-attributes { { $snippet "status" } ", if specified, is a gadget that will be used as the window's status bar." } { { $snippet "gadgets" } " is a sequence of gadgets that will be placed inside the window." } { { $snippet "pixel-format-attributes" } " is a sequence of " { $link "ui.pixel-formats-attributes" } " that the window will request for its OpenGL pixel format." } + { { $snippet "window-controls" } " is a sequence of " { $link "ui.gadgets.worlds-window-controls" } " that will be placed in the window." } } ; HELP: set-fullscreen @@ -262,3 +267,31 @@ ARTICLE: "ui" "UI framework" { $subsection "ui-backend" } ; ABOUT: "ui" + +HELP: close-button +{ $description "Asks for a close button to be available for a window. Without a close button, a window cannot be closed by the user and must be closed by the program using " { $link close-window } "." } ; + +HELP: minimize-button +{ $description "Asks for a minimize button to be available for a window." } ; + +HELP: maximize-button +{ $description "Asks for a maximize button to be available for a window." } ; + +HELP: resize-handles +{ $description "Asks for resize controls to be available for a window. Without resize controls, the window size will not be changeable by the user." } ; + +HELP: small-title-bar +{ $description "Asks for a window to have a small title bar. Without a title bar, the " { $link close-button } ", " { $link minimize-button } ", and " { $link maximize-button } " controls will not be available. A small title bar may have other side effects in the window system, such as causing the window to not show up in the system task switcher and to float over other Factor windows." } ; + +HELP: normal-title-bar +{ $description "Asks for a window to have a title bar. Without a title bar, the " { $link close-button } ", " { $link minimize-button } ", and " { $link maximize-button } " controls will not be available." } ; + +ARTICLE: "ui.gadgets.worlds-window-controls" "Window controls" +"The following window controls can be placed in a " { $link world } " window:" +{ $subsection close-button } +{ $subsection minimize-button } +{ $subsection maximize-button } +{ $subsection resize-handles } +{ $subsection small-title-bar } +{ $subsection normal-title-bar } +"Provide a sequence of these values in the " { $snippet "window-controls" } " slot of the " { $link world-attributes } " tuple you pass to " { $link open-window } "." ; diff --git a/basis/windows/user32/user32.factor b/basis/windows/user32/user32.factor index 2272695953..40c10d0f5b 100755 --- a/basis/windows/user32/user32.factor +++ b/basis/windows/user32/user32.factor @@ -582,6 +582,28 @@ CONSTANT: SWP_NOREPOSITION SWP_NOOWNERZORDER CONSTANT: SWP_DEFERERASE 8192 CONSTANT: SWP_ASYNCWINDOWPOS 16384 +CONSTANT: MF_ENABLED HEX: 0000 +CONSTANT: MF_GRAYED HEX: 0001 +CONSTANT: MF_DISABLED HEX: 0002 +CONSTANT: MF_STRING HEX: 0000 +CONSTANT: MF_BITMAP HEX: 0004 +CONSTANT: MF_UNCHECKED HEX: 0000 +CONSTANT: MF_CHECKED HEX: 0008 +CONSTANT: MF_POPUP HEX: 0010 +CONSTANT: MF_MENUBARBREAK HEX: 0020 +CONSTANT: MF_MENUBREAK HEX: 0040 +CONSTANT: MF_UNHILITE HEX: 0000 +CONSTANT: MF_HILITE HEX: 0080 +CONSTANT: MF_OWNERDRAW HEX: 0100 +CONSTANT: MF_USECHECKBITMAPS HEX: 0200 +CONSTANT: MF_BYCOMMAND HEX: 0000 +CONSTANT: MF_BYPOSITION HEX: 0400 +CONSTANT: MF_SEPARATOR HEX: 0800 +CONSTANT: MF_DEFAULT HEX: 1000 +CONSTANT: MF_SYSMENU HEX: 2000 +CONSTANT: MF_HELP HEX: 4000 +CONSTANT: MF_RIGHTJUSTIFY HEX: 4000 +CONSTANT: MF_MOUSESELECT HEX: 8000 LIBRARY: user32 @@ -807,7 +829,7 @@ FUNCTION: BOOL DrawIcon ( HDC hDC, int X, int Y, HICON hIcon ) ; ! FUNCTION: DrawTextW ! FUNCTION: EditWndProc FUNCTION: BOOL EmptyClipboard ( ) ; -! FUNCTION: EnableMenuItem +FUNCTION: BOOL EnableMenuItem ( HMENU hMenu, UINT uIDEnableItem, UINT uEnable ) ; ! FUNCTION: EnableScrollBar ! FUNCTION: EnableWindow ! FUNCTION: EndDeferWindowPos @@ -975,7 +997,7 @@ FUNCTION: int GetPriorityClipboardFormat ( UINT* paFormatPriorityList, int cForm ! FUNCTION: GetSubMenu ! FUNCTION: GetSysColor FUNCTION: HBRUSH GetSysColorBrush ( int nIndex ) ; -! FUNCTION: GetSystemMenu +FUNCTION: HMENU GetSystemMenu ( HWND hWnd, BOOL bRevert ) ; ! FUNCTION: GetSystemMetrics ! FUNCTION: GetTabbedTextExtentA ! FUNCTION: GetTabbedTextExtentW diff --git a/core/sets/sets-docs.factor b/core/sets/sets-docs.factor index 3670b10d3c..298fcbeeae 100755 --- a/core/sets/sets-docs.factor +++ b/core/sets/sets-docs.factor @@ -1,4 +1,5 @@ -USING: kernel help.markup help.syntax sequences quotations assocs ; +USING: assocs hashtables help.markup help.syntax kernel +quotations sequences ; IN: sets ARTICLE: "sets" "Set-theoretic operations on sequences" @@ -19,6 +20,13 @@ $nl { $subsection set= } "A word used to implement the above:" { $subsection unique } +"Counting elements in a sequence:" +{ $subsection histogram } +{ $subsection histogram* } +"Combinators for implementing histogram:" +{ $subsection sequence>assoc } +{ $subsection sequence>assoc* } +{ $subsection sequence>hashtable } "Adding elements to sets:" { $subsection adjoin } { $subsection conjoin } @@ -125,3 +133,73 @@ HELP: gather { "seq" sequence } { "quot" quotation } { "newseq" sequence } } { $description "Maps a quotation onto a sequence, concatenates the results of the mapping, and removes duplicates." } ; + +HELP: histogram +{ $values + { "seq" sequence } + { "hashtable" hashtable } +} +{ $examples + { $example "! Count the number of times an element appears in a sequence." + "USING: prettyprint sets ;" + "\"aaabc\" histogram ." + "H{ { 97 3 } { 98 1 } { 99 1 } }" + } +} +{ $description "Returns a hashtable where the keys are the elements of the sequence and the values are the number of times they appeared in that sequence." } ; + +HELP: histogram* +{ $values + { "hashtable" hashtable } { "seq" sequence } + { "hashtable" hashtable } +} +{ $examples + { $example "! Count the number of times the elements of two sequences appear." + "USING: prettyprint sets ;" + "\"aaabc\" histogram \"aaaaaabc\" histogram* ." + "H{ { 97 9 } { 98 2 } { 99 2 } }" + } +} +{ $description "Takes an existing hashtable and uses " { $link histogram } " to continue counting the number of occurences of each element." } ; + +HELP: sequence>assoc +{ $values + { "seq" sequence } { "quot" quotation } { "exemplar" "an exemplar assoc" } + { "assoc" assoc } +} +{ $examples + { $example "! Iterate over a sequence and increment the count at each element" + "USING: assocs prettyprint sets ;" + "\"aaabc\" [ inc-at ] H{ } sequence>assoc ." + "H{ { 97 3 } { 98 1 } { 99 1 } }" + } +} +{ $description "Iterates over a sequence, allowing elements of the sequence to be added to a newly created " { $snippet "assoc" } " according to the passed quotation." } ; + +HELP: sequence>assoc* +{ $values + { "assoc" assoc } { "seq" sequence } { "quot" quotation } + { "assoc" assoc } +} +{ $examples + { $example "! Iterate over a sequence and add the counts to an existing assoc" + "USING: assocs prettyprint sets kernel ;" + "H{ { 97 2 } { 98 1 } } clone \"aaabc\" [ inc-at ] sequence>assoc* ." + "H{ { 97 5 } { 98 2 } { 99 1 } }" + } +} +{ $description "Iterates over a sequence, allowing elements of the sequence to be added to an existing " { $snippet "assoc" } " according to the passed quotation." } ; + +HELP: sequence>hashtable +{ $values + { "seq" sequence } { "quot" quotation } + { "hashtable" hashtable } +} +{ $examples + { $example "! Count the number of times an element occurs in a sequence" + "USING: assocs prettyprint sets ;" + "\"aaabc\" [ inc-at ] sequence>hashtable ." + "H{ { 97 3 } { 98 1 } { 99 1 } }" + } +} +{ $description "Iterates over a sequence, allowing elements of the sequence to be added to a hashtable according to the passed quotation." } ; diff --git a/core/sets/sets-tests.factor b/core/sets/sets-tests.factor index 838a0a82b8..be195a62cd 100644 --- a/core/sets/sets-tests.factor +++ b/core/sets/sets-tests.factor @@ -29,3 +29,13 @@ IN: sets.tests [ f ] [ { } { 1 } intersects? ] unit-test [ f ] [ { 1 } { } intersects? ] unit-test + +[ + H{ + { 97 2 } + { 98 2 } + { 99 2 } + } +] [ + "aabbcc" histogram +] unit-test diff --git a/core/sets/sets.factor b/core/sets/sets.factor index 062b624e8f..421d43bb3d 100755 --- a/core/sets/sets.factor +++ b/core/sets/sets.factor @@ -54,3 +54,25 @@ PRIVATE> : set= ( seq1 seq2 -- ? ) [ unique ] bi@ = ; + +assoc) ( seq quot assoc -- assoc ) + [ swap curry each ] keep ; inline + +PRIVATE> + +: sequence>assoc* ( assoc seq quot: ( obj assoc -- ) -- assoc ) + rot (sequence>assoc) ; inline + +: sequence>assoc ( seq quot: ( obj assoc -- ) exemplar -- assoc ) + clone (sequence>assoc) ; inline + +: sequence>hashtable ( seq quot: ( obj hashtable -- ) -- hashtable ) + H{ } sequence>assoc ; inline + +: histogram* ( hashtable seq -- hashtable ) + [ inc-at ] sequence>assoc* ; + +: histogram ( seq -- hashtable ) + [ inc-at ] sequence>hashtable ; diff --git a/extra/half-floats/half-floats-tests.factor b/extra/half-floats/half-floats-tests.factor index d026ca2933..001cc6200b 100644 --- a/extra/half-floats/half-floats-tests.factor +++ b/extra/half-floats/half-floats-tests.factor @@ -25,7 +25,7 @@ IN: half-floats.tests [ -1.5 ] [ HEX: be00 bits>half ] unit-test [ 1/0. ] [ HEX: 7c00 bits>half ] unit-test [ -1/0. ] [ HEX: fc00 bits>half ] unit-test -[ t ] [ HEX: 7e00 bits>half fp-nan? ] unit-test +[ t ] [ HEX: 7e00 bits>half fp-nan? ] unit-test C-STRUCT: halves { "half" "tom" } diff --git a/extra/window-controls-demo/authors.txt b/extra/window-controls-demo/authors.txt new file mode 100755 index 0000000000..f13c9c1e77 --- /dev/null +++ b/extra/window-controls-demo/authors.txt @@ -0,0 +1 @@ +Joe Groff diff --git a/extra/window-controls-demo/summary.txt b/extra/window-controls-demo/summary.txt new file mode 100755 index 0000000000..e84535ab11 --- /dev/null +++ b/extra/window-controls-demo/summary.txt @@ -0,0 +1 @@ +Open windows with different control sets diff --git a/extra/window-controls-demo/window-controls-demo.factor b/extra/window-controls-demo/window-controls-demo.factor new file mode 100755 index 0000000000..89e4c7001f --- /dev/null +++ b/extra/window-controls-demo/window-controls-demo.factor @@ -0,0 +1,43 @@ +! (c)2009 Joe Groff bsd license +USING: accessors assocs kernel locals sequences ui +ui.gadgets ui.gadgets.worlds ; +IN: window-controls-demo + +CONSTANT: window-control-sets-to-test + H{ + { "No controls" { } } + { "Normal title bar" { normal-title-bar } } + { "Small title bar" { small-title-bar close-button } } + { "Close button" { normal-title-bar close-button } } + { "Close and minimize buttons" { normal-title-bar close-button minimize-button } } + { "Minimize button" { normal-title-bar minimize-button } } + { "Close, minimize, and maximize buttons" { normal-title-bar close-button minimize-button maximize-button } } + { "Resizable" { normal-title-bar close-button minimize-button maximize-button resize-handles } } + } + +TUPLE: window-controls-demo-world < world + windows ; + +M: window-controls-demo-world end-world + windows>> [ close-window ] each ; + +M: window-controls-demo-world pref-dim* + drop { 400 400 } ; + +: attributes-template ( -- x ) + T{ world-attributes + { world-class window-controls-demo-world } + } clone ; + +: window-controls-demo ( -- ) + attributes-template V{ } clone window-control-sets-to-test + [| title attributes windows controls | + f attributes + title >>title + controls >>window-controls + open-window* + windows >>windows + windows push + ] with with assoc-each ; + +MAIN: window-controls-demo