Draw border on only some sides (issue #580, thanks @stophe)
This commit is contained in:
parent
5a5d8fd978
commit
78bc8b5c74
5 changed files with 85 additions and 15 deletions
13
src/config.c
13
src/config.c
|
@ -239,6 +239,19 @@ void add_entry(char *key, char *value)
|
|||
read_border_color_press = 0;
|
||||
} else if (strcmp(key, "border_width") == 0) {
|
||||
g_array_index(backgrounds, Background, backgrounds->len - 1).border.width = atoi(value);
|
||||
} else if (strcmp(key, "border_sides") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
bg->border.mask = 0;
|
||||
if (strchr(value, 'l') || strchr(value, 'L'))
|
||||
bg->border.mask |= BORDER_LEFT;
|
||||
if (strchr(value, 'r') || strchr(value, 'R'))
|
||||
bg->border.mask |= BORDER_RIGHT;
|
||||
if (strchr(value, 't') || strchr(value, 'T'))
|
||||
bg->border.mask |= BORDER_TOP;
|
||||
if (strchr(value, 'b') || strchr(value, 'B'))
|
||||
bg->border.mask |= BORDER_BOTTOM;
|
||||
if (!bg->border.mask)
|
||||
bg->border.width = 0;
|
||||
} else if (strcmp(key, "background_color") == 0) {
|
||||
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);
|
||||
extract_values(value, &value1, &value2, &value3);
|
||||
|
|
|
@ -36,6 +36,7 @@ Area *mouse_over_area = NULL;
|
|||
void init_background(Background *bg)
|
||||
{
|
||||
memset(bg, 0, sizeof(Background));
|
||||
bg->border.mask = BORDER_TOP | BORDER_BOTTOM | BORDER_LEFT | BORDER_RIGHT;
|
||||
}
|
||||
|
||||
void initialize_positions(void *obj, int offset)
|
||||
|
@ -454,12 +455,18 @@ void draw_background(Area *a, cairo_t *c)
|
|||
a->bg->fill_color.rgb[1],
|
||||
a->bg->fill_color.rgb[2],
|
||||
a->bg->fill_color.alpha);
|
||||
// Not sure about this
|
||||
draw_rect(c,
|
||||
a->bg->border.width,
|
||||
a->bg->border.width,
|
||||
a->width - (2.0 * a->bg->border.width),
|
||||
a->height - (2.0 * a->bg->border.width),
|
||||
a->bg->border.mask & BORDER_LEFT ? a->bg->border.width : 0,
|
||||
a->bg->border.mask & BORDER_TOP ? a->bg->border.width : 0,
|
||||
a->width
|
||||
- (a->bg->border.mask & BORDER_LEFT ? a->bg->border.width : 0)
|
||||
- (a->bg->border.mask & BORDER_RIGHT ? a->bg->border.width : 0),
|
||||
a->height
|
||||
- (a->bg->border.mask & BORDER_TOP ? a->bg->border.width : 0)
|
||||
- (a->bg->border.mask & BORDER_BOTTOM ? a->bg->border.width : 0),
|
||||
a->bg->border.radius - a->bg->border.width / 1.571);
|
||||
|
||||
cairo_fill(c);
|
||||
}
|
||||
|
||||
|
@ -485,12 +492,17 @@ void draw_background(Area *a, cairo_t *c)
|
|||
a->bg->border.color.rgb[1],
|
||||
a->bg->border.color.rgb[2],
|
||||
a->bg->border.color.alpha);
|
||||
draw_rect(c,
|
||||
a->bg->border.width / 2.0,
|
||||
a->bg->border.width / 2.0,
|
||||
a->width - a->bg->border.width,
|
||||
a->height - a->bg->border.width,
|
||||
a->bg->border.radius);
|
||||
draw_rect_on_sides(c,
|
||||
a->bg->border.mask & BORDER_LEFT ? a->bg->border.width / 2. : 0,
|
||||
a->bg->border.mask & BORDER_TOP ? a->bg->border.width / 2.0 : 0,
|
||||
a->width
|
||||
- (a->bg->border.mask & BORDER_LEFT ? a->bg->border.width / 2. : 0)
|
||||
- (a->bg->border.mask & BORDER_RIGHT ? a->bg->border.width / 2. : 0),
|
||||
a->height
|
||||
- (a->bg->border.mask & BORDER_TOP ? a->bg->border.width / 2. : 0)
|
||||
- (a->bg->border.mask & BORDER_BOTTOM ? a->bg->border.width / 2. : 0),
|
||||
a->bg->border.radius,
|
||||
a->bg->border.mask);
|
||||
|
||||
cairo_stroke(c);
|
||||
}
|
||||
|
|
|
@ -124,6 +124,15 @@ typedef struct Color {
|
|||
double alpha;
|
||||
} Color;
|
||||
|
||||
typedef enum BorderMask {
|
||||
BORDER_TOP = 1 << 0,
|
||||
BORDER_BOTTOM = 1 << 1,
|
||||
BORDER_LEFT = 1 << 2,
|
||||
BORDER_RIGHT = 1 << 3
|
||||
} BorderMask;
|
||||
|
||||
#define BORDER_ALL (BORDER_TOP | BORDER_BOTTOM | BORDER_LEFT | BORDER_RIGHT)
|
||||
|
||||
typedef struct Border {
|
||||
// It's essential that the first member is color
|
||||
Color color;
|
||||
|
@ -131,6 +140,8 @@ typedef struct Border {
|
|||
int width;
|
||||
// Corner radius
|
||||
int radius;
|
||||
// Mask: bitwise OR of BorderMask
|
||||
int mask;
|
||||
} Border;
|
||||
|
||||
typedef struct Background {
|
||||
|
|
|
@ -508,20 +508,53 @@ Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int bri
|
|||
|
||||
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
|
||||
{
|
||||
if (r > 0.0) {
|
||||
double c1 = 0.55228475 * r;
|
||||
draw_rect_on_sides(c, x, y, w, h, r, BORDER_ALL);
|
||||
}
|
||||
|
||||
cairo_move_to(c, x + r, y);
|
||||
void draw_rect_on_sides(cairo_t *c, double x, double y, double w, double h, double r, int border_mask)
|
||||
{
|
||||
double c1 = 0.55228475 * r;
|
||||
cairo_move_to(c, x + r, y);
|
||||
// Top line
|
||||
if (border_mask & BORDER_TOP)
|
||||
cairo_rel_line_to(c, w - 2 * r, 0);
|
||||
else
|
||||
cairo_rel_move_to(c, w - 2 * r, y);
|
||||
// Top right corner
|
||||
if (r > 0 && (border_mask & BORDER_TOP) && (border_mask & BORDER_RIGHT))
|
||||
cairo_rel_curve_to(c, c1, 0.0, r, c1, r, r);
|
||||
else
|
||||
cairo_rel_move_to(c, r, r);
|
||||
// Right line
|
||||
if (border_mask & BORDER_RIGHT)
|
||||
cairo_rel_line_to(c, 0, h - 2 * r);
|
||||
else
|
||||
cairo_rel_move_to(c, 0, h - 2 * r);
|
||||
// Bottom right corner
|
||||
if (r > 0 && (border_mask & BORDER_RIGHT) && (border_mask & BORDER_BOTTOM))
|
||||
cairo_rel_curve_to(c, 0.0, c1, c1 - r, r, -r, r);
|
||||
else
|
||||
cairo_rel_move_to(c, -r, r);
|
||||
// Bottom line
|
||||
if (border_mask & BORDER_BOTTOM)
|
||||
cairo_rel_line_to(c, -w + 2 * r, 0);
|
||||
else
|
||||
cairo_rel_move_to(c, -w + 2 * r, 0);
|
||||
// Bottom left corner
|
||||
if (r > 0 && (border_mask & BORDER_LEFT) && (border_mask & BORDER_BOTTOM))
|
||||
cairo_rel_curve_to(c, -c1, 0, -r, -c1, -r, -r);
|
||||
else
|
||||
cairo_rel_move_to(c, -r, -r);
|
||||
// Left line
|
||||
if (border_mask & BORDER_LEFT)
|
||||
cairo_rel_line_to(c, 0, -h + 2 * r);
|
||||
else
|
||||
cairo_rel_move_to(c, 0, -h + 2 * r);
|
||||
// Top left corner
|
||||
if (r > 0 && (border_mask & BORDER_LEFT) && (border_mask & BORDER_TOP))
|
||||
cairo_rel_curve_to(c, 0, -c1, r - c1, -r, r, -r);
|
||||
} else
|
||||
cairo_rectangle(c, x, y, w, h);
|
||||
else
|
||||
cairo_rel_move_to(c, r, -r);
|
||||
}
|
||||
|
||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h)
|
||||
|
|
|
@ -108,6 +108,7 @@ void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color
|
|||
|
||||
// Draws a rounded rectangle
|
||||
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);
|
||||
void draw_rect_on_sides(cairo_t *c, double x, double y, double w, double h, double r, int border_mask);
|
||||
|
||||
// Clears the pixmap (with transparent color)
|
||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h);
|
||||
|
|
Loading…
Reference in a new issue