Subversion Repositories Kolibri OS

Rev

Rev 383 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;Оптимизированный компонент CheckBox (Исходный вариант от Maxxxx32)
  2. ;Оптимизирован вывод строки надписи для CheckBox'a + теперь, при проверке не происходит подсчет кол-ва символов в строке
  3. ;Оптимизация команд - отказался от сохранения регистров в стеке.
  4. ;21.02.2007 добавил код от Heavyiron, дописал макросы для использования системных цветов
  5. ;19.02.2007 общее улучшение кода, уменьшение размера и использование системных цветов для отображения checkbox
  6. ;17.07.2006 произведена оптимизация, при установке чек бокса в положение включено последующие чек боксы в тот же промежуток времени не проверяются
  7. ;22.08.2006 произведена оптимизация команд, приняты во внимание замечания DIAMOND'а.
  8. ;<Lrz>  - Теплов Алексей  www.lrz.land.ru
  9.  
  10. macro version_ch           ;для совместимости со старыми версиями checkbox все цвета задаются ручками
  11. {
  12. ch_struc_size=24
  13. ch_left equ [edi]    ;координата начала рисования по х
  14. ch_top equ [edi+2]   ;координата начала рисования по у
  15. ch_color equ [edi+4]
  16. ch_border_color equ [edi+8] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно
  17. ch_text_color equ   [edi+12];[edi+4]  ;цвет текста
  18. ch_text_ptr equ [edi+16]    ;указатель на начало текстовой строки
  19. ch_text_length equ [edi+20] ;длина надписи (2^64 такой длины может быть текст)
  20. ch_flags equ [edi+22]       ;флаги
  21. }
  22.  
  23. macro   version_ch1        ;продвинутая версия, использует цвета скина.
  24. {
  25. ch_struc_size=12
  26. ch_left equ [edi]    ;координата начала рисования по х
  27. ch_top equ [edi+2]   ;координата начала рисования по у
  28. ch_color equ [sc.work] ;
  29. ch_border_color equ [sc.work_graph] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно
  30. ch_text_color equ   [sc.work_text];[edi+4]  ;цвет текста
  31. ch_text_ptr equ [edi+4]    ;указатель на начало текстовой строки
  32. ch_text_length equ [edi+8] ;длина надписи (2^64 такой длины может быть текст)
  33. ch_flags equ [edi+10]       ;флаги
  34. }
  35.  
  36. macro use_check_box
  37. {
  38. ch_text_margin=4     ;расстояние от прямоугольника чек бокса до надписи
  39. ch_size=11           ;размер квадрата чек бокса
  40. check_box:
  41. .draw:
  42.        pusha   ;сохраним все регистры
  43.        mov eax,13
  44.        mov ebx,ch_left
  45.        shl ebx,16
  46.        add ebx,ch_size
  47.        mov ecx,ch_top
  48.        shl ecx,16
  49.        add ecx,ch_size
  50.        mov edx,ch_border_color
  51.        mcall ;рисуем рамку
  52.  
  53.        mov edx,ch_color
  54.        add ebx,1 shl 16 - 2
  55.        add ecx,1 shl 16 - 2
  56.        mcall ;закрашиваем внутренности чекбокса
  57.  
  58.        test word ch_flags,2  ;достать значение бита из переменной и поместить в  флаг CF
  59.        jz   @f                ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@
  60.        call .draw_ch  ;нарисовать включенный чек бокс
  61. @@:
  62. ;----------------------------
  63. ;расчет куда будет произведен вывод текста
  64. ;----------------------------
  65.         movzx ebx,word ch_left        ;загрузить значение х для чек бокса
  66.         add   ebx,(ch_size+ch_text_margin) ;добавить размер стороны и расстояние на котором начнется вывод текста
  67.         shl   ebx,16                ;сдвинем на 16 разрядов в лево (умножим на 65536)
  68.         mov   bx,ch_top        ;загрузим значение по y
  69.         add   ebx,(ch_size-9+1)        ;добавим значение длины стороны -9+1
  70.         mov   ecx,ch_text_color        ;загрузим цвет надписи
  71.        
  72.         mov   edx,ch_text_ptr                ;укажем адрес от куда нужно выводить строку
  73.         movzx esi,word ch_text_length ;Загрузим длину надписи в esi
  74.         ;внесем в eax значение вывода надписи на канву
  75.         mov   eax,4
  76.         mcall                  ;Вывод
  77. popa                              ;восстановить значения регистров из стека
  78. ret                               ;выйдем из процедуры
  79.  
  80. .clear_ch:                        ;очистка чек бокса
  81.         mov   edx,ch_color   ;цвет внутри чек бокса
  82.         jmp   @f             ;безусловный прыжок на нижнюю метку @@
  83.  
  84. .draw_ch:            ;нарисовать включенный чек бокс
  85.         mov   edx,ch_border_color        ;загрузить цвет
  86. @@:
  87.         movzx ebx,word ch_left  ;загрузить координату по х
  88.         add   ebx,(ch_size/3)   ;добавить (сторона прямоугольника/3)
  89.         shl   ebx,16            ;сдвинем на 16 разрядов в лево (умножим на 65536)
  90.         mov   bx,(ch_size/2)    ;загрузить (сторона прямоугольника/2)
  91.         mov   bp,bx             ;сохраним регистр bx в регистре указателя базы
  92.         ;push        bx
  93.         movzx ecx,word ch_top ;загрузить координату по у
  94.         mov   eax,13          ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс
  95.         add   ecx,(ch_size/3) ;добавить (сторона прямоугольника/3)
  96.         shl   ecx,16          ;сдвинем на 16 разрядов в лево (умножим на 65536)
  97.         mov   cx,bp           ;загрузим значения регистра указателя базы в cx
  98.         ;pop        cx
  99.         mcall            ;вывод
  100. ret                                ;выйти из процедуры
  101. .mouse:      ;обработка мыши
  102. pusha
  103.         mov  eax,37           ;будем что то делать если у нас что - нить нажато
  104.         mov  ebx,2            ;внести в регистр значение 2
  105.         mcall             ;проверка не нажал ли пользователь кнопку мышки
  106.         test eax,eax   ;проверка если у нас в eax=0, то установим флаг и выйдем
  107.         jnz  @f         ;перейти на нижнюю метку @@
  108.         btr  word ch_flags,2  ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
  109.         popa                  ;если ничего не произошло, то восстановим значения регистров из стека
  110.         ret                   ;выход
  111. @@:
  112.         bts  word ch_flags,2   ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено
  113.         jc   .mouse_end         ;если CF=1 то перейти  в конец т.е. это выход
  114.         movzx  esi,word ch_text_length ;загрузить кол-во символов в текстовой строке
  115.         ;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea
  116.         ;lea esi,[eax*2+eax]
  117.         ;shl eax,1
  118.         imul esi,6             ; или можно и так умножить на 6
  119.         add  esi,ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи
  120.  
  121.         mov  eax,37             ;получим координаты мышки
  122.         mov  ebx,1              ;добавить 1
  123.         mcall               ;получить координаты курсора относительно окна
  124.        
  125.         movzx ebx,word ch_top  ;загрузить в bx значение координаты у
  126.         cmp   ax,bx              ;сравнить с с координатой курсора
  127.         jl   .mouse_end          ;SF <> OF если меньше
  128.         add   ebx,ch_size        ;добавить размер
  129.         cmp   ax,bx              ;сравнить
  130.         jg   .mouse_end          ;ZF = 0 и SF = OF если больше
  131.              
  132.         shr   eax,16              ;разделим на 65536 или просто сдвинем биты на 16 значений
  133.         movzx ebx,word ch_left  ;произведем аналогичное сравнение
  134.         cmp   ax,bx            ;сравнить регистры
  135.         jl   .mouse_end        ;если меньше
  136.         add   ebx,ch_size      ;добавить длину стороны прямоугольника
  137.         add   ebx,esi          ;Учесть в значении по х еще и длину надписи к чекбоксу
  138.         cmp   ax,bx            ;стравнить регистры
  139.         jg   .mouse_end        ;если больше
  140.  
  141.         bts  word ch_flags,1  ;извлечение значения заданного бита в флаг cf и изменение его значения на 1.
  142.         jc   @f                ;CF=1 то перейти на нижнюю @@
  143.        
  144.         call .draw_ch        ;отобразить включенный чек бокс
  145.         mov   dword [esp+24],1 ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0
  146.         jmp  .mouse_end       ;выйти
  147. @@:
  148.         btr   word ch_flags,1  ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
  149.         call .clear_ch         ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
  150. .mouse_end:
  151. popa                                ;восстановить регистры из стека
  152. ret                                 ;выйти
  153. }
  154.  
  155. struc check_box1 left,top,text,text_length,flags
  156. {        ;структура параметров для чек бокса
  157. .left: dw left      ;+0        положение по х
  158. .top: dw top        ;+2        положение по у
  159. .text: dd text      ;+16       адрес в коде программы где расположен текстр
  160. .text_length: dw text_length ;+20       длина текста
  161. .flags: dw flags+0  ;+22            флаги
  162. }
  163. struc check_box left,top,color,border_color,text_color,text,text_length,flags
  164. {        ;структура параметров для чек бокса
  165. .left: dw left      ;+0        ;положение по х
  166. .top: dw top        ;положение по у
  167. .color: dd color    ;цвет внутри чекбокса
  168. .border_color: dd border_color ;цвет рамки
  169. .text_color: dd text_color     ;цвет надписи
  170. .text: dd text                 ;адрес в коде программы где расположен текст
  171. .text_length: dw text_length   ;длина текста
  172. .flags: dw flags+0   ;+22        
  173. }
  174. ch_flag_en=10b
  175.  
  176. macro draw_check_boxes start,end        ;рисовать чек боксы
  177. {
  178.         mov  edi,start                       ;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
  179.         mov  ecx,((end-start)/ch_struc_size) ;Количество чек боксов
  180. @@:
  181.         call check_box.draw       ;Отобразить чек бокс
  182.         add  edi,ch_struc_size     ;Указатель на последующие чек боксы  т.е. +28
  183.         loop @b        ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@
  184. }
  185. macro mouse_check_boxes start,end        ;установка чек боксов, в зависимости от события
  186. {
  187.         mov  edi,start           ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
  188.         mov  ecx,((end-start)/ch_struc_size)        ;Количество чек боксов
  189. @@:          
  190.         call check_box.mouse     ;проверка мышки и обработка событий
  191.         add  edi,ch_struc_size   ;Указатель на последующие чек боксы
  192.         loop @b        ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@
  193. }
  194. ;Если нужно отобразить один чекер
  195. macro draw_check_box start        ;рисовать чек боксы
  196. {
  197.         mov  edi,start            ;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
  198.         call check_box.draw       ;Отобразить чек бокс
  199. }
  200. macro mouse_check_box start       ;установка чек боксов, в зависимости от события
  201. {
  202.         mov  edi,start            ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
  203.         call check_box.mouse      ;проверка мышки и обработка событий
  204. }