Subversion Repositories Kolibri OS

Rev

Rev 109 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
;
2
;   DESKTOP CONTEXT MENU
3
;   written by Ivan Poddubny
4
;
5
;   Автор - Иван Поддубный
6
;   e-mail: ivan-yar@bk.ru
7
;
8
;   Compile with flat assembler
9
;
10
include 'lang.inc'
11
include 'macros.inc'
12
 
13
meos_app_start
14
code
15
 
16
  mov   eax,40       ; установим маску событий
17
  mov   ebx,100000b  ; нас интересует только мышь
18
  int   0x40
19
 
20
still:               ; главный цикл основного процесса
21
 
22
  mov   eax,10       ; ждём события
23
  int   0x40
24
 
25
  mov   eax,37       ; какие нажаты кпопки?
26
  mov   ebx,2
27
  int   0x40
28
 
29
  cmp   eax,2        ; если не правая, возврат
30
  jne   still
31
 
32
;---поехали!---
33
 
34
;  mov   eax,37       ; это для отладки - если мышь в точке (0;0), закроемся
35
;  xor   ebx,ebx
36
;  int   0x40
37
;  test  eax,eax      ; курсор в точке (0;0), т.е. eax = 0
38
;  je    exit
39
 
40
 
41
  mov   eax,9        ; получим число процессов в системе
42
  mov   ebx,procinfo
43
  xor   ecx,ecx
44
  int   0x40
45
 
46
  inc   eax          ; теперь в eax содержится число процессов + 1
47
  mov   [processes],eax
48
  mov   ecx,1
49
 
50
 new_process:
51
  pushad
52
  mov   eax,9        ; получим информацию о процессе; номер - в ecx
53
  mov   ebx,procinfo
54
  int   0x40
55
  mov   eax,37       ; координаты курсора
56
  xor   ebx,ebx
57
  int   0x40
58
  mov   ebx,eax                  ; eax = cursor_x
59
  shr   eax,16                   ; ebx = cursor_y
60
  and   ebx,0xffff
61
  mov   [curx1],eax              ; curx1 = cursor_x
62
  mov   [cury1],ebx              ; cury1 = cursor_y
63
  mov   eax,[procinfo.x_start]   ; eax = wnd_x_start
64
  mov   ebx,[procinfo.y_start]   ; ebx = wnd_y_start
65
 
66
  mov   ecx,[procinfo.x_size]
67
  add   ecx,eax                  ; ecx = wnd_x_end
68
  mov   edx,[procinfo.y_size]
69
  add   edx,ebx                  ; ecx = wnd_y_end
70
 
71
  cmp   eax,[curx1]  ; wnd_x_start > cursor_x => курсор левее окна
72
  jg    ne_goden
73
  cmp   ecx,[curx1]  ; wnd_x_end   < cursor_x => курсор правее окна
74
  jl    ne_goden
75
  cmp   ebx,[cury1]  ; wnd_y_start > cursor_y => курсор выше окна
76
  jg    ne_goden
77
  cmp   edx,[cury1]  ; wnd_y_end   < cursor_y => курсор ниже окна
78
  jl    ne_goden
79
 
80
goden:               ; клик был внутри какого-то окна, поэтому ничего не делаем
81
  popad
82
  jmp   still
83
 
84
ne_goden:            ; клик был снаружи рассматриваемого окна, поэтому
85
  popad
86
  inc   ecx
87
  cmp   ecx,[processes]
88
  jl    new_process  ; либо сморим следующее окно, либо запускаем меню
89
 
90
 
91
@@:             ; подождём, пока пользователь не отпустил правую кнопку мыши
92
  mov   eax,37
93
  mov   ebx,2   ; функция 37-2:
94
  int   0x40    ;   нажаты ли кнопки мыши?
95
  cmp   eax,ebx ; если отпустил, (eax != 2)
96
  jnz   @f      ;   идём в начало главного цикла
97
 
98
  mov   eax,5   ; иначе
99
  mov   ebx,2   ;   подождём 2 мс
100
  int   0x40
101
 
102
  jmp   @b      ;   и проверим мышь опять
103
@@:
104
 
105
; если уже было открыто меню, нужно подождать, пока оно закроется:
106
@@:
107
  cmp   [menu_opened],0
108
  je    @f
109
  mov   eax,5
110
  mov   ebx,3  ; ждём 3 мс
111
  int   0x40
112
  jmp   @b
113
@@:
114
 
115
  mov   eax,51           ; а теперь можно смело запускать процесс (поток) меню
116
  mov   ebx,1            ; создаём поток (thread)
117
  mov   ecx,start_wnd    ; точка входа потока
118
  mov   edx,stack_wnd    ; вершина стэка для потока
119
  int   0x40
120
 
121
  jmp   still
122
 
123
 
124
 
125
exit_menu:            ; если выходим из меню, надо записать в [menu_opened] 0
126
  mov   [menu_opened],0
127
exit:                 ; сюда мы идём, когда выходим из основного процесса
128
  or    eax,-1        ; eax = -1
129
  int   0x40
130
 
131
 
132
 
133
 
134
; здесь стартует процесс меню
135
start_wnd:
136
  mov   [menu_opened],1
137
  mov   eax,40      ; установим маску желаемых событий для этого процесса
138
  mov   ebx,100101b ; меню + кнопки + перерисовка
139
  int   0x40
140
 
142 diamond 141
red:
142
  call  draw_window
143
 
31 halyavin 144
still2:             ; главный цикл процесса меню
145
 
146
  mov   eax,10      ; ждём события
147
  int   0x40
148
 
149
  cmp   eax,1       ; перерисовка?
150
  je    red
151
  cmp   eax,3       ; кнопка?
152
  je    button
153
  cmp   eax,6       ; мышь?
154
  je    mouse
155
 
156
  jmp   still2      ; вернёмся в начало главного цикла
157
 
158
 
159
; ОБРАБОТЧИК МЫШИ
160
mouse:            ; когда пользователь нажмёт кнопку мыши, закроемся
161
  mov   eax,37
162
  mov   ebx,2     ; какие кнопки нажаты?
163
  int   0x40
164
  test  eax,eax   ; никакие? - тогда прекрасно! вернёмся в гланый цикл
165
  jz    still2
166
  jmp   exit_menu ; а если всё-таки нажаты - закроем окно
167
 
168
 
169
; НАЖАТА КНОПКА
170
button:
171
  mov   eax,17        ; получить идентификатор нажатой кнопки
172
  int   0x40
173
 
142 diamond 174
  sub   ah,10         ; сравниваем с 10
31 halyavin 175
  jl    nofuncbtns    ; если меньше - закрываем меню
176
 
177
  movzx ebx,ah        ; получили номер программы в списке в ebx
142 diamond 178
  mov   esi, [startapps + ebx*4]
179
  mov   edi, start_info.path
31 halyavin 180
  cld
181
 @@:
182
  lodsb
183
  stosb
184
  test  al, al
185
  jnz   @b
142 diamond 186
  mcall 70, start_info
31 halyavin 187
 
188
;  mov   eax,5         ; подождём, пока программа запуститься
189
;  mov   ebx,1         ; а то её окно не будет отрисовано (баг в ядре???)
190
;  int   0x40          ; раскомментируйте эти строки, если у вас проблемы
191
                       ; с отрисовкой
192
 
193
nofuncbtns:           ; закрываем меню
194
  jmp   exit_menu
195
 
196
 
197
 
198
_BTNS_            = 8     ; количество кнопок ("пунктов меню")
199
 
200
if lang eq ru
201
  font            = 0x00000000
202
  string_length   = 20          ; длина строки
203
  wnd_x_size      = 133         ; ширина окна
204
  header_pos      = 36 shl 16 + 7
205
else
206
  font            = 0x10000000
207
  string_length   = 12          ; длина строки
208
  wnd_x_size      = 105         ; ширина окна
209
  header_pos      = 23 shl 16 + 7
210
end if
211
 
212
;*******************************
213
;********  РИСУЕМ ОКНО  ********
214
;*******************************
215
 
216
draw_window:
217
 
218
  mov   eax,12           ; начинаем "рисовать"
219
  mov   ebx,1
220
  int   0x40
221
 
222
  mov   eax,[curx1]      ; текущие координаты курсора
223
  mov   [curx],eax       ; запишем в координаты окна
224
  mov   eax,[cury1]
225
  mov   [cury],eax
226
 
227
; теперь будем считать координаты окна, чтобы оно за край экрана не вылезло
228
  mov   eax,14                ; получим размер экрана
229
  int   0x40
230
  mov   ebx,eax
231
  shr   eax,16                ; в eax - x_screen
232
  and   ebx,0xffff            ; в ebx - y_screen
233
  add   eax,-wnd_x_size       ; eax = [x_screen - ширина окна]
234
  add   ebx,-_BTNS_*15-21     ; ebx = [y_screen - высота окна]
235
 
236
  cmp   eax,[curx]
237
  jg    .okx                  ; если окно слишком близко к правому краю,
238
  add   [curx],-wnd_x_size    ; сдвинем его влево на 100
239
 .okx:
240
 
241
  cmp   ebx, [cury]
242
  jg    .oky                  ; по вертикали точно также
243
  add   [cury], -_BTNS_*15-21
244
 .oky:
245
 
246
  mov   eax, 48                   ; получить системные цвета
247
  mov   ebx, 3
248
  mov   ecx, sc                   ;  адрес структуры
249
  mov   edx, sizeof.system_colors ;  и ее размер
250
  int   0x40
251
 
252
  xor   eax, eax           ; функция 0 - создать окно
253
  mov   ebx, [curx]        ;  ebx = [координата по x] shl 16 + [ширина]
254
  shl   ebx, 16
255
  add   ebx, wnd_x_size
256
  mov   ecx, [cury]        ;  ecx = [координата по y] shl 16 + [высота]
257
  shl   ecx, 16
258
  add   ecx, _BTNS_*15+21
259
  mov   edx, [sc.work]     ;  цвет рабочей области
260
  mov   esi, [sc.grab]     ;  цвет заголовка
261
  or    esi, 0x81000000
262
  mov   edi, [sc.frame]    ;  цвет рамки
263
  int   0x40
264
 
265
  mov   eax, 4             ; заголовок
266
  mov   ebx, header_pos    ;  [x] shl 16 + [y]
267
  mov   ecx, [sc.grab_text];  шрифт и цвет (серый)
268
  or    ecx, 0x10000000
142 diamond 269
;  add   ecx, -0x333333
270
  push  ecx
271
  push  ecx
272
  xor   edx,edx
273
.dec_color:
274
  sub   byte [esp+edx], 0x33
275
  jae   @f
276
  mov   byte [esp+edx], 0
277
@@:
278
  inc   edx
279
  jnp   .dec_color
280
  pop   ecx
31 halyavin 281
  mov   edx, header        ;  адрес заголовка
282
  mov   esi, header.size   ;  длина заголовка ("M E N U")
283
  int   0x40
142 diamond 284
  pop   ecx
31 halyavin 285
  add   ebx, 1 shl 16      ;  сдвинем вправо на 1
286
  int   0x40
287
 
288
  mov   ebx, 1*65536+wnd_x_size-2  ; начинаем делать кнопки
289
  mov   ecx, 20*65536+15
290
  mov   edx, 10 or 0x40000000 ; бит 30 установлен => кнопка не рисуется
291
 
292
  mov   edi,_BTNS_           ; количество кнопок (счётчик)
293
 
294
 newbtn:                     ; начало цикла
295
  mov   eax,8                ;  создаём кнопку
296
  int   0x40
297
 
298
                             ;  пишем текст на кнопке
299
  pushad                     ;   спасаем регистры
300
  shr   ecx, 16
301
  and   ebx, 0xffff0000
302
  add   ebx, ecx             ;   ebx = [x] shl 16 + [y];
303
  add   ebx, 10*65536+4      ;   ebx += смещение относительно края кнопки;
304
  mov   ecx, [sc.work_text]  ;   шрифт и цвет
305
  or    ecx, font
306
  add   edx, -10             ;   edx = номер кнопки;
307
  imul  edx, string_length   ;   edx *= длина строки;
308
  add   edx, text            ;   edx += text;  теперь в edx адрес строки
309
  mov   esi, string_length   ;   в esi - длина строки
310
  mov   eax, 4               ;   функция 4 - вывод текста
311
  int   0x40
312
  popad
313
 
314
  inc   edx                  ;  номер кнопки++;
315
  add   ecx,15*65536         ;  увеличим смещение по y
316
  dec   edi                  ;  уменьшим счётчик
317
  jnz   newbtn               ; если не ноль, повторим всё ещё раз
318
 
319
  mov   eax,12               ; закончили "рисовать"
320
  mov   ebx,2
321
  int   0x40
322
 
323
ret                          ; возврат
324
 
325
 
326
 
327
; ДАННЫЕ ПРОГРАММЫ
328
DATA
329
 
330
  macro strtbl name, [string]
331
  {
332
   common
333
     label name dword
334
   forward
335
     local str
336
     dd str
337
   forward
338
     str db string
339
  }
340
 
341
  strtbl startapps       ,\
342
    <"/RD/1/PIC4",0>     ,\
343
    <"/RD/1/DESKTOP",0>  ,\
344
    <"/RD/1/MV",0>       ,\
345
    <"/RD/1/JPEGVIEW",0> ,\
346
    <"/RD/1/CPU",0>      ,\
347
    <"/RD/1/SPANEL",0>   ,\
142 diamond 348
    <"/RD/1/ICON2",0> ,\
31 halyavin 349
    <"/RD/1/VRR",0>
350
 
351
;  header:            ; заголовок
352
;    db 'M E N U'
353
;  header_len = $ - header
354
 
355
;  text:              ; текст на кнопках
356
;    db 'Background  '; 12
357
;    db 'Colors      '
358
;    db 'MeView      '
359
;    db 'Processes   '
360
;    db 'Panel setup '
361
;    db 'Icon manager'
362
 
142 diamond 363
  sz header, "KolibriOS"
31 halyavin 364
 
365
  lsz text,\
366
    en, 'Background  ',\
367
    en, 'Colors      ',\
368
    en, 'MeView      ',\
369
    en, 'JpegView    ',\
370
    en, 'Processes   ',\
371
    en, 'Panel setup ',\
372
    en, 'Icon manager',\
373
    en, 'VRR         ',\
374
    \
375
    ru, 'Генератор обоев     ',\
376
    ru, 'Системные цвета     ',\
377
    ru, 'Просмотр BMP        ',\
378
    ru, 'Просмотр JPEG       ',\
379
    ru, 'Процессы            ',\
380
    ru, 'Настройка панели    ',\
381
    ru, 'Управление иконками ',\
382
    ru, 'Настройка монитора  '
383
 
142 diamond 384
start_info:
385
        .mode   dd      7
386
                dd      0
387
        .params dd      0
388
                dd      0
389
                dd      0
390
                db      0
391
                dd      start_info.path
31 halyavin 392
 
393
; НЕИНИЦИАЛИЗИРОВАННЫЕ ДАННЫЕ
394
UDATA
395
  processes   dd ?              ; количество процессов в системе
396
  curx1       dd ?              ; координаты курсора
397
  cury1       dd ?
398
  curx        dd ?              ; координаты окна меню
399
  cury        dd ?
400
 
401
  menu_opened db ?              ; открыто меню или нет? (1-да, 0-нет)
402
 
142 diamond 403
align 4
404
start_info.path rb 256
31 halyavin 405
 
406
  sc       system_colors        ; системные цвета
407
  procinfo process_information  ; информация о процессе
408
 
409
  rb 1024                       ; стэк для окна меню - хватит и 1 Кб
410
  align 32
411
  stack_wnd:
412
 
413
 
414
MEOS_APP_END
415
; КОНЕЦ ПРОГРАММЫ