244 lines
6.6 KiB
C
244 lines
6.6 KiB
C
#include <assert.h>
|
|
|
|
#include <dockapp.h>
|
|
|
|
#include "buttonbar.h"
|
|
#include "xobjects.h"
|
|
#include "pixmaps.h"
|
|
#include "options.h"
|
|
#include "menu.h"
|
|
|
|
/* item number for last known highlight position */
|
|
static int OldPos = -1 ;
|
|
/* Graphic context used to draw highlight */
|
|
static GC HighlightGC = 0 ;
|
|
/* position where bar will be shown next time */
|
|
static int BarX=0, BarY=0 ;
|
|
|
|
extern void ButtonBar_Build (void)
|
|
{
|
|
int i, n ;
|
|
int h, j, w ;
|
|
int width, height ;
|
|
GC imgOp ;
|
|
GC maskOp ;
|
|
XGCValues gc ;
|
|
Pixmap image, mask ;
|
|
int x, y ;
|
|
int x0, y0 ;
|
|
XSetWindowAttributes wa ;
|
|
|
|
n = Menu_GetNbEntries () ;
|
|
assert (n > 0) ;
|
|
h = Menu_GetNbRows () ;
|
|
w = Menu_GetNbColumns () ;
|
|
width = TileXSize * w ;
|
|
height = TileYSize * h ;
|
|
|
|
|
|
ButtonBarWindow = XCreateSimpleWindow (
|
|
DADisplay, DefaultRootWindow (DADisplay), 0, 0, width, height, 0,
|
|
BlackPixel (DADisplay, DefaultScreen (DADisplay)),
|
|
BlackPixel (DADisplay, DefaultScreen (DADisplay))) ;
|
|
ButtonBarImage = XCreatePixmap (DADisplay, ButtonBarWindow,
|
|
width, height, DADepth) ;
|
|
imgOp = XCreateGC (DADisplay, ButtonBarWindow, 0, & gc) ;
|
|
|
|
HighlightBehindMask = XCreatePixmap (DADisplay, ButtonBarWindow,
|
|
width, height, 1) ;
|
|
maskOp = XCreateGC (DADisplay, HighlightBehindMask, 0, & gc) ;
|
|
|
|
/* first apply tile to whole bar */
|
|
for (i=0; i<w; i++)
|
|
for (j=0; j<h; j++)
|
|
XCopyArea (DADisplay, TileImage, ButtonBarImage, imgOp, 0, 0,
|
|
TileXSize, TileYSize, TileXSize*i, TileYSize*j) ;
|
|
|
|
/* initialize "behind" mask to all 1's */
|
|
XSetFunction (DADisplay, maskOp, GXset) ;
|
|
XFillRectangle (DADisplay, HighlightBehindMask, maskOp,
|
|
0, 0, width, height) ;
|
|
/* and copy behind mask cells from highlight mask */
|
|
if (HighlightMask != 0)
|
|
{
|
|
XSetFunction (DADisplay, maskOp, GXcopy) ;
|
|
for (i=0; i<w; i++)
|
|
for (j=0; j<h; j++)
|
|
XCopyArea (DADisplay, HighlightMask, HighlightBehindMask,
|
|
maskOp,
|
|
0, 0, TileXSize, TileYSize, TileXSize*i, TileYSize*j) ;
|
|
}
|
|
|
|
/* then apply each pixmap of menu entry */
|
|
/* and build a global invert mask for highlight "behind" */
|
|
for (i=0; i<n; i++)
|
|
{
|
|
Pixmaps_FindLoad (Menu_GetEntryPixmap (i),
|
|
& image, & mask, & width, & height) ;
|
|
|
|
/* center pixmap within its cell */
|
|
x = (width >= TileXSize ? 0 : (TileXSize-width)/2) ;
|
|
y = (height >= TileYSize ? 0 : (TileYSize-height)/2) ;
|
|
|
|
/* use GC to draw with pixmap's mask in the right cell */
|
|
x0 = TileXSize*(i/h) ;
|
|
y0 = TileYSize*(i%h) ;
|
|
gc.clip_x_origin = x0 + x ;
|
|
gc.clip_y_origin = y0 + y ;
|
|
gc.clip_mask = mask ; /* may be None */
|
|
XChangeGC (DADisplay, imgOp,
|
|
GCClipXOrigin | GCClipYOrigin | GCClipMask, & gc) ;
|
|
XCopyArea (DADisplay, image, ButtonBarImage, imgOp, 0, 0,
|
|
width, height, gc.clip_x_origin, gc.clip_y_origin) ;
|
|
|
|
/* update highlight behind mask: cell &= ~iconmask */
|
|
if (HighlightBehind && mask != None)
|
|
{
|
|
/* use "andInverted" (dst &= ~src) */
|
|
XSetFunction (DADisplay, maskOp, GXandInverted) ;
|
|
XCopyArea (DADisplay, mask, HighlightBehindMask, maskOp,
|
|
0, 0, width, height, gc.clip_x_origin, gc.clip_y_origin) ;
|
|
}
|
|
/* or highlight behind cell &= 0 if no mask */
|
|
else
|
|
if (HighlightBehind && mask == None)
|
|
{
|
|
XSetFunction (DADisplay, maskOp, GXclear) ;
|
|
XFillRectangle (DADisplay, HighlightBehindMask, maskOp,
|
|
gc.clip_x_origin, gc.clip_y_origin, width, height) ;
|
|
}
|
|
|
|
XFreePixmap (DADisplay, image) ;
|
|
if (mask != 0) XFreePixmap (DADisplay, mask) ;
|
|
}
|
|
|
|
XFreeGC (DADisplay, imgOp) ;
|
|
XFreeGC (DADisplay, maskOp) ;
|
|
|
|
wa.background_pixmap = ButtonBarImage ;
|
|
wa.event_mask = ButtonPressMask | ButtonReleaseMask ;
|
|
if (! ClickOnly) wa.event_mask |= EnterWindowMask | LeaveWindowMask ;
|
|
if (HighlightImage != 0) wa.event_mask |= PointerMotionMask ;
|
|
wa.override_redirect = True ;
|
|
XChangeWindowAttributes (DADisplay, ButtonBarWindow,
|
|
CWBackPixmap | CWEventMask | CWOverrideRedirect, & wa) ;
|
|
}
|
|
|
|
extern void ButtonBar_SetPositionFromDockApp (int dockx, int docky,
|
|
int dockw, int dockh)
|
|
{
|
|
int xMid, scrWidth, h, scrHeight ;
|
|
int x, y ;
|
|
|
|
(void) dockh;
|
|
|
|
/* compute y */
|
|
scrHeight = DisplayHeight (DADisplay, DefaultScreen (DADisplay)) ;
|
|
y = docky ;
|
|
h = TileYSize * Menu_GetNbRows () ;
|
|
if (y + h >= scrHeight)
|
|
{
|
|
y = scrHeight - h ;
|
|
}
|
|
|
|
/* compute x */
|
|
scrWidth = DisplayWidth (DADisplay, DefaultScreen (DADisplay)) ;
|
|
xMid = dockx + dockw/2 ;
|
|
if (xMid*2 < scrWidth)
|
|
{
|
|
/* we are rather on left, expand to right */
|
|
x = dockx + dockw ;
|
|
}
|
|
else
|
|
{
|
|
/* we are rather on right, expand to left */
|
|
x = dockx - TileXSize * Menu_GetNbColumns () ;
|
|
}
|
|
|
|
BarX = x ;
|
|
BarY = y ;
|
|
}
|
|
|
|
extern void ButtonBar_Show (void)
|
|
{
|
|
XMoveWindow (DADisplay, ButtonBarWindow, BarX, BarY) ;
|
|
XMapRaised (DADisplay, ButtonBarWindow) ;
|
|
}
|
|
|
|
static void BuildHighlightGC (void)
|
|
{
|
|
XGCValues gc ;
|
|
gc.clip_mask = HighlightBehindMask ;
|
|
HighlightGC = XCreateGC (DADisplay, DAWindow,
|
|
GCClipMask, & gc) ;
|
|
}
|
|
|
|
extern void ButtonBar_Highlight (int col, int row)
|
|
{
|
|
int h ;
|
|
int newPos ;
|
|
|
|
if (HighlightImage == 0) return ;
|
|
|
|
h = Menu_GetNbRows () ;
|
|
newPos = col*h + row ;
|
|
|
|
if (newPos != OldPos)
|
|
{
|
|
int x, y ;
|
|
XGCValues gc ;
|
|
|
|
/* first clear old highlight position */
|
|
ButtonBar_Unhighlight () ;
|
|
|
|
/* don't draw highlight on empty slots */
|
|
if (newPos >= Menu_GetNbEntries ()) return ;
|
|
|
|
/* compute new draw position */
|
|
x = col * TileXSize ;
|
|
y = row * TileYSize ;
|
|
/* and draw it */
|
|
if (HighlightGC == 0) BuildHighlightGC () ;
|
|
gc.clip_x_origin = HighlightBehind ? 0 : x ;
|
|
gc.clip_y_origin = HighlightBehind ? 0 : y ;
|
|
XChangeGC (DADisplay, HighlightGC,
|
|
GCClipXOrigin | GCClipYOrigin, & gc) ;
|
|
XCopyArea (DADisplay, HighlightImage, ButtonBarWindow,
|
|
HighlightGC, 0, 0, TileXSize, TileYSize, x, y) ;
|
|
|
|
OldPos = newPos ;
|
|
}
|
|
}
|
|
|
|
extern void ButtonBar_Unhighlight (void)
|
|
{
|
|
int x, y, h ;
|
|
|
|
if (HighlightImage == 0 || OldPos < 0) return ;
|
|
|
|
h = Menu_GetNbRows () ;
|
|
x = (OldPos / h) * TileXSize ;
|
|
y = (OldPos % h) * TileYSize ;
|
|
XClearArea (DADisplay, ButtonBarWindow,
|
|
x, y, TileXSize, TileYSize, False) ;
|
|
OldPos = -1 ;
|
|
}
|
|
|
|
extern void ButtonBar_Hide (void)
|
|
{
|
|
XUnmapWindow (DADisplay, ButtonBarWindow) ;
|
|
OldPos = -1 ;
|
|
}
|
|
|
|
extern void ButtonBar_Rebuild (void)
|
|
{
|
|
XDestroyWindow (DADisplay, ButtonBarWindow) ;
|
|
if (HighlightGC != 0)
|
|
{
|
|
XFreeGC (DADisplay, HighlightGC) ;
|
|
HighlightGC = 0 ;
|
|
}
|
|
OldPos = -1 ;
|
|
ButtonBar_Build () ;
|
|
}
|