Audacity 3.2.0
AColor.cpp
Go to the documentation of this file.
1
2/**********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 AColor.cpp
7
8 Dominic Mazzoni
9
10
11********************************************************************//********************************************************************/
19
20#include "AColor.h"
21#include "AColorResources.h"
22
23#include <wx/colour.h>
24#include <wx/dc.h>
25#include <wx/dcmemory.h>
26#include <wx/graphics.h>
27#include <wx/settings.h>
28#include <wx/utils.h>
29
30#include "AllThemeResources.h"
31#include "Theme.h"
32
33bool AColor::inited = false;
34wxBrush AColor::lightBrush[2];
35wxBrush AColor::mediumBrush[2];
36wxBrush AColor::darkBrush[2];
37wxPen AColor::lightPen[2];
38wxPen AColor::mediumPen[2];
39wxPen AColor::darkPen[2];
40
42wxBrush AColor::indicatorBrush[2];
44// wxPen AColor::playRegionPen[2];
46
47wxBrush AColor::muteBrush[2];
48wxBrush AColor::soloBrush;
49
51
55
65
68
69// The spare pen and brush possibly help us cut down on the
70// number of pens and brushes we need.
72wxBrush AColor::spareBrush;
73
74wxPen AColor::uglyPen;
75wxBrush AColor::uglyBrush;
76
77namespace
78{
79 //Simplified variation of nine patch scale drawing
80 //https://en.wikipedia.org/wiki/9-slice_scaling
81 //Bitmap and rect expected to have at least 3px in both directions
82 void DrawNinePatch(wxDC& dc, wxBitmap& bitmap, const wxRect& r, int mid = 1)
83 {
84 assert(bitmap.GetWidth() == mid + (bitmap.GetWidth() - mid) / 2 + (bitmap.GetWidth() - mid) / 2);
85 assert(bitmap.GetHeight() == mid + (bitmap.GetHeight() - mid) / 2 + (bitmap.GetHeight() - mid) / 2);
86 assert(r.width >= bitmap.GetWidth() - mid);
87 assert(r.height >= bitmap.GetHeight() - mid);
88 wxMemoryDC memDC;
89 memDC.SelectObject(bitmap);
90
91 // image slices
92
93 const auto uw0 = (bitmap.GetWidth() - mid) / 2;
94 const auto uw1 = mid;
95 const auto uw2 = bitmap.GetWidth() - uw0 - uw1;
96
97 const auto vh0 = (bitmap.GetHeight() - mid) / 2;
98 const auto vh1 = mid;
99 const auto vh2 = bitmap.GetHeight() - vh1 - vh0;
100
101 const auto u0 = 0;
102 const auto u1 = uw0;
103 const auto u2 = uw0 + uw1;
104
105 const auto v0 = 0;
106 const auto v1 = vh0;
107 const auto v2 = vh0 + vh1;
108
109 //Button geometry
110
111 const auto xw0 = std::min(uw0, r.width / 2);
112 const auto xw2 = std::min(uw2, r.width / 2);
113 const auto xw1 = std::max(r.width - xw0 - xw2, 0);
114
115 const auto yh0 = std::min(vh0, r.height / 2);
116 const auto yh2 = std::min(vh2, r.height / 2);
117 const auto yh1 = std::max(r.height - yh0 - yh2, 0);
118
119 const auto x0 = r.x;
120 const auto x1 = r.x + xw0;
121 const auto x2 = r.x + xw0 + xw1;
122
123 const auto y0 = r.y;
124 const auto y1 = r.y + yh0;
125 const auto y2 = r.y + yh0 + yh1;
126
127 //Draw corners
128 dc.StretchBlit(x0, y0, xw0, yh0, &memDC, u0, v0, uw0, vh0, wxCOPY, true);
129 dc.StretchBlit(x2, y0, xw2, yh0, &memDC, u2, v0, uw2, vh0, wxCOPY, true);
130 dc.StretchBlit(x0, y2, xw0, yh2, &memDC, u0, v2, uw0, vh2, wxCOPY, true);
131 dc.StretchBlit(x2, y2, xw2, yh2, &memDC, u2, v2, uw2, vh2, wxCOPY, true);
132
133 if(xw1 > 0 && yh1 > 0)//Draw middle
134 {
135 dc.StretchBlit(x1, y0, xw1, yh0, &memDC, u1, v0, uw1, vh0, wxCOPY, true);
136
137 dc.StretchBlit(x0, y1, xw0, yh1, &memDC, u0, v1, uw0, vh1, wxCOPY, true);
138 dc.StretchBlit(x1, y1, xw1, yh1, &memDC, u1, v1, uw1, vh1, wxCOPY, true);
139 dc.StretchBlit(x2, y1, xw2, yh1, &memDC, u2, v1, uw2, vh1, wxCOPY, true);
140
141 dc.StretchBlit(x1, y2, xw1, yh2, &memDC, u1, v2, uw1, vh2, wxCOPY, true);
142 }
143 }
144
145 int GetButtonImageIndex(bool up, bool selected, bool highlight)
146 {
147 // There are eight button states in the TCP.
148 // A theme might not differentiate among them all. That's up to
149 // the theme designer.
150 // Button highlighted (i.e. hovered over) or not.
151 // Track selected or not
152 // Button up or down.
153 // Highlight in most themes is lighter than not highlighted.
154 if ( highlight && selected)
155 return up ? bmpHiliteUpButtonExpandSel : bmpHiliteButtonExpandSel;
156 if ( highlight )
157 return up ? bmpHiliteUpButtonExpand : bmpHiliteButtonExpand;
158 if( selected )
159 return up ? bmpUpButtonExpandSel : bmpDownButtonExpandSel;
160 return up ? bmpUpButtonExpand : bmpDownButtonExpand;
161 }
162}
163
164//
165// Draw an upward or downward pointing arrow.
166//
167void AColor::Arrow(wxDC & dc, wxCoord x, wxCoord y, int width, bool down)
168{
169 if (width & 0x01) {
170 width--;
171 }
172
173 wxPoint pt[3];
174 int half = width / 2;
175
176 if (down) {
177 pt[0].x = 0; pt[0].y = 0;
178 pt[1].x = width; pt[1].y = 0;
179 pt[2].x = half; pt[2].y = half;
180 }
181 else {
182 pt[0].x = 0; pt[0].y = half;
183 pt[1].x = half; pt[1].y = 0;
184 pt[2].x = width; pt[2].y = half;
185 }
186
187 dc.DrawPolygon(3, pt, x, y);
188}
189
190//
191// Draw a line, inclusive of endpoints,
192// compensating for differences in wxWidgets versions across platforms
193//
194void AColor::Line(wxDC & dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
195{
196 const wxPoint points[] { { x1, y1 }, { x2, y2 } };
197 Lines( dc, 2, points );
198}
199
200void AColor::Line(wxDC& dc, const wxPoint& from, const wxPoint& to)
201{
202 Line( dc, from.x, from.y, to.x, to.y);
203}
204
205// Draw lines, INCLUSIVE of all endpoints
206void AColor::Lines(wxDC &dc, size_t nPoints, const wxPoint points[])
207{
208 if ( nPoints <= 1 ) {
209 if (nPoints == 1)
210 dc.DrawPoint( points[0] );
211 return;
212 }
213
214 for (size_t ii = 0; ii < nPoints - 1; ++ii) {
215 const auto &p1 = points[ii];
216 const auto &p2 = points[ii + 1];
217
218 // As of 2.8.9 (possibly earlier), wxDC::DrawLine() on the Mac draws the
219 // last point since it is now based on the NEW wxGraphicsContext system.
220 // Make the other platforms do the same thing since the other platforms
221 // "may" follow they get wxGraphicsContext going.
222
223 // PRL: as of 3.1.1, I still observe that on Mac, the last point is
224 // included, contrary to what documentation says. Also that on Windows,
225 // sometimes it is the first point that is excluded.
226
227#if defined(__WXMAC__) || defined(__WXGTK3__)
228 dc.DrawLine(p1, p2);
229#else
230 dc.DrawPoint(p1);
231 if ( p1 != p2 ) {
232 dc.DrawLine(p1, p2);
233 }
234#endif
235 }
236
237#if defined(__WXMAC__) || defined(__WXGTK3__)
238 ;
239#else
240 dc.DrawPoint( points[ nPoints - 1 ] );
241#endif
242}
243
244//
245// Draws a focus rectangle (Taken directly from wxWidgets source)
246//
247void AColor::DrawFocus(wxDC & dc, wxRect & rect)
248{
249 // draw the pixels manually: note that to behave in the same manner as
250 // DrawRect(), we must exclude the bottom and right borders from the
251 // rectangle
252 wxCoord x1 = rect.GetLeft(),
253 y1 = rect.GetTop(),
254 x2 = rect.GetRight(),
255 y2 = rect.GetBottom();
256
257 // -1 for brush, so it just sets the pen colour, and does not change the brush.
258 UseThemeColour( &dc, -1, clrTrackPanelText );
259
260 wxCoord z;
261 for ( z = x1 + 1; z < x2; z += 2 )
262 dc.DrawPoint(z, y1);
263
264 wxCoord shift = z == x2 ? 0 : 1;
265 for ( z = y1 + shift; z < y2; z += 2 )
266 dc.DrawPoint(x2, z);
267
268 shift = z == y2 ? 0 : 1;
269 for ( z = x2 - shift; z > x1; z -= 2 )
270 dc.DrawPoint(z, y2);
271
272 shift = z == x1 ? 0 : 1;
273 for ( z = y2 - shift; z > y1; z -= 2 )
274 dc.DrawPoint(x1, z);
275
276}
277
278void AColor::Bevel(wxDC & dc, bool up, const wxRect & r)
279{
280 AColor::Dark(&dc, false);
281
282 AColor::Line(dc, r.x, r.y, r.x + r.width, r.y);
283 AColor::Line(dc, r.x, r.y, r.x, r.y + r.height);
284
285 AColor::Line(dc, r.x + r.width, r.y, r.x + r.width, r.y + r.height);
286 AColor::Line(dc, r.x, r.y + r.height, r.x + r.width, r.y + r.height);
287}
288
289void AColor::ButtonStretch(wxDC& dc, bool up, const wxRect& r, bool selected, bool highlight)
290{
292 dc,
293 theTheme.Bitmap(GetButtonImageIndex(up, selected, highlight)),
294 r, 2
295 );
296}
297
298void AColor::Bevel2(wxDC & dc, bool up, const wxRect & r, bool bSel, bool bHighlight)
299{
300 auto& Bmp = theTheme.Bitmap( GetButtonImageIndex(up, bSel, bHighlight) );
301 wxMemoryDC memDC;
302 memDC.SelectObject(Bmp);
303
304 int h = std::min(r.height, Bmp.GetHeight());
305
306 dc.Blit( r.x,r.y,r.width/2, h, &memDC, 0, 0, wxCOPY, true );
307 int r2 = r.width - r.width/2;
308 dc.Blit( r.x+r.width/2,r.y,r2, h, &memDC,
309 Bmp.GetWidth() - r2, 0, wxCOPY, true );
310}
311
312void AColor::DrawHStretch(wxDC& dc, const wxRect& rect, wxBitmap& bitmap)
313{
314 wxMemoryDC srcDC;
315 srcDC.SelectObject(bitmap);
316
317 const auto sh = bitmap.GetHeight();
318 const auto dh = rect.height;
319 const auto w0 = std::min((bitmap.GetWidth() - 1) / 2, rect.width / 2);
320 const auto dx0 = rect.x;
321 const auto dx1 = rect.x + w0;
322 const auto dx2 = rect.x + rect.width - w0;
323
324 dc.StretchBlit(dx0, rect.y, w0, dh, &srcDC, 0, 0, w0, sh, wxCOPY, true);
325 dc.StretchBlit(dx1, rect.y, rect.width - w0 * 2, dh, &srcDC, w0, 0, 1, sh, wxCOPY, true);
326 dc.StretchBlit(dx2, rect.y, w0, dh, &srcDC, bitmap.GetWidth() - w0, 0, w0, sh, wxCOPY, true);
327}
328
329void AColor::DrawFrame(wxDC& dc, const wxRect& r, wxBitmap& bitmap, int mid = 1)
330{
331 DrawNinePatch(dc, bitmap, r, mid);
332}
333
334
335wxColour AColor::Blend( const wxColour & c1, const wxColour & c2 )
336{
337 wxColour c3(
338 (c1.Red() + c2.Red())/2,
339 (c1.Green() + c2.Green())/2,
340 (c1.Blue() + c2.Blue())/2);
341 return c3;
342}
343
344void AColor::BevelTrackInfo(wxDC & dc, bool up, const wxRect & r, bool highlight)
345{
346 Bevel( dc, up, r );
347}
348
349// Set colour of and select brush and pen.
350// Use -1 to omit brush or pen.
351// If pen omitted, then the same colour as the brush will be used.
352// alpha for the brush is normally 255, but if set will make a difference
353// on mac (only) currently.
354void AColor::UseThemeColour( wxDC * dc, int iBrush, int iPen, int alpha )
355{
356 if (!inited)
357 Init();
358 // do nothing if no colours set.
359 if( (iBrush == -1) && ( iPen ==-1))
360 return;
361 wxColour col = wxColour(0,0,0);
362 if( iBrush !=-1 ){
363 col = theTheme.Colour( iBrush );
364 col.Set( col.Red(), col.Green(), col.Blue(), alpha);
365 spareBrush.SetColour( col );
366 dc->SetBrush( spareBrush );
367 }
368 if( iPen != -1)
369 col = theTheme.Colour( iPen );
370 sparePen.SetColour( col );
371 dc->SetPen( sparePen );
372}
373
374void AColor::UseThemeColour( wxGraphicsContext * gc, int iBrush, int iPen, int alpha )
375{
376 if (!inited)
377 Init();
378 // do nothing if no colours set.
379 if( (iBrush == -1) && ( iPen ==-1))
380 return;
381 wxColour col = wxColour(0,0,0);
382 if( iBrush !=-1 ){
383 col = theTheme.Colour( iBrush );
384 col.Set( col.Red(), col.Green(), col.Blue(), alpha);
385 spareBrush.SetColour( col );
386 gc->SetBrush( spareBrush );
387 }
388 if( iPen != -1)
389 col = theTheme.Colour( iPen );
390 sparePen.SetColour( col );
391 gc->SetPen( sparePen );
392}
393
394
395void AColor::Light(wxDC * dc, bool selected, bool highlight)
396{
397 if (!inited)
398 Init();
399 int index = (int) selected;
400 auto &brush = highlight ? AColor::uglyBrush : lightBrush[index];
401 dc->SetBrush( brush );
402 auto &pen = highlight ? AColor::uglyPen : lightPen[index];
403 dc->SetPen( pen );
404}
405
406void AColor::Medium(wxDC * dc, bool selected)
407{
408 if (!inited)
409 Init();
410 int index = (int) selected;
411 dc->SetBrush(mediumBrush[index]);
412 dc->SetPen(mediumPen[index]);
413}
414
415void AColor::MediumTrackInfo(wxDC * dc, bool selected)
416{
417 UseThemeColour( dc, selected ? clrTrackInfoSelected : clrTrackInfo );
418}
419
420
421void AColor::Dark(wxDC * dc, bool selected, bool highlight)
422{
423 if (!inited)
424 Init();
425 int index = (int) selected;
426 auto &brush = highlight ? AColor::uglyBrush : darkBrush[index];
427 dc->SetBrush( brush );
428 auto &pen = highlight ? AColor::uglyPen : darkPen[index];
429 dc->SetPen( pen );
430}
431
432void AColor::TrackPanelBackground(wxDC * dc, bool selected)
433{
434 UseThemeColour( dc, selected ? clrMediumSelected : clrTrackBackground );
435}
436
437void AColor::CursorColor(wxDC * dc)
438{
439 if (!inited)
440 Init();
441
442 dc->SetLogicalFunction(wxCOPY);
443 dc->SetPen(cursorPen);
444}
445
446void AColor::IndicatorColor(wxDC * dc, bool bIsNotRecording)
447{
448 if (!inited)
449 Init();
450 int index = (int) bIsNotRecording;
451 dc->SetPen(indicatorPen[index]);
452 dc->SetBrush(indicatorBrush[index]);
453}
454
455void AColor::TrackFocusPen(wxDC * dc, int level)
456{
457 if (!inited)
458 Init();
459 dc->SetPen(trackFocusPens[level]);
460}
461
462void AColor::SnapGuidePen(wxDC * dc)
463{
464 if (!inited)
465 Init();
466 dc->SetPen(snapGuidePen);
467}
468
469void AColor::Mute(wxDC * dc, bool on, bool selected, bool soloing)
470{
471 if (!inited)
472 Init();
473 int index = (int) selected;
474 if (on) {
475 dc->SetPen(*wxBLACK_PEN);
476 dc->SetBrush(muteBrush[(int) soloing]);
477 }
478 else {
479 dc->SetPen(*wxTRANSPARENT_PEN);
480 dc->SetBrush(mediumBrush[index]);
481 }
482}
483
484void AColor::Solo(wxDC * dc, bool on, bool selected)
485{
486 if (!inited)
487 Init();
488 int index = (int) selected;
489 if (on) {
490 dc->SetPen(*wxBLACK_PEN);
491 dc->SetBrush(soloBrush);
492 }
493 else {
494 dc->SetPen(*wxTRANSPARENT_PEN);
495 dc->SetBrush(mediumBrush[index]);
496 }
497}
498
500
502{
503 inited=false;
504 Init();
507}
508
509wxColour InvertOfColour( const wxColour & c )
510{
511 return wxColour( 255-c.Red(), 255-c.Green(), 255-c.Blue() );
512}
513
514// Fix up the cursor colour, if it is 'unacceptable'.
515// Unacceptable if it is too close to the background colour.
516wxColour CursorColour( )
517{
518 wxColour cCursor = theTheme.Colour( clrCursorPen );
519 wxColour cBack = theTheme.Colour( clrMedium );
520
521 int d = theTheme.ColourDistance( cCursor, cBack );
522
523 // Pen colour is fine, if there is plenty of contrast.
524 if( d > 200 )
525 return theTheme.Colour( clrCursorPen );
526
527 // otherwise return same colour as a selection.
528 return theTheme.Colour( clrSelected );
529}
530
532{
533 if (inited)
534 return;
535
536 wxColour light = theTheme.Colour( clrLight );
537 // wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT);
538 wxColour med = theTheme.Colour( clrMedium );
539 // wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
540 wxColour dark = theTheme.Colour( clrDark );
541 // wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW);
542
543 wxColour lightSelected = theTheme.Colour( clrLightSelected );
544 wxColour medSelected = theTheme.Colour( clrMediumSelected );
545 wxColour darkSelected = theTheme.Colour( clrDarkSelected );
546
547
548 clippingPen.SetColour(0xCC, 0x11, 0x00);
549
550 theTheme.SetPenColour( envelopePen, clrEnvelope );
551 theTheme.SetPenColour( WideEnvelopePen, clrEnvelope );
552 theTheme.SetBrushColour( envelopeBrush, clrEnvelope );
553
554 WideEnvelopePen.SetWidth( 3 );
555
556 theTheme.SetBrushColour( labelTextNormalBrush, clrLabelTextNormalBrush );
557 theTheme.SetBrushColour( labelTextEditBrush, clrLabelTextEditBrush );
558 theTheme.SetBrushColour( labelUnselectedBrush, clrLabelUnselectedBrush );
559 theTheme.SetBrushColour( labelSelectedBrush, clrLabelSelectedBrush );
561 theTheme.SetPenColour( labelSyncLockSelPen, clrSyncLockSel );
562 theTheme.SetPenColour( labelSurroundPen, clrLabelSurroundPen );
563
564 // These colors were modified to avoid using reserved colors red and green
565 // for the buttons.
566 theTheme.SetBrushColour( muteBrush[0], clrMuteButtonActive);
567 theTheme.SetBrushColour( muteBrush[1], clrMuteButtonVetoed);
568 theTheme.SetBrushColour( soloBrush, clrMuteButtonActive);
569
570 cursorPen.SetColour( CursorColour() );
571 theTheme.SetPenColour( indicatorPen[0], clrRecordingPen);
572 theTheme.SetPenColour( indicatorPen[1], clrPlaybackPen);
573 theTheme.SetBrushColour( indicatorBrush[0], clrRecordingBrush);
574 theTheme.SetBrushColour( indicatorBrush[1], clrPlaybackBrush);
575
576 theTheme.SetBrushColour( playRegionBrush[0],clrRulerRecordingBrush);
577
578 //Determine tooltip color
579 tooltipPen.SetColour( wxSystemSettingsNative::GetColour(wxSYS_COLOUR_INFOTEXT) );
580 tooltipBrush.SetColour( wxSystemSettingsNative::GetColour(wxSYS_COLOUR_INFOBK) );
581
582 uglyPen.SetColour( wxColour{ 0, 255, 0 } ); // saturated green
583 uglyBrush.SetColour( wxColour{ 255, 0, 255 } ); // saturated magenta
584
585 // A tiny gradient of yellow surrounding the current focused track
586 theTheme.SetPenColour( trackFocusPens[0], clrTrackFocus0);
587 theTheme.SetPenColour( trackFocusPens[1], clrTrackFocus1);
588 theTheme.SetPenColour( trackFocusPens[2], clrTrackFocus2);
589
590 // A vertical line indicating that the selection or sliding has
591 // been snapped to the nearest boundary.
592 theTheme.SetPenColour( snapGuidePen, clrSnapGuide);
593
594 // unselected
595 lightBrush[0].SetColour(light);
596 mediumBrush[0].SetColour(med);
597 darkBrush[0].SetColour(dark);
598 lightPen[0].SetColour(light);
599 mediumPen[0].SetColour(med);
600 darkPen[0].SetColour(dark);
601
602 // selected
603 lightBrush[1].SetColour(lightSelected);
604 mediumBrush[1].SetColour(medSelected);
605 darkBrush[1].SetColour(darkSelected);
606 lightPen[1].SetColour(lightSelected);
607 mediumPen[1].SetColour(medSelected);
608 darkPen[1].SetColour(darkSelected);
609
610 inited = true;
611}
612
613// These colours are chosen so that black text shows up OK on them.
614const int AColor_midicolors[16][3] = {
615 {255, 102, 102}, // 1=salmon
616 {204, 0, 0}, // 2=red
617 {255, 117, 23}, // 3=orange
618 {255, 255, 0}, // 4=yellow
619 {0, 204, 0}, // 5=green
620 {0, 204, 204}, // 6=turquoise
621 {125, 125, 255}, // 7=blue
622 {153, 0, 255}, // 8=blue-violet
623
624 {140, 97, 54}, // 9=brown
625 {120, 120, 120}, // 10=gray (drums)
626 {255, 175, 40}, // 11=lt orange
627 {102, 255, 102}, // 12=lt green
628 {153, 255, 255}, // 13=lt turquoise
629 {190, 190, 255}, // 14=lt blue
630 {204, 102, 255}, // 15=lt blue-violet
631 {255, 51, 204} // 16=lt red-violet
632};
633
634void AColor::MIDIChannel(wxDC * dc, int channel /* 1 - 16 */ )
635{
636 if (channel >= 1 && channel <= 16) {
637 const int *colors = AColor_midicolors[channel - 1];
638
639 dc->SetPen(wxPen(wxColour(colors[0],
640 colors[1], colors[2]), 1, wxPENSTYLE_SOLID));
641 dc->SetBrush(wxBrush(wxColour(colors[0],
642 colors[1], colors[2]), wxBRUSHSTYLE_SOLID));
643 } else {
644 dc->SetPen(wxPen(wxColour(153, 153, 153), 1, wxPENSTYLE_SOLID));
645 dc->SetBrush(wxBrush(wxColour(153, 153, 153), wxBRUSHSTYLE_SOLID));
646 }
647
648}
649
650void AColor::LightMIDIChannel(wxDC * dc, int channel /* 1 - 16 */ )
651{
652 if (channel >= 1 && channel <= 16) {
653 const int *colors = AColor_midicolors[channel - 1];
654
655 dc->SetPen(wxPen(wxColour(127 + colors[0] / 2,
656 127 + colors[1] / 2,
657 127 + colors[2] / 2), 1, wxPENSTYLE_SOLID));
658 dc->SetBrush(wxBrush(wxColour(127 + colors[0] / 2,
659 127 + colors[1] / 2,
660 127 + colors[2] / 2), wxBRUSHSTYLE_SOLID));
661 } else {
662 dc->SetPen(wxPen(wxColour(204, 204, 204), 1, wxPENSTYLE_SOLID));
663 dc->SetBrush(wxBrush(wxColour(204, 204, 204), wxBRUSHSTYLE_SOLID));
664 }
665
666}
667
668void AColor::DarkMIDIChannel(wxDC * dc, int channel /* 1 - 16 */ )
669{
670 if (channel >= 1 && channel <= 16) {
671 const int *colors = AColor_midicolors[channel - 1];
672
673 dc->SetPen(wxPen(wxColour(colors[0] / 2,
674 colors[1] / 2,
675 colors[2] / 2), 1, wxPENSTYLE_SOLID));
676 dc->SetBrush(wxBrush(wxColour(colors[0] / 2,
677 colors[1] / 2,
678 colors[2] / 2), wxBRUSHSTYLE_SOLID));
679 } else {
680 dc->SetPen(wxPen(wxColour(102, 102, 102), 1, wxPENSTYLE_SOLID));
681 dc->SetBrush(wxBrush(wxColour(102, 102, 102), wxBRUSHSTYLE_SOLID));
682 }
683
684}
685
686
687
688unsigned char AColor::gradient_pre[ColorGradientTotal][colorSchemes][gradientSteps][3];
689
691 if (gradient_inited) return;
692 gradient_inited = 1;
693
694 // Keep in correspondence with enum SpectrogramSettings::ColorScheme
695
696 // colorScheme 0: Color (New)
697 std::copy_n(&specColormap[0][0], gradientSteps * 3, &gradient_pre[ColorGradientUnselected][0][0][0]);
698 std::copy_n(&selColormap[0][0], gradientSteps * 3, &gradient_pre[ColorGradientTimeSelected][0][0][0]);
700 std::fill_n(&gradient_pre[ColorGradientEdge][0][0][0], gradientSteps * 3, 0);
701
702
703 for (int selected = 0; selected < ColorGradientTotal; selected++) {
704 // Get color scheme from Theme
705 const int gsteps = 4;
706 float gradient[gsteps + 1][3];
707 theTheme.Colour( clrSpectro1 ) = theTheme.Colour( clrUnselected );
708 theTheme.Colour( clrSpectro1Sel ) = theTheme.Colour( clrSelected );
709 int clrFirst = (selected == ColorGradientUnselected ) ? clrSpectro1 : clrSpectro1Sel;
710 for(int j=0;j<(gsteps+1);j++){
711 wxColour c = theTheme.Colour( clrFirst+j );
712 gradient[ j] [0] = c.Red()/255.0;
713 gradient[ j] [1] = c.Green()/255.0;
714 gradient[ j] [2] = c.Blue()/255.0;
715 }
716
717 // colorScheme 1: Color (from theme)
718 for (int i = 0; i<gradientSteps; i++) {
719 float r, g, b;
720 float value = float(i)/gradientSteps;
721
722 int left = (int)(value * gsteps);
723 int right = (left == gsteps ? gsteps : left + 1);
724
725 float rweight = (value * gsteps) - left;
726 float lweight = 1.0 - rweight;
727
728 r = (gradient[left][0] * lweight) + (gradient[right][0] * rweight);
729 g = (gradient[left][1] * lweight) + (gradient[right][1] * rweight);
730 b = (gradient[left][2] * lweight) + (gradient[right][2] * rweight);
731
732 switch (selected) {
734 // not dimmed
735 break;
736
738 float temp;
739 temp = r;
740 r = g;
741 g = b;
742 b = temp;
743 break;
744
746 // partly dimmed
747 r *= 0.75f;
748 g *= 0.75f;
749 b *= 0.75f;
750 break;
751
752
753 // For now edge colour is just black (or white if grey-scale)
754 // Later we might invert or something else funky.
756 // fully dimmed
757 r = 0;
758 g = 0;
759 b = 0;
760 break;
761 }
762 gradient_pre[selected][1][i][0] = (unsigned char) (255 * r);
763 gradient_pre[selected][1][i][1] = (unsigned char) (255 * g);
764 gradient_pre[selected][1][i][2] = (unsigned char) (255 * b);
765 }
766
767 // colorScheme 3: Inverse Grayscale
768 for (int i = 0; i < gradientSteps; i++) {
769 float r, g, b;
770 float value = float(i) / gradientSteps;
771
772 r = g = b = value;
773
774 switch (selected) {
776 // not dimmed
777 break;
778
780 // else fall through to SAME grayscale colour as normal selection.
781 // The white lines show it up clearly enough.
782
784 // partly dimmed
785 r = r * 0.75f + 0.25f;
786 g = g * 0.75f + 0.25f;
787 b = b * 0.75f + 0.25f;
788 break;
789
791 r = 1.0f;
792 g = 1.0f;
793 b = 1.0f;
794 break;
795 }
796 gradient_pre[selected][3][i][0] = (unsigned char)(255 * r);
797 gradient_pre[selected][3][i][1] = (unsigned char)(255 * g);
798 gradient_pre[selected][3][i][2] = (unsigned char)(255 * b);
799 }
800
801 // colorScheme 2: Grayscale (=Old grayscale)
802 for (int i = 0; i<gradientSteps; i++) {
803 float r, g, b;
804 float value = float(i)/gradientSteps;
805
806 r = g = b = 0.84 - 0.84 * value;
807
808 switch (selected) {
810 // not dimmed
811 break;
812
814 // else fall through to SAME grayscale colour as normal selection.
815 // The white lines show it up clearly enough.
816
818 // partly dimmed
819 r *= 0.75f;
820 g *= 0.75f;
821 b *= 0.75f;
822 break;
823
824
825 // For now edge colour is just black (or white if grey-scale)
826 // Later we might invert or something else funky.
828 // fully dimmed
829 r = 1.0f;
830 g = 1.0f;
831 b = 1.0f;
832 break;
833 }
834 gradient_pre[selected][2][i][0] = (unsigned char) (255 * r);
835 gradient_pre[selected][2][i][1] = (unsigned char) (255 * g);
836 gradient_pre[selected][2][i][2] = (unsigned char) (255 * b);
837 }
838 }
839}
840
842{
843 ReInit();
844 theTheme.Publish({});
845}
wxColour InvertOfColour(const wxColour &c)
Definition: AColor.cpp:509
wxColour CursorColour()
Definition: AColor.cpp:516
const int AColor_midicolors[16][3]
Definition: AColor.cpp:614
const unsigned char specColormap[256][3]
const unsigned char freqSelColormap[256][3]
const unsigned char selColormap[256][3]
int min(int a, int b)
THEME_API Theme theTheme
Definition: Theme.cpp:82
static wxBrush mediumBrush[2]
Definition: AColor.h:99
static void Arrow(wxDC &dc, wxCoord x, wxCoord y, int width, bool down=true)
Definition: AColor.cpp:167
static wxBrush labelSelectedBrush
Definition: AColor.h:123
static wxBrush darkBrush[2]
Definition: AColor.h:100
static void Solo(wxDC *dc, bool on, bool selected)
Definition: AColor.cpp:484
static void Bevel2(wxDC &dc, bool up, const wxRect &r, bool bSel=false, bool bHighlight=false)
Definition: AColor.cpp:298
static wxPen trackFocusPens[3]
Definition: AColor.h:128
static wxPen clippingPen
Definition: AColor.h:114
static wxPen WideEnvelopePen
Definition: AColor.h:117
static void IndicatorColor(wxDC *dc, bool bIsNotRecording)
Definition: AColor.cpp:446
static wxPen sparePen
Definition: AColor.h:144
static void Mute(wxDC *dc, bool on, bool selected, bool soloing)
Definition: AColor.cpp:469
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:194
@ ColorGradientTotal
Definition: AColor.h:34
@ ColorGradientUnselected
Definition: AColor.h:29
@ ColorGradientTimeAndFrequencySelected
Definition: AColor.h:31
@ ColorGradientEdge
Definition: AColor.h:32
@ ColorGradientTimeSelected
Definition: AColor.h:30
static wxColour Blend(const wxColour &c1, const wxColour &c2)
Definition: AColor.cpp:335
static void PreComputeGradient()
Definition: AColor.cpp:690
static wxBrush uglyBrush
Definition: AColor.h:141
static bool inited
Definition: AColor.h:146
static wxBrush lightBrush[2]
Definition: AColor.h:98
static wxBrush playRegionBrush[1]
Definition: AColor.h:109
static void SnapGuidePen(wxDC *dc)
Definition: AColor.cpp:462
static void CursorColor(wxDC *dc)
Definition: AColor.cpp:437
static void Lines(wxDC &dc, size_t nPoints, const wxPoint points[])
Definition: AColor.cpp:206
static wxPen labelSurroundPen
Definition: AColor.h:126
static void Bevel(wxDC &dc, bool up, const wxRect &r)
Definition: AColor.cpp:278
static wxBrush muteBrush[2]
Definition: AColor.h:111
static wxPen cursorPen
Definition: AColor.h:105
static void Light(wxDC *dc, bool selected, bool highlight=false)
Definition: AColor.cpp:395
static void LightMIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:650
static void ReInit()
Definition: AColor.cpp:501
static wxPen tooltipPen
Definition: AColor.h:131
static wxPen lightPen[2]
Definition: AColor.h:101
static wxPen mediumPen[2]
Definition: AColor.h:102
static void MediumTrackInfo(wxDC *dc, bool selected)
Definition: AColor.cpp:415
static void ApplyUpdatedImages()
Definition: AColor.cpp:841
static wxBrush envelopeBrush
Definition: AColor.h:118
static wxBrush labelTextNormalBrush
Definition: AColor.h:120
static wxBrush labelTextEditBrush
Definition: AColor.h:121
static void DrawFrame(wxDC &dc, const wxRect &r, wxBitmap &bitmap, int mid)
Definition: AColor.cpp:329
static wxPen uglyPen
Definition: AColor.h:140
static const int gradientSteps
Definition: AColor.h:136
static void DrawHStretch(wxDC &dc, const wxRect &rect, wxBitmap &bitmap)
Definition: AColor.cpp:312
static void Init()
Definition: AColor.cpp:531
static void Dark(wxDC *dc, bool selected, bool highlight=false)
Definition: AColor.cpp:421
static void Medium(wxDC *dc, bool selected)
Definition: AColor.cpp:406
static void ButtonStretch(wxDC &dc, bool up, const wxRect &r, bool selected=false, bool highlight=false)
Draw a button that fills a given rect.
Definition: AColor.cpp:289
static wxBrush labelSyncLockSelBrush
Definition: AColor.h:124
static wxPen envelopePen
Definition: AColor.h:116
static unsigned char gradient_pre[ColorGradientTotal][colorSchemes][gradientSteps][3]
Definition: AColor.h:137
static wxBrush tooltipBrush
Definition: AColor.h:132
static void MIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:634
static wxBrush indicatorBrush[2]
Definition: AColor.h:107
static void TrackFocusPen(wxDC *dc, int level)
Definition: AColor.cpp:455
static void BevelTrackInfo(wxDC &dc, bool up, const wxRect &r, bool highlight=false)
Definition: AColor.cpp:344
static void TrackPanelBackground(wxDC *dc, bool selected)
Definition: AColor.cpp:432
static wxBrush soloBrush
Definition: AColor.h:112
static wxBrush labelUnselectedBrush
Definition: AColor.h:122
static wxPen darkPen[2]
Definition: AColor.h:103
static wxPen snapGuidePen
Definition: AColor.h:129
static wxPen indicatorPen[2]
Definition: AColor.h:106
static wxBrush spareBrush
Definition: AColor.h:145
static void UseThemeColour(wxDC *dc, int iBrush, int iPen=-1, int alpha=255)
Definition: AColor.cpp:354
static void DarkMIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:668
static void DrawFocus(wxDC &dc, wxRect &r)
Definition: AColor.cpp:247
static bool gradient_inited
Definition: AColor.h:134
static wxPen labelSyncLockSelPen
Definition: AColor.h:125
CallbackReturn Publish(const Message &message)
Send a message to connected callbacks.
Definition: Observer.h:207
wxColour & Colour(int iIndex)
void SetBrushColour(wxBrush &Brush, int iIndex)
wxBitmap & Bitmap(int iIndex)
int ColourDistance(wxColour &From, wxColour &To)
Definition: Theme.cpp:285
void SetPenColour(wxPen &Pen, int iIndex)
void DrawNinePatch(wxDC &dc, wxBitmap &bitmap, const wxRect &r, int mid=1)
Definition: AColor.cpp:82
int GetButtonImageIndex(bool up, bool selected, bool highlight)
Definition: AColor.cpp:145