; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TCheckbox object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents GUI checkbox.
;_________________________________________________________________________________________
module "TCheckbox library"


; Button states for the field TCheckbox._state

cbsNeutral    = 0
cbsHovered    = 1
cbsPressed    = 2

cbsDisabled   = 3


object TCheckbox, TWindow

; private fields

  ._state       dd ?      ; internal state variable.

  ._OnClick     dd ?

  ._checked     dd ?

; parameters

  param .Checked, .GetChecked, .SetChecked
  param .OnClick, ._OnClick, ._OnClick

; methods

  ; parameters handling methods

  method .GetChecked
  method .SetChecked, .value

  ; system events methods

  method .Create, .Parent

  method .Paint

  method .EventMouseEnter
  method .EventMouseLeave

  method .EventButtonPress, .button, .kbdState, .x, .y
  method .EventButtonRelease, .button, .kbdState, .x, .y

  method .EventKeyPress, .utf8, .scancode, .kbdState
  method .EventKeyRelease, .scancode, .kbdState

endobj


; new


method TCheckbox.Create
begin
        inherited [.Parent]

        mov     eax, [.self]
        mov     [eax+TCheckbox.__want_focus], TRUE
        mov     [eax+TCheckbox._cursor], mcHand
        return
endp





method TCheckbox.Paint

 .bounds TBounds
 .canvas dd ?

 .caption dd ?
 .enabled dd ?
 .checked dd ?

begin
        pushad

        mov     esi, [.self]

        get     edx, esi, TCheckbox:Action
        test    edx, edx
        jz      .get_normal

        get     eax, edx, TAction:Caption
        stdcall StrDupMem, eax
        mov     [.caption], eax

        get     [.checked], edx, TAction:Checked
        jmp     .get_enabled

.get_normal:

        get     [.caption], esi, TCheckbox:Caption
        get     [.checked], esi, TCheckbox:Checked


.get_enabled:
        get     [.enabled], esi, TCheckbox:Enabled

.paint_it:
        get     eax, esi, TWindow:Canvas
        mov     [.canvas], eax

        test    eax, eax
        jz      .finish


        mov     eax, [esi+TCheckbox._state]
        cmp     [.enabled], 0
        jne     .state_ok

        mov     eax, cbsDisabled

.state_ok:
        mov     edi, [GUI.clCheckboxBack+4*eax]    ; background color

        get     ecx, esi, TCheckbox:height
        mov     edx, [GUI.cbIconSize]
        sub     ecx, edx
        sar     ecx, 1

        mov     [.bounds.x], 0
        mov     [.bounds.y], ecx
        mov     [.bounds.width], edx
        mov     [.bounds.height], edx

        mov     eax, [GUI.clDialogBk]
        and     eax, $00ffffff
        or      eax, $01000000
        stdcall DrawSolidRect, [.canvas], 0, 0, [esi+TCheckbox._width], [esi+TCheckbox._height], eax

        lea     eax, [.bounds]

        mov     ebx, [GUI.borderCheckbox]
        cmp     [.enabled], 0
        jne     .border_ok

        or      ebx, bxDisabled

.border_ok:
        stdcall DrawBoxDefault, [.canvas], eax, edi, ebx, [GUI.boxBorderWidth]

        mov     [.bounds.x], 0
        mov     [.bounds.y], ecx
        mov     [.bounds.width], edx
        mov     [.bounds.height], edx

; first draw the icon and then resize bounds for the text.

        cmp     [.checked], 0
        je      .icon_ok

        mov     eax, [GUI.iconCheckedGray]
        cmp     [.enabled], 0
        je      .draw_icon

        mov     eax, [GUI.iconChecked]

.draw_icon:

        stdcall BlendImage, [.canvas], [.bounds.x], [.bounds.y], eax, 0, 0, [eax+TImage.width], [eax+TImage.height]

.icon_ok:
        mov     ecx, [.bounds.width]
        mov     edx, [esi+TCheckbox._width]
        mov     ebx, [esi+TCheckbox._height]

        add     ecx, [GUI.cbMargin]
        sub     edx, ecx

        mov     eax, [.caption]
        test    eax, eax
        jz      .textok

        mov     edi, [GUI.clCheckboxTxt]
        cmp     [.enabled], 0
        jne     .txt_color_ok

        mov     edi, [GUI.clCheckboxTxtGray]

.txt_color_ok:
        stdcall DrawTextBox, [.canvas], eax, ecx, 0, edx, ebx, 0, dtfAlignLeft or dtfAlignMiddle, [GUI.DefaultFont], edi
        stdcall StrDel, eax

.textok:
        cmp     esi, [__FocusedWindow]
        jne     .not_focused

        mov     eax, [.bounds.y]
        add     eax, 15
        stdcall DrawSolidRect, [.canvas], 0, eax, 13, 2, [GUI.clBorderFocused]

.not_focused:
.finish:

        inherited

        popad
        return
endp




method TCheckbox.EventMouseEnter
begin
        mov     eax, [.self]
        mov     [eax+TCheckbox._state], cbsHovered
        exec    eax, TCheckbox:Refresh

        inherited
        return
endp




method TCheckbox.EventMouseLeave
begin
        mov     eax, [.self]

        mov     [eax+TCheckbox._state], cbsNeutral
        exec    eax, TCheckbox:Refresh

        inherited
        return
endp




method TCheckbox.EventButtonPress
begin
        push    eax

        mov     eax, [.self]
        mov     [eax+TCheckbox._state], cbsPressed

        get     eax, [.self], TCheckbox:Checked
        xor     eax, 1
        set     [.self], TCheckbox:Checked, eax

        get     eax, [.self], TCheckbox:OnClick
        test    eax, eax
        jz      .finish

        stdcall eax, [.self], [.button]

.finish:
        exec    [.self], TCheckbox:Refresh
        pop     eax
        return
endp



method TCheckbox.EventButtonRelease
begin
        pushad

        mov     esi, [.self]
        mov     [esi+TCheckbox._state], cbsHovered
        exec    esi, TCheckbox:Refresh

        popad
        return
endp




method TCheckbox.EventKeyPress
begin
        push    ecx

        cmp     [.utf8], ' '
        jne     .finish

        mov     ecx, [.self]
        cmp     [ecx+TCheckbox._state], cbsPressed
        je      .finish

        exec    ecx, TWindow:EventButtonPress, mbLeft, [.kbdState], 0, 0

        mov     [ecx+TCheckbox._state], cbsPressed
        exec    ecx, TWindow:Refresh

.finish:
        inherited [.utf8], [.scancode], [.kbdState]
        pop     ecx
        return
endp




method TCheckbox.EventKeyRelease
begin
        push    ecx

        mov     ecx, [.self]
        mov     [ecx+TCheckbox._state], cbsNeutral

        exec    ecx, TWindow:Refresh
        pop     ecx

        return
endp



method TCheckbox.GetChecked
begin
        push    ecx edx

        mov     edx, [.self]
        mov     ecx, [edx+TCheckbox.__action]
        jecxz   .native

        get     eax, ecx, TAction:Checked
        jmp     .finish

.native:
        mov     eax, [edx+TCheckbox._checked]

.finish:
        pop     edx ecx
        return
endp



method TCheckbox.SetChecked
begin
        pushad

        mov     ecx, [.self]
        mov     eax, [.value]

        get     edx, ecx, TCheckbox:Checked

        cmp     eax, edx
        je      .finish

        cmp     [ecx+TCheckbox.__action], 0
        je      .action_ok

        set     [ecx+TCheckbox.__action], TAction:Checked, eax

.action_ok:
        mov     [ecx+TCheckbox._checked], eax
        exec    ecx, TWindow:Refresh

.finish:
        popad
        return
endp




endmodule