Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; <Lrz> 21.07.2006 добавлена функция кнопки Del, теперь можно удалять символы при помощи данной колавиши
  2. ; Автор: Евтихов Максим (Maxxxx32) email: maxxxxm@mail.ru
  3. ; Дата последних изменений: 13.07.06 10:40
  4. ;  Напишите в исходном коде своей программы use_edit_box,
  5. ; это вставит необходимые процедуры в код вашей программы.
  6. ;  Процедуры:
  7. ;   edit_box.draw - полная перерисовка;
  8. ;   edit_box.key - обработка клавиатуры;
  9. ;   edit_box.mouse - обработка мыши;
  10. ;   edit_box.focus - установка фокуса;
  11. ;   edit_box.blur - его размывание;
  12. ;   edit_box.get_n - получить количество прорисовываемых символов.
  13. ;  При вызове любых из этих процедур в регистре edi следует
  14. ; оставить указатель на структуру.
  15. ;  Пример структуры:
  16. ; some_edit edit_box 100,10,30,0x00ffffff,0,0x00aaaaaa,0,255,some_edit_text
  17. ; длина, лево, верх, цвет фона, цвет рамки, если выбран,
  18. ; цвет рамки, если не выбран, максимальное количество символов,
  19. ; указатель на буфер, где будут хранится символы. Буфер должен
  20. ; оканчиваться нулем, например если максимальное количество 255:
  21. ;  some_edit_text:
  22. ;       rb      256 ;255+1
  23.  
  24. ;  Пример вызова процедуры:
  25. ;       mov     edi,some_edit
  26. ;       call    edit_box.draw
  27.  
  28. ;  При вызове процедуры edit_box.key код клавиши должен
  29. ; находится в ah, то есть перед вызовом этой процедуры надо вызвать
  30. ; 2-ую сисемную функцию, например:
  31. ;       mov     eax,2
  32. ;       int     0x40
  33. ;       mov     edi,some_edit1
  34. ;       call    edit_box.key
  35. ;       mov     edi,some_edit2
  36. ;       call    edit_box.key
  37. ;  Перед вызовом обработчика мыши следует проверить, является ли окно
  38. ; активным.
  39. ;  Если щелчок мыши был пройзведен за пределами edit box
  40. ; фокус теряется.
  41. macro use_edit_box
  42. {
  43. edit_box:
  44. ed_width       equ [edi]
  45. ed_left         equ [edi+2]
  46. ed_top         equ [edi+4]
  47. ed_color       equ [edi+6]
  48. ed_focus_border_color   equ [edi+10]
  49. ed_blur_border_color   equ [edi+14]
  50. ed_text_color   equ [edi+18]
  51. ed_flags       equ [edi+22]
  52. ed_max equ [edi+24]
  53. ed_size equ [edi+26]
  54. ed_pos equ [edi+28]
  55. ed_offset       equ [edi+30]
  56. ed_text equ [edi+32]
  57. ed_height=14 ; высота
  58. ;==========================================================
  59. ;=== процедура прорисовки =================================
  60. ;==========================================================
  61. .draw:
  62. pusha
  63. ;--- рисуем рамку ---
  64.         call    .draw_border
  65.  
  66. .draw_bg_cursor_text:
  67. ;--- изменяем смещение, если надо ---
  68.         call    .check_offset
  69. ;--- рисуем внутреннюю область ---
  70.         call    .draw_bg
  71. .draw_cursor_text:
  72. ;--- рисуем курсор ---
  73.         ;--- может его не надо рисовать ----
  74.         bt      word ed_flags,1
  75.         jnc     @f
  76.         call    .draw_cursor
  77. @@:
  78.         call    .draw_text
  79. popa
  80. ret
  81.  
  82. ;----------------------------------------------------------
  83. ;--- процедура прорисовки текста --------------------------
  84. ;----------------------------------------------------------
  85. .draw_text:
  86. ;--- вычисляем, сколько помещается символов ---
  87.         call    .get_n
  88. ;--- чтобы мусор не рисовать ---
  89.         movsx   esi,word ed_size
  90.         sub     si,ed_offset
  91.         cmp     ax,si
  92.         ja      @f
  93.         mov     si,ax
  94. @@:
  95.  
  96. ;--- рисуем текст ---
  97.         mov     eax,4
  98.         mov     bx,ed_left
  99.         add     bx,2
  100.         shl     ebx,16
  101.         mov     bx,ed_top
  102.         add     bx,4
  103.         mov     ecx,ed_text_color
  104.         movsx   edx,word ed_offset
  105.         add     edx,ed_text
  106.         int     0x40
  107. ret
  108.  
  109. ;----------------------------------------------------------
  110. ;--- процедура прорисовки фона ----------------------------
  111. ;----------------------------------------------------------
  112. .draw_bg_eax:
  113. pusha
  114.         movsx   ebx,ax
  115.         lea     ebx,[ebx*2+ebx]
  116.         shl     bx,1
  117.         shl     ebx,16
  118.         shr     eax,16
  119.         lea     eax,[eax*2+eax]
  120.         shl     ax,1
  121.         add     ax,ed_left
  122.         add     ax,2
  123.         mov     bx,ax
  124.         ror     ebx,16
  125.         jmp     @f
  126. .draw_bg:
  127. pusha
  128.         mov     bx,ed_left
  129.         inc     bx
  130.         shl     ebx,16
  131.         mov     bx,ed_width
  132.         dec     bx
  133.  
  134. @@:
  135.         mov     cx,ed_top
  136.         inc     cx
  137.         shl     ecx,16
  138.         mov     cx,ed_height
  139.         dec     cx
  140.  
  141.         mov     edx,ed_color
  142.         mov     eax,13
  143.         int     0x40
  144. popa
  145. ret
  146.  
  147. ;----------------------------------------------------------
  148. ;--- процедура получения количества символов --------------
  149. ;----------------------------------------------------------
  150. .get_n:
  151.         xor     edx,edx
  152.         movsx   eax,word ed_width
  153.         sub     ax,4
  154.         mov     bx,6
  155.         div     bx
  156. ret
  157.  
  158. ;----------------------------------------------------------
  159. ;--- процедура рисования курсора --------------------------
  160. ;----------------------------------------------------------
  161. .clear_cursor:
  162.         mov     edx,ed_color
  163.         jmp     @f
  164. .draw_cursor:
  165.         mov     edx,ed_text_color
  166. @@:
  167.         movsx   ebx,word ed_pos
  168.         sub     bx,ed_offset
  169.         ;lea     ebx,[ebx*2+ebx]
  170.         ;shl     ebx,1
  171.         imul    ebx,6
  172.         add     bx,ed_left
  173.         inc     bx
  174.         push    bx
  175.         shl     ebx,16
  176.         pop     bx
  177.         mov     cx,ed_top
  178.         add     cx,2
  179.         push    cx
  180.         shl     ecx,16
  181.         pop     cx
  182.         add     cx,ed_height-4
  183.         mov     eax,38
  184.         int     0x40
  185. ret
  186.  
  187. ;----------------------------------------------------------
  188. ;--- процедура рисования рамки ----------------------------
  189. ;----------------------------------------------------------
  190. .draw_border:
  191. ;--- цвет рамки ---
  192.         bt      word ed_flags,1
  193.         mov     edx,ed_focus_border_color
  194.         jc     @f
  195.         mov     edx,ed_blur_border_color
  196. @@:
  197. ;--- сверху ---
  198.         mov     bx,ed_left
  199.         push    bx
  200.         shl     ebx,16
  201.         pop     bx
  202.         add     bx,ed_width
  203.         mov     cx,ed_top
  204.         push    cx
  205.         shl     ecx,16
  206.         pop     cx
  207.         mov     eax,38
  208.         int     0x40
  209.  
  210. ;--- снизу ---
  211.         push    cx
  212.         add     cx,ed_height
  213.         push    cx
  214.         shl     ecx,16
  215.         pop     cx
  216.         int     0x40
  217.  
  218. ;--- слева ---
  219.         pop     cx
  220.         push    bx
  221.         sub     bx,ed_width
  222.         int     0x40
  223.  
  224. ;--- справа ---
  225.         pop     bx
  226.         push    bx
  227.         shl     ebx,16
  228.         pop     bx
  229.         int     0x40
  230. ret
  231.  
  232. ;----------------------------------------------------------
  233. ;--- проверка, зашел ли курсор за границы и, если надо, ---
  234. ;--- изменяем смещение ------------------------------------
  235. ;--- eax = 1, если не изменилось или eax = 0, если
  236. ; изменилось
  237. ;----------------------------------------------------------
  238. .check_offset:
  239.         push    word ed_offset
  240.         call    .get_n
  241. ;--- правее ---
  242.         mov     bx,ed_offset
  243.         add     bx,ax
  244.         cmp     bx,ed_pos
  245.         ja      @f
  246.         mov     bx,ed_pos
  247.         mov     cx,ax
  248.         shr     cx,2
  249.         sub     bx,cx
  250.         mov     cx,ax
  251.         shr     cx,1
  252.         sub     bx,cx
  253.         mov     ed_offset,bx
  254. @@:
  255. ;--- левее ---
  256.         mov     bx,ed_offset
  257.         cmp     bx,ed_pos
  258.         jb      @f
  259.         mov     bx,ed_pos
  260.         mov     cx,ax
  261.         shr     cx,2
  262.         sub     bx,cx
  263.         jnc     $+5
  264.         xor     bx,bx
  265.         mov     ed_offset,bx
  266. @@:
  267.         xor     eax,eax
  268.         pop     bx
  269.         cmp     bx,ed_offset
  270.         jne     @f
  271.         inc     eax
  272. @@:
  273. ret
  274.  
  275. ;==========================================================
  276. ;=== обработка клавиатуры =================================
  277. ;==========================================================
  278. .key:
  279. pusha
  280.         bt      word ed_flags,1 ; если не в фокусе, выходим
  281.         jc     @f
  282.         popa
  283.         ret
  284. @@:
  285.  
  286. ;----------------------------------------------------------
  287. ;--- проверяем, что нажато --------------------------------
  288. ;----------------------------------------------------------
  289.         cmp     ah,8
  290.         je      .backspace
  291.         cmp     ah,0xb6
  292.         je      .delete
  293.         cmp     ah,176
  294.         je      .left
  295.         cmp     ah,179
  296.         je      .right
  297.         cmp     ah,180
  298.         je      .home
  299.         cmp     ah,181
  300.         je      .end
  301.  
  302. ;--- нажата другая клавиша ---
  303.         bt      word ed_flags,15  ; только цифры ?
  304.         jnc     @f
  305.         cmp     ah,'0'
  306.         jb      .no_figure
  307.         cmp     ah,'9'
  308.         ja      .no_figure
  309.         jmp     @f
  310. .no_figure:
  311.         popa
  312.         ret
  313. @@:
  314.         ; проверяем, находится ли курсор в конце
  315.         mov     bx,ed_max
  316.         cmp     bx,ed_pos
  317.         jne     @f ; если да, в конец процедуры
  318.         popa
  319.         ret
  320. @@:
  321.         ; сдвигаем символы после курсора вправо
  322.         mov     edx,ed_text
  323.         dec     edx
  324.         xor     ecx,ecx
  325.         mov     cx,ed_size
  326.         cmp     cx,ed_pos
  327.         je      @f
  328. .mov_right_next:
  329.         mov     bh,[edx+ecx]
  330.         mov     [edx+ecx+1],bh
  331.         dec     cx
  332.         cmp     cx,ed_pos
  333.         jne     .mov_right_next
  334. @@:
  335.  
  336.  
  337.         ; вставляем код клавиши туда, где курсор
  338.         mov     edx,ed_text
  339.         movsx   ebx,word ed_pos
  340.         mov     [ebx+edx],ah
  341.  
  342.         call    .clear_cursor
  343.         ; увеличиваем значение размера и позиции
  344.         inc     word ed_pos
  345.         mov     bx,ed_size
  346.         cmp     bx,ed_max
  347.         je      .draw_bg_cursor_text;.key_end_draw
  348.         inc     word ed_size
  349.  
  350.         ;push    word ed_offset
  351.         call    .check_offset
  352.         ;pop     ax
  353.         ;cmp     ax,ed_offset
  354.         ;jne     .draw_bg_cursor_text
  355.         test    eax,eax
  356.         jz      .draw_bg_cursor_text
  357.  
  358.         call    .get_n
  359.         sub     ax,ed_pos
  360.         add     ax,ed_offset
  361.         inc     ax
  362.         shl     eax,16
  363.         mov     ax,ed_pos
  364.         sub     ax,ed_offset
  365.         dec     ax
  366.         ror     eax,16
  367.         call    .draw_bg_eax
  368.  
  369.         jmp    .draw_cursor_text
  370.  
  371.         ;jmp     .draw_cursor_text;.key_end_draw
  372.  
  373. .delete:       
  374.         mov     dx,ed_size
  375.         mov     cx,ed_pos
  376.         ;inc    edx
  377.         ;add    ecx,900
  378.         ;sub    ecx,1
  379.         cmp     dx,cx
  380.         jg      @f
  381.         popa
  382.         ret
  383.  
  384. @@:    
  385.         mov     edx,ed_text
  386.         ;dec    edx
  387. .mov_stop_next:
  388.         mov     bh,[edx+ecx+1]
  389.         mov     [edx+ecx],bh
  390.         inc     cx
  391.         mov     bx,ed_size
  392.         ;dec    bx
  393.         ;dec    bx
  394.         cmp     cx,bx
  395.         jne     .mov_stop_next
  396.  
  397.         ; уменьшаем значение позиции и размера
  398.         ;dec    word ed_pos
  399.         dec     word ed_size
  400.                 ;push    word ed_offset
  401.         call    .check_offset
  402.         ;pop     ax
  403.         ;cmp     ax,ed_offset
  404.         ;jne     .draw_bg_cursor_text
  405.         test    eax,eax
  406.         jz      .draw_bg_cursor_text
  407.  
  408.         call    .get_n
  409.         sub     ax,ed_pos
  410.         add     ax,ed_offset
  411.         shl     eax,16
  412.         mov     ax,ed_pos
  413.         sub     ax,ed_offset
  414.         ror     eax,16
  415.         call    .draw_bg_eax
  416.  
  417.         jmp    .draw_cursor_text
  418. popa
  419. ret
  420.  
  421. ;--- нажата клавиша backspace ---
  422. .backspace:
  423.         ; проверяем, курсор у левого края ?
  424.         mov     bx,ed_pos
  425.         ;cmp     bx,0
  426.         ;jne     @f; .key_end ; если да, в конец
  427.         test    bx,bx
  428.         jnz     @f
  429.         popa
  430.         ret
  431. @@:
  432.  
  433.         ; сдвигаем символы после курсора влево
  434.         mov     edx,ed_text
  435.         dec     edx
  436.         movsx   ecx,word ed_pos
  437.  
  438. .mov_left_next:
  439.         mov     bh,[edx+ecx+1]
  440.         mov     [edx+ecx],bh
  441.         inc     cx
  442.         mov     bx,ed_size
  443.         inc     bx
  444.         cmp     cx,bx
  445.         jne     .mov_left_next
  446.  
  447.         ; уменьшаем значение позиции и размера
  448.         dec     word ed_pos
  449.         dec     word ed_size
  450.  
  451.         ;push    word ed_offset
  452.         call    .check_offset
  453.         ;pop     ax
  454.         ;cmp     ax,ed_offset
  455.         ;jne     .draw_bg_cursor_text
  456.         test    eax,eax
  457.         jz      .draw_bg_cursor_text
  458.  
  459.         call    .get_n
  460.         sub     ax,ed_pos
  461.         add     ax,ed_offset
  462.         shl     eax,16
  463.         mov     ax,ed_pos
  464.         sub     ax,ed_offset
  465.         ror     eax,16
  466.         call    .draw_bg_eax
  467.  
  468.         jmp    .draw_cursor_text
  469. popa
  470. ret
  471.  
  472. ;--- нажата клавиша left ---
  473. .left:
  474.         mov     bx,ed_pos
  475.         ;cmp     bx,0
  476.         ;je      @f
  477.         test    bx,bx
  478.         jz      @f
  479.         call    .clear_cursor
  480.         dec     word ed_pos
  481.         call    .check_offset
  482.         test    eax,eax
  483.         jz      .draw_bg_cursor_text
  484.         call    .draw_cursor
  485. @@:
  486. popa
  487. ret
  488.  
  489. ;--- нажата клавиша right ---
  490. .right:
  491.         mov     bx,ed_pos
  492.         cmp     bx,ed_size
  493.         je      @f
  494.         call    .clear_cursor
  495.         inc     word ed_pos
  496.         call    .check_offset
  497.         test    eax,eax
  498.         jz      .draw_bg_cursor_text
  499.         call    .draw_cursor
  500. @@:
  501. popa
  502. ret
  503.  
  504. .home:
  505.         mov     bx,ed_pos
  506.         test    bx,bx
  507.         jz      @f
  508.         call    .clear_cursor
  509.         xor     eax,eax
  510.         mov     ed_pos,ax
  511.         call    .check_offset
  512.         test    eax,eax
  513.         jz      .draw_bg_cursor_text
  514.         call    .draw_cursor
  515. @@:
  516. popa
  517. ret
  518.  
  519. .end:
  520.         mov     bx,ed_pos
  521.         cmp     bx,ed_size
  522.         je      @f
  523.         call    .clear_cursor
  524.         mov     ax,ed_size
  525.         mov     ed_pos,ax
  526.         call    .check_offset
  527.         test    eax,eax
  528.         jz      .draw_bg_cursor_text
  529.         call    .draw_cursor
  530. @@:
  531. popa
  532. ret
  533.  
  534.  
  535. ;==========================================================
  536. ;=== обработка мыши =======================================
  537. ;==========================================================
  538. .mouse:
  539. pusha
  540. ;----------------------------------------------------------
  541. ;--- получаем состояние кнопок мыши -----------------------
  542. ;----------------------------------------------------------
  543.         mov     eax,37
  544.         mov     ebx,2
  545.         int     0x40
  546. ;----------------------------------------------------------
  547. ;--- проверяем состояние ----------------------------------
  548. ;----------------------------------------------------------
  549.         bt      eax,0
  550.         jc      .mouse_left_button
  551.  
  552.         bt      eax,1
  553.         jc      @f
  554.         btr     word ed_flags,2
  555. @@:
  556.  
  557.         popa
  558.         ret
  559.  
  560. .mouse_left_button:
  561. ;----------------------------------------------------------
  562. ;--- получаем координаты мыши -----------------------------
  563. ;----------------------------------------------------------
  564.         bts     word ed_flags,2
  565.         jc      .mouse_pressed
  566.         mov     eax,37
  567.         ;mov     ebx,1
  568.         xor     ebx,ebx
  569.         inc     ebx
  570.         int     0x40
  571. ;----------------------------------------------------------
  572. ;--- проверяем, попадает ли курсор в edit box -------------
  573. ;----------------------------------------------------------
  574.         mov     bx,ed_top
  575.         cmp     ax,bx
  576.         jl      ._blur;.mouse_end_no_focus
  577.  
  578.         add     bx,ed_height
  579.         cmp     ax,bx
  580.         jg      ._blur;.mouse_end_no_focus
  581.  
  582.         shr     eax,16
  583.  
  584.         mov     bx,ed_left
  585.         cmp     ax,bx
  586.         jl      ._blur;.mouse_end_no_focus
  587.  
  588.         add     bx,ed_width
  589.         cmp     ax,bx
  590.         jg      ._blur;.mouse_end_no_focus
  591.  
  592. ;--- изменяем позицию курсора ---
  593.         push    eax
  594.         call    .clear_cursor
  595.         pop     eax
  596.         xor     dx,dx
  597.         sub     ax,ed_left
  598.         add     ax,2
  599.         mov     bx,6
  600.         div     bx
  601.         add     ax,ed_offset
  602.         cmp     ax,ed_size
  603.         jna      @f
  604.         mov     ax,ed_size
  605. @@:
  606.         mov     ed_pos,ax
  607.         call    .check_offset
  608.         test    eax,eax
  609.         jz      .draw_bg_cursor_text
  610.         call    .draw_cursor
  611.  
  612.         call    .focus
  613.  
  614. .mouse_pressed:
  615. popa
  616. ret
  617.  
  618. ;.mouse_end_no_focus:
  619. ;        call    .blur
  620. ;popa
  621. ;ret
  622.  
  623.  
  624. ;----------------------------------------------------------
  625. ;--- процедура установки фокуса ---------------------------
  626. ;----------------------------------------------------------
  627. .blur:
  628. pusha
  629. ._blur:
  630.         bt      word ed_flags,14
  631.         jc      @f
  632.         btr     word ed_flags,1
  633.         jnc     @f
  634.         call    .clear_cursor
  635.         jmp     .blur_end
  636. .focus:
  637. pusha
  638.         bts     word ed_flags,1
  639.         jc      @f
  640.         call    .draw_cursor
  641. .blur_end:
  642.         call    .draw_border
  643. @@:
  644. popa
  645. ret
  646.  
  647. ;----------------------------------------------------------
  648. ;--- процедура размывания фокуса --------------------------
  649. ;----------------------------------------------------------
  650. ;.blur:
  651. ;pusha
  652. ;._blur:
  653.         ;btr      word ed_flags,1
  654.         ;jnc     @f
  655.         ;call    .draw_border
  656.         ;call    .clear_cursor
  657. ;@@:
  658. ;popa
  659. ;ret
  660. }
  661. ed_figure_only=1000000000000000b
  662. ed_always_focus=100000000000000b
  663. ed_focus=10b
  664. ed_struc_size=36
  665. macro draw_edit_boxes start,end
  666. {
  667.         mov     edi,start
  668.         mov     ecx,((end-start)/ed_struc_size)
  669. @@:
  670.         call    edit_box.draw
  671.         add     edi,ed_struc_size
  672.         loop    @b
  673. }
  674.  
  675. macro mouse_edit_boxes start,end
  676. {
  677.         mov     edi,start
  678.         mov     ecx,((end-start)/ed_struc_size)
  679. @@:
  680.         call    edit_box.mouse
  681.         add     edi,ed_struc_size
  682.         loop    @b
  683. }
  684.  
  685. macro key_edit_boxes start,end
  686. {
  687.         mov     edi,start
  688.         mov     ecx,((end-start)/ed_struc_size)
  689. @@:
  690.         call    edit_box.key
  691.         add     edi,ed_struc_size
  692.         loop    @b
  693. }
  694.  
  695. struc  edit_box width,left,top,color,focus_border_color,\
  696.        blur_border_color,text_color,max,text,flags,size
  697. {
  698. .width dw width
  699. .left dw left
  700. .top dw top
  701. .color dd color
  702. .focus_border_color dd focus_border_color
  703. .blur_border_color dd blur_border_color
  704. .text_color dd text_color
  705. .flags dw flags+0
  706. .max dw max
  707. .size dw size+0
  708. .pos dw 0
  709. .offset dw 0
  710. .text dd text
  711. }
  712.  
  713. macro edit_boxes_set_sys_color start,end,color_table
  714. {
  715.         mov     edi,start
  716.         mov     ecx,((end-start)/ed_struc_size)
  717.         mov     esi,color_table
  718. @@:
  719.         mov     eax,[esi+36]
  720.         mov     ebx,[esi+20]
  721.         mov     ed_focus_border_color,eax
  722.         shr     bh,1
  723.         shr     bl,1
  724.         shr     ah,1
  725.         shr     al,1
  726.         add     ah,bh
  727.         add     al,bl
  728.         ror     eax,16
  729.         ror     ebx,16
  730.         shr     bl,1
  731.         shr     al,1
  732.         add     al,bl
  733.         ror     eax,16
  734.         mov     ed_blur_border_color,eax
  735.         add     edi,ed_struc_size
  736.         loop    @b
  737. }
  738.  
  739. macro draw_edit_box ed_ptr
  740. {
  741.         mov     edi,ed_ptr
  742.         call    edit_box.draw
  743. }
  744.  
  745. macro mouse_edit_box ed_ptr
  746. {
  747.         mov     edi,ed_ptr
  748.         call    edit_box.mouse
  749. }
  750.  
  751. macro key_edit_box ed_ptr
  752. {
  753.         mov     edi,ed_ptr
  754.         call    edit_box.key
  755. }