Rev 6706 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6689 | siemargl | 1 | ; ---------------------------------------------------------------------------- ; |
2 | ; Tooltip widget |
||
3 | ; |
||
4 | ; Created by Siemargl, 2016 |
||
5 | ; |
||
6 | ; Changelist |
||
7 | ; 161107 - initial version + test |
||
8 | |||
9 | |||
10 | ; http://stackoverflow.com/questions/8976600/fasm-how-to-send-struct-to-proc |
||
11 | virtual at edi |
||
12 | ttip tooltip ?, ?, ?, ?, ?, ?, ?, ?, ? |
||
13 | end virtual |
||
14 | |||
15 | ; ---------------------------------------------------------------------------- ; |
||
16 | ; инициализация всей цепочки тултипов, формирование размеров и буферов памяти |
||
17 | ; return eax zero if fails |
||
18 | align 16 |
||
19 | proc tooltip_init uses esi edi, ttip:dword |
||
20 | locals |
||
21 | max_len dw ? ;maximum chars in line |
||
22 | lines dw ? ;lines in tooltip |
||
23 | endl |
||
24 | |||
25 | mov edi, [ttip] |
||
26 | jmp .tail_call |
||
27 | .list_next: |
||
28 | ; init statics |
||
29 | mov [ttip.mouse], 0 |
||
30 | mov [ttip.tm_strt], 0 |
||
31 | mov [ttip.video_y], 0 |
||
32 | mov [ttip.video_x], 0 |
||
33 | mov [ttip.video], 0 |
||
34 | stdcall get_font_size, [ttip.col_txt] |
||
35 | mov [ttip.font_sz], eax |
||
36 | |||
37 | ; count num of lines and max len |
||
38 | mov esi, [ttip.txt] |
||
39 | mov [lines], 1 ; lines |
||
40 | mov [max_len], 0 ; max_len |
||
41 | .line: |
||
42 | mov ecx, 0 ; len |
||
43 | .symb: |
||
44 | mov al, [esi] |
||
45 | cmp al, 0 |
||
46 | je .eos |
||
47 | cmp al, 13 |
||
48 | jne .next |
||
49 | inc [lines] |
||
50 | inc esi |
||
51 | cmp cx, [max_len] ; detect max |
||
52 | jle @f |
||
53 | mov [max_len], cx |
||
54 | @@: |
||
55 | jmp .line |
||
56 | .next: |
||
57 | inc ecx |
||
58 | inc esi |
||
59 | jmp .symb |
||
60 | .eos:; string ended, we have correct width and hight |
||
61 | cmp cx, [max_len] ; detect max |
||
62 | jle @f |
||
63 | mov [max_len], cx |
||
64 | @@: |
||
65 | |||
66 | mov eax, [ttip.font_sz] |
||
67 | shr eax, 16 |
||
68 | imul [max_len] |
||
69 | mov dx, ax ; width in pixels |
||
70 | mov [ttip.video_w], ax |
||
71 | mov eax, [ttip.font_sz] ; lo word == h |
||
72 | and eax, $FFFF |
||
73 | imul ax, [lines] |
||
74 | mov [ttip.video_h], ax |
||
75 | imul [ttip.video_w] |
||
76 | imul eax, 3 ; eax have now width * height in pixels *3 |
||
77 | ; getmem |
||
78 | invoke mem.alloc, eax |
||
79 | mov [ttip.video], eax |
||
80 | test eax, eax |
||
81 | je .exitp ; malloc fails |
||
82 | |||
83 | ; cycle list |
||
84 | mov edi, [ttip.next] |
||
85 | .tail_call: |
||
86 | test edi, edi |
||
87 | jne .list_next |
||
88 | xor eax, eax |
||
6706 | siemargl | 89 | inc eax ; good return |
6689 | siemargl | 90 | .exitp: |
91 | ret |
||
92 | endp |
||
93 | |||
94 | ; ---------------------------------------------------------------------------- ; |
||
95 | ; очистка памяти всей цепочки тултипов |
||
96 | align 4 |
||
97 | proc tooltip_delete uses edi, ttip:dword |
||
98 | mov edi, [ttip] |
||
99 | jmp .tail_call |
||
100 | .list_next: |
||
101 | mov eax, [ttip.video] |
||
102 | test eax, eax |
||
103 | je @f |
||
104 | invoke mem.free, eax |
||
105 | @@: |
||
106 | mov edi, [ttip.next] |
||
107 | .tail_call: |
||
108 | test edi, edi |
||
109 | jne .list_next |
||
110 | ret |
||
111 | endp |
||
112 | |||
113 | ; ---------------------------------------------------------------------------- ; |
||
114 | ; показ нужного из всей цепочки тултипов при бездействии (event 0) |
||
115 | align 4 |
||
116 | proc tooltip_test_show uses edi ebx, ttip:dword |
||
117 | mov edi, [ttip] |
||
118 | jmp .tail_call |
||
119 | .list_next: |
||
120 | cmp [ttip.tm_strt], 0 ; таймер 0, значит мы не в зоне |
||
121 | je .nextp |
||
122 | cmp [ttip.video_y], 0 ; тултип уже отображен |
||
123 | ;;; jne .redraw |
||
124 | jne .nextp |
||
125 | mcall SF_SYSTEM_GET, SSF_TIME_COUNT |
||
126 | movzx ebx, [ttip.tm_wait] |
||
127 | sub eax, ebx |
||
128 | cmp eax, [ttip.tm_strt] |
||
129 | jl .exitp ; мог быть только один |
||
130 | ; время оттикало, сохраняем область и рисуемся |
||
131 | ;CopyScreen(shadow_buf, 5*skinned+x+wForm.left, GetSkinHeight()*skinned+y+wForm.top, w, h); |
||
132 | mcall SF_THREAD_INFO, proc_info, -1 |
||
133 | movzx edx, word [proc_info + 34] ; window x position |
||
134 | add edx, 5 |
||
135 | shl edx, 16 |
||
136 | mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT |
||
137 | movzx ebx, word [proc_info + 38] ; window y position |
||
138 | add eax, ebx |
||
139 | add edx, eax ; x_y |
||
140 | add edx, [ttip.mouse] |
||
141 | add edx, 20 ; pixels below mouse |
||
142 | mov ecx, dword [ttip.video_h] ; w_h |
||
143 | mcall SF_GET_IMAGE, [ttip.video] |
||
144 | |||
145 | mov eax, [ttip.mouse] ; сохраним позицию где рисуемся |
||
146 | add eax, 20 ; pixels below mouse |
||
147 | mov [ttip.video_y], ax |
||
148 | shr eax, 16 |
||
149 | mov [ttip.video_x], ax |
||
150 | .redraw: ; рисуемся относительно мыши!!! |
||
151 | stdcall tooltip_draw, edi |
||
152 | |||
153 | jmp .exitp ; мог быть только один |
||
154 | .nextp: |
||
155 | mov edi, [ttip.next] |
||
156 | .tail_call: |
||
157 | test edi, edi |
||
158 | jne .list_next |
||
159 | .exitp: |
||
160 | ret |
||
161 | endp |
||
162 | |||
163 | ; рисуемся относительно мыши!!! |
||
164 | ; internal func |
||
165 | proc tooltip_draw uses esi edi ebx, ttip:dword |
||
166 | locals |
||
167 | line dw ? ;line # drawing |
||
168 | ptr_li dd ? ;line begin |
||
169 | endl |
||
170 | mov edi, [ttip] |
||
171 | ; draw square |
||
172 | movzx ebx, [ttip.video_x] |
||
173 | shl ebx, 16 |
||
174 | mov bx, [ttip.video_w] |
||
175 | movzx ecx, [ttip.video_y] |
||
176 | shl ecx, 16 |
||
177 | mov cx, [ttip.video_h] |
||
178 | mcall SF_DRAW_RECT, , , [ttip.col_bkg] |
||
179 | |||
180 | ; цикл по строкам |
||
181 | ; count num of lines and max len |
||
182 | mov esi, [ttip.txt] |
||
183 | mov [line], 0 ; line # |
||
184 | .line: |
||
185 | mov ecx, 0 ; len |
||
186 | mov [ptr_li], esi |
||
187 | .symb: |
||
188 | mov al, [esi] |
||
189 | cmp al, 0 |
||
190 | je @f |
||
191 | cmp al, 13 |
||
192 | jne .next |
||
193 | @@: |
||
194 | ; draw line if len > 0 |
||
195 | test ecx, ecx |
||
196 | je @f |
||
197 | ; draw single line |
||
198 | pushad |
||
199 | mov esi, ecx ; length |
||
200 | movzx ebx, [ttip.video_x] |
||
201 | shl ebx, 16 |
||
202 | mov eax, [ttip.font_sz] |
||
203 | and eax, $FFFF |
||
204 | imul ax, [line] |
||
205 | add ax, [ttip.video_y] |
||
206 | add ebx, eax |
||
207 | mov ecx, [ttip.col_txt] |
||
208 | and ecx, $37FFFFFF |
||
209 | mov edx, [ptr_li] |
||
210 | mcall SF_DRAW_TEXT |
||
211 | popad |
||
212 | @@: |
||
213 | cmp byte ptr esi, 0 |
||
214 | je .exitp |
||
215 | inc [line] |
||
216 | inc esi |
||
217 | jmp .line |
||
218 | .next: |
||
219 | inc ecx |
||
220 | inc esi |
||
221 | jmp .symb |
||
222 | .exitp: |
||
223 | ret |
||
224 | endp |
||
225 | |||
226 | ; ---------------------------------------------------------------------------- ; |
||
227 | ; убрать тултипы при щелчке мыши или съезде из зоны. для всей цепочки тултипов при событии мыши |
||
228 | ; если mouse_coord == -1 опросит мышь |
||
229 | align 4 |
||
230 | proc tooltip_mouse, ttip:dword |
||
231 | locals |
||
232 | mouse_coord dd ? |
||
233 | mouse_but dd ? |
||
234 | endl |
||
235 | pushad |
||
236 | ; опросим мышь и рассуем по тултипам |
||
237 | mcall SF_MOUSE_GET, SSF_WINDOW_POSITION |
||
238 | mov [mouse_coord], eax |
||
239 | mcall SF_MOUSE_GET, SSF_BUTTON |
||
240 | mov [mouse_but], eax |
||
241 | mov edi, [ttip] |
||
242 | .list_next: |
||
243 | test edi, edi |
||
244 | je .exitp |
||
245 | cmp [mouse_but], 0 ; при щелчке стираемся |
||
246 | jne @f |
||
247 | ; попадаем ли в зону контроля |
||
248 | mov eax, [mouse_coord] |
||
249 | mov [ttip.mouse], eax ; место где была замечена мышь! (хз зачем) |
||
250 | mov ecx, eax |
||
251 | shr ecx, 16 |
||
252 | cmp cx, [ttip.zone_x] ; zone_x is higher word |
||
253 | jl @f |
||
254 | cmp ax, [ttip.zone_y] |
||
255 | jl @f |
||
256 | mov cx, [ttip.zone_w] |
||
257 | add cx, [ttip.zone_x] |
||
258 | shl ecx, 16 |
||
259 | cmp eax, ecx ; x+w < mouse_x (mouse_y in low word ignored) |
||
260 | jge @f |
||
261 | mov cx, [ttip.zone_y] |
||
262 | add cx, [ttip.zone_h] |
||
263 | cmp ax, cx |
||
264 | jge @f |
||
265 | ; мы в зоне - засекаем старт, если его не было |
||
266 | cmp [ttip.tm_strt], 0 |
||
267 | jne .nextp |
||
268 | mcall SF_SYSTEM_GET, SSF_TIME_COUNT |
||
269 | mov [ttip.tm_strt], eax |
||
270 | jmp .nextp |
||
271 | @@: |
||
272 | ; если есть буфер, вернуть картинку взад, иначе идем дальше по цепочке |
||
273 | mov [ttip.tm_strt], 0 |
||
274 | cmp [ttip.video_y], 0 |
||
275 | je .nextp |
||
276 | movzx ecx, [ttip.video_w] |
||
277 | shl ecx, 16 |
||
278 | mov cx, [ttip.video_h] |
||
279 | movzx edx, [ttip.video_x] |
||
280 | shl edx, 16 |
||
281 | mov dx, [ttip.video_y] |
||
282 | mcall SF_PUT_IMAGE, [ttip.video] |
||
283 | mov [ttip.video_y], 0 |
||
284 | ;jmp exitp ; мог быть только один - отмена - обработать нужно все сбросы таймеров |
||
285 | .nextp: |
||
286 | ;mov eax, [ttip].next |
||
287 | ;stdcall tooltip_mouse, [ttip].next, [mouse_coord], [mouse_but] |
||
288 | ; tail call unroll recursion |
||
289 | mov edi, [ttip.next] |
||
290 | jmp .list_next |
||
291 | .exitp: |
||
292 | popad |
||
293 | ret |
||
294 | endp |
||
295 | |||
296 | ; ---------------------------------------------------------------------------- ; |
||
297 | ; decrypt font size as of SysFn 4 |
||
298 | ; returns eax = (x,y) |
||
299 | align 4 |
||
300 | proc get_font_size, color:dword ; x86 calling convention uses eax ecx edx |
||
301 | ;font = color >> 24; |
||
302 | ;int font_multipl = (font & 7) + 1; |
||
303 | ;if (font & 0x10) // 8x16 |
||
304 | ;{ |
||
305 | ; ed->width_sym = 8 * font_multipl; |
||
306 | ; ed->hight_sym = 16 * font_multipl; |
||
307 | ;} else // 6x9 |
||
308 | ;{ |
||
309 | ; ed->width_sym = 6 * font_multipl; |
||
310 | ; ed->hight_sym = 9 * font_multipl; |
||
311 | ;} |
||
312 | mov edx, [color] |
||
313 | shr edx, 24 ; font |
||
314 | |||
315 | mov ecx, edx ; font_multipl |
||
316 | and ecx, 7 |
||
317 | inc ecx |
||
318 | |||
319 | test edx, $10 |
||
320 | mov edx, ecx |
||
321 | jz @f |
||
322 | ; 8x16 |
||
323 | shl edx, 3 + 16 ; x == width |
||
324 | mov eax, edx |
||
325 | mov edx, ecx |
||
326 | shl edx, 4 ; y == hight |
||
327 | jmp .exitp |
||
328 | @@: |
||
329 | ; 6x9 |
||
330 | imul edx, 6 ; x == width |
||
331 | shl edx, 16 |
||
332 | mov eax, edx |
||
333 | mov edx, ecx |
||
334 | imul edx, 9 ; y == hight |
||
335 | .exitp: |
||
336 | or eax, edx |
||
337 | ret |
||
338 | endp |
||
339 | |||
340 | ;--------------------------------------------------------------------- |
||
341 | ;--- ДАННЫЕ ПРОГРАММЫ ---------------------------------------------- |
||
342 | ;--------------------------------------------------------------------- |
||
343 | |||
344 | proc_info rd 1024> |
||
345 |