root/rebgui-widgets.r

Revision 117, 15.9 kB (checked in by ashley, 6 weeks ago)

Fixed remaining look & feel issues
Updated RebDOC.r and tour.r

Line 
1REBOL [
2        Title:          "RebGUI widgets"
3        Owner:          "Ashley G. Trüter"
4        Purpose:        "The RebGUI base widget set."
5        History: {
6                18      led fixed to use reduce [false] instead of [#[false]] (which fails under encap)
7                26      Removed drop-tree/number-field includes
8                48      Incorporated Cyphre's changes
9                49      Added spinner widget
10                50      Replaced spaces with tabs
11                53      Removed chevron widget
12                56      set-sizes fix for group-box
13                58      set-sizes fix for group-box
14                61      Replaced set-sizes, set-fonts and set-colors funcs with local rebind
15                62      Added default-para-indented
16                        Cleaned up choose function
17                        Added menu widget
18                        Added default-text
19                        Cleaned up sizes/font-height logic
20                63      Added link widget
21                65      Button updated with options [focus]
22                        Added size to default-text
23                        Added tooltip widget as a placeholder
24                68      Removed button options [focus] as fixed by set-focus
25                69      Added symbol & calendar widgets
26                71      calendar now hilights last day clicked
27                74      moved 'rebface into widgets and made global
28                        Fixed shift+hilight formula (pekr)
29                78      Added chat widget
30                93      Added on-edit
31                98      Fixed edit-list auto-complete bug by adding hacks to face-iterator and choose functions
32                105     Added vid widget
33                107     Added tree widget
34                108     Fixed tree widget
35                        Renamed vid.r to style.r
36                        Added sheet.r
37                        Added scroll-panel.r
38                111     Added on-resize
39                112     Added pill.r
40        }
41]
42
43widgets: make object! [
44
45        rebind: make function! [] [
46                default-edge/color:             colors/text
47                default-edge/size:              as-pair sizes/edge sizes/edge
48                theme-edge/color:               colors/theme-dark
49                theme-edge/size:                default-edge/size
50                outline-edge/color:             colors/outline-light
51                outline-edge/size:              default-edge/size
52                default-font/size:              sizes/font
53                default-font/name:              effects/font
54                default-font-bold:              make default-font [style: 'bold]
55                default-font-heading:   make default-font [style: 'bold color: colors/page align: 'center shadow: 1x1]
56                default-font-large:             make default-font [size: sizes/font * 2]
57                default-font-right:             make default-font [align: 'right]
58                default-font-top:               make default-font [valign: 'top]
59                default-para-indented/origin/x: sizes/line
60                default-text/text: copy ""
61                sizes/font-height: second size-text default-text
62                foreach w next find first self 'choose [
63                        widgets/:w/rebind
64                ]
65        ]
66
67        ;
68        ;       --- Default edge, font, para, feel & action objects ---
69        ;
70
71        default-edge: make object! [
72                color:  colors/text
73                image:  none
74                effect: none
75                size:   as-pair sizes/edge sizes/edge
76        ]
77
78        theme-edge: make default-edge [
79                color:  colors/theme-dark
80        ]
81
82        outline-edge: make default-edge [
83                color:  colors/outline-light
84        ]
85
86        default-font: make object! [
87                name:   effects/font
88                style:  none
89                size:   sizes/font
90                color:  colors/text
91                offset: 0x0
92                space:  0x0
93                align:  'left
94                valign: 'middle
95                shadow: none
96        ]
97
98        default-font-bold: make default-font [
99                style:  'bold
100        ]
101
102        default-font-heading: make default-font [
103                style:  'bold
104                color:  colors/page
105                align:  'center
106                shadow: 1x1
107        ]
108
109        default-font-large: make default-font [
110                size:   sizes/font * 2
111        ]
112
113        default-font-right: make default-font [
114                align:  'right
115        ]
116
117        default-font-top: make default-font [
118                valign: 'top
119        ]
120
121        default-para: make object! [
122                origin: 2x2
123                margin: 2x2
124                indent: 0x0
125                tabs:   0
126                wrap?:  false
127                scroll: 0x0
128        ]
129
130        ; Unfortunately, offset-to-caret returns end of the string when offset is between two lines,
131        ; which is only possible when indent/y > 0. This ought to be submitted to rambo as a rebol/view bug.
132        ; I would not use indent until it is fixed.
133        ; offset-to-caret needs to work correctly to allow the new area widget functionality of keeping
134        ; the caret visible when scrolling. -AntonR
135
136        ;default-para-wrap: make default-para [origin: 2x0 indent: 0x2 wrap?: true]
137
138        default-para-wrap: make default-para [
139                origin: 2x0
140                indent: 0x0
141                wrap?:  true
142        ]
143
144        default-para-indented: make default-para [
145                origin: as-pair sizes/line 2
146        ]
147
148        default-feel: make object! [
149                redraw:
150                detect:
151                over:
152                engage: none
153        ]
154
155        default-action: make object! [
156                on-alt-click:
157                on-away:
158                on-click:
159                on-dbl-click:
160                on-edit:
161                on-focus:
162                on-key:
163                on-over:
164                on-resize:
165                on-scroll:
166                on-unfocus: none
167        ]
168
169        set 'rebface: make subface [
170                feel:   default-feel
171                action: default-action
172                options: []
173                rebind: init: tip: none
174        ]
175
176        default-text: make rebface [
177                size:   10000x10000
178                text:   ""
179                font:   default-font
180                para:   default-para
181        ]
182
183        sizes/font-height: second size-text default-text
184
185        ;
186        ;       --- Date spec ---
187        ;
188
189        ;       header
190        date-spec: [
191                tight
192                symbol 9x6 data 'rewind         [face/parent-face/data/year: face/parent-face/data/year - 1             show face/parent-face]
193                symbol 9x6 data 'left           [face/parent-face/data/month: face/parent-face/data/month - 1   show face/parent-face]
194                symbol 34x6                                     [set-data face/parent-face first face/parent-face/options]
195                symbol 9x6 data 'right          [face/parent-face/data/month: face/parent-face/data/month + 1   show face/parent-face]
196                symbol 9x6 data 'forward        [face/parent-face/data/year: face/parent-face/data/year + 1             show face/parent-face]
197                return
198        ]
199        ;       day labels
200        foreach day locale*/days [
201                insert tail date-spec compose [label 10 (copy/part day 3) font [align: 'center]]
202        ]
203        insert tail date-spec [return bar]
204        ;       7x6 day slots
205        loop 6 [
206                insert tail date-spec 'return
207                loop 7 [
208                        insert tail date-spec [
209                                box 10x6 font [align: 'center valign: 'middle] edge [size: 0x0 color: colors/state-dark] feel [
210                                        over: make function! [face act pos] [
211                                                either all [act face/text] [
212                                                        face/parent-face/data/day: to integer! face/text
213                                                        set-title face/parent-face form face/parent-face/data
214                                                        select-face face
215                                                ] [deselect-face face]
216                                        ]
217                                        engage: make function! [face act event] [
218                                                all [
219                                                        act = 'down
220                                                        face/text
221                                                        face/parent-face/data/day: to integer! face/text
222                                                        poke face/parent-face/options 1 face/parent-face/data
223                                                        face/parent-face/action/on-click face/parent-face
224                                                ]
225                                                all [
226                                                        find [up alt-up] act
227                                                        face/feel/over face false none
228                                                ]
229                                        ]
230                                ]
231                        ]
232                ]
233        ]
234
235        ;
236        ;       --- Iterator function ---
237        ;
238
239        face-iterator: make rebface [
240                type:   'face-iterator
241                pane:   []
242                data:   []
243                timeout: now/time/precise
244                feel:   make default-feel [
245                        redraw: make function! [face act pos] [
246                                if all [act = 'show face/size <> face/old-size] [face/resize]
247                        ]
248                        engage: make function! [face act event /local i] [
249                                if act = 'time [
250                                        if (now/time/precise - face/timeout) > 0:00:0.2 [
251                                                face/action face
252                                                face/rate: none
253                                                show face
254                                        ]
255
256                                ]
257                                if act = 'key [
258                                        do select [
259                                                #"^A"   [       ; CTRL-A
260                                                        if find face/options 'multi [
261                                                                clear face/picked
262                                                                repeat i face/rows [insert tail face/picked i]
263                                                                face/action face
264                                                        ]
265                                                ]
266                                                down    [       ; DnAr
267                                                        i: 1 + last face/picked
268                                                        if i <= face/rows [
269                                                                i: min face/rows i
270                                                                insert clear face/picked i
271                                                                if find [table text-list] face/parent-face/type [
272                                                                        face/timeout: now/time/precise
273                                                                        face/rate: 60                                                           
274                                                                        if i > (face/scroll + face/lines) [
275                                                                                face/pane/2/data: 1 / (face/rows - face/lines) * ((min (face/rows - face/lines + 1) (i - face/lines + 1)) - 1)
276                                                                                face/scroll: face/scroll + 1
277                                                                        ]
278                                                                ]
279                                                        ]
280                                                ]
281                                                up              [       ; UpAr
282                                                        i: -1 + last face/picked
283                                                        if i > 0 [
284                                                                i: max 1 i
285                                                                insert clear face/picked i
286                                                                if find [table text-list] face/parent-face/type [
287                                                                        face/timeout: now/time/precise
288                                                                        face/rate: 60
289                                                                        if i = face/scroll [
290                                                                                face/pane/2/data: 1 / (face/rows - face/lines) * ((min (face/rows - face/lines + 1) i) - 1)
291                                                                                face/scroll: face/scroll - 1
292                                                                        ]
293                                                                ]
294                                                        ]
295                                                ]
296                                                #"^M"   [       ; Enter
297                                                        all [find [table text-list] face/parent-face/type face/action face]
298                                                ]
299                                        ] event/key
300                                        show face
301                                ]
302                        ]
303                ]
304                lines:  none    ; number of current visible lines
305                rows:   none    ; number of data rows
306                cols:   1               ; number of columns (> 1 table option only)
307                widths: none    ; pixel width of each column (table option only)
308                aligns: none    ; column aligns
309                picked: []              ; current selection(s)
310                scroll: 0               ; scroll offset
311                resize: make function! [] [     ; window size change(s)
312                        lines: to integer! size/y / sizes/line
313                        pane/2/show?: either rows > lines [
314                                scroll: max 0 min scroll rows - lines
315                                true
316                        ][
317                                scroll: 0
318                                false
319                        ]
320                ]
321                redraw: make function! [] [     ; data change(s)
322                        clear picked
323                        rows: either empty? data [0] [(length? data) / cols]
324                        resize
325                        pane/2/ratio: either zero? rows [1] [lines / rows]
326                        show self
327                ]
328                selected: make function! [/local blk] [
329                        if empty? picked [return none]  ; are any rows selected?
330                        either any [find options 'multi parent-face/type = 'table] [
331                                all [rows = length? picked return data] ; are all rows selected?
332                                blk: copy []
333                                either cols = 1 [
334                                        foreach row picked [insert tail blk pick data row]
335                                ][
336                                        foreach row picked [
337                                                repeat col cols [
338                                                        insert tail blk pick data -1 + row * cols + col
339                                                ]
340                                        ]
341                                ]
342                                blk
343                        ][
344                                blk: pick data first picked
345                        ]
346                ]
347                init:   make function! [/local p] [
348                        ;       remove XY span directives
349                        attempt [remove find span #X]
350                        attempt [remove find span #Y]
351                        ;       calculate lines & rows
352                        lines: to integer! size/y / sizes/line
353                        rows: (length? data) / cols
354                        ;       iterated line handler
355                        clear pane
356                        p: self
357                        insert pane make subface [
358                                size: p/size
359                                span: p/span
360                                pane: make function! [face index /local col-offset clr] [
361                                        either integer? index [
362                                                if index <= min lines rows [
363                                                        line/offset/y: index - 1 * sizes/line
364                                                        line/size/x: size/x
365                                                        index: index + scroll
366                                                        either p/parent-face/type = 'table [
367                                                                col-offset: 0
368                                                                repeat i p/cols [
369                                                                        line/pane/:i/offset/x: col-offset
370                                                                        line/pane/:i/size/x: p/widths/:i - sizes/cell ; column gap
371                                                                        all [
372                                                                                p/pane/2/show?
373                                                                                i = p/cols
374                                                                                line/pane/:i/size/x: line/pane/:i/size/x + (p/size/x - p/pane/2/size/x - (line/pane/:i/offset/x + line/pane/:i/size/x))
375                                                                        ]
376                                                                        line/pane/:i/text: replace/all form pick p/data index - 1 * cols + i "^/" "¶"
377                                                                        line/pane/:i/font/color: either find p/options 'no-action [
378                                                                                colors/text
379                                                                        ][
380                                                                                either find picked index [colors/page] [colors/text]
381                                                                        ]
382                                                                        col-offset: col-offset + pick widths i
383                                                                ]
384                                                        ][
385                                                                line/text: replace/all form pick face/parent-face/data index "^/" "¶"
386                                                                line/font/color: either find p/options 'no-action [
387                                                                        colors/text
388                                                                ][
389                                                                        either find picked index [colors/page] [colors/text]
390                                                                ]
391                                                        ]
392                                                        line/color: either find p/options 'no-action [none] [if find picked index [colors/theme-light]]
393                                                        if all [
394                                                                line/color = colors/theme-light
395                                                                face/parent-face/type = 'choose
396                                                        ] [face/parent-face/auto: pick face/parent-face/data index]     ; drop-list auto hack fix
397                                                        line/data: index
398                                                        line
399                                                ]
400                                        ] [to integer! index/y / sizes/line + 1]
401                                ]
402                                text: ""
403                                line: make rebface [
404                                        size:   as-pair 0 sizes/line
405                                        font:   make default-font []
406                                        feel:   make default-feel [
407                                                over: make function! [face into pos] [
408                                                        if find face/parent-face/parent-face/options 'over [
409                                                                either into [insert clear picked data] [clear picked]
410                                                                show face
411                                                        ]
412                                                ]
413                                                engage: make function! [face act event /local p a b] [
414                                                        p: face/parent-face
415                                                        either event/double-click [
416                                                                all [act = 'down p/parent-face/dbl-action p/parent-face]
417                                                        ][
418                                                                if find [up alt-up] act [
419                                                                        ;       allow parent to get key events
420                                                                        view*/focal-face: p
421                                                                        view*/caret: tail p/text
422                                                                        either find p/parent-face/options 'multi [
423                                                                                ;       unflag previous selections?
424                                                                                unless any [event/control event/shift] [clear picked]
425                                                                                either all [event/control find picked data] [
426                                                                                        remove find picked data
427                                                                                ][
428                                                                                        unless find picked data [insert tail picked data]
429                                                                                ]
430                                                                                ;       shift highlight any gap between last two highlighted entries
431                                                                                if all [event/shift 1 < length? picked] [
432                                                                                        clear next picked
433                                                                                        repeat i (max data first picked) - (a: min data first picked) + 1 [
434                                                                                                b: i + a - 1
435                                                                                                all [b <> first picked insert tail picked b]
436                                                                                        ]
437                                                                                ]
438                                                                        ] [insert clear picked data]
439                                                                        ;       perform action if any
440                                                                        show p
441                                                                        unless find p/parent-face/options 'no-action [
442                                                                                either act = 'up [
443                                                                                        p/parent-face/action p/parent-face
444                                                                                ][
445                                                                                        p/parent-face/alt-action p/parent-face
446                                                                                ]
447                                                                        ]
448                                                                ]
449                                                        ]
450                                                ]
451                                        ]
452                                ]
453                        ]
454                        ;       table?
455                        if find options 'table [
456                                pane/1/line/pane: copy []
457                                repeat i cols [
458                                        insert tail pane/1/line/pane make subface [
459                                                size:   as-pair 0 sizes/line
460                                                font:   make default-font [align: aligns/:i]
461                                        ]
462                                ]
463                        ]
464                        ;       vertical scroller
465                        insert tail pane make slider [
466                                tip:    none
467                                offset: as-pair p/size/x - sizes/slider 0
468                                size:   as-pair sizes/slider p/size/y
469                                span:   case [
470                                        none? p/span    [none]
471                                        all [find p/span #H find p/span #W] [#XH]
472                                        find p/span #H  [#H]
473                                        find p/span #W  [#X]
474                                ]
475                                options:[arrows]
476                                show?:  either rows > lines [true] [false]
477                                action: make default-action [
478                                        on-click: make function! [face] [
479                                                scroll: to integer! rows - lines * data
480                                                show face/parent-face
481                                        ]
482                                ]
483                                ratio:  either rows > 0 [lines / rows] [1]
484                        ]
485                        pane/2/init
486                ]
487        ]
488
489        ;
490        ;       --- Choose function ---
491        ;
492
493        choose: make function! [
494                parent [object!] "Widget to appear in relation to"
495                width [integer!] "Width in pixels"
496                xy [pair!] "Offset of choice box"
497                items [block!] "Block of items to display"
498                /local popup result
499        ][
500                result: none
501                popup: make face-iterator [
502                        type:           'choose
503                        offset:         xy
504                        size:           as-pair width sizes/line * min length? items to-integer parent/parent-face/size/y - xy/y / sizes/line
505                        color:          colors/page
506                        data:           items
507                        edge:           outline-edge
508                        feel:           system/words/face/feel
509                        options:        [over]  ; required to detect mouse-over and display hilight bar
510                        action:         make function! [face] [result: pick data first picked hide-popup]
511                        alt-action:     none
512                        dbl-action:     none
513                        auto:           none
514                ]
515                popup/init
516                show-popup/window/away popup parent/parent-face
517                do-events
518                either parent/type = 'edit-list [popup/auto] [result]   ; hack for auto bug
519        ]
520
521        ;
522        ;       --- Widget definitions ---
523        ;
524
525        #include %widgets/anim.r
526        #include %widgets/pill.r
527        #include %widgets/area.r
528        #include %widgets/arrow.r
529        #include %widgets/bar.r
530        #include %widgets/box.r
531        #include %widgets/button.r
532        #include %widgets/calendar.r
533        #include %widgets/chat.r
534        #include %widgets/check.r
535        #include %widgets/check-group.r
536        #include %widgets/drop-list.r
537        #include %widgets/edit-list.r
538        #include %widgets/field.r
539        #include %widgets/group-box.r
540        #include %widgets/heading.r
541        #include %widgets/image.r
542        #include %widgets/label.r
543        #include %widgets/led.r
544        #include %widgets/led-group.r
545        #include %widgets/link.r
546        #include %widgets/menu.r
547        #include %widgets/panel.r
548        #include %widgets/password.r
549        #include %widgets/pie-chart.r
550        #include %widgets/progress.r
551        #include %widgets/radio-group.r
552        #include %widgets/scroll-panel.r
553        #include %widgets/sheet.r
554        #include %widgets/slider.r
555        #include %widgets/spinner.r
556        #include %widgets/splitter.r
557        #include %widgets/style.r
558        #include %widgets/symbol.r
559        #include %widgets/table.r
560        #include %widgets/tab-panel.r
561        #include %widgets/text.r
562        #include %widgets/text-list.r
563        #include %widgets/title-group.r
564        #include %widgets/tool-bar.r
565        #include %widgets/tooltip.r
566        #include %widgets/tree.r
567]
Note: See TracBrowser for help on using the browser.