Browse Source

add alignment

master
phillbush 4 years ago
parent
commit
27c03246ca
4 changed files with 50 additions and 17 deletions
  1. +3
    -0
      config.h
  2. +9
    -0
      xmenu.1
  3. +32
    -17
      xmenu.c
  4. +6
    -0
      xmenu.h

+ 3
- 0
config.h View File

@@ -17,6 +17,9 @@ static struct Config config = {
.separator_pixels = 3, /* space around separator */
.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.
* Their values must be less than .height_pixels.


+ 9
- 0
xmenu.1 View File

@@ -168,6 +168,15 @@ The size in pixels of the border around the menu.
.TP
.B xmenu.separatorWidth
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
The following script illustrates the use of


+ 32
- 17
xmenu.c View File

@@ -228,6 +228,14 @@ initresources(void)
config.border_color = strdup(xval.addr);
if (XrmGetResource(xdb, "xmenu.font", "*", &type, &xval) == True)
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);
}
@@ -583,29 +591,26 @@ static void
setupitems(struct Menu *menu)
{
struct Item *item;
int itemwidth;

menu->w = config.width_pixels;
menu->maxtextw = 0;
for (item = menu->list; item != NULL; item = item->next) {
int itemwidth;
int textwidth;

item->y = menu->h;

if (item->label == NULL) /* height for separator item */
item->h = config.separator_pixels;
else
item->h = config.height_pixels;
menu->h += item->h;

if (item->label)
textwidth = drawtext(NULL, NULL, 0, 0, 0, item->label);
item->textw = drawtext(NULL, NULL, 0, 0, 0, item->label);
else
textwidth = 0;
item->textw = 0;

/*
* 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
* 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
* 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;
menu->w = MAX(menu->w, itemwidth);
menu->maxtextw = MAX(menu->maxtextw, item->textw);
}
}

@@ -811,12 +817,12 @@ loadicon(const char *file)
static void
drawitems(struct Menu *menu)
{
XftDraw *dsel, *dunsel;
struct Item *item;
int textx;
int x, y;

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,
DefaultDepth(dpy, screen));

@@ -831,21 +837,30 @@ drawitems(struct Menu *menu)

item->sel = item->unsel;
} else {

item->sel = XCreatePixmap(dpy, menu->win, menu->w, item->h,
DefaultDepth(dpy, screen));
XSetForeground(dpy, dc.gc, dc.selected[ColorBG].pixel);
XFillRectangle(dpy, item->sel, dc.gc, 0, 0, menu->w, item->h);

/* draw text */
x = config.horzpadding;
x += (iflag || !menu->hasicon) ? 0 : config.horzpadding + config.iconsize;
textx = config.horzpadding;
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);
dunsel = XftDrawCreate(dpy, item->unsel, visual, colormap);
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);
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(dunsel);



+ 6
- 0
xmenu.h View File

@@ -3,6 +3,9 @@
/* enum for keyboard menu navigation */
enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };

/* enum for text alignment */
enum {LeftAlignment, CenterAlignment, RightAlignment};

/* macros */
#define LEN(x) (sizeof (x) / sizeof (x[0]))
#define MAX(x,y) ((x)>(y)?(x):(y))
@@ -34,6 +37,7 @@ struct Config {
int triangle_height;
int iconpadding;
int horzpadding;
int alignment;

/* the values below are set by options */
int monitor;
@@ -64,6 +68,7 @@ struct Item {
char *file; /* filename of the icon */
int y; /* item y position relative to menu */
int h; /* item height */
int textw; /* text width */
struct Item *prev; /* previous item */
struct Item *next; /* next item */
struct Menu *submenu; /* submenu spawned by clicking on item */
@@ -85,6 +90,7 @@ struct Menu {
int x, y, w, h; /* menu geometry */
int hasicon; /* whether the menu has item with icons */
int drawn; /* whether the menu was already drawn */
int maxtextw; /* maximum text width */
unsigned level; /* menu level relative to root */
Window win; /* menu window to map on the screen */
};

Loading…
Cancel
Save