source: trunk/Lucide/SOURCE/gui/pmtoolbar.cpp @ 33

Last change on this file since 33 was 2, checked in by Eugene Romanenko, 16 years ago

First import

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