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