Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
383 heavyiron 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
;  - Теплов Алексей  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
485 heavyiron 51
       mcall ;рисуем рамку
383 heavyiron 52
 
53
       mov edx,ch_color
54
       add ebx,1 shl 16 - 2
55
       add ecx,1 shl 16 - 2
485 heavyiron 56
       mcall ;закрашиваем внутренности чекбокса
383 heavyiron 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
485 heavyiron 76
        mcall                  ;Вывод
383 heavyiron 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
485 heavyiron 99
        mcall            ;вывод
383 heavyiron 100
ret                                ;выйти из процедуры
101
.mouse:      ;обработка мыши
102
pusha
103
        mov  eax,37           ;будем что то делать если у нас что - нить нажато
104
        mov  ebx,2            ;внести в регистр значение 2
485 heavyiron 105
        mcall             ;проверка не нажал ли пользователь кнопку мышки
383 heavyiron 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
485 heavyiron 123
        mcall               ;получить координаты курсора относительно окна
383 heavyiron 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   ;длина текста
366 Lrz 172
.flags: dw flags+0   ;+22
383 heavyiron 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      ;проверка мышки и обработка событий
144 Lrz 204
}