Subversion Repositories Kolibri OS

Rev

Rev 529 | 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
 
604 Rus 16
  mov	eax, 48 		  ; получить системные цвета
17
  mov	ebx, 3
18
  mov	ecx, sc 		  ;  адрес структуры
19
  mov	edx, sizeof.system_colors ;  и ее размер
485 heavyiron 20
  mcall
21
 
604 Rus 22
  mov	eax,40	     ; установим маску событий
23
  mov	ebx,100000b  ; нас интересует только мышь
485 heavyiron 24
  mcall
31 halyavin 25
 
604 Rus 26
still:		     ; главный цикл основного процесса
31 halyavin 27
 
604 Rus 28
  mov	eax,10	     ; ждём события
485 heavyiron 29
  mcall
31 halyavin 30
 
604 Rus 31
  mov	eax,37	     ; какие нажаты кпопки?
32
  mov	ebx,2
485 heavyiron 33
  mcall
31 halyavin 34
 
604 Rus 35
  cmp	eax,ebx        ; если не правая, возврат
36
  jne	still
31 halyavin 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
 
604 Rus 47
  mov	eax,9	     ; получим число процессов в системе
48
  mov	ebx,procinfo
49
  xor	ecx,ecx
485 heavyiron 50
  mcall
31 halyavin 51
 
604 Rus 52
  inc	eax	     ; теперь в eax содержится число процессов + 1
53
  mov	[processes],eax
54
  mov	ecx,1
31 halyavin 55
 
56
 new_process:
57
  pushad
604 Rus 58
  mov	eax,9	     ; получим информацию о процессе; номер - в ecx
59
  mov	ebx,procinfo
485 heavyiron 60
  mcall
604 Rus 61
  mov	eax,37	     ; координаты курсора
62
  xor	ebx,ebx
485 heavyiron 63
  mcall
604 Rus 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
604 Rus 71
	test	[procinfo.wnd_state], 2
72
	jnz	ne_goden
154 diamond 73
; \end{diamond}[18.09.2006]
604 Rus 74
  mov	eax,[procinfo.box.left]   ; eax = wnd_x_start
75
  mov	ebx,[procinfo.box.top]	  ; ebx = wnd_y_start
31 halyavin 76
 
604 Rus 77
  mov	ecx,[procinfo.box.width]
78
  add	ecx,eax 		 ; ecx = wnd_x_end
79
  mov	edx,[procinfo.box.height]
80
  add	edx,ebx 		 ; ecx = wnd_y_end
31 halyavin 81
 
604 Rus 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
31 halyavin 90
 
604 Rus 91
goden:		     ; клик был внутри какого-то окна, поэтому ничего не делаем
31 halyavin 92
  popad
604 Rus 93
  jmp	still
31 halyavin 94
 
604 Rus 95
ne_goden:	     ; клик был снаружи рассматриваемого окна, поэтому
31 halyavin 96
  popad
604 Rus 97
  inc	ecx
98
  cmp	ecx,[processes]
99
  jl	new_process  ; либо сморим следующее окно, либо запускаем меню
31 halyavin 100
 
101
 
604 Rus 102
@@:		; подождём, пока пользователь не отпустил правую кнопку мыши
103
  mov	eax,37
104
  mov	ebx,2	; функция 37-2:
485 heavyiron 105
  mcall    ;   нажаты ли кнопки мыши?
604 Rus 106
  test	eax,ebx ; если отпустил, (eax != 2)
107
  jz	@f	;   идём в начало главного цикла
31 halyavin 108
 
604 Rus 109
  mov	eax,5	; иначе
110
  ;mov   ebx,2   ;   подождём 2 мс
485 heavyiron 111
  mcall
31 halyavin 112
 
604 Rus 113
  jmp	@b	;   и проверим мышь опять
31 halyavin 114
@@:
115
 
116
; если уже было открыто меню, нужно подождать, пока оно закроется:
117
@@:
604 Rus 118
  cmp	[menu_opened],0
119
  je	@f
120
  mov	eax,5
121
  mov	ebx,3  ; ждём 3 мс
485 heavyiron 122
  mcall
604 Rus 123
  jmp	@b
31 halyavin 124
@@:
125
 
604 Rus 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
 
604 Rus 132
  jmp	still
31 halyavin 133
 
134
 
135
 
604 Rus 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:
604 Rus 147
  mov	[menu_opened],1
148
  mov	eax,40	    ; установим маску желаемых событий для этого процесса
149
  mov	ebx,100101b ; меню + кнопки + перерисовка
485 heavyiron 150
  mcall
31 halyavin 151
 
142 diamond 152
red:
604 Rus 153
  call	draw_window
142 diamond 154
 
604 Rus 155
still2: 	    ; главный цикл процесса меню
31 halyavin 156
 
604 Rus 157
  mov	eax,10	    ; ждём события
485 heavyiron 158
  mcall
31 halyavin 159
 
604 Rus 160
  cmp	eax,1	    ; перерисовка?
161
  je	red
162
  cmp	eax,3	    ; кнопка?
163
  je	button
164
  cmp	eax,6	    ; мышь?
165
  je	mouse
31 halyavin 166
 
604 Rus 167
  jmp	still2	    ; вернёмся в начало главного цикла
31 halyavin 168
 
169
 
170
; ОБРАБОТЧИК МЫШИ
604 Rus 171
mouse:		  ; когда пользователь нажмёт кнопку мыши, закроемся
172
  mov	eax,37
173
  mov	ebx,2	  ; какие кнопки нажаты?
485 heavyiron 174
  mcall
604 Rus 175
  test	eax,eax   ; никакие? - тогда прекрасно! вернёмся в гланый цикл
176
  jz	still2
177
  jmp	exit_menu ; а если всё-таки нажаты - закроем окно
31 halyavin 178
 
179
 
180
; НАЖАТА КНОПКА
181
button:
604 Rus 182
  mov	eax,17	      ; получить идентификатор нажатой кнопки
485 heavyiron 183
  mcall
31 halyavin 184
 
604 Rus 185
  sub	ah,10	      ; сравниваем с 10
186
  jl	nofuncbtns    ; если меньше - закрываем меню
31 halyavin 187
 
604 Rus 188
  movzx ebx,ah	      ; получили номер программы в списке в ebx
189
  mov	esi, [startapps + ebx*4]
190
  mov	edi, start_info.path
31 halyavin 191
  cld
192
 @@:
193
  lodsb
194
  stosb
604 Rus 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          ; раскомментируйте эти строки, если у вас проблемы
604 Rus 202
		       ; с отрисовкой
31 halyavin 203
 
604 Rus 204
nofuncbtns:	      ; закрываем меню
205
  jmp	exit_menu
31 halyavin 206
 
207
 
208
 
604 Rus 209
_BTNS_		  = 6	  ; количество кнопок ("пунктов меню")
31 halyavin 210
 
211
if lang eq ru
604 Rus 212
  font		  = 0x00000000
213
  string_length   = 20		; длина строки
214
  wnd_x_size	  = 133 	; ширина окна
215
  title_pos	 = 36 shl 16 + 7
31 halyavin 216
else
604 Rus 217
  font		  = 0x10000000
218
  string_length   = 12		; длина строки
219
  wnd_x_size	  = 105 	; ширина окна
220
  title_pos	 = 23 shl 16 + 7
31 halyavin 221
end if
222
 
223
;*******************************
224
;********  РИСУЕМ ОКНО  ********
225
;*******************************
226
 
227
draw_window:
228
 
604 Rus 229
  mov	eax,12		 ; начинаем "рисовать"
230
  mov	ebx,1
485 heavyiron 231
  mcall
31 halyavin 232
 
604 Rus 233
  mov	eax,[curx1]	 ; текущие координаты курсора
234
  mov	[curx],eax	 ; запишем в координаты окна
235
  mov	eax,[cury1]
236
  mov	[cury],eax
31 halyavin 237
 
238
; теперь будем считать координаты окна, чтобы оно за край экрана не вылезло
604 Rus 239
  mov	eax,14		      ; получим размер экрана
485 heavyiron 240
  mcall
604 Rus 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 - высота окна]
31 halyavin 246
 
604 Rus 247
  cmp	eax,[curx]
248
  jg	.okx		      ; если окно слишком близко к правому краю,
249
  add	[curx],-wnd_x_size    ; сдвинем его влево на 100
31 halyavin 250
 .okx:
251
 
604 Rus 252
  cmp	ebx, [cury]
253
  jg	.oky		      ; по вертикали точно также
254
  add	[cury], -_BTNS_*15-21
31 halyavin 255
 .oky:
256
 
604 Rus 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
 
604 Rus 270
  mov	eax, 4		   ; заголовок
271
  mov	ebx, title_pos	  ;  [x] shl 16 + [y]
272
  mov	ecx, [sc.grab_text];  шрифт и цвет (серый)
273
  or	ecx, 0x10000000
142 diamond 274
;  add   ecx, -0x333333
604 Rus 275
  push	ecx
276
  push	ecx
277
  xor	edx,edx
142 diamond 278
.dec_color:
604 Rus 279
  sub	byte [esp+edx], 0x33
280
  jae	@f
281
  mov	byte [esp+edx], 0
142 diamond 282
@@:
604 Rus 283
  inc	edx
284
  jnp	.dec_color
285
  pop	ecx
286
  mov	edx, title	  ;  адрес заголовка
287
  mov	esi, title.size   ;  длина заголовка ("M E N U")
485 heavyiron 288
  mcall
604 Rus 289
  pop	ecx
290
  add	ebx, 1 shl 16	   ;  сдвинем вправо на 1
485 heavyiron 291
  mcall
31 halyavin 292
 
604 Rus 293
  mov	ebx, 1*65536+wnd_x_size-2  ; начинаем делать кнопки
294
  mov	ecx, 20*65536+15
295
  mov	edx, 10 or 0x40000000 ; бит 30 установлен => кнопка не рисуется
31 halyavin 296
 
604 Rus 297
  mov	edi,_BTNS_	     ; количество кнопок (счётчик)
31 halyavin 298
 
604 Rus 299
 newbtn:		     ; начало цикла
300
  mov	eax,8		     ;  создаём кнопку
485 heavyiron 301
  mcall
31 halyavin 302
 
604 Rus 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
 
604 Rus 319
  inc	edx		     ;  номер кнопки++;
320
  add	ecx,15*65536	     ;  увеличим смещение по y
321
  dec	edi		     ;  уменьшим счётчик
322
  jnz	newbtn		     ; если не ноль, повторим всё ещё раз
31 halyavin 323
 
604 Rus 324
  mov	eax,12		     ; закончили "рисовать"
325
  mov	ebx,2
485 heavyiron 326
  mcall
31 halyavin 327
 
604 Rus 328
ret			     ; возврат
31 halyavin 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
 
604 Rus 346
  strtbl startapps	 ,\
347
    <"/sys/PIC4",0>	,\
348
    <"/sys/DESKTOP",0>	,\
529 spraid 349
    <"/sys/ICON",0>,\
604 Rus 350
    <"/sys/SETUP",0>	,\
529 spraid 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:
604 Rus 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
604 Rus 382
  processes   dd ?		; количество процессов в системе
383
  curx1       dd ?		; координаты курсора
31 halyavin 384
  cury1       dd ?
604 Rus 385
  curx	      dd ?		; координаты окна меню
386
  cury	      dd ?
31 halyavin 387
 
604 Rus 388
  menu_opened db ?		; открыто меню или нет? (1-да, 0-нет)
31 halyavin 389
 
142 diamond 390
align 4
391
start_info.path rb 256
31 halyavin 392
 
604 Rus 393
  sc	   system_colors	; системные цвета
394
  procinfo process_information	; информация о процессе
31 halyavin 395
 
604 Rus 396
  rb 1024			; стэк для окна меню - хватит и 1 Кб
31 halyavin 397
  align 32
398
  stack_wnd:
399
 
400
 
401
MEOS_APP_END
402
; КОНЕЦ ПРОГРАММЫ