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