-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbutton.c
More file actions
83 lines (82 loc) · 2.47 KB
/
button.c
File metadata and controls
83 lines (82 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright 2017, Alisa Bedard
#include "button.h"
#include <stdlib.h>
#include <string.h>
#include "XSTextWidget.h"
#include "config.h"
#include "font.h"
#include "libjb/xcb.h"
#include "text_widget.h"
#include "XSXData.h"
static void draw(struct XSButton * restrict b)
{
xcb_connection_t * xc = b->widget.X->xc;
xcb_image_text_8(xc, b->length, b->widget.Window, b->widget.X->button_gc,
XSTATUS_CONST_PAD, b->font_size.height, b->label);
}
static void invert(struct XSButton * restrict b)
{
struct XSXData *X = b->widget.X;
xcb_connection_t * xc = X->xc;
xcb_poly_fill_rectangle(xc, b->widget.Window, X->invert_gc,
1, &(xcb_rectangle_t){0, 0, b->widget.Geometry[2], b->font_size.height});
xcb_flush(xc);
}
static pixel_t get_bg(struct XSXData * X)
{
static pixel_t p; // cache the result
return p ? p : (p = jb_get_pixel(X->xc, X->colormap, XSTATUS_BUTTON_BG));
}
static inline uint16_t get_width(uint8_t fw, const char * label)
{
return fw * strlen(label) + fw;
}
static inline uint8_t get_height(uint8_t fh)
{
return fh + (XSTATUS_CONST_PAD >> 1);
}
static xcb_rectangle_t get_geometry(struct XSButton * b)
{
return (xcb_rectangle_t){.x = b->widget.Geometry[0],
.y = b->widget.Geometry[1] = 0,
.width = b->widget.Geometry[2] =
get_width(b->font_size.width, b->label), .height =
b->widget.Geometry[3] = get_height(b->font_size.height)};
}
static void create_window(struct XSButton * b)
{
struct XSXData * X = b->widget.X;
const xcb_window_t w = b->widget.Window;
xcb_connection_t * restrict xc = b->widget.X->xc;
{ // g scope, vm scope, em scope
enum {
VM = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
EM = XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_BUTTON_PRESS
| XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW,
CFP = XCB_COPY_FROM_PARENT,
BORDER = 0
};
const xcb_rectangle_t g = get_geometry(b);
xcb_create_window(xc, CFP, w, X->window,
g.x, g.y, g.width, g.height, BORDER,
CFP, CFP, VM, (uint32_t[]){get_bg(X), EM});
}
xcb_map_window(xc, w);
}
struct XSButton * createButton(struct XSXData * restrict XData,
char * Label, int16_t const XPosition) {
struct XSButton * b = calloc(1, sizeof(struct XSButton));
b->widget.X = XData;
b->widget.Window = xcb_generate_id(XData->xc);
b->label = Label;
b->length = strlen(Label);
b->draw = draw;
b->enter = invert;
b->font_size = xstatus_get_font_size();
b->widget.Geometry[0] = XPosition;
create_window(b);
draw(b);
return b;
}