From 19d77c51930f04c714a1f58bd71f0f2d49259dc4 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Tue, 16 Jun 2009 18:14:22 -0500 Subject: [PATCH 01/12] let gl-error know about GL_INVALID_FRAMEBUFFER_OPERATION_EXT error. add helper word to link a GL program with named multiple render targets --- basis/opengl/opengl.factor | 3 ++- basis/opengl/shaders/shaders.factor | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/basis/opengl/opengl.factor b/basis/opengl/opengl.factor index 72ca8b8cdb..7d79516a2c 100644 --- a/basis/opengl/opengl.factor +++ b/basis/opengl/opengl.factor @@ -25,6 +25,7 @@ IN: opengl { HEX: 0503 "Stack overflow" } { HEX: 0504 "Stack underflow" } { HEX: 0505 "Out of memory" } + { HEX: 0506 "Invalid framebuffer operation" } } at "Unknown error" or ; TUPLE: gl-error code string ; @@ -190,4 +191,4 @@ MACRO: set-draw-buffers ( buffers -- ) GL_PROJECTION glMatrixMode glLoadIdentity GL_MODELVIEW glMatrixMode - glLoadIdentity ; \ No newline at end of file + glLoadIdentity ; diff --git a/basis/opengl/shaders/shaders.factor b/basis/opengl/shaders/shaders.factor index 15fab1aae0..a946fd16f4 100755 --- a/basis/opengl/shaders/shaders.factor +++ b/basis/opengl/shaders/shaders.factor @@ -61,10 +61,21 @@ PREDICATE: fragment-shader < gl-shader (fragment-shader?) ; ! Programs +: ( 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 -- ? ) From 3231fcd05205877a6ff045ebd1facd5a222d7594 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Wed, 17 Jun 2009 22:47:51 -0500 Subject: [PATCH 02/12] interface for controlling window controls (close, minimize, resize, titlebar, etc.). cocoa backend --- basis/cocoa/cocoa.factor | 1 + basis/cocoa/windows/windows.factor | 29 ++++++++++++++------------- basis/ui/backend/cocoa/cocoa.factor | 15 +++++++++++++- basis/ui/gadgets/worlds/worlds.factor | 24 ++++++++++++++++++++-- 4 files changed, 52 insertions(+), 17 deletions(-) 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/ui/backend/cocoa/cocoa.factor b/basis/ui/backend/cocoa/cocoa.factor index aa84ee43c5..acb35df82d 100755 --- a/basis/ui/backend/cocoa/cocoa.factor +++ b/basis/ui/backend/cocoa/cocoa.factor @@ -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 at ] map 0 [ bitor ] reduce ; + 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 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 ; From b75999aac6ab5388aa81dc0da2d58c3999549ea9 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Wed, 17 Jun 2009 23:00:30 -0500 Subject: [PATCH 03/12] fix cocoa close-window to work on windows without close buttons --- basis/ui/backend/cocoa/cocoa.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basis/ui/backend/cocoa/cocoa.factor b/basis/ui/backend/cocoa/cocoa.factor index acb35df82d..7e78fcc8b8 100755 --- a/basis/ui/backend/cocoa/cocoa.factor +++ b/basis/ui/backend/cocoa/cocoa.factor @@ -158,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* ; From 48b06d622177c512e1d9ec14a820298342e03fee Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Thu, 18 Jun 2009 09:53:17 -0500 Subject: [PATCH 04/12] window-controls-demo for testing/showing off window controls --- extra/window-controls-demo/authors.txt | 1 + extra/window-controls-demo/summary.txt | 1 + .../window-controls-demo.factor | 42 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100755 extra/window-controls-demo/authors.txt create mode 100755 extra/window-controls-demo/summary.txt create mode 100755 extra/window-controls-demo/window-controls-demo.factor 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..70000c8268 --- /dev/null +++ b/extra/window-controls-demo/window-controls-demo.factor @@ -0,0 +1,42 @@ +! (c)2009 Joe Groff bsd license +USING: accessors assocs kernel locals sequences ui +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" { normal-title-bar close-button } } + { "Close and minimize buttons" { normal-title-bar close-button 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 From 33dcb989435c985da4581a3a8403b787ceb7014b Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Thu, 18 Jun 2009 09:57:49 -0500 Subject: [PATCH 05/12] oops, forgot a USING --- basis/literals/literals.factor | 4 ++++ extra/half-floats/half-floats-tests.factor | 2 +- extra/window-controls-demo/window-controls-demo.factor | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) 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/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/window-controls-demo.factor b/extra/window-controls-demo/window-controls-demo.factor index 70000c8268..aee6337f97 100755 --- a/extra/window-controls-demo/window-controls-demo.factor +++ b/extra/window-controls-demo/window-controls-demo.factor @@ -1,6 +1,6 @@ ! (c)2009 Joe Groff bsd license USING: accessors assocs kernel locals sequences ui -ui.gadgets.worlds ; +ui.gadgets ui.gadgets.worlds ; IN: window-controls-demo CONSTANT: window-control-sets-to-test From 76b3e5fea24f70e2b1265f622b67224170168a8d Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Thu, 18 Jun 2009 11:41:34 -0500 Subject: [PATCH 06/12] win32 support for window-controls --- basis/game-input/dinput/dinput.factor | 2 +- basis/math/bitwise/bitwise-docs.factor | 21 ++++- basis/math/bitwise/bitwise.factor | 10 ++- basis/ui/backend/cocoa/cocoa.factor | 4 +- basis/ui/backend/windows/windows.factor | 77 ++++++++++++++----- basis/windows/user32/user32.factor | 26 ++++++- .../window-controls-demo.factor | 3 +- 7 files changed, 114 insertions(+), 29 deletions(-) mode change 100644 => 100755 basis/math/bitwise/bitwise-docs.factor 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/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 styleMask } : world>styleMask ( world -- n ) - window-controls>> [ window-control>styleMask at ] map 0 [ bitor ] reduce ; + window-controls>> window-control>styleMask symbols>flags ; M:: cocoa-ui-backend (open-window) ( world -- ) world [ [ dim>> ] dip ] diff --git a/basis/ui/backend/windows/windows.factor b/basis/ui/backend/windows/windows.factor index 551d89b66c..a63837a0da 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,36 @@ 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? ; + +: world>style ( world -- n ) + window-controls>> + [ window-control>style symbols>flags ] + [ needs-sysmenu? [ WS_SYSMENU bitor ] when ] bi ; + +: 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 ; @@ -571,8 +599,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 +612,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 +627,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 +666,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 +786,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/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/extra/window-controls-demo/window-controls-demo.factor b/extra/window-controls-demo/window-controls-demo.factor index aee6337f97..89e4c7001f 100755 --- a/extra/window-controls-demo/window-controls-demo.factor +++ b/extra/window-controls-demo/window-controls-demo.factor @@ -7,9 +7,10 @@ CONSTANT: window-control-sets-to-test H{ { "No controls" { } } { "Normal title bar" { normal-title-bar } } - { "Small title bar" { small-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 } } } From 5f2bced2e3553db8aafdfc3944d438ab316324a3 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Thu, 18 Jun 2009 12:20:50 -0500 Subject: [PATCH 07/12] docs for window-controls --- basis/ui/gadgets/worlds/worlds-docs.factor | 2 ++ basis/ui/ui-docs.factor | 33 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) 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/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 } "." ; From 10ab07224fdc819bf3c1364c26eed27048863f59 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Thu, 18 Jun 2009 15:09:03 -0500 Subject: [PATCH 08/12] make windows without titlebars on win32 actually not have titlebars --- basis/ui/backend/windows/windows.factor | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/basis/ui/backend/windows/windows.factor b/basis/ui/backend/windows/windows.factor index a63837a0da..3b174c5e8d 100755 --- a/basis/ui/backend/windows/windows.factor +++ b/basis/ui/backend/windows/windows.factor @@ -246,10 +246,14 @@ CONSTANT: window-control>ex-style : 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 ] bi ; + [ needs-sysmenu? [ WS_SYSMENU bitor ] when ] + [ has-titlebar? [ WS_POPUP flags bitor ] unless ] tri ; : world>ex-style ( world -- n ) window-controls>> window-control>ex-style symbols>flags ; @@ -270,12 +274,12 @@ CONSTANT: window-control>ex-style : 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{ From 97f0a24e45e5c20a94586fe51de9c430257ae8c1 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 18 Jun 2009 17:29:41 -0500 Subject: [PATCH 09/12] add histogram and sequence>assoc to sets --- core/sets/sets-docs.factor | 80 ++++++++++++++++++++++++++++++++++++- core/sets/sets-tests.factor | 10 +++++ core/sets/sets.factor | 22 ++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/core/sets/sets-docs.factor b/core/sets/sets-docs.factor index 3670b10d3c..1e4ceb5680 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 "! Count the number of times the elements of two sequences appear." + "USING: 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 "! Count the number of times the elements of two sequences appear." + "USING: prettyprint sets ;" + "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 the elements of two sequences appear." + "USING: 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 ; From 801366df9854f52bec059ffd73d380e668c1c024 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 18 Jun 2009 17:32:10 -0500 Subject: [PATCH 10/12] minor cleanup --- basis/roman/roman.factor | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) 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: + From 03b8e1b7561ddf53c9e035df46eb7169a786743e Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 18 Jun 2009 19:29:10 -0500 Subject: [PATCH 11/12] don't write docs with auto-use enabled --- core/sets/sets-docs.factor | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/sets/sets-docs.factor b/core/sets/sets-docs.factor index 1e4ceb5680..298fcbeeae 100755 --- a/core/sets/sets-docs.factor +++ b/core/sets/sets-docs.factor @@ -168,8 +168,8 @@ HELP: sequence>assoc { "assoc" assoc } } { $examples - { $example "! Count the number of times the elements of two sequences appear." - "USING: prettyprint sets ;" + { $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 } }" } @@ -182,8 +182,8 @@ HELP: sequence>assoc* { "assoc" assoc } } { $examples - { $example "! Count the number of times the elements of two sequences appear." - "USING: prettyprint sets ;" + { $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 } }" } @@ -196,8 +196,8 @@ HELP: sequence>hashtable { "hashtable" hashtable } } { $examples - { $example "! Count the number of times the elements of two sequences appear." - "USING: prettyprint sets ;" + { $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 } }" } From a99f8f5741c80129c8e4dec42ed61fc288b11dfd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 18 Jun 2009 19:30:17 -0500 Subject: [PATCH 12/12] Fix hang when loading ui.backend.windows --- basis/ui/backend/windows/windows.factor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basis/ui/backend/windows/windows.factor b/basis/ui/backend/windows/windows.factor index 3b174c5e8d..03a86fe25f 100755 --- a/basis/ui/backend/windows/windows.factor +++ b/basis/ui/backend/windows/windows.factor @@ -253,7 +253,7 @@ CONSTANT: window-control>ex-style window-controls>> [ window-control>style symbols>flags ] [ needs-sysmenu? [ WS_SYSMENU bitor ] when ] - [ has-titlebar? [ WS_POPUP flags bitor ] unless ] tri ; + [ has-titlebar? [ WS_POPUP bitor ] unless ] tri ; : world>ex-style ( world -- n ) window-controls>> window-control>ex-style symbols>flags ;