source: trunk/Lucide/gui/pmtoolbar.cpp @ 393

Last change on this file since 393 was 367, checked in by dmik, 12 years ago

Merged bramches/kmk (r294:365) to trunk.

File size: 27.7 KB
Line 
1/*
2 *  PM Toolbar implementation.
3 *  by Eugene Romanenko
4 *
5 *  This code is in the public domain and has no copyright.
6 */
7
8#include "os2all.h"
9
10#include <string.h>
11#include <malloc.h>
12#include <stdlib.h>
13
14#include "tb_spl.h"
15
16
17class t_timer
18{
19    protected:
20        long msecs;
21    public:
22        t_timer();
23        void reset();
24        long elapsed();
25};
26
27inline t_timer::t_timer() { reset(); }
28
29void t_timer::reset()
30{
31    DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &msecs, sizeof( msecs ) );
32}
33
34long t_timer::elapsed()
35{
36    long now;
37    DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &now, sizeof( now ) );
38    return ( now - msecs );
39}
40
41static char *newstrdup( const char *s )
42{
43    if ( s == NULL ) {
44        return NULL;
45    }
46    char *temp = new char[ strlen( s ) + 1 ];
47    strcpy( temp, s );
48    return temp;
49}
50
51const unsigned long lBufMax = 256;
52
53static char *newstrdup( HAB hab, ULONG resId, HMODULE hModule )
54{
55    char *pBuf = new char[ lBufMax ];
56    WinLoadString( hab, hModule, resId, lBufMax, pBuf );
57    char *b = newstrdup( pBuf );
58    delete pBuf;
59    return b;
60}
61
62
63static void InternalDrawTransparentBitmap( HPS hps, HPS hpsDraw, PPOINTL drawptl,
64                                           PBITMAPINFOHEADER pbmih )
65{
66    int             blen, hlen;
67    PUCHAR          buf;
68    PBITMAPINFO2    pbmi;
69    LONG            color, transColor;
70
71    hlen = sizeof( BITMAPINFO2 ) + sizeof( RGB ) * 256;
72    blen = ( ( pbmih->cBitCount * pbmih->cx + 31 ) / 32 ) * pbmih->cPlanes * 4;
73
74    pbmi = (PBITMAPINFO2)malloc( hlen );
75    memset( pbmi, 0, hlen );
76    buf = (PUCHAR)malloc( blen );
77    memset( buf, 0, blen );
78
79    pbmi->cbFix = 16;
80    pbmi->cPlanes = pbmih->cPlanes;
81    pbmi->cBitCount = pbmih->cBitCount;
82
83    POINTL ptl = { 0, 0 };
84    int x, y, k;
85    BOOL first = TRUE;
86    for ( y = 0; y < pbmih->cy; y++ )
87    {
88        GpiQueryBitmapBits( hps, y, 1, (PBYTE)buf, pbmi );
89
90        for ( x = 0; x < pbmih->cx; x++ )
91        {
92            k = x * 3;
93            color = ((buf[k]) | (buf[k+1] << 8) | (buf[k+2] << 16));
94            if ( first )
95            {
96                transColor = color;
97                first = FALSE;
98            }
99            else
100            {
101                if ( color != transColor )
102                {
103                    ptl.x = x + drawptl->x;
104                    ptl.y = y + drawptl->y;
105                    GpiSetColor( hpsDraw, color );
106                    GpiSetPel( hpsDraw, &ptl );
107                }
108            }
109        }
110    }
111
112    free( pbmi );
113    free( buf );
114}
115
116BOOL DrawTransparentBitmap( HAB hab, HPS hpsDraw, PPOINTL drawptl, HBITMAP hbmp )
117{
118    HDC               hdc;
119    HPS               hps;
120    SIZEL             siz;
121    BITMAPINFOHEADER  bmi;
122    HBITMAP           hbm, hbmPre;
123
124    if ( hbmp == NULLHANDLE ) {
125        return FALSE;
126    }
127
128    hdc = DevOpenDC( hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE );
129    if ( hdc == NULLHANDLE ) {
130        return FALSE;
131    }
132    siz.cx = siz.cy = 0;
133    hps = GpiCreatePS( hab, hdc, &siz, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
134    if ( hps == NULLHANDLE ) {
135        DevCloseDC( hdc );
136        return FALSE;
137    }
138
139    BITMAPINFOHEADER b = { 0 };
140    GpiQueryBitmapParameters( hbmp, &b );
141
142    if ( ( b.cx == 0 ) || ( b.cy == 0 ) )
143    {
144        GpiDestroyPS( hps );
145        DevCloseDC( hdc );
146        return FALSE;
147    }
148
149    bmi.cbFix     = sizeof( BITMAPINFOHEADER );
150    bmi.cx        = b.cx;
151    bmi.cy        = b.cy;
152    bmi.cPlanes   = 1;
153    bmi.cBitCount = 24;
154
155    hbm = GpiCreateBitmap( hps, (PBITMAPINFOHEADER2)&bmi, 0, NULL, NULL );
156    if ( hbm == NULLHANDLE ) {
157        GpiDestroyPS( hps );
158        DevCloseDC( hdc );
159        return FALSE;
160    }
161
162    hbmPre = GpiSetBitmap( hps, hbm );
163
164    POINTL ptl = { 0, 0 };
165    WinDrawBitmap( hps, hbmp, NULL, &ptl, 0, 0, DBM_NORMAL );
166
167    GpiCreateLogColorTable( hpsDraw, 0, LCOLF_RGB, 0, 0, NULL );
168    InternalDrawTransparentBitmap( hps, hpsDraw, drawptl, &bmi );
169
170    GpiSetBitmap( hps, hbmPre );
171    GpiDeleteBitmap( hbm );
172    GpiDestroyPS( hps );
173    DevCloseDC( hdc );
174    return TRUE;
175}
176
177static LONG getBmpClr( HPS hps, PBITMAPINFOHEADER2 pbmih2 )
178{
179    int             blen, hlen;
180    PUCHAR          buf;
181    PBITMAPINFO2    pbmi;
182    LONG            color;
183
184    hlen = sizeof( BITMAPINFO2 ) + sizeof( RGB ) * 256;
185    blen = ( ( pbmih2->cBitCount * pbmih2->cx + 31 ) / 32 ) * pbmih2->cPlanes * 4;
186
187    pbmi = (PBITMAPINFO2)malloc( hlen );
188    memset( pbmi, 0, hlen );
189    buf = (PUCHAR)malloc( blen );
190    memset( buf, 0, blen );
191
192    pbmi->cbFix = 16;
193    pbmi->cPlanes = pbmih2->cPlanes;
194    pbmi->cBitCount = pbmih2->cBitCount;
195
196    LONG r = GpiQueryBitmapBits( hps, 0, 1, (PBYTE)buf, pbmi );
197
198    if ( r < 0 ) {
199        color = -1;
200    } else {
201        color = ( (buf[0] << 16) | (buf[1] << 8) | buf[2] );
202    }
203
204    free( pbmi );
205    free( buf );
206
207    return color;
208}
209
210static LONG getBitmapColor( HAB hab, HBITMAP hbmp )
211{
212    HDC               hdc;
213    HPS               hps;
214    SIZEL             siz;
215    BITMAPINFOHEADER2 bmi;
216    HBITMAP           hbm, hbmPre;
217    LONG              color;
218
219    if ( hbmp == NULLHANDLE ) {
220        return -1;
221    }
222
223    hdc = DevOpenDC( hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE );
224    if ( hdc == NULLHANDLE ) {
225        return -1;
226    }
227    siz.cx = siz.cy = 0;
228    hps = GpiCreatePS( hab, hdc, &siz, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
229    if ( hps == NULLHANDLE ) {
230        DevCloseDC( hdc );
231        return -1;
232    }
233
234    BITMAPINFOHEADER b = { 0 };
235    GpiQueryBitmapParameters( hbmp, &b );
236
237    if ( ( b.cx == 0 ) || ( b.cy == 0 ) ) {
238        GpiDestroyPS( hps );
239        DevCloseDC( hdc );
240        return -1;
241    }
242
243    bmi.cbFix = sizeof( BITMAPINFOHEADER2 );
244    bmi.cx            = b.cx;
245    bmi.cy            = b.cy;
246    bmi.cPlanes       = 1;
247    bmi.cBitCount     = 24;
248    bmi.ulCompression = 0;
249    bmi.cclrUsed      = 0;
250    bmi.cclrImportant = 0;
251
252    hbm = GpiCreateBitmap( hps, &bmi, 0, NULL, NULL );
253    if ( hbm == NULLHANDLE ) {
254        GpiDestroyPS( hps );
255        DevCloseDC( hdc );
256        return -1;
257    }
258
259    hbmPre = GpiSetBitmap( hps, hbm );
260
261    POINTL ptl = { 0, 0 };
262    WinDrawBitmap( hps, hbmp, NULL, &ptl, 0, 0, DBM_NORMAL );
263
264    color = getBmpClr( hps, &bmi );
265
266    GpiSetBitmap( hps, hbmPre );
267    GpiDeleteBitmap( hbm );
268    GpiDestroyPS( hps );
269    DevCloseDC( hdc );
270    return color;
271}
272
273#define ITYPE_PUSHBUTTON    1
274#define ITYPE_SEPARATOR     2
275#define ITYPE_CONTROL       3
276
277#define TOOLBAR_XINDENT 4
278#define TOOLBAR_YINDENT 4
279#define TOOLBAR_SSIZE   2
280
281
282struct twsItem
283{
284    BYTE    type;
285    BOOL    checked;
286    BOOL    enabled;
287    USHORT  cmd;
288    char    *bText;
289    HBITMAP hbmp;
290    LONG    tcolor;
291    RECTL   rcl;
292    HWND    bubble;
293    HWND    hmenu;
294    t_timer *tmr;
295    // if control
296    HWND  ctrlHandle;
297
298    twsItem *next;
299    twsItem();
300    ~twsItem();
301};
302
303twsItem::twsItem()
304{
305    type    = ITYPE_PUSHBUTTON;
306    checked = FALSE;
307    enabled = TRUE;
308    cmd     = 0;
309    bText   = NULL;
310    hbmp    = NULLHANDLE;
311    tcolor  = -1;
312    bubble  = NULLHANDLE;
313    hmenu   = NULLHANDLE;
314    tmr     = NULL;
315    next    = NULL;
316    ctrlHandle = NULLHANDLE;
317}
318
319twsItem::~twsItem()
320{
321    if ( hbmp != NULLHANDLE ) {
322        GpiDeleteBitmap( hbmp );
323    }
324    if ( bText != NULL ) {
325        delete bText;
326    }
327    if ( tmr != NULL ) {
328        delete tmr;
329    }
330    if ( ctrlHandle != NULLHANDLE ) {
331        WinDestroyWindow( ctrlHandle );
332    }
333}
334
335
336class toolbarWndStruct
337{
338    private:
339        ULONG size;
340        twsItem *pitem;
341    public:
342        BOOL bPressed;
343        HAB  hab;
344        BOOL mshowed;
345        USHORT pictSize;
346
347        toolbarWndStruct();
348        ~toolbarWndStruct();
349        twsItem *get( ULONG i );
350        VOID add( HWND hwnd, BYTE type, void *s );
351        ULONG getSize() const  {  return size;  }
352        BOOL queryCheck( USHORT cmd );
353        VOID setCheck( USHORT cmd, BOOL chk );
354        VOID enableItem( USHORT cmd, BOOL en );
355        VOID setBubbleText( USHORT cmd, PCSZ text );
356};
357
358toolbarWndStruct::toolbarWndStruct()
359{
360    bPressed = FALSE;
361    hab = NULLHANDLE;
362    size = 0;
363    mshowed = FALSE;
364    pictSize = DEFAULT_PICTSIZE;
365    pitem = new twsItem;
366}
367
368toolbarWndStruct::~toolbarWndStruct()
369{
370    twsItem *t = pitem;
371    for ( ULONG j = 0; j < size; j++ ) {
372        twsItem *tmp = t->next;
373        delete t;
374        t = tmp;
375    }
376    delete t;
377}
378
379twsItem *toolbarWndStruct::get( ULONG i )
380{
381    twsItem *t = pitem;
382    for ( ULONG j = 0; j < i; j++ ) {
383        twsItem *tmp = t->next;
384        t = tmp;
385    }
386    return t;
387}
388
389BOOL toolbarWndStruct::queryCheck( USHORT cmd )
390{
391    BOOL rval = FALSE;
392    for ( ULONG i = 0; i < size; i++ )
393    {
394        twsItem *ti = get( i );
395        if ( ti->cmd == cmd ) {
396            rval = ti->checked;
397            break;
398        }
399    }
400    return rval;
401}
402
403VOID toolbarWndStruct::setCheck( USHORT cmd, BOOL chk )
404{
405    for ( ULONG i = 0; i < size; i++ )
406    {
407        twsItem *ti = get( i );
408        if ( ti->cmd == cmd ) {
409            ti->checked = chk;
410            break;
411        }
412    }
413}
414
415VOID toolbarWndStruct::enableItem( USHORT cmd, BOOL en )
416{
417    for ( ULONG i = 0; i < size; i++ )
418    {
419        twsItem *ti = get( i );
420        if ( ti->cmd == cmd )
421        {
422            ti->enabled = en;
423
424            // …á«š ª­®¯ª  § ¯à¥é ¥âáï, 〠«šâì ¢á¯«ë¢ îéãî
425            // ¯®€áª §ªã š â ©¬¥à
426            if ( !en )
427            {
428                if ( ti->bubble != NULLHANDLE ) {
429                    WinDestroyWindow( ti->bubble );
430                    ti->bubble = NULLHANDLE;
431                }
432                if ( ti->tmr != NULL ) {
433                    delete ti->tmr;
434                    ti->tmr = NULL;
435                }
436            }
437
438            break;
439        }
440    }
441}
442
443VOID toolbarWndStruct::add( HWND hwnd, BYTE type, void *s )
444{
445    AddBtnStruct *bs = (AddBtnStruct *)s;
446    AddCtrlStruct *cs = (AddCtrlStruct *)s;
447
448    twsItem *i = get( size );
449
450    i->type = type;
451    switch ( type )
452    {
453        case ITYPE_PUSHBUTTON:
454            i->cmd  = bs->cmd;
455            i->checked = bs->checked;
456            i->enabled = bs->enabled;
457            break;
458
459        case ITYPE_SEPARATOR:
460            i->cmd  = 0;
461            i->checked = FALSE;
462            i->enabled = FALSE;
463            break;
464
465        case ITYPE_CONTROL:
466            i->cmd  = 0;
467            i->checked = FALSE;
468            i->enabled = TRUE;
469            i->ctrlHandle = cs->ctrlHandle;
470            break;
471    }
472
473    i->next = new twsItem;
474    if ( size == 0 )
475    {
476        i->rcl.xLeft   = TOOLBAR_XINDENT * 2;
477        i->rcl.yBottom = TOOLBAR_YINDENT;
478    }
479    else
480    {
481        twsItem *tmp = get( size - 1 );
482        i->rcl.xLeft = tmp->rcl.xRight + ( TOOLBAR_XINDENT * 2 );
483        i->rcl.yBottom = TOOLBAR_YINDENT; //tmp->rcl.yBottom;
484    }
485
486    i->rcl.yTop = i->rcl.yBottom + pictSize - 1;
487    if ( i->type == ITYPE_SEPARATOR ) {
488        i->rcl.xRight = i->rcl.xLeft + TOOLBAR_SSIZE - 1;
489    } else if ( i->type == ITYPE_CONTROL ) {
490        i->rcl.xRight = i->rcl.xLeft + cs->cx - 1;
491        //if ( cs->cy < 0 ) {
492            //i->rcl.yTop = i->rcl.yBottom + cs->cy - 1;
493            i->rcl.yBottom += cs->cy;
494        //}
495        WinSetWindowPos( i->ctrlHandle, HWND_TOP,
496                         i->rcl.xLeft, i->rcl.yBottom,
497                         i->rcl.xRight-i->rcl.xLeft, i->rcl.yTop-i->rcl.yBottom + 1,
498                         SWP_SIZE|SWP_MOVE|SWP_ZORDER|SWP_SHOW );
499    } else {
500        i->rcl.xRight = i->rcl.xLeft + pictSize - 1;
501    }
502
503    size++;
504
505    if ( i->type == ITYPE_PUSHBUTTON )
506    {
507        if ( bs->bubbleText != NULL ) {
508            i->bText = newstrdup( bs->bubbleText );
509        } else if ( bs->bubbleRes != 0 ) {
510            i->bText = newstrdup( WinQueryAnchorBlock( hwnd ),
511                                  bs->bubbleRes, bs->bubbleHmod );
512        }
513
514        if ( bs->pictRes != 0 )
515        {
516            HPS hps = WinGetPS( hwnd );
517            i->hbmp = GpiLoadBitmap( hps, bs->pictHmod, bs->pictRes, 0, 0 );
518            WinReleasePS( hps );
519
520            i->tcolor = getBitmapColor( hab, i->hbmp );
521        }
522
523        if ( bs->menuRes != 0 ) {
524            i->hmenu = WinLoadMenu( hwnd, bs->menuHmod, bs->menuRes );
525        }
526    }
527
528    if ( i->type == ITYPE_CONTROL )
529    {
530        if ( cs->bubbleText != NULL ) {
531            i->bText = newstrdup( cs->bubbleText );
532        } else if ( bs->bubbleRes != 0 ) {
533            i->bText = newstrdup( WinQueryAnchorBlock( hwnd ),
534                                  cs->bubbleRes, cs->bubbleHmod );
535        }
536    }
537}
538
539VOID toolbarWndStruct::setBubbleText( USHORT cmd, PCSZ text )
540{
541    for ( ULONG i = 0; i < size; i++ )
542    {
543        twsItem *ti = get( i );
544        if ( ti->cmd == cmd )
545        {
546            if ( ti->bText != NULL ) {
547                delete ti->bText;
548                ti->bText = NULL;
549            }
550
551            if ( text != NULL ) {
552                ti->bText = newstrdup( text );
553            }
554
555            break;
556        }
557    }
558}
559
560static VOID drFr( HPS hps, PRECTL prcl, BOOL framed, BOOL pressed )
561{
562    POINTL ptl;
563    if ( framed )
564    {
565        GpiSetColor( hps, pressed ? SYSCLR_BUTTONDARK : SYSCLR_BUTTONLIGHT );
566        ptl.x = prcl->xLeft - 2;
567        ptl.y = prcl->yBottom - 2;
568        GpiMove( hps, &ptl );
569        ptl.y = prcl->yTop + 2;
570        GpiLine( hps, &ptl );
571        ptl.x = prcl->xRight + 2;
572        GpiLine( hps, &ptl );
573        GpiSetColor( hps, pressed ? SYSCLR_BUTTONLIGHT : SYSCLR_BUTTONDARK );
574        ptl.y = prcl->yBottom - 2;
575        GpiLine( hps, &ptl );
576        ptl.x = prcl->xLeft - 2;
577        GpiLine( hps, &ptl );
578    }
579    else
580    {
581        GpiSetColor( hps, SYSCLR_MENU );
582        ptl.x = prcl->xLeft - 2;
583        ptl.y = prcl->yBottom - 2;
584        GpiMove( hps, &ptl );
585        ptl.x = prcl->xRight + 2;
586        ptl.y = prcl->yTop + 2;
587        GpiBox( hps, DRO_OUTLINE, &ptl, 0, 0 );
588    }
589}
590
591static VOID htDraw( HPS hps, PRECTL r, BOOL halfTone )
592{
593    POINTL ptl;
594    LONG i, j;
595    GpiSetColor( hps, halfTone ? SYSCLR_MENU : CLR_WHITE );
596    for ( i = 0; i <= ( r->xRight - r->xLeft ); i++ )
597    {
598        ptl.x = i + r->xLeft;
599        for ( j = 0; j <= ( r->yTop - r->yBottom ); j++ )
600        {
601            ptl.y = j + r->yBottom;
602            if ( !( j & 1 ) )
603            {
604                if ( i & 1 ) {
605                    ptl.y++;
606                }
607                GpiSetPel( hps, &ptl );
608            }
609        }
610    }
611}
612
613static VOID btnDraw( HAB hab, HPS hps, twsItem *ti, USHORT pictSize )
614{
615    BOOL useSafeDraw = ( getenv( "ERTOOLBARSAFEDRAW" ) != NULL );
616
617    LONG ltabl[ 1 ] = { ti->tcolor };
618
619    if ( !useSafeDraw )
620    {
621        GpiCreateLogColorTable( hps, 0, LCOLF_CONSECRGB, 100, 1, ltabl );
622        GpiSetBackMix( hps, BM_SRCTRANSPARENT );
623        GpiSetBackColor( hps, 100 );
624    }
625
626    if ( ti->checked )
627    {
628        RECTL rcl = { ti->rcl.xLeft - 1, ti->rcl.yBottom - 1,
629                      ti->rcl.xRight + 1, ti->rcl.yTop + 1 };
630        htDraw( hps, &rcl, FALSE );
631    }
632    POINTL aptl[ 4 ] = { { ti->rcl.xLeft, ti->rcl.yBottom },
633                         { ti->rcl.xRight, ti->rcl.yTop },
634                         { 0, 0 }, { pictSize, pictSize } };
635    if ( useSafeDraw ) {
636        DrawTransparentBitmap( hab, hps, &aptl[ 0 ], ti->hbmp );
637    } else {
638        GpiWCBitBlt( hps, ti->hbmp, 4L, aptl, ROP_SRCCOPY, BBO_IGNORE );
639    }
640
641    if ( !ti->enabled ) {
642        htDraw( hps, &ti->rcl, TRUE );
643    }
644    if ( ti->checked ) {
645        drFr( hps, &ti->rcl, TRUE, TRUE );
646    }
647}
648
649static VOID sepDraw( HPS hps, twsItem *ti )
650{
651    POINTL ptl = { ti->rcl.xLeft, ti->rcl.yBottom };
652    GpiMove( hps, &ptl );
653    GpiSetColor( hps, SYSCLR_BUTTONDARK );
654    ptl.y = ti->rcl.yTop;
655    GpiLine( hps, &ptl );
656    ptl.x++;
657    GpiMove( hps, &ptl );
658    ptl.y = ti->rcl.yBottom;
659    GpiSetColor( hps, SYSCLR_BUTTONLIGHT );
660    GpiLine( hps, &ptl );
661}
662
663static VOID drawFramed( HWND hwnd, PRECTL prcl, BOOL framed, BOOL pressed )
664{
665    HPS hps = WinGetPS( hwnd );
666    drFr( hps, prcl, framed, pressed );
667    WinReleasePS( hps );
668}
669
670
671static CHAR ppFont[]     = "8.Helv";
672static ULONG ulBackColor = CLR_CYAN;
673static ULONG ulForeColor = CLR_BLACK;
674
675static VOID wrkMouseMove( HAB hab, HWND hwnd, MPARAM mp1, twsItem *ti )
676{
677    if ( ti->type == ITYPE_SEPARATOR ) {
678        return;
679    }
680    if ( !ti->enabled ) {
681        return;
682    }
683
684    POINTL ptl = { SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) };
685    if ( WinPtInRect( hab, &ti->rcl, &ptl ) )
686    {
687        if ( ti->type == ITYPE_PUSHBUTTON ) {
688            drawFramed( hwnd, &ti->rcl, TRUE, FALSE );
689        }
690
691        if ( !( WinQueryWindowUShort( WinQueryWindow( hwnd, QW_PARENT ),
692                                      QWS_FLAGS ) & FF_ACTIVE ) ) {
693            return;
694        }
695
696        if ( ti->bText == NULL ) {
697            return;
698        }
699
700        if ( ti->bubble == NULLHANDLE )
701        {
702            if ( ti->tmr == NULL ) {
703                ti->tmr = new t_timer;
704            }
705            else
706            {
707                if ( ti->tmr->elapsed() > 500 )
708                {
709                    delete ti->tmr;
710                    ti->tmr = NULL;
711                    HPS hpsTemp;
712                    HWND hwndBC;
713                    ULONG ulStyle = FCF_BORDER | FCF_NOBYTEALIGN;
714                    LONG  lWidth,lHight;
715                    POINTL txtPointl[ TXTBOX_COUNT ];
716                    POINTL ptlWork;
717                    ptlWork.x = ti->rcl.xLeft + ( ( ti->rcl.xRight - ti->rcl.xLeft ) / 2 );
718                    ptlWork.y = ti->rcl.yBottom;
719                    ti->bubble = WinCreateStdWindow( HWND_DESKTOP, 0,
720                                       &ulStyle, WC_STATIC, "",
721                                       SS_TEXT | DT_CENTER |  DT_VCENTER,
722                                       NULLHANDLE, 2, &hwndBC );
723                    WinSetPresParam( hwndBC, PP_FONTNAMESIZE, sizeof( ppFont ), ppFont );
724                    WinSetPresParam( hwndBC, PP_BACKGROUNDCOLORINDEX, sizeof( ulBackColor ), &ulBackColor );
725                    WinSetPresParam( hwndBC, PP_FOREGROUNDCOLORINDEX, sizeof( ulForeColor ), &ulForeColor );
726
727                    hpsTemp = WinGetPS( hwndBC );
728
729                    GpiQueryTextBox( hpsTemp, strlen( ti->bText ),
730                                     ti->bText, TXTBOX_COUNT,
731                                     (PPOINTL)&txtPointl[ 0 ] );
732                    WinReleasePS( hpsTemp );
733
734                    WinSetWindowText( hwndBC, ti->bText );
735
736                    lWidth = txtPointl[ TXTBOX_TOPRIGHT ].x -
737                             txtPointl[ TXTBOX_TOPLEFT ].x + 6;
738
739                    lHight = txtPointl[TXTBOX_TOPLEFT   ].y -
740                             txtPointl[TXTBOX_BOTTOMLEFT].y + 4;
741
742                    WinMapWindowPoints( hwnd, HWND_DESKTOP, &ptlWork, 1 );
743
744                    if( ( ptlWork.y - ( lHight + 5 ) ) < 0 ) {
745                        ptlWork.y = 1;
746                    } else {
747                        ptlWork.y -= ( lHight + 5 );
748                    }
749
750                    if ( ( ptlWork.x + lWidth ) >= WinQuerySysValue( HWND_DESKTOP, SV_CXFULLSCREEN ) ) {
751                        ptlWork.x = WinQuerySysValue( HWND_DESKTOP, SV_CXFULLSCREEN )
752                                        - lWidth - 1;
753                    }
754
755                    WinSetWindowPos( ti->bubble, HWND_TOP, ptlWork.x,
756                                     ptlWork.y, lWidth, lHight,
757                                     SWP_SHOW | SWP_MOVE | SWP_SIZE );
758                }
759            }
760        }
761    }
762    else
763    {
764        if ( ti->checked ) {
765            drawFramed( hwnd, &ti->rcl, TRUE, TRUE );
766        } else {
767            drawFramed( hwnd, &ti->rcl, FALSE, FALSE );
768        }
769        if ( ti->bubble != NULLHANDLE ) {
770            WinDestroyWindow( ti->bubble );
771            ti->bubble = NULLHANDLE;
772        }
773        if ( ti->tmr != NULL ) {
774            delete ti->tmr;
775            ti->tmr = NULL;
776        }
777    }
778}
779
780
781static VOID wrkMouseDown( HAB hab, HWND hwnd, MPARAM mp1, twsItem *ti,
782                          BOOL up, BOOL *inPtl )
783{
784    if ( ti->type != ITYPE_PUSHBUTTON ) {
785        return;
786    }
787    if ( !ti->enabled ) {
788        return;
789    }
790
791    POINTL ptl = { SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) };
792    if ( WinPtInRect( hab, &ti->rcl, &ptl ) )
793    {
794        drawFramed( hwnd, &ti->rcl, TRUE, !up );
795        if ( up )
796        {
797            WinSendMsg( WinQueryWindow( hwnd, QW_PARENT ), WM_COMMAND,
798                        MPFROMSHORT( ti->cmd ),
799                        MPFROM2SHORT( CMDSRC_OTHER, TRUE ) );
800        }
801        *inPtl = TRUE;
802    }
803}
804
805static VOID showPopup( toolbarWndStruct *tws, HWND hwnd, MPARAM mp1, twsItem *ti )
806{
807    if ( ti->type != ITYPE_PUSHBUTTON ) {
808        return;
809    }
810    if ( !ti->enabled ) {
811        return;
812    }
813    if ( ti->hmenu == NULLHANDLE ) {
814        return;
815    }
816    if ( tws->mshowed ) {
817        return;
818    }
819
820    POINTL ptl = { SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) };
821    if ( WinPtInRect( tws->hab, &ti->rcl, &ptl ) )
822    {
823        tws->mshowed = TRUE;
824        USHORT id = SHORT1FROMMR( WinSendMsg( ti->hmenu, MM_ITEMIDFROMPOSITION,
825                                              MPFROMSHORT( 0 ), MPVOID ) );
826        WinPopupMenu( hwnd, WinQueryWindow( hwnd, QW_PARENT ),
827                      ti->hmenu, ptl.x, ptl.y, id,
828                      PU_POSITIONONITEM | PU_MOUSEBUTTON1DOWN | PU_MOUSEBUTTON1 );
829    }
830}
831
832static int sss = 0;
833
834static MRESULT EXPENTRY toolbarProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
835{
836    toolbarWndStruct *tws = (toolbarWndStruct *)WinQueryWindowULong( hwnd, sizeof( ULONG ) );
837    if ( tws == NULL )
838    {
839        tws = new toolbarWndStruct;
840        tws->hab = WinQueryAnchorBlock( hwnd );
841        WinSetWindowULong( hwnd, sizeof( ULONG ), (ULONG)tws );
842        WinStartTimer( tws->hab, hwnd, 2, 500 );
843    }
844
845    switch ( msg )
846    {
847        case TBM_ADDBUTTON:
848            tws->add( hwnd, ITYPE_PUSHBUTTON, mp1 );
849            return (MRESULT)(TRUE);
850
851        case TBM_ADDSEPARATOR:
852            tws->add( hwnd, ITYPE_SEPARATOR, NULL );
853            return (MRESULT)(TRUE);
854
855        case TBM_ADDCONTROL:
856            tws->add( hwnd, ITYPE_CONTROL, mp1 );
857            return (MRESULT)(TRUE);
858
859        case TBM_QUERYCHECK:
860            return (MRESULT)tws->queryCheck( SHORT1FROMMP( mp1 ) );
861
862        case TBM_SETCHECK:
863            tws->setCheck( SHORT1FROMMP( mp1 ), (BOOL)mp2 );
864            WinInvalidateRect( hwnd, NULL, TRUE );
865            return (MRESULT)(TRUE);
866
867        case TBM_ENABLEITEM:
868            tws->enableItem( SHORT1FROMMP( mp1 ), (BOOL)mp2 );
869            WinInvalidateRect( hwnd, NULL, TRUE );
870            return (MRESULT)(TRUE);
871
872        case TBM_SETBUBBLETEXT:
873            tws->setBubbleText( SHORT1FROMMP( mp1 ), (PCSZ)mp2 );
874            return (MRESULT)(TRUE);
875
876        case TBM_SETPICTSIZE:
877            tws->pictSize = SHORT1FROMMP( mp1 );
878            return (MRESULT)(TRUE);
879
880        case WM_DESTROY:
881            delete tws;
882            break;
883
884        case WM_PAINT:
885            {
886                RECTL rcl;
887                POINTL ptl;
888                HPS hps = WinBeginPaint( hwnd, NULLHANDLE, NULL );
889                WinQueryWindowRect( hwnd, &rcl );
890                rcl.yTop = tws->pictSize + TOOLBAR_HEIGHT_ADD;
891                rcl.yBottom++;
892                WinFillRect( hps, &rcl, SYSCLR_MENU );
893                ptl.x = rcl.xLeft;
894                ptl.y = rcl.yBottom - 1;
895                GpiMove( hps, &ptl );
896                ptl.x = rcl.xRight;
897                GpiSetColor( hps, SYSCLR_BUTTONDARK );
898                GpiLine( hps, &ptl );
899
900                for ( ULONG i = 0; i < tws->getSize(); i++ )
901                {
902                    twsItem *ti = tws->get( i );
903                    switch ( ti->type )
904                    {
905                        case ITYPE_PUSHBUTTON:
906                            btnDraw( tws->hab, hps, ti, tws->pictSize );
907                            break;
908
909                        case ITYPE_SEPARATOR:
910                            sepDraw( hps, ti );
911                            break;
912                    }
913                }
914                WinEndPaint( hps );
915            }
916            return (MRESULT)(FALSE);
917
918        case WM_MOUSEMOVE:
919            {
920                for ( ULONG i = 0; i < tws->getSize(); i++ ) {
921                    twsItem *ti = tws->get( i );
922                    wrkMouseMove( tws->hab, hwnd, mp1, ti );
923                }
924            }
925            break;
926
927        case WM_BUTTON1DOWN:
928            {
929                BOOL inPtl = FALSE;
930                tws->bPressed = TRUE;
931                tws->mshowed = FALSE;
932                WinStartTimer( tws->hab, hwnd, 3, 500 );
933                for ( ULONG i = 0; i < tws->getSize(); i++ ) {
934                    twsItem *ti = tws->get( i );
935                    wrkMouseDown( tws->hab, hwnd, mp1, ti, FALSE, &inPtl );
936                }
937                if ( !inPtl ) {
938                    WinSetActiveWindow( HWND_DESKTOP, hwnd );
939                }
940            }
941            return (MRESULT)(FALSE);
942
943        case WM_BUTTON1UP:
944            {
945                BOOL inPtl = FALSE;
946                WinStopTimer( tws->hab, hwnd, 3 );
947                tws->bPressed = FALSE;
948                tws->mshowed = FALSE;
949                for ( ULONG i = 0; i < tws->getSize(); i++ ) {
950                    twsItem *ti = tws->get( i );
951                    wrkMouseDown( tws->hab, hwnd, mp1, ti, TRUE, &inPtl );
952                }
953            }
954            break;
955
956        case WM_TIMER:
957            {
958                switch ( SHORT1FROMMP( mp1 ) )
959                {
960                    case 2:
961                    {
962                        if ( !tws->bPressed )
963                        {
964                            POINTL ptl;
965                            WinQueryPointerPos( HWND_DESKTOP, &ptl );
966                            WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1 );
967                            MPARAM mp = MPFROM2SHORT( ptl.x, ptl.y );
968                            for ( ULONG i = 0; i < tws->getSize(); i++ ) {
969                                twsItem *ti = tws->get( i );
970                                wrkMouseMove( tws->hab, hwnd, mp, ti );
971                            }
972                        }
973                        break;
974                    }
975
976                    case 3:
977                    {
978                        if ( tws->bPressed )
979                        {
980                            POINTL ptl;
981                            WinQueryPointerPos( HWND_DESKTOP, &ptl );
982                            WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1 );
983                            MPARAM mp = MPFROM2SHORT( ptl.x, ptl.y );
984                            for ( ULONG i = 0; i < tws->getSize(); i++ ) {
985                                twsItem *ti = tws->get( i );
986                                showPopup( tws, hwnd, mp, ti );
987                            }
988                        }
989                        break;
990                    }
991                }
992            }
993            return (MRESULT)(FALSE);
994
995        case WM_ERASEBACKGROUND:
996            return (MRESULT)(FALSE);
997    }
998    return WinDefWindowProc( hwnd, msg, mp1, mp2 );
999}
1000
1001
1002BOOL InitPMToolbarClass( HAB hab )
1003{
1004    return WinRegisterClass( hab, WC_ER_TOOLBAR, toolbarProc,
1005                             CS_SIZEREDRAW, sizeof( ULONG ) * 2 );
1006}
1007
Note: See TracBrowser for help on using the repository browser.