Rune - Further Object abstraction work
[rune.git] / classes / gadgets / button.d
1 # GADGETS/BUTTON.D      - Button Gadget
2 #
3 # (c)Copyright 2020-2021, Matthew Dillon, All Rights Reserved.
4 #    See the COPYRIGHT file at the base of the Rune distribution.
5
6 public
7 subclass ButtonFrame from Frame {
8     int holding;
9     public string_p text;
10 }
11
12 public method
13 void
14 ButtonFrame.createButton(
15     lvalue ButtonFrame @this, Frame @parent,
16     int w, int h,
17     int mount, string_p text
18 ) {
19     if (w <= 0)
20         w = parent->textWidth(text, Str.strlen(text)) + (2 + 2);
21     if (h <= 0)
22         h = parent->textHeight() + (2 + 2);
23
24     this.createFrame("button", parent, w, h, mount);
25     this->holding = 0;
26     this->text = text;
27     this->refreshVisibleFrame();
28 }
29
30 refine public method 
31 int
32 ButtonFrame.mouseMoved(Event @ev)
33 {
34     # The button held state controls the button depress graphic, but if 
35     # the mouse moves out of bounds while the button is held we have to
36     # restore or re-depress the graphic.
37     #
38     switch(this->holding) {
39     case Event.XK_Pointer_Button1:
40         if (this->mouseOutOfBounds(ev)) {
41             this->holding = -this->holding;
42             this->refreshVisibleFrame();
43         }
44         break;
45     case -Event.XK_Pointer_Button1:
46         if (this->mouseInBounds(ev)) {
47             this->holding = -this->holding;
48             this->refreshVisibleFrame();
49         }
50         break;
51     }
52     return(0);
53 }
54
55 refine public method 
56 int
57 ButtonFrame.buttonPressed(Event @ev)
58 {
59     switch(ev->keySym) {
60     case Event.XK_Pointer_Button1:
61         if (this->mouseInBounds(ev)) {
62             this->holding = ev->keySym;
63             this->setMouseFocus();
64         } else {
65             this->holding = -ev->keySym;
66         }
67         this->refreshVisibleFrame();
68         break;
69     case -Event.XK_Pointer_Button1:
70         # button release, execute the button function if appropriate
71         #
72         int hold = this->holding;
73
74         this->holding = 0;
75         this->refreshVisibleFrame();
76         this->clearMouseFocus();
77         if (this->mouseInBounds(ev) && hold == Event.XK_Pointer_Button1) {
78             this->buttonExecute();
79         }
80         break;
81     default:
82         break;
83     }
84     return(0);
85 }
86
87 public method
88 void
89 ButtonFrame.buttonExecute()
90 {
91     /* user refines */
92 }
93
94 refine public method
95 bool
96 ButtonFrame.refreshFrame(int x, int y, int w, int h)
97 {
98     Pen @pen1;
99     Pen @pen2;
100     int descent;
101
102     if (this->checklinked() == FALSE)
103         return(0);
104     if (this->holding == Event.XK_Pointer_Button1) {
105         pen1 = this->darkPen;
106         pen2 = this->lightPen;
107     } else {
108         pen1 = this->lightPen;
109         pen2 = this->darkPen;
110     }
111     this->pen = pen1;
112     this->drawLine(0, 0, this->bounds.w - 2, 0);
113     this->drawLine(0, 1, this->bounds.w - 3, 1);
114     this->drawLine(0, 0, 0, this->bounds.h - 1);
115     this->drawLine(1, 0, 1, this->bounds.h - 2);
116     this->pen = pen2;
117     this->drawLine(1, this->bounds.h - 1,
118                    this->bounds.w - 1, this->bounds.h - 1);
119     this->drawLine(2, this->bounds.h - 2,
120                    this->bounds.w - 1, this->bounds.h - 2);
121     this->drawLine(this->bounds.w - 1, 0,
122                    this->bounds.w - 1, this->bounds.h - 1);
123     this->drawLine(this->bounds.w - 2, 1,
124                    this->bounds.w - 2, this->bounds.h - 1);
125     this->pen = this->textPen;
126     descent = this->textPen->textDescent();
127     this->fillText(2, this->bounds.h - 2 - descent, this->bounds.w - 4,
128                   this->text, Str.strlen(this->text));
129     this->pen = NULL;
130
131     return(0);
132 }
133
134 public method
135 void
136 ButtonFrame.setTextFGColor(int r, int g, int b)
137 {
138     this->textPen->setFGColor(r, g, b);
139 }
140
141 public method
142 void
143 ButtonFrame.setTextBGColor(int r, int g, int b)
144 {
145     this->textPen->setBGColor(r, g, b);
146 }