Subversion Repositories Kolibri OS

Rev

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