1 // Button class implementation
2 
3 #include "button.h"
4 #include "round1"
5 #include "round2"
6 #include "round3"
7 #include "round4"
8 #include "round1_rev"
9 #include "round2_rev"
10 #include "round3_rev"
11 #include "round4_rev"
12 
button(char * l)13 button::button(char* l) : (0, ExposureMask|ButtonPressMask|ButtonReleaseMask|
14 			   EnterWindowMask|LeaveWindowMask, 0, True, 0)
15 {
16   label = l;
17   set_width_height(text_width(label) + hm * 2, char_height() + vm * 2);
18 }
19 
button(container * parent,char * l)20 button::button(container* parent, char* l) :
21        (parent, ExposureMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
22 	LeaveWindowMask, 0, True, 0)
23 {
24   label = l;
25   set_width_height(text_width(label) + hm * 2, char_height() + vm * 2);
26 }
27 
draw_round(char * bits,int x,int y)28 void button::draw_round(char* bits, int x, int y)
29 {
30   XImage ximage;
31   ximage.height = round1_height;
32   ximage.width = round1_width;
33   ximage.depth = 1;
34   ximage.xoffset = 0;
35   ximage.format = XYBitmap;
36   ximage.data = bits;
37   ximage.byte_order = LSBFirst;
38   ximage.bitmap_unit = 8;
39   ximage.bitmap_bit_order = LSBFirst;
40   ximage.bitmap_pad = 8;
41   ximage.bytes_per_line = (round1_width+7)/8;
42   XPutImage(display(), window(), gc(), &ximage, 0, 0,
43 	    x, y, round1_width, round1_height);
44 }
45 
reverse_round(char * bits,int x,int y)46 void button::reverse_round(char* bits, int x, int y)
47 {
48   XImage ximage;
49   ximage.height = round1_height;
50   ximage.width = round1_width;
51   ximage.depth = 1;
52   ximage.xoffset = 0;
53   ximage.format = XYBitmap;
54   ximage.data = bits;
55   ximage.byte_order = LSBFirst;
56   ximage.bitmap_unit = 8;
57   ximage.bitmap_bit_order = LSBFirst;
58   ximage.bitmap_pad = 8;
59   ximage.bytes_per_line = (round1_width+7)/8;
60   XPutImage(display(), window(), igc(), &ximage, 0, 0,
61 	    x, y, round1_width, round1_height);
62 }
63 
draw_round_box()64 void button::draw_round_box()
65 {
66   draw_round(round1_bits, 0, 0);
67   draw_round(round2_bits, width() - round1_width, 0);
68   draw_round(round3_bits, width() - round1_width, height() - round1_height);
69   draw_round(round4_bits, 0, height() - round1_height);
70   XDrawLine(display(), window(), gc(), 0, round1_height,
71 	    0, height() - round1_height);
72   XDrawLine(display(), window(), gc(), width() - 1, round1_height,
73 	    width() - 1, height() - round1_height);
74   XDrawLine(display(), window(), gc(), round1_width, 0,
75 	    width() - round1_width, 0);
76   XDrawLine(display(), window(), gc(), round1_width, height() - 1,
77 	    width() - round1_height, height() - 1);
78 }
79 
reverse_round_box()80 void button::reverse_round_box()
81 {
82   reverse_round(round1_rev_bits, 0, 0);
83   reverse_round(round2_rev_bits, width() - round1_width, 0);
84   reverse_round(round3_rev_bits, width() - round1_width,
85 	     height() - round1_height);
86   reverse_round(round4_rev_bits, 0, height() - round1_height);
87   XFillRectangle(display(), window(), igc(), round1_width, 1,
88 		 width() - round1_width * 2, height() - 2);
89   XFillRectangle(display(), window(), igc(), 1, round1_height,
90 		 round1_width - 1, height() - round1_height * 2);
91   XFillRectangle(display(), window(), igc(), width() - round1_width,
92 		 round1_height, round1_width - 1,
93 		 height() - round1_height * 2);
94 }
95 
handle(XEvent * event)96 Bool button::handle(XEvent* event)
97 {
98   if (event->xany.window == window())
99     {
100       switch (event->type)
101 	{
102 	case Expose:
103 	  out(label, width() - text_width(label) >> 1, char_ascent() + vm);
104 	  draw_round_box();
105 	  break;
106 	case ButtonPress:
107 	  if (!pressed)
108 	    {
109 	      reverse_round_box();
110 	      pressed = event->xbutton.button;
111 	    }
112 	  break;
113 	case ButtonRelease:
114 	  if (event->xbutton.button == pressed)
115 	    {
116 	      reverse_round_box();
117 	      pressed = 0;
118 	    }
119 	  else
120 	    return True;
121 	  break;
122 	case EnterNotify:
123 	  pressed = 0;
124 	  switch (event->xcrossing.state)
125 	    {
126 	    case Button1Mask:
127 	      pressed = Button1;
128 	      break;
129 	    case Button2Mask:
130 	      pressed = Button2;
131 	      break;
132 	    case Button3Mask:
133 	      pressed = Button3;
134 	      break;
135 	    case Button4Mask:
136 	      pressed = Button4;
137 	      break;
138 	    case Button5Mask:
139 	      pressed = Button5;
140 	    }
141 	  if (pressed)
142 	    reverse_round_box();
143 	  break;
144 	case LeaveNotify:
145 	  if (pressed)
146 	    {
147 	      reverse_round_box();
148 	      pressed = 0;
149 	    }
150 	}
151       basic::handle(event);
152       return True;
153     }
154   return False;
155 }
156