; <Lrz> 21.07.2006 ¤®¡ ¢«¥­  äã­ªæ¨ï ª­®¯ª¨ Del, ⥯¥àì ¬®¦­® 㤠«ïâì ᨬ¢®«ë ¯à¨ ¯®¬®é¨ ¤ ­­®© ª®« ¢¨è¨
; €¢â®à: …¢â¨å®¢ Œ ªá¨¬ (Maxxxx32) email: maxxxxm@mail.ru
; „ â  ¯®á«¥¤­¨å ¨§¬¥­¥­¨©: 13.07.06 10:40
;   ¯¨è¨â¥ ¢ ¨á室­®¬ ª®¤¥ ᢮¥© ¯à®£à ¬¬ë use_edit_box,
; íâ® ¢áâ ¢¨â ­¥®¡å®¤¨¬ë¥ ¯à®æ¥¤ãàë ¢ ª®¤ ¢ è¥© ¯à®£à ¬¬ë.
;  à®æ¥¤ãàë:
;   edit_box.draw - ¯®«­ ï ¯¥à¥à¨á®¢ª ;
;   edit_box.key - ®¡à ¡®âª  ª« ¢¨ âãàë;
;   edit_box.mouse - ®¡à ¡®âª  ¬ëè¨;
;   edit_box.focus - ãáâ ­®¢ª  䮪ãá ;
;   edit_box.blur - ¥£® à §¬ë¢ ­¨¥;
;   edit_box.get_n - ¯®«ãç¨âì ª®«¨ç¥á⢮ ¯à®à¨á®¢ë¢ ¥¬ëå ᨬ¢®«®¢.
;  à¨ ¢ë§®¢¥ «î¡ëå ¨§ íâ¨å ¯à®æ¥¤ãà ¢ ॣ¨áâॠedi á«¥¤ã¥â
; ®áâ ¢¨âì 㪠§ â¥«ì ­  áâàãªâãàã.
;  à¨¬¥à áâàãªâãàë:
; some_edit edit_box 100,10,30,0x00ffffff,0,0x00aaaaaa,0,255,some_edit_text
; ¤«¨­ , «¥¢®, ¢¥àå, 梥â ä®­ , 梥â à ¬ª¨, ¥á«¨ ¢ë¡à ­,
; 梥â à ¬ª¨, ¥á«¨ ­¥ ¢ë¡à ­, ¬ ªá¨¬ «ì­®¥ ª®«¨ç¥á⢮ ᨬ¢®«®¢,
; 㪠§ â¥«ì ­  ¡ãä¥à, £¤¥ ¡ã¤ãâ åà ­¨âáï ᨬ¢®«ë. ãä¥à ¤®«¦¥­
; ®ª ­ç¨¢ âìáï ­ã«¥¬, ­ ¯à¨¬¥à ¥á«¨ ¬ ªá¨¬ «ì­®¥ ª®«¨ç¥á⢮ 255:
;  some_edit_text:
;       rb      256 ;255+1

;  à¨¬¥à ¢ë§®¢  ¯à®æ¥¤ãàë:
;       mov     edi,some_edit
;       call    edit_box.draw

;  à¨ ¢ë§®¢¥ ¯à®æ¥¤ãàë edit_box.key ª®¤ ª« ¢¨è¨ ¤®«¦¥­
; ­ å®¤¨âáï ¢ ah, â® ¥áâì ¯¥à¥¤ ¢ë§®¢®¬ í⮩ ¯à®æ¥¤ãàë ­ ¤® ¢ë§¢ âì
; 2-ãî á¨á¥¬­ãî äã­ªæ¨î, ­ ¯à¨¬¥à:
;       mov     eax,2
;       int     0x40
;       mov     edi,some_edit1
;       call    edit_box.key
;       mov     edi,some_edit2
;       call    edit_box.key
;  ¥à¥¤ ¢ë§®¢®¬ ®¡à ¡®â稪  ¬ëè¨ á«¥¤ã¥â ¯à®¢¥à¨âì, ï¥âáï «¨ ®ª­®
;  ªâ¨¢­ë¬.
;  …᫨ 饫箪 ¬ëè¨ ¡ë« ¯à®©§¢¥¤¥­ §  ¯à¥¤¥« ¬¨ edit box
; 䮪ãá â¥àï¥âáï.
macro use_edit_box
{
edit_box:
ed_width        equ [edi]
ed_left         equ [edi+2]
ed_top          equ [edi+4]
ed_color        equ [edi+6]
ed_focus_border_color   equ [edi+10]
ed_blur_border_color    equ [edi+14]
ed_text_color   equ [edi+18]
ed_flags        equ [edi+22]
ed_max  equ [edi+24]
ed_size equ [edi+26]
ed_pos  equ [edi+28]
ed_offset       equ [edi+30]
ed_text equ [edi+32]
ed_height=14 ; ¢ëá®â 
;==========================================================
;=== ¯à®æ¥¤ãà  ¯à®à¨á®¢ª¨ =================================
;==========================================================
.draw:
pusha
;--- à¨á㥬 à ¬ªã ---
        call    .draw_border

.draw_bg_cursor_text:
;--- ¨§¬¥­ï¥¬ ᬥ饭¨¥, ¥á«¨ ­ ¤® ---
        call    .check_offset
;--- à¨á㥬 ¢­ãâ७­îî ®¡« áâì ---
        call    .draw_bg
.draw_cursor_text:
;--- à¨á㥬 ªãàá®à ---
        ;--- ¬®¦¥â ¥£® ­¥ ­ ¤® à¨á®¢ âì ----
        bt      word ed_flags,1
        jnc     @f
        call    .draw_cursor
@@:
        call    .draw_text
popa
ret

;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  ¯à®à¨á®¢ª¨ ⥪áâ  --------------------------
;----------------------------------------------------------
.draw_text:
;--- ¢ëç¨á«ï¥¬, ᪮«ìª® ¯®¬¥é ¥âáï ᨬ¢®«®¢ ---
        call    .get_n
;--- çâ®¡ë ¬ãá®à ­¥ à¨á®¢ âì ---
        movsx   esi,word ed_size
        sub     si,ed_offset
        cmp     ax,si
        ja      @f
        mov     si,ax
@@:

;--- à¨á㥬 ⥪áâ ---
        mov     eax,4
        mov     bx,ed_left
        add     bx,2
        shl     ebx,16
        mov     bx,ed_top
        add     bx,4
        mov     ecx,ed_text_color
        movsx   edx,word ed_offset
        add     edx,ed_text
        int     0x40
ret

;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  ¯à®à¨á®¢ª¨ ä®­  ----------------------------
;----------------------------------------------------------
.draw_bg_eax:
pusha
        movsx   ebx,ax
        lea     ebx,[ebx*2+ebx]
        shl     bx,1
        shl     ebx,16
        shr     eax,16
        lea     eax,[eax*2+eax]
        shl     ax,1
        add     ax,ed_left
        add     ax,2
        mov     bx,ax
        ror     ebx,16
        jmp     @f
.draw_bg:
pusha
        mov     bx,ed_left
        inc     bx
        shl     ebx,16
        mov     bx,ed_width
        dec     bx

@@:
        mov     cx,ed_top
        inc     cx
        shl     ecx,16
        mov     cx,ed_height
        dec     cx

        mov     edx,ed_color
        mov     eax,13
        int     0x40
popa
ret

;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  ¯®«ã祭¨ï ª®«¨ç¥á⢠ ᨬ¢®«®¢ --------------
;----------------------------------------------------------
.get_n:
        xor     edx,edx
        movsx   eax,word ed_width
        sub     ax,4
        mov     bx,6
        div     bx
ret

;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  à¨á®¢ ­¨ï ªãàá®à  --------------------------
;----------------------------------------------------------
.clear_cursor:
        mov     edx,ed_color
        jmp     @f
.draw_cursor:
        mov     edx,ed_text_color
@@:
        movsx   ebx,word ed_pos
        sub     bx,ed_offset
        ;lea     ebx,[ebx*2+ebx]
        ;shl     ebx,1
        imul    ebx,6
        add     bx,ed_left
        inc     bx
        push    bx
        shl     ebx,16
        pop     bx
        mov     cx,ed_top
        add     cx,2
        push    cx
        shl     ecx,16
        pop     cx
        add     cx,ed_height-4
        mov     eax,38
        int     0x40
ret

;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  à¨á®¢ ­¨ï à ¬ª¨ ----------------------------
;----------------------------------------------------------
.draw_border:
;--- 梥â à ¬ª¨ ---
        bt      word ed_flags,1
        mov     edx,ed_focus_border_color
        jc     @f
        mov     edx,ed_blur_border_color
@@:
;--- ᢥàåã ---
        mov     bx,ed_left
        push    bx
        shl     ebx,16
        pop     bx
        add     bx,ed_width
        mov     cx,ed_top
        push    cx
        shl     ecx,16
        pop     cx
        mov     eax,38
        int     0x40

;--- á­¨§ã ---
        push    cx
        add     cx,ed_height
        push    cx
        shl     ecx,16
        pop     cx
        int     0x40

;--- á«¥¢  ---
        pop     cx
        push    bx
        sub     bx,ed_width
        int     0x40

;--- á¯à ¢  ---
        pop     bx
        push    bx
        shl     ebx,16
        pop     bx
        int     0x40
ret

;----------------------------------------------------------
;--- ¯à®¢¥àª , § è¥« «¨ ªãàá®à §  £à ­¨æë ¨, ¥á«¨ ­ ¤®, ---
;--- ¨§¬¥­ï¥¬ ᬥ饭¨¥ ------------------------------------
;--- eax = 1, ¥á«¨ ­¥ ¨§¬¥­¨«®áì ¨«¨ eax = 0, ¥á«¨
; ¨§¬¥­¨«®áì
;----------------------------------------------------------
.check_offset:
        push    word ed_offset
        call    .get_n
;--- ¯à ¢¥¥ ---
        mov     bx,ed_offset
        add     bx,ax
        cmp     bx,ed_pos
        ja      @f
        mov     bx,ed_pos
        mov     cx,ax
        shr     cx,2
        sub     bx,cx
        mov     cx,ax
        shr     cx,1
        sub     bx,cx
        mov     ed_offset,bx
@@:
;--- «¥¢¥¥ ---
        mov     bx,ed_offset
        cmp     bx,ed_pos
        jb      @f
        mov     bx,ed_pos
        mov     cx,ax
        shr     cx,2
        sub     bx,cx
        jnc     $+5
        xor     bx,bx
        mov     ed_offset,bx
@@:
        xor     eax,eax
        pop     bx
        cmp     bx,ed_offset
        jne     @f
        inc     eax
@@:
ret

;==========================================================
;=== ®¡à ¡®âª  ª« ¢¨ âãàë =================================
;==========================================================
.key:
pusha
        bt      word ed_flags,1 ; ¥á«¨ ­¥ ¢ 䮪ãá¥, ¢ë室¨¬
        jc     @f
        popa
        ret
@@:

;----------------------------------------------------------
;--- ¯à®¢¥à塞, çâ® ­ ¦ â® --------------------------------
;----------------------------------------------------------
        cmp     ah,8
        je      .backspace
	cmp	ah,0xb6
	je	.delete
        cmp     ah,176
        je      .left
        cmp     ah,179
        je      .right
        cmp     ah,180
        je      .home
        cmp     ah,181
        je      .end

;--- ­ ¦ â  ¤àã£ ï ª« ¢¨è  ---
        bt      word ed_flags,15  ; ⮫쪮 æ¨äàë ?
        jnc     @f
        cmp     ah,'0'
        jb      .no_figure
        cmp     ah,'9'
        ja      .no_figure
        jmp     @f
.no_figure:
        popa
        ret
@@:
        ; ¯à®¢¥à塞, ­ å®¤¨âáï «¨ ªãàá®à ¢ ª®­æ¥
        mov     bx,ed_max
        cmp     bx,ed_pos
        jne     @f ; ¥á«¨ ¤ , ¢ ª®­¥æ ¯à®æ¥¤ãàë
        popa
        ret
@@:
        ; ᤢ¨£ ¥¬ ᨬ¢®«ë ¯®á«¥ ªãàá®à  ¢¯à ¢®
        mov     edx,ed_text
        dec     edx
        xor     ecx,ecx
        mov     cx,ed_size
        cmp     cx,ed_pos
        je      @f
.mov_right_next:
        mov     bh,[edx+ecx]
        mov     [edx+ecx+1],bh
        dec     cx
        cmp     cx,ed_pos
        jne     .mov_right_next
@@:


        ; ¢áâ ¢«ï¥¬ ª®¤ ª« ¢¨è¨ â㤠, £¤¥ ªãàá®à
        mov     edx,ed_text
        movsx   ebx,word ed_pos
        mov     [ebx+edx],ah

        call    .clear_cursor
        ; 㢥«¨ç¨¢ ¥¬ §­ ç¥­¨¥ à §¬¥à  ¨ ¯®§¨æ¨¨
        inc     word ed_pos
        mov     bx,ed_size
        cmp     bx,ed_max
        je      .draw_bg_cursor_text;.key_end_draw
        inc     word ed_size

        ;push    word ed_offset
        call    .check_offset
        ;pop     ax
        ;cmp     ax,ed_offset
        ;jne     .draw_bg_cursor_text
        test    eax,eax
        jz      .draw_bg_cursor_text

        call    .get_n
        sub     ax,ed_pos
        add     ax,ed_offset
        inc     ax
        shl     eax,16
        mov     ax,ed_pos
        sub     ax,ed_offset
        dec     ax
        ror     eax,16
        call    .draw_bg_eax

        jmp    .draw_cursor_text

        ;jmp     .draw_cursor_text;.key_end_draw

.delete:	
	mov	dx,ed_size
	mov	cx,ed_pos
	;inc	edx
	;add	ecx,900
	;sub	ecx,1
	cmp	dx,cx
	jg	@f
	popa
	ret

@@:	
	mov	edx,ed_text
	;dec	edx
.mov_stop_next:
	mov	bh,[edx+ecx+1]
	mov	[edx+ecx],bh
	inc	cx
	mov	bx,ed_size
	;dec	bx
	;dec	bx
	cmp	cx,bx
	jne	.mov_stop_next

	; 㬥­ìè ¥¬ §­ ç¥­¨¥ ¯®§¨æ¨¨ ¨ à §¬¥à 
	;dec	word ed_pos
	dec	word ed_size
		;push    word ed_offset
	call	.check_offset
	;pop     ax
	;cmp     ax,ed_offset
	;jne     .draw_bg_cursor_text
	test	eax,eax
	jz	.draw_bg_cursor_text

	call	.get_n
	sub	ax,ed_pos
	add	ax,ed_offset
	shl	eax,16
	mov	ax,ed_pos
	sub	ax,ed_offset
	ror	eax,16
	call	.draw_bg_eax

	jmp    .draw_cursor_text
popa
ret

;--- ­ ¦ â  ª« ¢¨è  backspace ---
.backspace:
        ; ¯à®¢¥à塞, ªãàá®à ã «¥¢®£® ªà ï ?
        mov     bx,ed_pos
        ;cmp     bx,0
        ;jne     @f; .key_end ; ¥á«¨ ¤ , ¢ ª®­¥æ
        test    bx,bx
        jnz     @f
        popa
        ret
@@:

        ; ᤢ¨£ ¥¬ ᨬ¢®«ë ¯®á«¥ ªãàá®à  ¢«¥¢®
        mov     edx,ed_text
        dec     edx
        movsx   ecx,word ed_pos

.mov_left_next:
        mov     bh,[edx+ecx+1]
        mov     [edx+ecx],bh
        inc     cx
        mov     bx,ed_size
        inc     bx
        cmp     cx,bx
        jne     .mov_left_next

        ; 㬥­ìè ¥¬ §­ ç¥­¨¥ ¯®§¨æ¨¨ ¨ à §¬¥à 
        dec     word ed_pos
        dec     word ed_size

        ;push    word ed_offset
        call    .check_offset
        ;pop     ax
        ;cmp     ax,ed_offset
        ;jne     .draw_bg_cursor_text
        test    eax,eax
        jz      .draw_bg_cursor_text

        call    .get_n
        sub     ax,ed_pos
        add     ax,ed_offset
        shl     eax,16
        mov     ax,ed_pos
        sub     ax,ed_offset
        ror     eax,16
        call    .draw_bg_eax

        jmp    .draw_cursor_text
popa
ret

;--- ­ ¦ â  ª« ¢¨è  left ---
.left:
        mov     bx,ed_pos
        ;cmp     bx,0
        ;je      @f
        test    bx,bx
        jz      @f
        call    .clear_cursor
        dec     word ed_pos
        call    .check_offset
        test    eax,eax
        jz      .draw_bg_cursor_text
        call    .draw_cursor
@@:
popa
ret

;--- ­ ¦ â  ª« ¢¨è  right ---
.right:
        mov     bx,ed_pos
        cmp     bx,ed_size
        je      @f
        call    .clear_cursor
        inc     word ed_pos
        call    .check_offset
        test    eax,eax
        jz      .draw_bg_cursor_text
        call    .draw_cursor
@@:
popa
ret

.home:
        mov     bx,ed_pos
        test    bx,bx
        jz      @f
        call    .clear_cursor
        xor     eax,eax
        mov     ed_pos,ax
        call    .check_offset
        test    eax,eax
        jz      .draw_bg_cursor_text
        call    .draw_cursor
@@:
popa
ret

.end:
        mov     bx,ed_pos
        cmp     bx,ed_size
        je      @f
        call    .clear_cursor
        mov     ax,ed_size
        mov     ed_pos,ax
        call    .check_offset
        test    eax,eax
        jz      .draw_bg_cursor_text
        call    .draw_cursor
@@:
popa
ret


;==========================================================
;=== ®¡à ¡®âª  ¬ëè¨ =======================================
;==========================================================
.mouse:
pusha
;----------------------------------------------------------
;--- ¯®«ãç ¥¬ á®áâ®ï­¨¥ ª­®¯®ª ¬ëè¨ -----------------------
;----------------------------------------------------------
        mov     eax,37
        mov     ebx,2
        int     0x40
;----------------------------------------------------------
;--- ¯à®¢¥à塞 á®áâ®ï­¨¥ ----------------------------------
;----------------------------------------------------------
        bt      eax,0
        jc      .mouse_left_button

        bt      eax,1
        jc      @f
        btr     word ed_flags,2
@@:

        popa
        ret

.mouse_left_button:
;----------------------------------------------------------
;--- ¯®«ãç ¥¬ ª®®à¤¨­ âë ¬ëè¨ -----------------------------
;----------------------------------------------------------
        bts     word ed_flags,2
        jc      .mouse_pressed
        mov     eax,37
        ;mov     ebx,1
        xor     ebx,ebx
        inc     ebx
        int     0x40
;----------------------------------------------------------
;--- ¯à®¢¥à塞, ¯®¯ ¤ ¥â «¨ ªãàá®à ¢ edit box -------------
;----------------------------------------------------------
        mov     bx,ed_top
        cmp     ax,bx
        jl      ._blur;.mouse_end_no_focus

        add     bx,ed_height
        cmp     ax,bx
        jg      ._blur;.mouse_end_no_focus

        shr     eax,16

        mov     bx,ed_left
        cmp     ax,bx
        jl      ._blur;.mouse_end_no_focus

        add     bx,ed_width
        cmp     ax,bx
        jg      ._blur;.mouse_end_no_focus

;--- ¨§¬¥­ï¥¬ ¯®§¨æ¨î ªãàá®à  ---
        push    eax
        call    .clear_cursor
        pop     eax
        xor     dx,dx
        sub     ax,ed_left
        add     ax,2
        mov     bx,6
        div     bx
        add     ax,ed_offset
        cmp     ax,ed_size
        jna      @f
        mov     ax,ed_size
@@:
        mov     ed_pos,ax
        call    .check_offset
        test    eax,eax
        jz      .draw_bg_cursor_text
        call    .draw_cursor

        call    .focus

.mouse_pressed:
popa
ret

;.mouse_end_no_focus:
;        call    .blur
;popa
;ret


;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  ãáâ ­®¢ª¨ 䮪ãá  ---------------------------
;----------------------------------------------------------
.blur:
pusha
._blur:
        bt      word ed_flags,14
        jc      @f
        btr     word ed_flags,1
        jnc     @f
        call    .clear_cursor
        jmp     .blur_end
.focus:
pusha
        bts     word ed_flags,1
        jc      @f
        call    .draw_cursor
.blur_end:
        call    .draw_border
@@:
popa
ret

;----------------------------------------------------------
;--- ¯à®æ¥¤ãà  à §¬ë¢ ­¨ï 䮪ãá  --------------------------
;----------------------------------------------------------
;.blur:
;pusha
;._blur:
        ;btr      word ed_flags,1
        ;jnc     @f
        ;call    .draw_border
        ;call    .clear_cursor
;@@:
;popa
;ret
}
ed_figure_only=1000000000000000b
ed_always_focus=100000000000000b
ed_focus=10b
ed_struc_size=36
macro draw_edit_boxes start,end
{
        mov     edi,start
        mov     ecx,((end-start)/ed_struc_size)
@@:
        call    edit_box.draw
        add     edi,ed_struc_size
        loop    @b
}

macro mouse_edit_boxes start,end
{
        mov     edi,start
        mov     ecx,((end-start)/ed_struc_size)
@@:
        call    edit_box.mouse
        add     edi,ed_struc_size
        loop    @b
}

macro key_edit_boxes start,end
{
        mov     edi,start
        mov     ecx,((end-start)/ed_struc_size)
@@:
        call    edit_box.key
        add     edi,ed_struc_size
        loop    @b
}

struc  edit_box width,left,top,color,focus_border_color,\
       blur_border_color,text_color,max,text,flags,size
{
.width dw width
.left dw left
.top dw top
.color dd color
.focus_border_color dd focus_border_color
.blur_border_color dd blur_border_color
.text_color dd text_color
.flags dw flags+0
.max dw max
.size dw size+0
.pos dw 0
.offset dw 0
.text dd text
}

macro edit_boxes_set_sys_color start,end,color_table
{
        mov     edi,start
        mov     ecx,((end-start)/ed_struc_size)
        mov     esi,color_table
@@:
        mov     eax,[esi+36]
        mov     ebx,[esi+20]
        mov     ed_focus_border_color,eax
        shr     bh,1
        shr     bl,1
        shr     ah,1
        shr     al,1
        add     ah,bh
        add     al,bl
        ror     eax,16
        ror     ebx,16
        shr     bl,1
        shr     al,1
        add     al,bl
        ror     eax,16
        mov     ed_blur_border_color,eax
        add     edi,ed_struc_size
        loop    @b
}

macro draw_edit_box ed_ptr
{
        mov     edi,ed_ptr
        call    edit_box.draw
}

macro mouse_edit_box ed_ptr
{
        mov     edi,ed_ptr
        call    edit_box.mouse
}

macro key_edit_box ed_ptr
{
        mov     edi,ed_ptr
        call    edit_box.key
}