1 /*
2 * Part of WCM Commander
3 * https://github.com/corporateshark/WCMCommander
4 * wcm@linderdaum.com
5 */
6
7 #include "toolbar.h"
8 #include "globals.h"
9
10 const int SPLITTER_WIDTH = 6;
11 const int XSPACE = 3;
12 const int YSPACE = 1;
13
ToolBar(Win * parent,const crect * rect,int iconSize)14 ToolBar::ToolBar( Win* parent, const crect* rect, int iconSize )
15 : Win( Win::WT_CHILD, 0, parent, rect ),
16 _iconSize( iconSize ),
17 _pressed( 0 ),
18 _ticks( 0 ),
19 _curTip( 0 ),
20 _nextTip( 0 )
21 {
22 OnChangeStyles();
23 }
24
25 int uiClassToolBar = GetUiID( "ToolBar" );
26
UiGetClassId()27 int ToolBar::UiGetClassId() { return uiClassToolBar; }
28
RecalcItems()29 void ToolBar::RecalcItems()
30 {
31 // crect cr = ClientRect();
32 int x = 2;
33 int y = 2;
34
35 wal::GC gc( this );
36 gc.Set( GetFont() );
37
38 for ( size_t i = 0; i < _list.size(); i++ )
39 {
40 Node* p = _list[i].ptr();
41
42 if ( p )
43 {
44 int w = 0;
45 int h = _iconSize;
46
47 if ( p->icon.ptr() && p->icon->Valid() )
48 {
49 w += _iconSize;
50 };
51
52 if ( w )
53 {
54 w += 2 + XSPACE * 2;
55 h += 2 + YSPACE * 2;
56 p->rect.Set( x, y, x + w, y + h );
57 x += w;
58 }
59 else { p->rect.Set( 0, 0, 0, 0 ); }
60
61 }
62 else
63 {
64 x += SPLITTER_WIDTH;
65 }
66 }
67 }
68
Clear()69 void ToolBar::Clear()
70 {
71 _list.clear();
72 }
73
74
AddCmd(int cmd,const char * tipText)75 void ToolBar::AddCmd( int cmd, const char* tipText )
76 {
77 if ( cmd != 0 )
78 {
79 clPtr<Node> p = new Node();
80 p->cmd = cmd;
81
82 if ( tipText && tipText[0] ) { p->tipText = utf8_to_unicode( tipText ); }
83
84 p->icon = new cicon( cmd, _iconSize, _iconSize );
85 _list.push_back( p );
86 RecalcItems();
87 }
88 }
89
90
AddSplitter()91 void ToolBar::AddSplitter()
92 {
93 if ( _list.size() > 0 && _list.back().ptr() )
94 {
95 _list.emplace_back( clPtr<Node>() );
96 }
97 }
98
OnChangeStyles()99 void ToolBar::OnChangeStyles()
100 {
101 int h = _iconSize;
102 h += 2 + 4 + YSPACE * 2;
103
104 LSize ls;
105 ls.x.minimal = ls.x.ideal = 0;
106 ls.x.maximal = 16000;
107 ls.y.minimal = ls.y.maximal = ls.y.ideal = h;
108 SetLSize( ls );
109 RecalcItems();
110 }
111
GetNodeByPos(int x,int y)112 ToolBar::Node* ToolBar::GetNodeByPos( int x, int y )
113 {
114 for ( size_t i = 0; i < _list.size(); i++ )
115 {
116 Node* p = _list[i].ptr();
117
118 if ( p && p->rect.In( cpoint( x, y ) ) )
119 {
120 return p;
121 }
122 }
123
124 return 0;
125 }
126
DrawNode(wal::GC & gc,Node * pNode,int state)127 void ToolBar::DrawNode( wal::GC& gc, Node* pNode, int state )
128 {
129 if ( !pNode ) { return; }
130
131 int W = pNode->rect.Width();
132 int H = pNode->rect.Height();
133
134 if ( W <= 0 || H <= 0 ) { return; }
135
136 int x = pNode->rect.left + 1 + XSPACE;
137 int y = pNode->rect.top + 1 + YSPACE;
138
139 unsigned bgColor = UiGetColor( uiBackground, uiItem, 0, 0x808080 ); //GetColor(0);
140 unsigned frameColor = ColorTone( bgColor, -150 );
141
142 if ( state == DRAW_PRESSED )
143 {
144 bgColor = ColorTone( bgColor, -50 );
145 }
146
147 gc.SetFillColor( bgColor );
148
149 {
150 crect r = pNode->rect;
151 r.Dec();
152 gc.FillRect( r );
153 }
154
155 if ( pNode->icon.ptr() && pNode->icon->Valid() )
156 {
157 pNode->icon->DrawF( gc, x, y );
158 x += _iconSize;
159 }
160
161 if ( state != DRAW_NORMAL )
162 {
163 DrawBorder( gc, pNode->rect, frameColor );
164 }
165 }
166
Paint(wal::GC & gc,const crect & paintRect)167 void ToolBar::Paint( wal::GC& gc, const crect& paintRect )
168 {
169 crect cr = ClientRect();
170 crect rect = cr;
171 unsigned colorBg = UiGetColor( uiBackground, 0, 0, 0x808080 ); //GetColor(0);
172
173 unsigned splitColor1 = ColorTone( colorBg, -70 );
174 unsigned splitColor2 = ColorTone( colorBg, 70 );
175
176 if ( g_WcmConfig.styleShow3DUI )
177 {
178 Draw3DButtonW2( gc, rect, colorBg, true );
179 rect.Dec();
180 rect.Dec();
181 }
182
183 gc.SetFillColor( colorBg );
184 gc.FillRect( rect );
185
186 gc.Set( GetFont() );
187 int x = 2;
188
189 for ( size_t i = 0; i < _list.size(); i++ )
190 {
191 Node* p = _list[i].ptr();
192
193 if ( p )
194 {
195 DrawNode( gc, p, _pressed == p ? DRAW_PRESSED : DRAW_NORMAL );
196 x += p->rect.Width();
197 }
198 else
199 {
200 gc.SetFillColor( splitColor1 );
201 int x1 = x + SPLITTER_WIDTH / 2;
202 gc.FillRect( crect( x1, rect.top, x1 + 1, rect.bottom ) );
203 gc.SetFillColor( splitColor2 );
204 gc.FillRect( crect( x1 + 2, rect.top, x1 + 2, rect.bottom ) );
205 x += SPLITTER_WIDTH;
206
207 }
208 }
209
210 return;
211 }
212
EventTimer(int tid)213 void ToolBar::EventTimer( int tid )
214 {
215 if ( _curTip != _nextTip )
216 {
217 _ticks++;
218
219 if ( _ticks > 0 )
220 {
221 _curTip = _nextTip;
222
223 if ( _nextTip && _nextTip->tipText.data() && _nextTip->tipText[0] )
224 {
225 ToolTipShow( this, _nextTip->rect.left + 3, _nextTip->rect.bottom + 5, _nextTip->tipText.data() );
226 }
227 }
228 }
229 }
230
EventMouse(cevent_mouse * pEvent)231 bool ToolBar::EventMouse( cevent_mouse* pEvent )
232 {
233 {
234 _ticks = 0;
235 //_mPoint = pEvent->Point();
236 _nextTip = GetNodeByPos( pEvent->Point().x, pEvent->Point().y );
237
238 if ( _curTip && !_nextTip )
239 {
240 ToolTipHide();
241 _curTip = _nextTip = 0;
242 }
243 }
244
245 switch ( pEvent->Type() )
246 {
247 case EV_MOUSE_PRESS:
248 case EV_MOUSE_DOUBLE:
249 {
250 ToolTipHide();
251 _curTip = _nextTip = 0;
252 DelAllTimers();
253
254 if ( pEvent->Button() != MB_L ) { break; }
255
256 Node* p = GetNodeByPos( pEvent->Point().x, pEvent->Point().y );
257
258 if ( !p ) { break; }
259
260 SetCapture();
261 _pressed = p;
262 Invalidate();
263 }
264 break;
265
266 case EV_MOUSE_RELEASE:
267 {
268 ToolTipHide();
269 _curTip = _nextTip = 0;
270 DelAllTimers();
271 SetTimer(0,200);
272
273 if ( pEvent->Button() != MB_L ) { break; }
274
275 if ( !_pressed ) { break; }
276
277 ReleaseCapture();
278 Node* p = GetNodeByPos( pEvent->Point().x, pEvent->Point().y );
279
280 if ( _pressed == p )
281 {
282 Command( p->cmd, 0, this, 0 );
283 }
284
285 _pressed = 0;
286 Invalidate();
287 }
288 break;
289
290 };
291
292 return true;
293 }
294
EventEnterLeave(cevent * pEvent)295 void ToolBar::EventEnterLeave( cevent* pEvent )
296 {
297 if ( pEvent->Type() == EV_LEAVE )
298 {
299 DelAllTimers();
300 ToolTipHide();
301 }
302 else
303 {
304 //printf("TIMER\n");
305 DelAllTimers();
306 SetTimer( 0, 200 );
307 }
308 }
309
~ToolBar()310 ToolBar::~ToolBar()
311 {
312 }
313