Subversion Repositories Kolibri OS

Rev

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