1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2007, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: vis.btnpic 07.02.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15
16 include {
17 "btn.g"
18 }
19 /* Компонента vBtnPic, порождена от vBtn
20 События
21 */
22 type vBtnPic <inherit = vBtn>
23 {
24 //Hidden Fields
25 ustr pImage
26 uint ptrImage
27 uint pLayout
28 uint pFlat
29
30 uint imgleft
31 uint imgtop
32 uint txtleft
33 uint txttop
34
35 uint flgEnter
36 //Events
37 }
38
39
40
41 define {
42 //Расположение картинки и текста
43 bplPicLeft = 0
44 bplPicTop = 1
45 }
46
47 /*------------------------------------------------------------------------------
48 Internal Methods
49 */
50 /* Метод iUpdateChecked
51 Связывает состояние кнопки с визуальным отображением
52 */
53 /*method vBtnPic.iUpdateChecked
54 {
55 if ( this.pBtnStyle == $bsAsCheckBox ||
56 this.pBtnStyle == $bsAsRadioBtn ) &&
57 this.pChecked != (this.WinMsg( $BM_GETCHECK ) == $BST_CHECKED)
58 {
59 uint tabstop = GetFocus()
60 this.WinMsg( $BM_CLICK )
61 SetFocus( tabstop )
62 }
63 }*/
64
65 method vBtnPic.iUpdateLayout
66 {
67 int pw, ph, pt, pl
68 int tw, th, tt, tl
69
70 RECT r
71 uint dc = GetDC( 0 )
72 r.right = .clloc.width
73 r.bottom = .clloc.height
74
75 SelectObject( dc, this.WinMsg( $WM_GETFONT ) )
76 DrawText( dc, this.pCaption.Text(this).ptr(), *this.pCaption.Text(this), r, $DT_CALCRECT )
77 ReleaseDC( 0, dc )
78 tw = r.right
79 th = r.bottom
80
81 if .ptrImage
82 {
83 pw = .ptrImage->Image.Width
84 ph = .ptrImage->Image.Height
85 }
86 if .pLayout == $bplPicTop
87 {
88 pl = .clloc.width - pw
89 pt = .clloc.height - ph - th
90 }
91 else
92 {
93 pl = .clloc.width - pw - tw
94 pt = .clloc.height - ph
95 }
96 pt = max( pt >> 1, 2 )
97 pl = max( pl >> 1, 2 )
98 if .pLayout == $bplPicTop
99 {
100 tl = max(( .clloc.width - tw )>> 1, 2)
101 tt = pt + ph + 2
102 }
103 else
104 {
105 tl = pl + pw + 2
106 tt = max(( .clloc.height - th ) >> 1, 2 )
107 }
108 .imgleft = pl
109 .imgtop = pt
110 .txtleft = tl
111 .txttop = tt
112 }
113
114 method vBtnPic.iUpdateImage()
115 {
116 /*uint im as this.GetImage( .pImage )
117 &im*/
118 .ptrImage = &this.GetImage( .pImage )
119 /*if &im
120 {
121 .pBitMap = im.himage
122 }
123 else
124 {
125 .pBitMap = 0
126 }*/
127 //.iUpdateImage()
128 .iUpdateLayout()
129 InvalidateRect( this.hwnd, 0->RECT, 1 )
130 }
131 /*------------------------------------------------------------------------------
132 Properties
133 */
134 /* Свойство ustr vBtnPic.Image - Get Set
135 Устанавливает или получает картинку
136 */
137 property ustr vBtnPic.Image <result>
138 {
139 result = this.pImage
140 }
141
142 property vBtnPic.Image( ustr val )
143 {
144 if val != this.pImage
145 {
146 this.pImage = val
147 .iUpdateImage()
148 }
149 //.iUpdateImage()
150 /*
151 this.pCaption.Value = val
152 .iUpdateCaption()
153 .iUpdateSize()
154 }*/
155 }
156
157 /* Свойство str vBtnPic.Layout - Get Set
158 Усотанавливает или получает взаимное расположение картинки текста
159 */
160 property uint vBtnPic.Layout
161 {
162 return this.pLayout
163 }
164
165 property vBtnPic.Layout( uint val )
166 {
167 if val != this.pLayout
168 {
169 this.pLayout = val
170 .iUpdateLayout()
171 InvalidateRect( this.hwnd, 0->RECT, 1 )
172 }
173 }
174
175 /* Свойство str vPicture.Flat - Get Set
176 Всплывающая кнопка как в toolbar
177 */
178 property uint vBtnPic.Flat
179 {
180 return this.pFlat
181 }
182
183 property vBtnPic.Flat( uint val )
184 {
185 if val != this.pFlat
186 {
187 this.pFlat = val
188 InvalidateRect( this.hwnd, 0->RECT, 1 )
189 }
190 }
191
192 /*------------------------------------------------------------------------------
193 Registration
194 */
195 /*Системный метод vBtnPic vBtnPic.init - Инициализация объекта
196 */
197 method vBtnPic vBtnPic.init( )
198 {
199 this.pTypeId = vBtnPic
200
201 this.pCanFocus = 1
202 this.pTabStop = 1
203 this.loc.width = 100
204 this.loc.height = 25
205 this.flgOwnerRedraw = 1
206 return this
207 }
208
209 //method uint vBtn.wmpaint <alias=vBtn_wmpaint>( winmsg wmsg )
210 method vBtnPic.mWinDrawItem <alias=vBtnPic_mWinDrawItem>( DRAWITEMSTRUCT ds )
211 {
212 uint off
213 if ds.itemState & $ODS_SELECTED : off = 1
214 if isThemed
215 {
216 pDrawThemeParentBackground->stdcall( this.hwnd, ds.hDC, 0 );
217
218 uint state
219 if .pEnabled
220 {
221 if ds.itemState & $ODS_SELECTED
222 {
223 state = $PBS_PRESSED
224 }
225 else
226 {
227 if .flgEnter
228 {
229 state |= $PBS_HOT
230 }
231 else
232 {
233 if .pChecked && ( this.pBtnStyle == $bsAsCheckBox ||
234 this.pBtnStyle == $bsAsRadioBtn )
235 {
236 state = ?( .pFlat, $TS_CHECKED,
237 $PBS_PRESSED )
238 }
239 else : state = $PBS_NORMAL //| $PBS_DEFAULTED
240 }
241 }
242 }
243 else
244 {
245 state = $PBS_DISABLED
246 }
247 pDrawThemeBackground->stdcall( ThemeData[?( .pFlat, $theme_toolbar, $theme_button )], ds.hDC, $BP_PUSHBUTTON, state, ds.rcItem, 0 )
248 }
249 else
250 {
251 uint state
252 if .pFlat
253 {
254 if ds.itemState & $ODS_SELECTED
255 {
256 state = 2
257 }
258 else
259 {
260 if .flgEnter
261 {
262 state = 4
263 }
264 else
265 {
266 state = 0
267 }
268 }
269 FillRect( ds.hDC, ds.rcItem, $COLOR_BTNFACE + 1 )
270 if state
271 {
272 DrawEdge( ds.hDC, ds.rcItem, state, 0xf )
273 }
274 }
275 else
276 {
277 if ds.itemState & $ODS_SELECTED
278 {
279 state |= 0x210
280 }
281 else
282 {
283 state |= 0x010
284 }
285 DrawFrameControl( ds.hDC, ds.rcItem, 4, state )
286 }
287 }
288 //uint hdc = CreateCompatibleDC(ds.hDC)
289 //uint hbmp// = LoadBitmap( 0, 32754 )
290 //hbmp = LoadImage( 0, "k:\\h_c.ico".ustr().ptr(), $IMAGE_ICON, 0, 0, $LR_LOADFROMFILE | $LR_DEFAULTSIZE )
291
292 SetBkMode( ds.hDC, $TRANSPARENT )
293 //print( "select \(SelectObject( ds.hDC, GetStockObject( $DEFAULT_GUI_FONT ) ))\n" )
294 if .ptrImage
295 {
296 //DrawIcon( ds.hDC, .imgleft + off, .imgtop + off, .ptrImage->Image.himage )
297 DrawIconEx( ds.hDC, .imgleft + off, .imgtop + off, ?( .Enabled, .ptrImage->Image.hImage, .ptrImage->Image.hDisImage ), .ptrImage->Image.Width, .ptrImage->Image.Height, 0, 0, $DI_COMPAT | $DI_NORMAL )
298 }
299 RECT r
300 r.left = .txtleft + off
301 r.top = .txttop + off
302 r.right = .clloc.width - 2
303 r.bottom = .clloc.height - 2
304 //uint lcolor
305 if !.Enabled
306 {
307 SetTextColor( ds.hDC, GetSysColor(16) )
308 }
309 DrawText(ds.hDC, .pCaption.Text(this).ptr(), *.pCaption.Text(this), r, $DT_LEFT | $DT_SINGLELINE )
310
311 if GetFocus() == this.hwnd
312 {
313 r.left = 3
314 r.top = 3
315 r.right = .clloc.width - 3
316 r.bottom = .clloc.height - 3
317 DrawFocusRect( ds.hDC, r )
318
319 }
320 //SetTextColor( ds.hDC, lcolor )
321 //wmsg.flags = 1
322 return
323 }
324
325 /*Виртуальный метод vBtnPic.mSetCaption - Обновить заголовок
326 */
327 method vBtnPic.mSetCaption <alias=vBtnPic_mSetCaption>( ustr caption )
328 {
329 // SetWindowText( this.hwnd, this.pCaption.Text( this ).ptr() )
330 this->vBtn.mSetCaption( caption )
331 .iUpdateLayout()
332 InvalidateRect( this.hwnd, 0->RECT, 1 )
333 }
334
335 /*Виртуальный метод vBtnPic.mPosChanged - Изменились размеры
336 */
337 method vBtnPic.mPosChanged <alias=vBtnPic_mPosChanged>(evparEvent ev)
338 {
339 this->vCtrl.mPosChanged(ev)
340 //SetWindowText( this.hwnd, this.pCaption.Text.ptr() )
341 .iUpdateLayout()
342 InvalidateRect( this.hwnd, 0->RECT, 1 )
343 }
344
345 /*Виртуальный метод vURL.mMouse - События от мыши
346 */
347 method uint vBtnPic.mMouse <alias=vBtnPic_mMouse>( evparMouse em )
348 {
349 if em.evmtype == $evmMove && !.flgEnter
350 {
351 .flgEnter = 1
352 TRACKMOUSEEVENT tm
353
354 tm.cbSize = sizeof( TRACKMOUSEEVENT )
355 tm.dwFlags = $TME_LEAVE
356 tm.hwndTrack = .hwnd
357 tm.dwHoverTime = 40
358 TrackMouseEvent(tm)
359 //print( "Enter \n" )
360 InvalidateRect( this.hwnd, 0->RECT, 1 )
361 }
362 elif em.evmtype == $evmLeave
363 {
364 //print( "Leave\n" )
365 .flgEnter = 0
366 InvalidateRect( this.hwnd, 0->RECT, 1 )
367 }
368 return 0
369 }
370
371 /*Виртуальный метод uint vBtnPic.mWinCmd - Обработка windows сообщения с командой
372 */
373 method uint vBtnPic.mWinCmd <alias=vBtnPic_mWinCmd>( uint ntfcmd, uint id )
374 {
375 if ntfcmd == $BN_CLICKED
376 {
377 //print( "clicked\n" )
378 if .pBtnStyle == $bsAsRadioBtn
379 {
380 uint owner as this.Owner->vCtrl
381 uint i
382 if &owner
383 {
384 fornum i=0, owner.pCtrls
385 {
386 uint btn as owner.Comps[i]->vCustomBtn
387 if &btn == &this
388 {
389 btn.Checked = 1
390 }
391 elif btn.TypeIs( vCustomBtn ) &&
392 btn.pBtnStyle == $bsAsRadioBtn
393 {
394 btn.Checked = 0//( btn.WinMsg( $BM_GETCHECK ) == $BST_CHECKED )
395 }
396 }
397 }
398 }
399 elif .pBtnStyle == $bsAsCheckBox
400 {
401 .Checked = !.pChecked//( .WinMsg( $BM_GETCHECK ) == $BST_CHECKED )
402 }
403 evparEvent ev
404 ev.sender = &this
405 this.OnClick.Run( ev, this )
406 }
407 return 0
408 }
409
410 /*Виртуальный метод uint vCustomBtn.mLangChanged - Изменение текущего языка
411 */
412 method vBtnPic.mLangChanged <alias=vBtnPic_mLangChanged>()
413 {
414 this->vBtn.mLangChanged()
415 .iUpdateImage()
416 }
417
418 func init_vBtnPic <entry>()
419 {
420 regcomp( vBtnPic, "vBtnPic", vBtn, $vCtrl_last,
421 %{ //%{$mCreateWin, vBtnPic_mCreateWin},
422 //%{$mWinCmd, vBtnPic_mWinCmd},
423 %{$mPosChanged, vBtnPic_mPosChanged },
424 //%{$mUpdateCaption, vBtnPic_mUpdateCaption},
425 %{$mSetCaption, vBtnPic_mSetCaption},
426 %{$mWinDrawItem, vBtnPic_mWinDrawItem},
427 %{$mLangChanged, vBtnPic_mLangChanged},
428 %{$mMouse, vBtnPic_mMouse}
429 },
430 0->collection )
431 //%{
432 // %{$WM_ERASEBKGND, vBtn_wmerasebkgnd } } )//,
433 //%{$WM_PAINT, vBtn_wmpaint } } )
434 //%{$WM_DRAWITEM , vBtn_wmpaint } } )
435
436
437 ifdef $DESIGNING {
438 cm.AddComp( vBtnPic, 1, "Additional", "btnpic" )
439
440 cm.AddProps( vBtnPic, %{
441 "Image" , ustr, 0,
442 "Layout" , uint, 0,
443 "Flat" , uint, 0
444 })
445 /*
446 cm.AddEvents( vBtnPic, %{
447 "OnClick" , "evparEvent"
448 })
449 */
450 cm.AddPropVals( vBtnPic, "Layout", %{
451 "bplPicLeft", $bplPicLeft,
452 "bplPicTop", $bplPicTop
453 })
454
455
456 }
457
458 }