source: trunk/mediafolder/c/helper/launchpad.cpp@ 133

Last change on this file since 133 was 133, checked in by gyoung, 21 months ago

Merge Lar's 2.9 branch into the trunk

File size: 36.6 KB
Line 
1/*
2 * This file is (C) Chris Wohlgemuth 2001
3 */
4/*
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#define INC_WIN
21#define INCL_PM
22#define INCL_GPI
23
24#include "mediafolder.hh"
25#include "launchpad.hh"
26#include "cwcdtrack.hh"
27
28#include <os2.h>
29#include "stdio.h"
30#include "stdlib.h"
31
32#include "sys_funcs.h"
33SOMClass* somhlpGetSomClass(char* chrClassName);
34
35extern HWND hwndShadow;// The handle of the help window
36extern PFNWP oldProc; //place for original button-procedure
37extern HWND hwndBubbleWindow;// The handle of the help window
38#define WM_NEWBUBBLE WM_USER+100 //Use ATOM later
39#define xVal 12 //x-distance of Bubble
40#define yVal 8 //y-distance of Bubble
41extern char chrTBFlyFontName[CCHMAXPATH];/* Font for toolbar fly over help */
42extern RGB rgbTBFlyForeground;
43extern RGB rgbTBFlyBackground;
44extern BOOL bTBFlyOverEnabled;
45extern int iTBFlyOverDelay;
46
47
48#define xButtonDelta 2
49#define xButtonOffset 6
50
51PFNWP pfnwpOldLPProc;
52LPList* lplAllLPads=NULL;
53
54extern PFNWP oldButtonProc2; //place for original button-procedure
55
56MRESULT EXPENTRY newButtonProc(HWND hwnd, ULONG msg,MPARAM mp1,MPARAM mp2 );
57MRESULT EXPENTRY shadowProc(HWND hwnd, ULONG msg,MPARAM mp1,MPARAM mp2 );
58
59
60BOOL APIENTRY myDrgDeleteDraginfoStrHandles(PDRAGINFO pDragInfo)
61{
62 /* a replacement for DrgDeleteDraginfoStrHandles */
63 /* because that routine will fail if any one hstr is invalid */
64
65 ULONG i,ulItems;
66 PDRAGITEM pDragItem;
67
68 ulItems = DrgQueryDragitemCount(pDragInfo);
69 for (i=0;i<ulItems;i++)
70 {
71 pDragItem = DrgQueryDragitemPtr(pDragInfo,i);
72 DrgDeleteStrHandle(pDragItem->hstrType);
73 DrgDeleteStrHandle(pDragItem->hstrRMF);
74 DrgDeleteStrHandle(pDragItem->hstrContainerName);
75 DrgDeleteStrHandle(pDragItem->hstrSourceName);
76 DrgDeleteStrHandle(pDragItem->hstrTargetName);
77 }
78 return TRUE;
79}
80
81
82/******************************************************************************/
83/* New button procedure which handles the context menu stuff for the objects */
84/* The fly over help is managed by the standard button replacement proc. */
85/******************************************************************************/
86static MRESULT EXPENTRY newLaunchPadButtonProc(HWND hwnd, ULONG msg,MPARAM mp1,MPARAM mp2 )
87{
88 POINTL ptl;
89 HWND hwndMenu;
90 WPObject * wpObject;
91 LPObject* lpo;
92 PDRAGINFO pDragInfo;
93 static BOOL bDrawn=FALSE;
94 static DRAGITEM DragItem;
95 static DRAGIMAGE DragImage;
96 static DRAGINFO *DragInfo;
97
98 switch (msg)
99 {
100 case WM_PAINT:
101 lpo=(LPObject*)WinQueryWindowULong(hwnd,QWL_USER);
102 if(lpo) {
103 BTNCDATA btCtrl={0};
104 WNDPARAMS wndParams={0};
105
106 // memset(&btCtrl,0,sizeof(btCtrl));
107 btCtrl.cb=sizeof(btCtrl);
108 if(somIsObj(lpo->wpObject)) {
109 btCtrl.hImage=lpo->wpObject->wpQueryIcon();
110 // memset(&wndParams,0,sizeof(wndParams));
111 wndParams.fsStatus=WPM_CTLDATA;
112 wndParams.cbCtlData=btCtrl.cb;
113 wndParams.pCtlData=&btCtrl;
114 WinSendMsg(hwnd,WM_SETWINDOWPARAMS,
115 MPFROMP(&wndParams),0);
116 }
117 }
118 break;
119 case WM_CONTEXTMENU:
120 if(!SHORT2FROMMP(mp2)) {
121
122 lpo=(LPObject*)WinQueryWindowULong(hwnd,QWL_USER);
123 if(lpo) {
124 wpObject=lpo->wpObject;
125 if(somIsObj(wpObject)) {
126 ptl.y=0;
127 ptl.x=0;
128 hwndMenu=wpObject->wpDisplayMenu(hwnd,hwnd,&ptl,MENU_OBJECTPOPUP,0);
129 }
130 return (MRESULT) TRUE;
131 }
132
133 }/* end of if(!SHORT2FROMMP(mp2)) */
134 break;
135 case DM_DRAGOVER:
136 {
137 BOOL bReturn=FALSE;
138
139 TRY_LOUD(LP_DRAGOVER) {
140 lpo=(LPObject*)WinQueryWindowULong(hwnd,QWL_USER);
141 if(lpo) {
142 wpObject=lpo->wpObject;
143 if(somIsObj(wpObject)) {
144 char chrClassName[10];
145 LONG lLength;
146
147 pDragInfo=(PDRAGINFO) mp1;
148 hwndMenu=pDragInfo->hwndSource;
149 lLength=sizeof(chrClassName);
150 WinQueryClassName(hwndMenu, lLength, chrClassName);
151 if(strcmp(chrClassName,"#37"))
152 hwndMenu=NULL;/* Source isn't a container */
153 if(!bDrawn) {
154 HPS hps;
155 RECTL rectl;
156 SWP swp;
157
158 /* Draw the rect */
159 hps=DrgGetPS(hwnd);
160 WinQueryWindowPos(hwnd,&swp);
161 rectl.xLeft=1;
162 rectl.yBottom=1;
163 rectl.xRight=swp.cx-1;
164 rectl.yTop=swp.cy-1;
165 //WinDrawBorder(hps,&rectl, 3, 3, 0, 0, DB_STANDARD|DB_PATINVERT);
166 DrgReleasePS(hps);
167 //bDrawn=TRUE;
168 }
169 bReturn=TRUE;
170 }
171 }
172 }
173 CATCH(LP_DRAGOVER)
174 {
175 } END_CATCH;
176 if(bReturn)
177 return wpObject->wpDragOver(hwndMenu,(PDRAGINFO) mp1);
178 break;
179 }
180 case DM_DRAGLEAVE:
181 {
182 RECTL rectl;
183 SWP swp;
184 HPS hps;
185
186 /* Remove target emphasis here */
187 hps=DrgGetPS(hwnd);
188 WinQueryWindowPos(hwnd,&swp);
189 rectl.xLeft=1;
190 rectl.yBottom=1;
191 rectl.xRight=swp.cx-1;
192 rectl.yTop=swp.cy-1;
193 // WinDrawBorder(hps,&rectl,3, 3, 0, 0, DB_STANDARD|DB_PATINVERT);
194 bDrawn=FALSE;
195 DrgReleasePS(hps);
196 return (MRESULT) FALSE;
197 }
198 case DM_DROP:
199 {
200 BOOL bReturn=FALSE;
201 char chrClassName[10];
202 LONG lLength;
203 PDRAGITEM pDragItem;
204
205 TRY_LOUD(LP_DROP) {
206 /* A drop on a toolbar button */
207 lpo=(LPObject*)WinQueryWindowULong(hwnd,QWL_USER);
208 if(lpo) {
209 wpObject=lpo->wpObject;
210 if(somIsObj(wpObject)) {
211 pDragInfo=(PDRAGINFO) mp1;
212 pDragItem=DrgQueryDragitemPtr(pDragInfo, 0);
213 hwndMenu=pDragInfo->hwndSource;
214 lLength=sizeof(chrClassName);
215 WinQueryClassName(hwndMenu, lLength, chrClassName);
216 if(strcmp(chrClassName,"#37"))
217 hwndMenu=NULL;/* Source isn't a container */
218 bReturn=TRUE;
219 }
220 }
221 }
222 CATCH(LP_DROP)
223 {
224 } END_CATCH;
225 if(bReturn)
226 return wpObject->wpDrop(hwndMenu,(PDRAGINFO) mp1, pDragItem);
227 break;
228 }
229 case WM_COMMAND:
230 TRY_LOUD(LP_COMMAND) {
231 lpo=(LPObject*)WinQueryWindowULong(hwnd,QWL_USER);
232 if(lpo) {
233 wpObject=lpo->wpObject;
234 if(somIsObj(wpObject)) {
235 if((SHORT)0x6d==SHORT1FROMMP(mp1)) {
236 /* Delete menu item */
237 if(wpObject->wpDelete(CONFIRM_DELETE|CONFIRM_DELETEFOLDER ) == OK_DELETE)
238 lpo->lpParent->lpRemoveButton(lpo);
239 }
240 else
241 wpObject->wpMenuItemSelected(NULL, SHORT1FROMMP(mp1));
242 }/* end of if(somIsObj(wpObject)) */
243 }
244 }
245 CATCH(LP_COMMAND)
246 {
247 } END_CATCH;
248 return (MRESULT) FALSE;
249 default:
250 break;
251 }
252 // call the standard flyover button procedure to handle the rest of the messages
253 return (newButtonProc)(hwnd,msg,mp1,mp2);
254};
255
256static BOOL bDrawn=FALSE;
257static RECTL rclDrawn;
258static MRESULT handleDragOver(HWND hwnd, MPARAM mp1, MPARAM mp2)
259{
260 ULONG ulNumberOfObjects;
261 PDRAGINFO pDragInfo;
262 HPS hps;
263 RECTL rectl;
264 SWP swp;
265 USHORT usIndicator=DOR_NEVERDROP,usOp=0;
266 WPObject *wpObject = NULL;
267
268 /* Get access to the dragInfo */
269 pDragInfo=(PDRAGINFO)mp1;
270 if (DrgAccessDraginfo(pDragInfo)) {
271 PDRAGITEM pDragItem = NULL;
272 SOMClass *cdTrackClass = NULL;
273
274 /* Get number of items */
275 ulNumberOfObjects = DrgQueryDragitemCount( pDragInfo);
276
277 if(ulNumberOfObjects>1) {
278 usIndicator = DOR_NODROP;
279 usOp = 0;
280 goto quit;
281 }
282
283 /* check if a WPS object was dropped, we do not accept anything else */
284 pDragItem = DrgQueryDragitemPtr(pDragInfo,0);
285 if (!DrgVerifyRMF(pDragItem,"DRM_OBJECT","DRF_OBJECT")) {
286 usIndicator = DOR_NEVERDROP;
287 usOp = 0;
288 goto quit;
289 } /* endif */
290
291 /*
292 refuse drop if WPS object pointer is not valid or if the object is
293 a descendant of MMCDTrack class (see Netlabs ticket #19)
294 */
295 wpObject = (WPObject *)OBJECT_FROM_PREC(pDragItem->ulItemID);
296 cdTrackClass = somhlpGetSomClass("MMCDTrack");
297 if (!somIsObj(wpObject) || wpObject->somIsA(cdTrackClass)) {
298 usIndicator = DOR_NEVERDROP;
299 usOp = 0;
300 goto quit;
301 } /* endif */
302
303 switch(pDragInfo->usOperation)
304 {
305 case DO_DEFAULT:
306 case DO_LINK:
307 if(!bDrawn) {
308 POINTL ptl;
309 launchPad * lp;
310
311 ptl.x=SHORT1FROMMP(mp2);
312 ptl.y=SHORT2FROMMP(mp2);
313 /* Pos in window coords */
314 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
315
316 hps=DrgGetPS(hwnd);
317 WinQueryWindowPos(hwnd,&swp);
318
319 rectl.xLeft=swp.cx;//-swp.cy;
320
321 lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER);
322 if(lp) {
323 if(lp->lpQueryNumObjects()==0) {
324 rectl.xLeft=0;
325 }
326 }
327
328 rectl.yTop=swp.cy-1;
329 rectl.yBottom=1;
330 if(ptl.x<rectl.xLeft) {
331 int numB;
332
333 numB=(ptl.x-xButtonOffset)/(swp.cy+xButtonDelta);
334 rectl.xLeft=((ptl.x-numB*swp.cy) > swp.cy/2 ? numB+1: numB);
335 rectl.xLeft*=(swp.cy+xButtonDelta);
336 rectl.xLeft-=(xButtonDelta)-xButtonOffset+xButtonDelta;
337 rectl.xRight=rectl.xLeft+(xButtonDelta*2);
338 }
339 else {
340 rectl.xRight=swp.cx-1;
341 }
342 rclDrawn=rectl;
343 WinDrawBorder(hps,&rectl, 2, 2, 0, 0, DB_STANDARD|DB_PATINVERT);
344 bDrawn=TRUE;
345
346 DrgReleasePS(hps);
347 }
348 usIndicator = DOR_DROP;
349 usOp = DO_LINK;
350 break;
351 default:
352 usIndicator = DOR_NODROPOP;
353 usOp = DO_LINK;
354 break;
355 }
356quit:
357 /* Free the draginfo */
358 DrgFreeDraginfo(pDragInfo);
359 }
360 return MRFROM2SHORT(usIndicator,usOp);
361}
362
363
364static MRESULT handleDragLeave(HWND hwnd, MPARAM mp1, MPARAM mp2)
365{
366 RECTL rectl;
367 SWP swp;
368 HPS hps;
369
370 /* Remove target emphasis here */
371 hps=DrgGetPS(hwnd);
372 WinDrawBorder(hps,&rclDrawn, 2, 2, 0, 0, DB_STANDARD|DB_PATINVERT);
373 DrgReleasePS(hps);
374 bDrawn=FALSE;
375 return (MRESULT) FALSE;
376}
377
378
379static MRESULT EXPENTRY launchPadWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
380{
381 WPFolder* thisPtr;
382 launchPad * lp;
383 LPObject *lpo;
384 static USHORT id=0;//Initialisation new in V1.00a
385
386 switch(msg)
387 {
388 case WM_PAINT:
389 {
390 RECTL rcl;
391 launchPad * lp;
392
393 HPS hps=WinBeginPaint(hwnd,NULLHANDLE, &rcl);
394 WinFillRect(hps, &rcl, SYSCLR_DIALOGBACKGROUND);
395 lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER);
396 if(lp) {
397 if(lp->lpQueryNumObjects()==0) {
398 WinQueryWindowRect(hwnd,&rcl);
399 WinDrawBorder(hps,&rcl,1,1,SYSCLR_WINDOWFRAME,SYSCLR_DIALOGBACKGROUND, DB_STANDARD);
400 }
401 }
402 WinEndPaint(hps);
403 return (MRESULT) 0;
404 }
405 case DM_DRAGOVER:
406 return handleDragOver(hwnd, mp1, mp2);
407 case DM_DROP:
408 {
409 TRY_LOUD(LP_FRAMEDROP) {
410 /* A new object dropped on the launchpad */
411 PDRAGINFO pDragInfo=(PDRAGINFO)mp1;
412 if(DrgAccessDraginfo(pDragInfo)) {
413 lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER);
414 if(lp) {
415 PDRAGITEM pDragItem=DrgQueryDragitemPtr( pDragInfo, 0);
416 WPObject *wpObject=(WPObject*)OBJECT_FROM_PREC(pDragItem->ulItemID);
417 POINTL ptl;
418 int numB;
419 SWP swp;
420
421 WinQueryWindowPos(hwnd,&swp);
422 ptl.x=pDragInfo->xDrop;
423 ptl.y=pDragInfo->yDrop;
424 /* Pos in window coords */
425 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
426 numB=(ptl.x-xButtonOffset)/(swp.cy+xButtonDelta);
427 numB=((ptl.x-numB*swp.cy) > swp.cy/2 ? numB+1: numB);
428
429 /* Do a link */
430 lp->lpAddButton(wpObject, numB);
431 }
432 myDrgDeleteDraginfoStrHandles(pDragInfo);
433 DrgFreeDraginfo(pDragInfo);
434 }
435 handleDragLeave(hwnd, mp1, mp2);
436 }
437 CATCH(LP_FRAMEDROP)
438 {
439 } END_CATCH;
440 return MRFROMLONG(0);
441 }
442 case DM_DRAGLEAVE:
443 return handleDragLeave(hwnd, mp1, mp2);
444 break;
445 case WM_COMMAND:
446 if(SHORT1FROMMP(mp2)==CMDSRC_PUSHBUTTON) {
447 /* It's a push button */
448 lpo=(LPObject*)WinQueryWindowULong(WinWindowFromID(hwnd,SHORT1FROMMP(mp1)),QWL_USER);
449 if(lpo) {
450 if(somIsObj(lpo->wpObject))
451 lpo->wpObject->wpViewObject(NULLHANDLE, OPEN_DEFAULT,0);
452 }
453 }
454 return (MRESULT)FALSE;
455 /***********************************************/
456 /* Stuff for fly over help */
457 case WM_MOUSEMOVE:
458 launchPad * lp;
459
460 lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER);
461 if(lp) {
462 if(lp->lpQueryNumObjects()!=0) {
463 break;
464 }
465 }
466
467 if(!hwndBubbleWindow)
468 WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, 2,(ULONG)iTBFlyOverDelay); // New timer for delay
469
470 break;
471 case WM_DESTROY:
472 WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,1);//Stop timer if running
473 if(hwndBubbleWindow)
474 WinDestroyWindow(hwndBubbleWindow);/* close the bubblewindow */
475 hwndBubbleWindow=0;
476 /* Stop delay timer if running */
477 WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd, 2);
478 break;
479
480 case WM_NEWBUBBLE:
481 ULONG bubbleEnabled;
482 HWND hwndStore;
483 POINTL ptl;
484 RECTL rclWork;
485 LONG ulWinTextLen;
486 POINTL aptlPoints[TXTBOX_COUNT];
487 LONG deltaX,deltaY;
488 HPS hps;
489 RECTL rcl;
490
491 /* we have to build a new information window */
492 if(hwndBubbleWindow){// if(){...} new in V1.00a
493 WinDestroyWindow(hwndBubbleWindow);/* close the bubblewindow */
494 hwndBubbleWindow=NULL;
495 }
496 // Query the pointer position
497 WinQueryPointerPos(HWND_DESKTOP,&ptl);
498 WinMapWindowPoints(HWND_DESKTOP,hwnd,&ptl,1);
499 WinQueryWindowRect(hwnd,&rclWork);
500 if(!hwndBubbleWindow
501 && WinPtInRect(WinQueryAnchorBlock(hwnd),&rclWork,&ptl)
502 && bTBFlyOverEnabled) {
503
504 static HWND hwndBubbleClient;
505 ULONG style=FCF_BORDER|FCF_NOBYTEALIGN;
506 char winText[255] = {0};
507
508 /* Get window text for size calculating */
509 lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER);
510 if(lp) {
511 strncpy(winText, lp->lpQueryFlyOverText(), sizeof(winText));
512 winText[sizeof(winText)-1]=0;
513 }
514
515 ulWinTextLen=(LONG)strlen(winText); // Query text length
516
517 /* Delete 'Returns' in object title */
518 char *pBuchst;
519 char *pRest;
520 pRest=winText;
521 while((pBuchst=strchr(pRest,13))!=NULL) {
522 *pBuchst=' ';
523 pBuchst++;
524 if(*pBuchst==10)
525 *pBuchst=' ';
526 pRest=pBuchst;
527 }
528
529 /* Create help window */
530 hwndBubbleWindow=WinCreateStdWindow(HWND_DESKTOP,
531 0,
532 &style,
533 WC_STATIC,
534 "",
535 SS_TEXT|DT_CENTER|DT_VCENTER,
536 NULLHANDLE,
537 400,
538 &hwndBubbleClient);
539
540 hwndShadow=WinCreateWindow(HWND_DESKTOP,
541 WC_STATIC,
542 "",
543 SS_TEXT|DT_CENTER|DT_VCENTER,
544 0, 0,
545 0, 0,
546 hwndBubbleWindow,
547 hwndBubbleWindow,
548 401,
549 NULLHANDLE,
550 NULLHANDLE);
551 oldProc=WinSubclassWindow(hwndShadow, shadowProc);
552
553 // Set the font for the help
554 WinSetPresParam(hwndBubbleClient,PP_FONTNAMESIZE,
555 sizeof(chrTBFlyFontName),
556 chrTBFlyFontName);
557 /* Calculate text size in pixel */
558 hps=WinBeginPaint(hwndBubbleClient,(HPS)NULL,(PRECTL)NULL);
559 GpiQueryTextBox(hps,ulWinTextLen,winText,TXTBOX_COUNT,aptlPoints);
560 WinEndPaint(hps);
561
562 /* Set colors */
563 WinSetPresParam(hwndBubbleClient,
564 PP_BACKGROUNDCOLOR,sizeof(rgbTBFlyBackground) ,
565 &rgbTBFlyBackground );
566 WinSetPresParam(hwndBubbleClient,
567 PP_FOREGROUNDCOLOR,sizeof(rgbTBFlyForeground) ,
568 &rgbTBFlyForeground );
569
570 /* Calculate bubble positon and show bubble */
571 WinQueryPointerPos(HWND_DESKTOP,&ptl);//Query pointer position in the desktop window
572 WinQueryWindowRect(HWND_DESKTOP,&rcl);//Query desktop size
573 aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+7+xVal+ptl.x
574 > rcl.xRight
575 ? deltaX=-aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x-xVal-xVal-7
576 : deltaX=0 ;
577
578 aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2+yVal+ptl.y
579 > rcl.yTop
580 ? deltaY=-aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y-2*yVal-7
581 : deltaY=0 ;
582 WinSetWindowPos(hwndBubbleWindow,
583 HWND_TOP,
584 ptl.x+xVal+deltaX,ptl.y+yVal+deltaY,
585 aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+8,
586 aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2,
587 SWP_ZORDER|SWP_SIZE|SWP_MOVE|SWP_SHOW);
588
589 WinSetWindowPos(hwndShadow,
590 hwndBubbleWindow,
591 ptl.x+xVal+deltaX+5
592 ,ptl.y+yVal+deltaY-5,
593 aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+8,
594 aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2,
595 SWP_ZORDER|SWP_SIZE|SWP_MOVE|SWP_SHOW);
596
597 /* Set bubble text */
598 WinSetWindowText(hwndBubbleClient,winText);
599 WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,1,35);
600 } // end if(!hwndBubbleWindow)
601 break;
602 case WM_TIMER:
603 switch (SHORT1FROMMP(mp1))
604 {
605 case 1: //Intervall timer
606 {
607 POINTL ptl;
608 RECTL rclWork;
609
610 /* Test pointer position */
611 WinQueryPointerPos(HWND_DESKTOP, &ptl);
612 WinMapWindowPoints(HWND_DESKTOP, hwnd,&ptl, 1);
613 WinQueryWindowRect(hwnd, &rclWork);
614 if(!WinPtInRect(WinQueryAnchorBlock(hwnd),&rclWork,&ptl))
615 { // Window has changed
616 WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, 1); // stop the running timer
617 if(hwndBubbleWindow)
618 WinDestroyWindow(hwndBubbleWindow);/* close the bubblewindow */
619 hwndBubbleWindow=0;
620 id=0;
621 }
622 break;
623 }
624 case 2:// delay over
625 {//our own timer.
626 POINTL ptl;
627 RECTL rclWork;
628
629 WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, 2);//Stop the delay timer
630 /* Check the pointer position */
631 WinQueryPointerPos(HWND_DESKTOP,&ptl);
632 WinMapWindowPoints(HWND_DESKTOP,hwnd,&ptl,1);
633 WinQueryWindowRect(hwnd,&rclWork);
634 if(WinPtInRect(WinQueryAnchorBlock(hwnd),&rclWork,&ptl))
635 WinPostMsg(hwnd,WM_NEWBUBBLE,NULL,NULL);//Request a help window
636 return (MRESULT)FALSE;
637 }
638 default:
639 break;
640 }
641 break;
642 default:
643 break;
644 }
645 return pfnwpOldLPProc(hwnd, msg, mp1, mp2);
646}
647
648void LPList::lplRefreshAllPads()
649{
650
651}
652
653LPObject::LPObject(HPOINTER hptr)
654{
655 hPtr=hptr;
656}
657
658LPObject::~LPObject(void)
659{
660}
661
662launchPad::launchPad(HWND hwndParent,HWND hwndOwner, BOOL bVisible, WPFolder *wpParent, LPList** lpadList, HWND hwndPrev, ULONG ulFl)
663{
664 LPList *lplTemp;
665
666 wpParentFolder=wpParent;
667 hwndPrevious=hwndPrev;
668 fl=ulFl;
669 lpList=lpadList;
670
671 /* Reset text */
672 chrFlyOverText[0]=0;
673
674 if((hwndLaunchPad=WinCreateWindow(hwndParent ,WC_FRAME, "Toolbar", FS_BORDER| (bVisible ? WS_VISIBLE: 0),
675 0, 0, 0, 0, hwndOwner, HWND_TOP, 1234, NULLHANDLE, NULLHANDLE))!=NULLHANDLE) {
676 WinSetWindowULong(hwndLaunchPad, QWL_USER,(ULONG) this);//Save object ptr.
677 pfnwpOldLPProc=WinSubclassWindow(hwndLaunchPad, launchPadWindowProc);
678 }
679
680 ulNumObjects=0;
681 lpoObjectList=NULL;
682
683 /* Add this pad to the list of pads */
684 if(!lplAllLPads) {
685 /* It's the first one */
686 if((lplAllLPads=new LPList)!=NULL) {
687 lplAllLPads->lpPad=this;
688 lplAllLPads->lplNext=NULL;
689 }
690 }
691 else {
692 if((lplTemp=new LPList)!=NULL) {
693 lplTemp->lpPad=this;
694 lplTemp->lplNext=lplAllLPads;
695 lplAllLPads=lplTemp;
696 }
697 }
698}
699
700launchPad::~launchPad()
701{
702 LPList *lplTemp, *lplTemp2;
703
704 lpSaveObjectList();
705 lpFreeObjectList();
706
707 if(hwndLaunchPad)
708 WinDestroyWindow(hwndLaunchPad);
709
710 /* Remove this pad from the list of pads */
711 lplTemp=lplAllLPads;
712
713 if(lplTemp->lpPad==this) {
714 lplAllLPads=lplTemp->lplNext;
715 delete(lplTemp);
716 }
717 else {
718 while(lplTemp->lplNext)
719 {
720 if(lplTemp->lplNext->lpPad==this) {
721 lplTemp2=lplTemp->lplNext;
722 lplTemp->lplNext=lplTemp->lplNext->lplNext;
723 delete(lplTemp2);
724 break;
725 }
726 lplTemp=lplTemp->lplNext;
727 }
728 }
729}
730
731BOOL launchPad::lpSetFlyOverText(char* chrText)
732{
733 strncpy(chrFlyOverText, chrText, sizeof(chrFlyOverText));
734 chrFlyOverText[sizeof(chrFlyOverText)-1]=0;
735
736 return TRUE;
737}
738
739PSZ launchPad::lpQueryFlyOverText(void)
740{
741 return chrFlyOverText;
742}
743
744BOOL launchPad::lpSetLaunchPadPos(HWND hwndInsertBehind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl)
745{
746 if(WinIsWindow(WinQueryAnchorBlock(hwndLaunchPad), hwndPrevious)) {
747 SWP swp;
748 WinQueryWindowPos(hwndPrevious,&swp);
749 return WinSetWindowPos(hwndLaunchPad, hwndInsertBehind, swp.x+swp.cx+x, y, cx, cy, fl);
750 }
751 else
752 return WinSetWindowPos(hwndLaunchPad, hwndInsertBehind, x, y, cx, cy, fl);
753}
754
755
756BOOL launchPad::lpSetConfiguration(char * chrTarget, char * chrConfigID_)
757{
758 HOBJECT hObject;
759 char chrSetup[CCHMAXPATH];
760
761 /* Destination of toolbar folder */
762 strncpy(chrConfigTarget, chrTarget,sizeof(chrConfigTarget));
763 chrConfigTarget[sizeof(chrConfigTarget)-1]=0;
764 /* The ID of the toolbar folder */
765 strncpy(chrConfigID, chrConfigID_,sizeof(chrConfigID));
766 chrConfigID[sizeof(chrConfigID)-1]=0;
767
768 /* First check the config folder */
769 if((hObject=WinQueryObject(chrConfigID))==NULLHANDLE)
770 {
771 /* Toolbar folder lost recreate it */
772 if(!SysCheckFileExists(chrConfigTarget))
773 return FALSE; /* No install dir defined */
774
775 if(fl & LP_USEOBJECTASPARAM) {
776 /* This isn't used yet */
777 sprintf(chrSetup, "HIDECLASSPAGE=1;OBJECTID=%s",chrConfigID);
778 if((hObject=WinCreateObject("CWMenuFolder", chrConfigID, chrSetup, chrConfigTarget,CO_FAILIFEXISTS))==NULLHANDLE)
779 return FALSE; /* Can't create new toolbar folder */
780 }
781 else {
782 sprintf(chrSetup, "OBJECTID=%s", chrConfigID);
783 if((hObject=WinCreateObject("WPFolder", chrConfigID, chrSetup, chrConfigTarget,CO_FAILIFEXISTS))==NULLHANDLE)
784 return FALSE; /* Can't create new toolbar folder */
785 }
786 }
787
788 lpBuildObjectList(chrConfigID);
789
790 return TRUE;
791}
792
793WPFolder* launchPad::lpQueryParentFolder()
794{
795 return wpParentFolder;
796}
797
798void launchPad::lpRefreshLaunchPad()
799{
800 /* Refresh all launchpads */
801 LPList *lplTemp;
802
803 //lplTemp=lplAllLPads;
804 lplTemp=*lpList;
805
806 while(lplTemp)
807 {
808 if(lplTemp->lpPad) {
809 lplTemp->lpPad->lpFreeObjectList();
810 lplTemp->lpPad->lpReBuildObjectList();
811 lplTemp->lpPad->lpFillPad();
812 }
813 lplTemp=lplTemp->lplNext;
814 }
815 return;
816}
817
818BOOL launchPad::lpRemoveButton(LPObject *lpObject)
819{
820 int a;
821 LPObject* lpoTemp, *lpoTemp2;
822
823 /* Find object in list */
824 lpoTemp=lpoObjectList;
825
826 if(lpoTemp==lpObject) {
827 lpoObjectList=lpoTemp->lpoNext;
828
829 delete(lpObject);
830 ulNumObjects--;
831 }
832 else {
833 while(lpoTemp->lpoNext)
834 {
835 if(lpoTemp->lpoNext==lpObject) {
836 lpoTemp->lpoNext=lpObject->lpoNext;
837
838 delete(lpObject);
839 ulNumObjects--;
840 break;
841 }
842 lpoTemp=lpoTemp->lpoNext;
843 }
844 }
845
846 lpSaveObjectList();
847 lpRefreshLaunchPad();
848
849 return TRUE;
850}
851
852
853BOOL launchPad::lpAddButton(WPObject* wpObject, int iPos)
854{
855 HOBJECT hObject;
856 SOMClass *folderClass;
857 char chrSetup[CCHMAXPATH];
858 WPObject *wpTempObject;
859 LPObject *lpoTemp, *lpoTemp2, *lpoTempNew;
860 int a;
861
862
863 /* First check the config folder */
864 if((hObject=WinQueryObject(chrConfigID))==NULLHANDLE)
865 {
866 /* Toolbar folder lost recreate it */
867 if(!SysCheckFileExists(chrConfigTarget))
868 return FALSE; /* No install dir defined */
869
870 if(fl & LP_USEOBJECTASPARAM) {
871 sprintf(chrSetup, "HIDECLASSPAGE=1;OBJECTID=%s", chrConfigID);
872 if((hObject=WinCreateObject("CWMenuFolder", chrConfigID, chrSetup, chrConfigTarget,CO_FAILIFEXISTS))==NULLHANDLE)
873 return FALSE; /* Can't create new toolbar folder */
874 }
875 else {
876 sprintf(chrSetup, "OBJECTID=%s", chrConfigID);
877 if((hObject=WinCreateObject("WPFolder", chrConfigID, chrSetup, chrConfigTarget,CO_FAILIFEXISTS))==NULLHANDLE)
878 return FALSE; /* Can't create new toolbar folder */
879 }
880 }
881
882 if(somIsObj(wpObject) && somIsObj(wpParentFolder)) {
883 folderClass=wpParentFolder->somGetClass();
884 if(somIsObj(folderClass)) {
885 /* Create a shadow in our toolbar folder */
886 wpTempObject=wpObject->wpCreateShadowObject((WPFolder*)((M_WPFolder*)folderClass)->wpclsQueryFolder(chrConfigID, FALSE), FALSE);
887 if(somIsObj(wpTempObject)) {
888 /* Get the persistent object handle */
889 hObject=wpTempObject->wpQueryHandle();
890
891 /* Find the insertion point */
892 /* iPos is the button after which we insert the new one. The list of objects is in reverse order. */
893 lpoTemp2=lpoObjectList;
894 if(iPos<ulNumObjects) {
895 lpoTemp=lpoTemp2;
896 for(a=ulNumObjects;a>iPos && lpoTemp; a--)
897 {
898 lpoTemp=lpoTemp2;
899 lpoTemp2=lpoTemp2->lpoNext;
900 }
901 }
902 else
903 lpoTemp=NULLHANDLE;
904
905 /* lpoTemp contains object */
906 /* Alloc a struct for this object to insert it on the toolbar */
907
908 if((lpoTempNew=new LPObject(wpTempObject->wpQueryIcon()))!=NULL) {
909 ULONG ulRC;
910
911 lpoTempNew->wpObject=wpTempObject;
912 lpoTempNew->wpObject->wpLockObject();
913 lpoTempNew->hObject=hObject;
914 // lpoTempNew->hPtr=wpTempObject->wpQueryIcon();
915
916 /* Title of the object */
917 strncpy(lpoTempNew->chrName, wpTempObject->wpQueryTitle(),sizeof(lpoTempNew->chrName));
918 lpoTempNew->lpParent=this;
919
920 if(lpoTemp) {
921 lpoTempNew->lpoNext=lpoTemp->lpoNext;
922 lpoTemp->lpoNext=lpoTempNew;
923 }
924 else {
925 lpoTempNew->lpoNext=lpoObjectList;
926 lpoObjectList=lpoTempNew;
927 }
928 ulNumObjects++;
929 }
930 }
931 }
932 }
933
934 lpSaveObjectList();
935 lpRefreshLaunchPad();
936
937 return TRUE;
938}
939
940
941BOOL launchPad::lpSaveObjectList()
942{
943 SOMClass *folderClass;
944 WPFolder *wpFolder;
945 char chrPath[CCHMAXPATH];
946 ULONG ulBufferSize;
947 HINI hIni;
948 char * memPtr;
949 HOBJECT *hObject;
950 HOBJECT hObject2;
951 int a;
952 LPObject *lpoTemp;
953
954 /* First check the config folder */
955 if((hObject2=WinQueryObject(chrConfigID))==NULLHANDLE)
956 {
957 /* Toolbar folder lost recreate it */
958 if(!SysCheckFileExists(chrConfigTarget))
959 return FALSE; /* No install dir defined */
960
961 sprintf(chrPath,"OBJECTID=%s",chrConfigID);
962 if((hObject2=WinCreateObject("WPFolder", chrConfigID, chrPath,chrConfigTarget,CO_FAILIFEXISTS))==NULLHANDLE)
963 return FALSE; /* Can't create new toolbar folder */
964 }
965
966 /* Get toolbar folder */
967 if(somIsObj(wpParentFolder)) {
968 folderClass=wpParentFolder->somGetClass();
969 if(somIsObj(folderClass))
970 wpFolder=(WPFolder*)((M_WPFolder*)folderClass)->wpclsQueryFolder(chrConfigID, FALSE);
971 if(!somIsObj(wpFolder))
972 return FALSE;
973 }
974 else
975 return FALSE;
976
977 // Fixme see line 1106
978 ulBufferSize=sizeof(chrPath);
979 wpFolder->wpQueryRealName(chrPath, &ulBufferSize, TRUE);
980 strcat(chrPath,"\\objects.ini");/* Ini-File containing the hobjects */
981
982 // WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, chrPath, "~launchPad", 123, MB_OK| MB_MOVEABLE);
983 do{
984 /* Open the ini-file */
985 if((hIni=PrfOpenProfile(WinQueryAnchorBlock(HWND_DESKTOP),chrPath))==NULLHANDLE)
986 break;
987
988 if((memPtr=(char*)malloc(ulNumObjects*sizeof(HOBJECT)))==NULL)
989 break;
990
991
992 hObject=(HOBJECT*)memPtr;
993
994 lpoTemp=lpoObjectList;
995 for(a=ulNumObjects;a>0 && lpoTemp; a--)
996 {
997 hObject[a-1]=lpoTemp->hObject;
998 lpoTemp=lpoTemp->lpoNext;
999 }
1000
1001 if(!PrfWriteProfileData(hIni,"objects","handles", hObject, ulNumObjects*sizeof(HOBJECT))) {
1002 free(hObject);
1003 break;
1004 }
1005
1006 free(hObject);
1007
1008 PrfCloseProfile(hIni);
1009 return TRUE;
1010 }while(TRUE);
1011
1012 if(hIni)
1013 PrfCloseProfile(hIni);
1014 return FALSE;
1015}
1016
1017BOOL launchPad::lpReBuildObjectList()
1018{
1019 return lpBuildObjectList( chrConfigID);
1020}
1021
1022BOOL launchPad::lpBuildObjectList(char * chrFolderID)
1023{
1024 WPObject* wpObject;
1025
1026 char chrText[200];
1027 ULONG ul;
1028
1029 SOMClass *folderClass;
1030 WPFolder *wpFolder;
1031 char chrPath[CCHMAXPATH];
1032 ULONG ulBufferSize;
1033 HINI hIni;
1034 char * memPtr;
1035 HOBJECT *hObjectArray;
1036 int a;
1037 LPObject *lpoTemp;
1038 WPObject * wpTempObject;
1039
1040
1041 /* Get toolbar folder */
1042 if(somIsObj(wpParentFolder)) {
1043 folderClass=wpParentFolder->somGetClass();
1044 if(somIsObj(folderClass))
1045 wpFolder=(WPFolder*)((M_WPFolder*)folderClass)->wpclsQueryFolder(chrFolderID, FALSE);
1046 if(!somIsObj(wpFolder))
1047 return FALSE;
1048 }
1049 else
1050 return FALSE;
1051 // Fixme wpFolder can be uninittailized if(somIsObj(wpParentFolder)) is false sould we return FALSE
1052 /* Build ini name */
1053 ulBufferSize=sizeof(chrPath);
1054 wpFolder->wpQueryRealName(chrPath, &ulBufferSize, TRUE);
1055 strcat(chrPath,"\\objects.ini");/* Ini-File containing the hobjects */
1056
1057 do{
1058 /* Open the ini-file */
1059 if((hIni=PrfOpenProfile(WinQueryAnchorBlock(HWND_DESKTOP),chrPath))==NULLHANDLE)
1060 break;
1061
1062 if(!PrfQueryProfileSize(hIni,"objects","handles", &ulBufferSize))
1063 break;
1064
1065 if(ulBufferSize==0)
1066 break;/* No entries yet */
1067
1068 if((memPtr=(char*)malloc(ulBufferSize))==NULL)
1069 break;
1070
1071 ulNumObjects=ulBufferSize/sizeof(HOBJECT);
1072
1073 if(!PrfQueryProfileData(hIni,"objects","handles", memPtr, &ulBufferSize)){
1074 free(memPtr);
1075 break;
1076 }
1077
1078 hObjectArray=(HOBJECT*)memPtr;
1079 ulBufferSize=ulNumObjects;
1080 for(a=0;a<ulBufferSize && lpoTemp; a++)
1081 {
1082 wpTempObject=((M_WPObject*)folderClass)->wpclsQueryObject(hObjectArray[a]);
1083 if(somIsObj(wpTempObject)) {
1084 if((lpoTemp=new LPObject(wpTempObject->wpQueryIcon()))!=NULL) {
1085 lpoTemp->wpObject=wpTempObject;
1086 wpTempObject->wpLockObject();
1087 lpoTemp->hObject=hObjectArray[a];
1088 // lpoTemp->hPtr=wpTempObject->wpQueryIcon();
1089 /* Title of the object */
1090 strncpy(lpoTemp->chrName, wpTempObject->wpQueryTitle(),sizeof(lpoTemp->chrName));
1091 lpoTemp->lpParent=this;
1092
1093 lpoTemp->lpoNext=lpoObjectList;
1094 lpoObjectList=lpoTemp;
1095 }
1096 }
1097 else {
1098 ulNumObjects--;
1099 }
1100 }/* for */
1101
1102 free(hObjectArray);
1103
1104 PrfCloseProfile(hIni);
1105 return TRUE;
1106 }while(TRUE);
1107
1108 if(hIni)
1109 PrfCloseProfile(hIni);
1110 return FALSE;
1111
1112}
1113
1114void launchPad::lpFreeObjectList()
1115{
1116 LPObject *lpoTemp, *lpoTemp2;
1117
1118 /* Free our object list */
1119 lpoTemp=lpoObjectList;
1120 while(lpoTemp) {
1121 lpoTemp2=lpoTemp->lpoNext;
1122 lpoTemp->wpObject->wpUnlockObject();
1123 delete (lpoTemp);
1124 lpoTemp=lpoTemp2;
1125 }
1126 lpoObjectList=NULL;
1127}
1128
1129BOOL launchPad::lpClearPad()
1130{
1131 LPObject *lpoTemp, *lpoTemp2;
1132 int a;
1133 HENUM hEnum;
1134 HWND hwnd;
1135
1136 /* Destroy all Buttons */
1137 hEnum=WinBeginEnumWindows(hwndLaunchPad);
1138 while((hwnd=WinGetNextWindow(hEnum))!=NULLHANDLE)
1139 WinDestroyWindow(hwnd);
1140 WinEndEnumWindows(hEnum);
1141
1142 return TRUE;
1143}
1144
1145
1146BOOL launchPad::lpFillPad()
1147{
1148 HOBJECT hObject;
1149 char chrSetup[CCHMAXPATH];
1150 WPFolder* wpFolder;
1151 LPObject *lpoTemp;
1152
1153 SWP swp;
1154 HWND hwndTemp;
1155 BTNCDATA btCtrl;
1156 WNDPARAMS wndParams;
1157 ULONG ulStyle;
1158 int a;
1159 LONG lXSize;
1160 HENUM hEnum;
1161 HWND hwndClient;
1162 LONG lCxSave;
1163
1164 /* Remove Buttons from pad */
1165 lpClearPad();
1166
1167 /* Resize the pad for all objects */
1168 if(!WinQueryWindowPos(hwndLaunchPad, &swp))
1169 return FALSE;
1170
1171
1172 lCxSave=swp.cx;
1173
1174 lXSize=(ulNumObjects == 0 ? swp.cy : (ulNumObjects) * (swp.cy+xButtonDelta) +2*xButtonOffset);
1175 lpSetLaunchPadPos( NULLHANDLE,0,0, lXSize , swp.cy, SWP_SIZE);
1176
1177 /* Move all controls on the right */
1178 /* Move all client windows so they keep their distance to the left border */
1179 hEnum=WinBeginEnumWindows(WinQueryWindow(hwndLaunchPad,QW_PARENT));
1180 while((hwndClient=WinGetNextWindow(hEnum))!=NULLHANDLE) {
1181 SWP swpClient;
1182
1183 WinQueryWindowPos(hwndClient,&swpClient);
1184 if(swpClient.x > swp.x)
1185 WinSetWindowPos(hwndClient, NULLHANDLE, swpClient.x+(lXSize-lCxSave), swpClient.y, 0, 0, SWP_MOVE);
1186 }/* while */
1187 WinEndEnumWindows(hEnum);
1188
1189 lpoTemp=lpoObjectList;
1190 for(a=ulNumObjects;a>0 && lpoTemp; a--)
1191 {
1192 /* Create Buttons */
1193 if((hwndTemp=WinCreateWindow(hwndLaunchPad, WC_BUTTON, lpoTemp->chrName, WS_VISIBLE, xButtonOffset+(a-1)*(swp.cy+xButtonDelta), 1, swp.cy-2, swp.cy-2,
1194 hwndLaunchPad, HWND_TOP, a*100,
1195 NULLHANDLE, NULLHANDLE))!=NULLHANDLE)
1196 {
1197 /* Change Style to mini icon */
1198 ulStyle=WinQueryWindowULong(hwndTemp,QWL_STYLE);
1199 ulStyle|=(BS_MINIICON);
1200 ulStyle&=~BS_TEXT;
1201 if(WinSetWindowULong(hwndTemp,QWL_STYLE,ulStyle)) {
1202 memset(&btCtrl,0,sizeof(btCtrl));
1203 btCtrl.cb=sizeof(btCtrl);
1204 btCtrl.hImage=lpoTemp->hPtr;
1205 memset(&wndParams,0,sizeof(wndParams));
1206 wndParams.fsStatus=WPM_CTLDATA;
1207 wndParams.cbCtlData=btCtrl.cb;
1208 wndParams.pCtlData=&btCtrl;
1209 WinSendMsg(hwndTemp,WM_SETWINDOWPARAMS,
1210 MPFROMP(&wndParams),0);
1211 /* Subclass button for flyover help */
1212 oldButtonProc2=WinSubclassWindow(hwndTemp, newLaunchPadButtonProc);
1213 /* Set the class pointer into the window words */
1214 WinSetWindowULong(hwndTemp,QWL_USER,(ULONG)lpoTemp);//Save object ptr.
1215 }
1216 }
1217 lpoTemp=lpoTemp->lpoNext;
1218 }
1219 return TRUE;
1220}
1221
Note: See TracBrowser for help on using the repository browser.