add alignment
This commit is contained in:
parent
1146fd8114
commit
27c03246ca
3
config.h
3
config.h
|
@ -17,6 +17,9 @@ static struct Config config = {
|
||||||
.separator_pixels = 3, /* space around separator */
|
.separator_pixels = 3, /* space around separator */
|
||||||
.gap_pixels = 0, /* gap between menus */
|
.gap_pixels = 0, /* gap between menus */
|
||||||
|
|
||||||
|
/* text alignment, set to LeftAlignment, CenterAlignment or RightAlignment */
|
||||||
|
.alignment = LeftAlignment,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The variables below cannot be set by X resources.
|
* The variables below cannot be set by X resources.
|
||||||
* Their values must be less than .height_pixels.
|
* Their values must be less than .height_pixels.
|
||||||
|
|
9
xmenu.1
9
xmenu.1
|
@ -168,6 +168,15 @@ The size in pixels of the border around the menu.
|
||||||
.TP
|
.TP
|
||||||
.B xmenu.separatorWidth
|
.B xmenu.separatorWidth
|
||||||
The size in pixels of the item separator.
|
The size in pixels of the item separator.
|
||||||
|
.TP
|
||||||
|
.B xmenu.alignment
|
||||||
|
If set to
|
||||||
|
.BR "\(dqleft\(dq" ,
|
||||||
|
.BR "\(dqcenter\(dq" ,
|
||||||
|
or
|
||||||
|
.BR "\(dqright\(dq" ,
|
||||||
|
text is aligned to the left, center, or right of the menu, respectively.
|
||||||
|
By default, text is aligned to the left.
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
The following script illustrates the use of
|
The following script illustrates the use of
|
||||||
|
|
49
xmenu.c
49
xmenu.c
|
@ -228,6 +228,14 @@ initresources(void)
|
||||||
config.border_color = strdup(xval.addr);
|
config.border_color = strdup(xval.addr);
|
||||||
if (XrmGetResource(xdb, "xmenu.font", "*", &type, &xval) == True)
|
if (XrmGetResource(xdb, "xmenu.font", "*", &type, &xval) == True)
|
||||||
config.font = strdup(xval.addr);
|
config.font = strdup(xval.addr);
|
||||||
|
if (XrmGetResource(xdb, "xmenu.alignment", "*", &type, &xval) == True) {
|
||||||
|
if (strcasecmp(xval.addr, "center") == 0)
|
||||||
|
config.alignment = CenterAlignment;
|
||||||
|
else if (strcasecmp(xval.addr, "left") == 0)
|
||||||
|
config.alignment = LeftAlignment;
|
||||||
|
else if (strcasecmp(xval.addr, "right") == 0)
|
||||||
|
config.alignment = RightAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
XrmDestroyDatabase(xdb);
|
XrmDestroyDatabase(xdb);
|
||||||
}
|
}
|
||||||
|
@ -583,29 +591,26 @@ static void
|
||||||
setupitems(struct Menu *menu)
|
setupitems(struct Menu *menu)
|
||||||
{
|
{
|
||||||
struct Item *item;
|
struct Item *item;
|
||||||
|
int itemwidth;
|
||||||
|
|
||||||
menu->w = config.width_pixels;
|
menu->w = config.width_pixels;
|
||||||
|
menu->maxtextw = 0;
|
||||||
for (item = menu->list; item != NULL; item = item->next) {
|
for (item = menu->list; item != NULL; item = item->next) {
|
||||||
int itemwidth;
|
|
||||||
int textwidth;
|
|
||||||
|
|
||||||
item->y = menu->h;
|
item->y = menu->h;
|
||||||
|
|
||||||
if (item->label == NULL) /* height for separator item */
|
if (item->label == NULL) /* height for separator item */
|
||||||
item->h = config.separator_pixels;
|
item->h = config.separator_pixels;
|
||||||
else
|
else
|
||||||
item->h = config.height_pixels;
|
item->h = config.height_pixels;
|
||||||
menu->h += item->h;
|
menu->h += item->h;
|
||||||
|
|
||||||
if (item->label)
|
if (item->label)
|
||||||
textwidth = drawtext(NULL, NULL, 0, 0, 0, item->label);
|
item->textw = drawtext(NULL, NULL, 0, 0, 0, item->label);
|
||||||
else
|
else
|
||||||
textwidth = 0;
|
item->textw = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set menu width
|
* set menu width
|
||||||
*
|
*
|
||||||
* the item width depends on the size of its label (textwidth),
|
* the item width depends on the size of its label (item->textw),
|
||||||
* and it is only used to calculate the width of the menu (which
|
* and it is only used to calculate the width of the menu (which
|
||||||
* is equal to the width of the largest item).
|
* is equal to the width of the largest item).
|
||||||
*
|
*
|
||||||
|
@ -614,9 +619,10 @@ setupitems(struct Menu *menu)
|
||||||
* if the iflag is set (icons are disabled) then the horizontal
|
* if the iflag is set (icons are disabled) then the horizontal
|
||||||
* padding appears 3 times: before the label and around the triangle.
|
* padding appears 3 times: before the label and around the triangle.
|
||||||
*/
|
*/
|
||||||
itemwidth = textwidth + config.triangle_width + config.horzpadding * 3;
|
itemwidth = item->textw + config.triangle_width + config.horzpadding * 3;
|
||||||
itemwidth += (iflag || !menu->hasicon) ? 0 : config.iconsize + config.horzpadding;
|
itemwidth += (iflag || !menu->hasicon) ? 0 : config.iconsize + config.horzpadding;
|
||||||
menu->w = MAX(menu->w, itemwidth);
|
menu->w = MAX(menu->w, itemwidth);
|
||||||
|
menu->maxtextw = MAX(menu->maxtextw, item->textw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,12 +817,12 @@ loadicon(const char *file)
|
||||||
static void
|
static void
|
||||||
drawitems(struct Menu *menu)
|
drawitems(struct Menu *menu)
|
||||||
{
|
{
|
||||||
|
XftDraw *dsel, *dunsel;
|
||||||
struct Item *item;
|
struct Item *item;
|
||||||
|
int textx;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
for (item = menu->list; item != NULL; item = item->next) {
|
for (item = menu->list; item != NULL; item = item->next) {
|
||||||
XftDraw *dsel, *dunsel;
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
item->unsel = XCreatePixmap(dpy, menu->win, menu->w, item->h,
|
item->unsel = XCreatePixmap(dpy, menu->win, menu->w, item->h,
|
||||||
DefaultDepth(dpy, screen));
|
DefaultDepth(dpy, screen));
|
||||||
|
|
||||||
|
@ -831,21 +837,30 @@ drawitems(struct Menu *menu)
|
||||||
|
|
||||||
item->sel = item->unsel;
|
item->sel = item->unsel;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
item->sel = XCreatePixmap(dpy, menu->win, menu->w, item->h,
|
item->sel = XCreatePixmap(dpy, menu->win, menu->w, item->h,
|
||||||
DefaultDepth(dpy, screen));
|
DefaultDepth(dpy, screen));
|
||||||
XSetForeground(dpy, dc.gc, dc.selected[ColorBG].pixel);
|
XSetForeground(dpy, dc.gc, dc.selected[ColorBG].pixel);
|
||||||
XFillRectangle(dpy, item->sel, dc.gc, 0, 0, menu->w, item->h);
|
XFillRectangle(dpy, item->sel, dc.gc, 0, 0, menu->w, item->h);
|
||||||
|
|
||||||
/* draw text */
|
/* draw text */
|
||||||
x = config.horzpadding;
|
textx = config.horzpadding;
|
||||||
x += (iflag || !menu->hasicon) ? 0 : config.horzpadding + config.iconsize;
|
textx += (iflag || !menu->hasicon) ? 0 : config.horzpadding + config.iconsize;
|
||||||
|
switch (config.alignment) {
|
||||||
|
case CenterAlignment:
|
||||||
|
textx += (menu->maxtextw - item->textw) / 2;
|
||||||
|
break;
|
||||||
|
case RightAlignment:
|
||||||
|
textx += menu->maxtextw - item->textw;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
dsel = XftDrawCreate(dpy, item->sel, visual, colormap);
|
dsel = XftDrawCreate(dpy, item->sel, visual, colormap);
|
||||||
dunsel = XftDrawCreate(dpy, item->unsel, visual, colormap);
|
dunsel = XftDrawCreate(dpy, item->unsel, visual, colormap);
|
||||||
XSetForeground(dpy, dc.gc, dc.selected[ColorFG].pixel);
|
XSetForeground(dpy, dc.gc, dc.selected[ColorFG].pixel);
|
||||||
drawtext(dsel, &dc.selected[ColorFG], x, 0, item->h, item->label);
|
drawtext(dsel, &dc.selected[ColorFG], textx, 0, item->h, item->label);
|
||||||
XSetForeground(dpy, dc.gc, dc.normal[ColorFG].pixel);
|
XSetForeground(dpy, dc.gc, dc.normal[ColorFG].pixel);
|
||||||
drawtext(dunsel, &dc.normal[ColorFG], x, 0, item->h, item->label);
|
drawtext(dunsel, &dc.normal[ColorFG], textx, 0, item->h, item->label);
|
||||||
XftDrawDestroy(dsel);
|
XftDrawDestroy(dsel);
|
||||||
XftDrawDestroy(dunsel);
|
XftDrawDestroy(dunsel);
|
||||||
|
|
||||||
|
|
6
xmenu.h
6
xmenu.h
|
@ -3,6 +3,9 @@
|
||||||
/* enum for keyboard menu navigation */
|
/* enum for keyboard menu navigation */
|
||||||
enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };
|
enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };
|
||||||
|
|
||||||
|
/* enum for text alignment */
|
||||||
|
enum {LeftAlignment, CenterAlignment, RightAlignment};
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
#define LEN(x) (sizeof (x) / sizeof (x[0]))
|
#define LEN(x) (sizeof (x) / sizeof (x[0]))
|
||||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||||
|
@ -34,6 +37,7 @@ struct Config {
|
||||||
int triangle_height;
|
int triangle_height;
|
||||||
int iconpadding;
|
int iconpadding;
|
||||||
int horzpadding;
|
int horzpadding;
|
||||||
|
int alignment;
|
||||||
|
|
||||||
/* the values below are set by options */
|
/* the values below are set by options */
|
||||||
int monitor;
|
int monitor;
|
||||||
|
@ -64,6 +68,7 @@ struct Item {
|
||||||
char *file; /* filename of the icon */
|
char *file; /* filename of the icon */
|
||||||
int y; /* item y position relative to menu */
|
int y; /* item y position relative to menu */
|
||||||
int h; /* item height */
|
int h; /* item height */
|
||||||
|
int textw; /* text width */
|
||||||
struct Item *prev; /* previous item */
|
struct Item *prev; /* previous item */
|
||||||
struct Item *next; /* next item */
|
struct Item *next; /* next item */
|
||||||
struct Menu *submenu; /* submenu spawned by clicking on item */
|
struct Menu *submenu; /* submenu spawned by clicking on item */
|
||||||
|
@ -85,6 +90,7 @@ struct Menu {
|
||||||
int x, y, w, h; /* menu geometry */
|
int x, y, w, h; /* menu geometry */
|
||||||
int hasicon; /* whether the menu has item with icons */
|
int hasicon; /* whether the menu has item with icons */
|
||||||
int drawn; /* whether the menu was already drawn */
|
int drawn; /* whether the menu was already drawn */
|
||||||
|
int maxtextw; /* maximum text width */
|
||||||
unsigned level; /* menu level relative to root */
|
unsigned level; /* menu level relative to root */
|
||||||
Window win; /* menu window to map on the screen */
|
Window win; /* menu window to map on the screen */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user