Subversion Repositories Kolibri OS

Rev

Rev 1362 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1334 mikedld 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;                                                              ;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
 
9
$Revision: 1376 $
10
 
11
 
12
button._.MAX_BUTTONS = 4095
13
 
14
 
15
;==============================================================================
16
;///// public functions ///////////////////////////////////////////////////////
17
;==============================================================================
18
 
19
struc SYS_BUTTON
20
{
21
  .pslot  dw ?
22
  .id_lo  dw ?
23
  .left   dw ?
24
  .width  dw ?
25
  .top    dw ?
26
  .height dw ?
27
  .id_hi  dw ?
28
  .sizeof:
29
}
30
virtual at 0
31
  SYS_BUTTON SYS_BUTTON
32
end virtual
33
 
34
iglobal
35
  mx                dw 0x0 ; keeps the x mouse's position when it was clicked
36
  my                dw 0x0 ; keeps the y mouse's position when it was clicked
37
  bPressedMouseXY_B db 0x0
38
  btn_down_determ   db 0x0
39
endg
40
 
41
align 4
42
;------------------------------------------------------------------------------
43
syscall_button: ;///// system function 8 //////////////////////////////////////
44
;------------------------------------------------------------------------------
1362 mikedld 45
;? Define/undefine GUI button object
1334 mikedld 46
;------------------------------------------------------------------------------
1362 mikedld 47
;; Define button:
48
;> ebx = pack[16(x), 16(width)]
49
;> ecx = pack[16(y), 16(height)]
50
;> edx = pack[8(flags), 24(button identifier)]
51
;>       flags bits:
52
;>          7 (31) = 0
53
;>          6 (30) = don't draw button
54
;>          5 (29) = don't draw button frame when pressed
55
;> esi = button color
1334 mikedld 56
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1362 mikedld 57
;; Undefine button:
58
;> edx = pack[8(flags), 24(button identifier)]
59
;>       flags bits:
60
;>          7 (31) = 1
1334 mikedld 61
;------------------------------------------------------------------------------
62
        ; do we actually need to undefine the button?
63
        test    edx, 0x80000000
64
        jnz     .remove_button
65
 
66
        ; do we have free button slots available?
67
        mov     edi, [BTN_ADDR]
68
        mov     eax, [edi]
69
        cmp     eax, button._.MAX_BUTTONS
70
        jge     .exit
71
 
72
        ; does it have positive size? (otherwise it doesn't have sense)
73
        or      bx, bx
74
        jle     .exit
75
        or      cx, cx
76
        jle     .exit
77
 
78
        ; make coordinates clientbox-relative
79
        push    eax
80
        mov     eax, [current_slot]
81
        rol     ebx, 16
82
        add     bx, word[eax + APPDATA.wnd_clientbox.left]
83
        rol     ebx, 16
84
        rol     ecx, 16
85
        add     cx, word[eax + APPDATA.wnd_clientbox.top]
86
        rol     ecx, 16
87
        pop     eax
88
 
89
        ; basic checks passed, define the button
90
        push    ebx ecx edx
91
        inc     eax
92
        mov     [edi], ax
93
        shl     eax, 4
94
        add     edi, eax
95
        ; NOTE: this code doesn't rely on SYS_BUTTON struct, please revise it
96
        ;       if you change something
97
        mov     ax, [CURRENT_TASK]
98
        stosw
99
        mov     ax, dx
100
        stosw               ; button id number: bits 0-15
101
        mov     eax, ebx
102
        rol     eax, 16
103
        stosd               ; x start | x size
104
        mov     eax, ecx
105
        rol     eax, 16
106
        stosd               ; y start | y size
107
        mov     eax, edx
108
        shr     eax, 16
109
        stosw               ; button id number: bits 16-31
110
        pop     edx ecx ebx
111
 
112
        ; do we also need to draw the button?
113
        test    edx, 0x40000000
114
        jnz     .exit
115
 
116
        ; draw button body
117
 
118
        pushad
119
 
120
        ; calculate window-relative coordinates
121
        movzx   edi, cx
122
        shr     ebx, 16
123
        shr     ecx, 16
124
        mov     eax, [TASK_BASE]
125
        add     ebx, [eax - twdw + WDATA.box.left]
126
        add     ecx, [eax - twdw + WDATA.box.top]
127
        mov     eax, ebx
128
        shl     eax, 16
129
        mov     ax, bx
130
        add     ax, word[esp + 16]
131
        mov     ebx, ecx
132
        shl     ebx, 16
133
        mov     bx, cx
134
 
135
        ; calculate initial color
136
        mov     ecx, esi
137
        cmp     [buttontype], 0
138
        je      @f
139
        call    button._.incecx2
140
 
141
        ; set button height counter
142
    @@: mov     edx, edi
143
 
144
  .next_line:
145
        call    button._.button_dececx
146
        push    edi
147
        xor     edi, edi
148
        call    [draw_line]
149
        pop     edi
150
        add     ebx, 0x00010001
151
        dec     edx
152
        jnz     .next_line
153
 
154
        popad
155
 
156
        ; draw button frame
157
 
158
        push    ebx ecx
159
 
160
        ; calculate window-relative coordinates
161
        shr     ebx, 16
162
        shr     ecx, 16
163
        mov     eax, [TASK_BASE]
164
        add     ebx, [eax - twdw + WDATA.box.left]
165
        add     ecx, [eax - twdw + WDATA.box.top]
166
 
167
        ; top border
168
        mov     eax, ebx
169
        shl     eax, 16
170
        mov     ax, bx
171
        add     ax, [esp + 4]
172
        mov     ebx, ecx
173
        shl     ebx, 16
174
        mov     bx, cx
175
        push    ebx
176
        xor     edi, edi
177
        mov     ecx, esi
178
        call    button._.incecx
179
        call    [draw_line]
180
 
181
        ; bottom border
182
        movzx   edx, word[esp + 4 + 0]
183
        add     ebx, edx
184
        shl     edx, 16
185
        add     ebx, edx
186
        mov     ecx, esi
187
        call    button._.dececx
188
        call    [draw_line]
189
 
190
        ; left border
191
        pop     ebx
192
        push    edx
193
        mov     edx, eax
194
        shr     edx, 16
195
        mov     ax, dx
196
        mov     edx, ebx
197
        shr     edx, 16
198
        mov     bx, dx
199
        add     bx, [esp + 4 + 0]
200
        pop     edx
201
        mov     ecx, esi
202
        call    button._.incecx
203
        call    [draw_line]
204
 
205
        ; right border
206
        mov     dx, [esp + 4]
207
        add     ax, dx
208
        shl     edx, 16
209
        add     eax, edx
210
        add     ebx, 0x00010000
211
        mov     ecx, esi
212
        call    button._.dececx
213
        call    [draw_line]
214
 
215
        pop     ecx ebx
216
 
217
  .exit:
218
        ret
219
 
220
; FIXME: mutex needed
221
syscall_button.remove_button:
222
        and     edx, 0x00ffffff
223
        mov     edi, [BTN_ADDR]
224
        mov     ebx, [edi]
225
        inc     ebx
226
        imul    esi, ebx, SYS_BUTTON.sizeof
227
        add     esi, edi
228
        xor     ecx, ecx
229
        add     ecx, -SYS_BUTTON.sizeof
230
 
231
  .next_button:
232
        dec     ebx
233
        jz      .exit
234
 
235
        add     ecx, SYS_BUTTON.sizeof
236
        add     esi, -SYS_BUTTON.sizeof
237
 
238
        ; does it belong to our process?
239
        mov     ax, [CURRENT_TASK]
240
        cmp     ax, [esi + SYS_BUTTON.pslot]
241
        jne     .next_button
242
 
243
        ; does the identifier match?
244
        mov     eax, dword[esi + SYS_BUTTON.id_hi - 2]
245
        mov     ax, [esi + SYS_BUTTON.id_lo]
246
        and     eax, 0x00ffffff
247
        cmp     edx, eax
248
        jne     .next_button
249
 
250
        ; okay, undefine it
1341 mikedld 251
        push    ebx
1334 mikedld 252
        mov     ebx, esi
253
        lea     eax, [esi + SYS_BUTTON.sizeof]
254
        call    memmove
255
        dec     dword[edi]
256
        add     ecx, -SYS_BUTTON.sizeof
1341 mikedld 257
        pop     ebx
1334 mikedld 258
        jmp     .next_button
259
 
260
  .exit:
261
        ret
262
 
263
align 4
264
;------------------------------------------------------------------------------
265
check_buttons: ;///////////////////////////////////////////////////////////////
266
;------------------------------------------------------------------------------
1362 mikedld 267
;? 
1334 mikedld 268
;------------------------------------------------------------------------------
269
        cmp     byte[BTN_DOWN], 0    ; mouse buttons pressed
270
        jnz     @f
271
        mov     [bPressedMouseXY_B], 0
272
        ret
273
 
274
    @@: pushad
275
        xor     esi, esi
276
        mov     edi, [BTN_ADDR]
277
        mov     edx, [edi]
278
        test    edx, edx
279
        jne     @f
280
        popad
281
        ret
282
 
283
        ;here i catch the coordinates when the mouse's button is clicked
284
    @@: push    ax
285
        cmp     [bPressedMouseXY_B], 0 ; FALSE
286
        jnz     @f
287
        mov     [bPressedMouseXY_B], 1 ; TRUE - it was already clicked
288
        mov     ax, [MOUSE_X]
289
        mov     [mx], ax
290
        mov     ax, [MOUSE_Y]
291
        mov     [my], ax
292
    @@: pop     ax
293
        ;and it is only refreshed after the mouse's button release
294
 
295
        push    esi
296
        inc     edx
297
        push    edx
298
 
299
  .buttonnewcheck:
300
        pop     edx
301
        pop     esi
302
        inc     esi
303
        cmp     edx, esi
304
        jge     .bch
305
 
306
        popad
307
        ret
308
 
309
  .bch:
310
        push    esi
311
        push    edx
312
        mov     eax, esi
313
        shl     eax, 4
314
        add     eax, edi
315
 
316
        ; check that button is at top of windowing stack
317
        movzx   ebx, [eax + SYS_BUTTON.pslot]
318
        movzx   ecx, word[WIN_STACK + ebx * 2]
319
        cmp     ecx, [TASK_COUNT]
320
        jne     .buttonnewcheck
321
 
322
        ; check that button start is inside window x/y end
323
        shl     ebx, 5
324
 
325
        test    [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED
326
        jnz     .buttonnewcheck
327
 
328
        movzx   edx, [eax + SYS_BUTTON.left]
329
        cmp     edx, [window_data + ebx + WDATA.box.width] ;ecx
330
        jge     .buttonnewcheck
331
 
332
        movzx   edx, [eax + SYS_BUTTON.top]
333
        cmp     edx, [window_data + ebx + WDATA.box.height] ;ecx
334
        jge     .buttonnewcheck
335
 
336
        ; check coordinates
337
 
338
        ; mouse x >= button x ?
339
        add     ebx, window_data
340
        mov     ecx, [ebx + WDATA.box.left]
341
        movzx   edx, [eax + SYS_BUTTON.left]
342
        add     edx, ecx
343
        mov     cx, [mx]   ;mov cx,[MOUSE_X]
344
        cmp     edx, ecx
345
        jg      .buttonnewcheck
346
 
347
        movzx   ebx, [eax + SYS_BUTTON.width]
348
        add     edx, ebx
349
        cmp     ecx, edx
350
        jg      .buttonnewcheck
351
 
352
        ; mouse y >= button y ?
353
        movzx   ebx, [eax + SYS_BUTTON.pslot]
354
        shl     ebx, 5
355
        add     ebx, window_data
356
        mov     ecx, [ebx + WDATA.box.top]
357
        movzx   edx, [eax + SYS_BUTTON.top]
358
        add     edx, ecx
359
        mov     cx, [my]  ;mov cx,[MOUSE_Y]
360
        cmp     edx, ecx
361
        jg      .buttonnewcheck
362
 
363
        movzx   ebx, [eax + SYS_BUTTON.height]
364
        add     edx, ebx
365
        cmp     ecx, edx
366
        jg      .buttonnewcheck
367
 
368
        ; mouse on button
369
 
370
        pop     edx
371
        pop     esi
372
 
373
        mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]     ; button id : bits 16-31
374
        mov     bx, [eax + SYS_BUTTON.id_lo]       ; button id : bits 00-16
375
        push    ebx
376
 
377
        mov     byte[MOUSE_DOWN], 1  ; no mouse down checks
378
        call    button._.negative_button
379
 
380
        pushad
381
        push    eax
382
        mov     al, [BTN_DOWN]
383
        mov     byte[btn_down_determ], al
384
        pop     eax
385
 
386
  .cbwaitmouseup:
387
        call    checkidle
388
        call    [draw_pointer]
389
 
390
        pushad
391
        call    stack_handler
392
        popad
393
 
394
        cmp     byte[BTN_DOWN], 0  ; mouse buttons pressed ?
395
        jnz     .cbwaitmouseup
396
        popad
397
 
398
        call    button._.negative_button
399
        mov     byte[MOUSE_BACKGROUND], 0  ; no mouse background
400
        mov     byte[DONT_DRAW_MOUSE], 0  ; draw mouse
401
 
402
        ; check coordinates
403
        pusha
404
 
405
        ; mouse x >= button x ?
406
        movzx   ebx, [eax + SYS_BUTTON.pslot]
407
        shl     ebx, 5
408
        add     ebx, window_data
409
        mov     ecx, [ebx + WDATA.box.left]
410
        movzx   edx, [eax + SYS_BUTTON.left]
411
        add     edx, ecx
412
        mov     cx, [MOUSE_X]
413
        cmp     edx, ecx
414
        jg      .no_on_button ;if we release the pointer out of the button area
415
 
416
        movzx   ebx, [eax + SYS_BUTTON.width]
417
        add     edx, ebx
418
        cmp     ecx, edx
419
        jg      .no_on_button
420
 
421
        ; mouse y >= button y ?
422
        movzx   ebx, [eax + SYS_BUTTON.pslot]
423
        shl     ebx, 5
424
        add     ebx, window_data
425
        mov     ecx, [ebx + WDATA.box.top]
426
        movzx   edx, [eax + SYS_BUTTON.top]
427
        add     edx, ecx
428
        mov     cx, [MOUSE_Y]
429
        cmp     edx, ecx
430
        jg      .no_on_button
431
 
432
        movzx   ebx, [eax + SYS_BUTTON.height]
433
        add     edx, ebx
434
        cmp     ecx, edx
435
        jg      .no_on_button
436
 
437
        popa
438
 
439
        mov     byte[BTN_COUNT], 1 ; no of buttons in buffer
440
        pop     ebx
441
        mov     [BTN_BUFF], ebx   ; lets put the button id in buffer
442
        push    ebx
443
        pusha
444
        jmp     .yes_on_button
445
 
446
  .no_on_button:
447
        mov     byte[BTN_COUNT], 0 ; no of buttons in buffer
448
 
449
  .yes_on_button:
450
        mov     byte[MOUSE_DOWN], 0 ; mouse down -> do not draw
451
        popa
452
        pop     ebx
453
        popa
454
        ret
455
 
456
;==============================================================================
457
;///// private functions //////////////////////////////////////////////////////
458
;==============================================================================
459
 
460
;------------------------------------------------------------------------------
461
button._.dececx: ;/////////////////////////////////////////////////////////////
462
;------------------------------------------------------------------------------
1362 mikedld 463
;? 
1334 mikedld 464
;------------------------------------------------------------------------------
465
        sub     cl, 0x20
466
        jnc     @f
467
        xor     cl, cl
468
    @@: sub     ch, 0x20
469
        jnc     @f
470
        xor     ch, ch
471
    @@: rol     ecx, 16
472
        sub     cl, 0x20
473
        jnc     @f
474
        xor     cl, cl
475
    @@: rol     ecx, 16
476
        ret
477
 
478
;------------------------------------------------------------------------------
479
button._.incecx: ;/////////////////////////////////////////////////////////////
480
;------------------------------------------------------------------------------
1362 mikedld 481
;? 
1334 mikedld 482
;------------------------------------------------------------------------------
483
        add     cl, 0x20
484
        jnc     @f
485
        or      cl, -1
486
    @@: add     ch, 0x20
487
        jnc     @f
488
        or      ch, -1
489
    @@: rol     ecx, 16
490
        add     cl, 0x20
491
        jnc     @f
492
        or      cl, -1
493
    @@: rol     ecx, 16
494
        ret
495
 
496
;------------------------------------------------------------------------------
497
button._.incecx2: ;////////////////////////////////////////////////////////////
498
;------------------------------------------------------------------------------
1362 mikedld 499
;? 
1334 mikedld 500
;------------------------------------------------------------------------------
501
        add     cl, 0x14
502
        jnc     @f
503
        or      cl, -1
504
    @@: add     ch, 0x14
505
        jnc     @f
506
        or      ch, -1
507
    @@: rol     ecx, 16
508
        add     cl, 0x14
509
        jnc     @f
510
        or      cl, -1
511
    @@: rol     ecx, 16
512
        ret
513
 
514
;------------------------------------------------------------------------------
515
button._.button_dececx: ;//////////////////////////////////////////////////////
516
;------------------------------------------------------------------------------
1362 mikedld 517
;? 
1334 mikedld 518
;------------------------------------------------------------------------------
519
        cmp     [buttontype], 1
520
        jne     .finish
521
 
522
        push    eax
523
        mov     al, 1
524
        cmp     edi, 20
525
        jg      @f
526
        mov     al, 2
527
 
528
    @@: sub     cl, al
529
        jnc     @f
530
        xor     cl, cl
531
    @@: sub     ch, al
532
        jnc     @f
533
        xor     ch, ch
534
    @@: rol     ecx, 16
535
        sub     cl, al
536
        jnc     @f
537
        xor     cl, cl
538
    @@: rol     ecx, 16
539
 
540
        pop     eax
541
 
542
  .finish:
543
        ret
544
 
545
;------------------------------------------------------------------------------
546
button._.negative_button: ;////////////////////////////////////////////////////
547
;------------------------------------------------------------------------------
1362 mikedld 548
;? 
1334 mikedld 549
;------------------------------------------------------------------------------
1362 mikedld 550
        ; if requested, do not display button border on press.
1334 mikedld 551
        test    ebx, 0x20000000
1362 mikedld 552
        jnz     .exit
1334 mikedld 553
 
554
        pushad
555
 
1362 mikedld 556
        xchg    esi, eax
1334 mikedld 557
 
1362 mikedld 558
        movzx   ecx, [esi + SYS_BUTTON.pslot]
559
        shl     ecx, 5
560
        add     ecx, window_data
1334 mikedld 561
 
1362 mikedld 562
        mov     eax, dword[esi + SYS_BUTTON.left]
563
        mov     ebx, dword[esi + SYS_BUTTON.top]
564
        add     eax, [ecx + WDATA.box.left]
565
        add     ebx, [ecx + WDATA.box.top]
566
        push    eax ebx
567
        pop     edx ecx
568
        rol     eax, 16
569
        rol     ebx, 16
570
        add     ax, cx
571
        add     bx, dx
1334 mikedld 572
 
1362 mikedld 573
        mov     esi, 0x01000000
574
        call    draw_rectangle.forced
1334 mikedld 575
 
1362 mikedld 576
        popad
1334 mikedld 577
 
1362 mikedld 578
  .exit:
1334 mikedld 579
        ret