Audacity 3.2.0
Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Attributes | List of all members
ThemeBase Class Referenceabstract

Theme management - Image loading and saving. More...

#include <Theme.h>

Inheritance diagram for ThemeBase:
[legend]
Collaboration diagram for ThemeBase:
[legend]

Classes

struct  RegisteredTheme
 

Public Types

using NameSet = std::unordered_set< wxString >
 
- Public Types inherited from Observer::Publisher< ThemeChangeMessage >
using message_type = ThemeChangeMessage
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const ThemeChangeMessage &) >
 Type of functions that can be connected to the Publisher. More...
 

Public Member Functions

 ThemeBase (void)
 
 ThemeBase (const ThemeBase &)=delete
 
ThemeBaseoperator= (const ThemeBase &)=delete
 
virtual ~ThemeBase (void)
 
virtual void EnsureInitialised ()=0
 
FilePath GetFilePath ()
 
void SetFilePath (const FilePath &path)
 
void SwitchTheme (teThemeType Theme)
 
void LoadTheme (teThemeType Theme)
 
void RegisterImage (NameSet &allNames, int &flags, int &iIndex, char const **pXpm, const wxString &Name)
 
void RegisterImage (NameSet &allNames, int &flags, int &iIndex, const wxImage &Image, const wxString &Name)
 
void RegisterColour (NameSet &allNames, int &iIndex, const wxColour &Clr, const wxString &Name)
 
teThemeType GetFallbackThemeType ()
 
void CreateImageCache ()
 
bool CreateOneImageCache (teThemeType id, bool bBinarySave)
 
bool ReadImageCache (teThemeType type={}, bool bOkIfNotFound=false)
 
void LoadThemeComponents (bool bOkIfNotFound=false)
 
void LoadOneThemeComponents (teThemeType id, bool bOkIfNotFound=false)
 
void SaveThemeComponents ()
 
bool SaveOneThemeComponents (teThemeType id)
 
void SaveThemeAsCode ()
 
void WriteImageDefs ()
 Writes a series of Macro definitions that can be used in the include file. More...
 
void WriteImageMap ()
 
void WriteOneImageMap (teThemeType id)
 
void RecolourBitmap (int iIndex, wxColour From, wxColour To)
 
void RecolourTheme ()
 
int ColourDistance (wxColour &From, wxColour &To)
 
wxColour & Colour (int iIndex)
 
wxBitmap & Bitmap (int iIndex)
 
wxImage & Image (int iIndex)
 
wxSize ImageSize (int iIndex)
 
void ReplaceImage (int iIndex, wxImage *pImage)
 
void RotateImageInto (int iTo, int iFrom, bool bClockwise)
 
void SetBrushColour (wxBrush &Brush, int iIndex)
 
void SetPenColour (wxPen &Pen, int iIndex)
 
wxImage MaskedImage (char const **pXpm, char const **pMask)
 
wxImage MakeImageWithAlpha (wxBitmap &Bmp)
 
void DeleteUnusedThemes ()
 
- Public Member Functions inherited from Observer::Publisher< ThemeChangeMessage >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Static Public Member Functions

static bool LoadPreferredTheme ()
 

Protected Attributes

FilePath mThemeDir
 
wxArrayString mBitmapNames
 
std::vector< int > mBitmapFlags
 
wxArrayString mColourNames
 
PreferredSystemAppearance mPreferredSystemAppearance { PreferredSystemAppearance::Light }
 
std::map< Identifier, ThemeSetmSets
 
ThemeSetmpSet = nullptr
 

Additional Inherited Members

- Static Public Attributes inherited from Observer::Publisher< ThemeChangeMessage >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from Observer::Publisher< ThemeChangeMessage >
CallbackReturn Publish (const ThemeChangeMessage &message)
 Send a message to connected callbacks. More...
 

Detailed Description

Theme management - Image loading and saving.

Base for the Theme class. ThemeBase is a generic non-Audacity specific class.

See also
Themability of Audacity

Definition at line 117 of file Theme.h.

Member Typedef Documentation

◆ NameSet

using ThemeBase::NameSet = std::unordered_set<wxString>

Definition at line 152 of file Theme.h.

Constructor & Destructor Documentation

◆ ThemeBase() [1/2]

ThemeBase::ThemeBase ( void  )

Definition at line 185 of file Theme.cpp.

186{
187}

◆ ThemeBase() [2/2]

ThemeBase::ThemeBase ( const ThemeBase )
delete

◆ ~ThemeBase()

ThemeBase::~ThemeBase ( void  )
virtual

Definition at line 189 of file Theme.cpp.

190{
191}

Member Function Documentation

◆ Bitmap()

wxBitmap & ThemeBase::Bitmap ( int  iIndex)

◆ Colour()

wxColour & ThemeBase::Colour ( int  iIndex)

Referenced by AboutDialog::AboutDialog(), SelectionBar::AddTitle(), AlphaBlend(), ProjectWindow::ApplyUpdatedTheme(), ASlider::ASlider(), auStaticText::auStaticText(), AColor::BevelTrackInfo(), TrackInfo::CloseTitleDrawFunction(), CursorColour(), WaveTrackVRulerControls::DoDraw(), AdornedRulerPanel::DoDrawMarks(), AdornedRulerPanel::DoDrawPlayRegion(), AdornedRulerPanel::DoDrawPlayRegionLimits(), LabelTrackView::Draw(), NoteTrackAffordanceControls::Draw(), WaveTrackAffordanceControls::Draw(), TimeTrackVRulerControls::Draw(), Ruler::Label::Draw(), TrackInfo::DrawCloseButton(), anonymous_namespace{TimeTrackView.cpp}::DrawHorzRulerAndCurve(), TrackInfo::DrawItems(), NoteTrack::DrawLabelControls(), anonymous_namespace{NoteTrackView.cpp}::DrawNoteTrack(), FrequencyPlotDialog::DrawPlot(), LWSlider::DrawToBitmap(), anonymous_namespace{TrackPanel.cpp}::DrawTrackName(), Grabber::Grabber(), HtmlColourOfIndex(), AColor::Init(), InitProjectWindow(), NumericTextCtrl::Layout(), LoadTheme(), MixerBoard::MakeButtonBitmap(), WaveTrackAffordanceControls::MakeTextEditHelper(), TrackInfo::MinimizeSyncLockDrawFunction(), MixerBoard::MixerBoard(), ToolManager::OnIndicatorPaint(), anonymous_namespace{RealtimeEffectPanel.cpp}::RealtimeEffectControl::OnPaint(), EqualizationPanel::OnPaint(), ToolBarResizer::OnPaint(), ToolBar::OnPaint(), ToolDock::OnPaint(), NumericTextCtrl::OnPaint(), EffectAutoDuck::Panel::OnPaint(), EffectCompressorPanel::OnPaint(), EffectScienFilterPanel::OnPaint(), MixerTrackCluster::OnPaint(), MeterPanel::OnPaint(), ToolFrame::OnPaint(), ThemedWindowWrapper< WindowBase >::OnThemeChange(), ThemedButtonWrapper< ButtonBase >::OnThemeChange(), OverlayImage(), FrequencyPlotDialog::Populate(), ControlToolBar::Populate(), DeviceToolBar::Populate(), EditToolBar::Populate(), MeterToolBar::Populate(), MixerToolBar::Populate(), ScrubbingToolBar::Populate(), SelectionBar::Populate(), ToolsToolBar::Populate(), TranscriptionToolBar::Populate(), AColor::PreComputeGradient(), ProjectWindow::ProjectWindow(), RecolourTheme(), AdornedRulerPanel::ReCreateButtons(), Ruler::Ruler(), ThemedWindowWrapper< WindowBase >::SetBackgroundColorIndex(), ThemedButtonWrapper< ButtonBase >::SetBackgroundColorIndex(), ThemedWindowWrapper< WindowBase >::SetForegroundColorIndex(), ToolDock::ToolDock(), MixerBoard::UpdatePrefs(), and AColor::UseThemeColour().

◆ ColourDistance()

int ThemeBase::ColourDistance ( wxColour &  From,
wxColour &  To 
)

Definition at line 307 of file Theme.cpp.

307 {
308 return
309 abs( From.Red() - To.Red() )
310 + abs( From.Green() - To.Green() )
311 + abs( From.Blue() - To.Blue() );
312}

Referenced by CursorColour(), LoadTheme(), MeterPanel::OnPaint(), and RecolourTheme().

Here is the caller graph for this function:

◆ CreateImageCache()

void ThemeBase::CreateImageCache ( )

Definition at line 614 of file Theme.cpp.

615{
616 ValueRestorer cleanup{ mpSet };
617 for (auto &[key, data] : GetThemeCacheLookup())
618 if (!CreateOneImageCache(key.Internal(), true))
619 // Some file failed to save, message was given
620 return;
622/* i18n-hint: A theme is a consistent visual style across an application's
623graphical user interface, including choices of colors, and similarity of images
624such as those on button controls. Audacity can load and save alternative
625themes. */
626 XO("Themes written to:\n %s/*/%s.")
628}
static const AudacityProject::AttachedObjects::RegisteredFactory key
#define XO(s)
Definition: Internat.h:31
static ThemeCacheLookup & GetThemeCacheLookup()
Definition: Theme.cpp:196
Abstract base class used in importing a file.
ThemeSet * mpSet
Definition: Theme.h:207
bool CreateOneImageCache(teThemeType id, bool bBinarySave)
Definition: Theme.cpp:630
FilePath GetFilePath()
Definition: Theme.cpp:149
Set a variable temporarily in a scope.
Definition: MemoryX.h:204
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:256
constexpr auto ImageCacheFileName
Definition: Theme.cpp:118

References CreateOneImageCache(), GetFilePath(), GetThemeCacheLookup(), anonymous_namespace{Theme.cpp}::ImageCacheFileName, key, mpSet, BasicUI::ShowMessageBox(), and XO.

Referenced by ThemePrefs::OnSaveThemeCache(), and SwitchTheme().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateOneImageCache()

bool ThemeBase::CreateOneImageCache ( teThemeType  id,
bool  bBinarySave 
)

Definition at line 630 of file Theme.cpp.

631{
632 SwitchTheme( id );
633 auto &resources = *mpSet;
634
635 wxImage ImageCache( ImageCacheWidth, ImageCacheHeight );
636 ImageCache.SetRGB( wxRect( 0,0,ImageCacheWidth, ImageCacheHeight), 1,1,1);//Not-quite black.
637
638 // Ensure we have an alpha channel...
639 if( !ImageCache.HasAlpha() )
640 {
641 ImageCache.InitAlpha();
642 }
643
644 FlowPacker context{ ImageCacheWidth };
645
646//#define IMAGE_MAP
647#ifdef IMAGE_MAP
648 wxLogDebug( wxT("<img src=\"ImageCache.png\" usemap=\"#map1\">" ));
649 wxLogDebug( wxT("<map name=\"map1\">") );
650#endif
651
652 // Save the bitmaps
653 for (size_t i = 0; i < resources.mImages.size() ; ++i)
654 {
655 wxImage &SrcImage = resources.mImages[i];
656 context.mFlags = mBitmapFlags[i];
657 if( !(mBitmapFlags[i] & resFlagInternal) )
658 {
659 context.GetNextPosition( SrcImage.GetWidth(), SrcImage.GetHeight());
660 ImageCache.SetRGB( context.Rect(), 0xf2, 0xb0, 0x27 );
661 if( !(context.mFlags & resFlagSkip) )
662 PasteSubImage( &ImageCache, &SrcImage,
663 context.mxPos + context.mBorderWidth,
664 context.myPos + context.mBorderWidth);
665 else
666 ImageCache.SetRGB( context.RectInner(), 1,1,1);
667#ifdef IMAGE_MAP
668 // No href in html. Uses title not alt.
669 wxRect R( context.Rect() );
670 wxLogDebug( wxT("<area title=\"Bitmap:%s\" shape=rect coords=\"%i,%i,%i,%i\">"),
671 mBitmapNames[i],
672 R.GetLeft(), R.GetTop(), R.GetRight(), R.GetBottom() );
673#endif
674 }
675 }
676
677 // Now save the colours.
678 int x,y;
679
680 context.SetColourGroup();
681 for (size_t i = 0; i < resources.mColours.size(); ++i)
682 {
683 context.GetNextPosition( iColSize, iColSize );
684 wxColour c = resources.mColours[i];
685 ImageCache.SetRGB( context.Rect() , 0xf2, 0xb0, 0x27 );
686 ImageCache.SetRGB( context.RectInner() , c.Red(), c.Green(), c.Blue() );
687
688 // YUCK! No function in wxWidgets to set a rectangle of alpha...
689 for(x=0;x<iColSize;x++)
690 {
691 for(y=0;y<iColSize;y++)
692 {
693 ImageCache.SetAlpha( context.mxPos + x, context.myPos+y, 255);
694 }
695 }
696#ifdef IMAGE_MAP
697 // No href in html. Uses title not alt.
698 wxRect R( context.Rect() );
699 wxLogDebug( wxT("<area title=\"Colour:%s\" shape=rect coords=\"%i,%i,%i,%i\">"),
700 mColourNames[i],
701 R.GetLeft(), R.GetTop(), R.GetRight(), R.GetBottom() );
702#endif
703 }
704#if TEST_CARD
705 for ( unsigned i = 0; i < ImageCacheWidth; ++i)
706 for ( unsigned j = 0; j < ImageCacheHeight; ++j) {
707 int r = j &0xff;
708 int g = i &0xff;
709 int b = (j >> 8) | ((i>>4)&0xf0);
710 wxRect R( i,j, 1, 1);
711 ImageCache.SetRGB( R, r, g, b );
712 ImageCache.SetAlpha( i,j, 255);
713 }
714#endif
715
716#ifdef IMAGE_MAP
717 wxLogDebug( "</map>" );
718#endif
719
720 using namespace BasicUI;
721
722 // IF bBinarySave, THEN saving to a normal PNG file.
723 if( bBinarySave )
724 {
725 auto dir = ThemeSubdir(GetFilePath(), id);
726 auto FileName = wxFileName{ dir, ImageCacheFileName }.GetFullPath();
727
728 // Perhaps we should prompt the user if they are overwriting
729 // an existing theme cache?
730#if 0
731 if( wxFileExists( FileName ))
732 {
733 auto message =
734// XO(
735//"Theme cache file:\n %s\nalready exists.\nAre you sure you want to replace it?")
736// .Format( FileName );
737 TranslatableString{ FileName };
738 ShowMessageBox( message );
739 return false;
740 }
741#endif
742#if 0
743 // Deliberate policy to use the fast/cheap blocky pixel-multiplication
744 // algorithm, as this introduces no artifacts on repeated scale up/down.
745 ImageCache.Rescale(
746 ImageCache.GetWidth()*4,
747 ImageCache.GetHeight()*4,
748 wxIMAGE_QUALITY_NEAREST );
749#endif
750 if( !ImageCache.SaveFile( FileName, wxBITMAP_TYPE_PNG ))
751 {
753 XO("Audacity could not write file:\n %s.")
754 .Format( FileName ));
755 return false;
756 }
757 }
758 // ELSE saving to a C code textual version.
759 else
760 {
761 // Generated header file is not put in the sub-directory for
762 // the theme, but is instead distinguished by a prefix on the file name.
763 // So the header can simply be copied into the source code tree.
764 auto dir = GetFilePath();
765 SourceOutputStream OutStream;
767 auto FileName = wxFileName{ dir, name }.GetFullPath();
768 if( !OutStream.OpenFile( FileName ))
769 {
771 XO("Audacity could not open file:\n %s\nfor writing.")
772 .Format( FileName ));
773 return false;
774 }
775 if( !ImageCache.SaveFile(OutStream, wxBITMAP_TYPE_PNG ) )
776 {
778 XO("Audacity could not write images to file:\n %s.")
779 .Format( FileName ));
780 return false;
781 }
782 }
783 return true;
784}
const TranslatableString name
Definition: Distortion.cpp:82
void PasteSubImage(wxImage *background, wxImage *foreground, int xoff, int yoff)
const int ImageCacheWidth
Definition: Theme.cpp:610
const int ImageCacheHeight
Definition: Theme.cpp:612
@ resFlagSkip
Definition: Theme.h:65
@ resFlagInternal
Definition: Theme.h:64
A cursor for iterating the theme bitmap.
Definition: Theme.h:70
Helper class based on wxOutputStream used to get a png file in text format.
Definition: Theme.cpp:551
int OpenFile(const FilePath &Filename)
Opens the file and also adds a standard comment at the start of it.
Definition: Theme.cpp:564
void SwitchTheme(teThemeType Theme)
Definition: Theme.cpp:217
wxArrayString mBitmapNames
Definition: Theme.h:200
wxArrayString mColourNames
Definition: Theme.h:202
std::vector< int > mBitmapFlags
Definition: Theme.h:201
Holds a msgid for the translation catalog; may also bind format arguments.
constexpr auto ThemeCacheFileName
Definition: Theme.cpp:129
FilePath ThemeSubdir(const FilePath &themeDir, Identifier id)
Has the side-effect of ensuring existence of the directory.
Definition: Theme.cpp:106
wxString ThemeFilePrefix(teThemeType id)
Definition: Theme.cpp:96

References GetFilePath(), anonymous_namespace{Theme.cpp}::iColSize, anonymous_namespace{Theme.cpp}::ImageCacheFileName, ImageCacheHeight, ImageCacheWidth, mBitmapFlags, mBitmapNames, mColourNames, mpSet, name, SourceOutputStream::OpenFile(), PasteSubImage(), resFlagInternal, resFlagSkip, BasicUI::ShowMessageBox(), SwitchTheme(), anonymous_namespace{Theme.cpp}::ThemeCacheFileName, anonymous_namespace{Theme.cpp}::ThemeFilePrefix(), anonymous_namespace{Theme.cpp}::ThemeSubdir(), and XO.

Referenced by CreateImageCache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DeleteUnusedThemes()

void ThemeBase::DeleteUnusedThemes ( )

Referenced by ThemePrefs::Cancel(), GUIPrefs::Commit(), and ThemePrefs::Commit().

Here is the caller graph for this function:

◆ EnsureInitialised()

virtual void ThemeBase::EnsureInitialised ( )
pure virtual

Implemented in Theme.

Referenced by ReadImageCache(), SwitchTheme(), and WriteImageDefs().

Here is the caller graph for this function:

◆ GetFallbackThemeType()

teThemeType ThemeBase::GetFallbackThemeType ( )

Definition at line 889 of file Theme.cpp.

889 {
890// Fallback must be an internally supported type,
891// to guarantee it is found.
892#ifdef EXPERIMENTAL_DA
893 return "dark";
894#else
895 return "light";
896#endif
897}

Referenced by ThemePrefs::OnReadThemeInternal(), and SwitchTheme().

Here is the caller graph for this function:

◆ GetFilePath()

FilePath ThemeBase::GetFilePath ( )

Definition at line 149 of file Theme.cpp.

150{
151 if (mThemeDir.empty())
153 wxFileName(FileNames::DataDir(), wxT("Theme")).GetFullPath());
154 return mThemeDir;
155}
FilePath mThemeDir
Definition: Theme.h:198
void SetFilePath(const FilePath &path)
Definition: Theme.cpp:157
FILES_API FilePath DataDir()
Audacity user data directory.

References FileNames::DataDir(), mThemeDir, and SetFilePath().

Referenced by CreateImageCache(), CreateOneImageCache(), LoadOneThemeComponents(), ReadImageCache(), WriteImageDefs(), and WriteOneImageMap().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Image()

wxImage & ThemeBase::Image ( int  iIndex)

Referenced by TrackArt::DrawSyncLockTiles(), ToolBar::MakeAlternateImages(), ToolBar::MakeButton(), ToolBar::MakeMacRecoloredImage(), TrackInfo::MinimizeSyncLockDrawFunction(), OverlayImage(), ReadImageCache(), RecolourBitmap(), RegisterImage(), and ToolBarGrabber::ToolBarGrabber().

Here is the caller graph for this function:

◆ ImageSize()

wxSize ThemeBase::ImageSize ( int  iIndex)

Referenced by EditToolBar::AddButton(), ScrubbingToolBar::AddButton(), TranscriptionToolBar::AddButton(), ControlToolBar::MakeAlternateImages(), TranscriptionToolBar::MakeAlternateImages(), ControlToolBar::MakeButton(), ToolsToolBar::MakeTool(), ReadImageCache(), and AdornedRulerPanel::ReCreateButtons().

Here is the caller graph for this function:

◆ LoadOneThemeComponents()

void ThemeBase::LoadOneThemeComponents ( teThemeType  id,
bool  bOkIfNotFound = false 
)

JKC:

Bug:
(wxWidgets) A png may have been saved with alpha, but when you load it, it comes back with a mask instead! (well I guess it is more efficient). Anyway, we want alpha and not a mask, so we call InitAlpha, and that transfers the mask into the alpha channel, and we're done.

Definition at line 1043 of file Theme.cpp.

References PackedArray::begin(), anonymous_namespace{Theme.cpp}::ColorFileName, PackedArray::end(), TranslatableString::Format(), GetFilePath(), mBitmapFlags, mBitmapNames, mColourNames, mpSet, name, names, resFlagInternal, BasicUI::ShowMessageBox(), str, SwitchTheme(), anonymous_namespace{Theme.cpp}::ThemeComponent(), anonymous_namespace{Theme.cpp}::ThemeComponentsDir(), Verbatim(), and XO.

Referenced by LoadThemeComponents().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadPreferredTheme()

bool ThemeBase::LoadPreferredTheme ( )
static

Definition at line 162 of file Theme.cpp.

163{
166 return true;
167}
static ThemeBase::RegisteredTheme theme
THEME_API Theme theTheme
Definition: Theme.cpp:82
THEME_API ChoiceSetting & GUITheme()
wxString Read() const
Definition: Prefs.cpp:327
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
void LoadTheme(teThemeType Theme)
Definition: Theme.cpp:255

References GUITheme(), LoadTheme(), ChoiceSetting::Read(), theme, and theTheme.

Referenced by ThemePrefs::Cancel(), GUIPrefs::Commit(), ThemePrefs::Commit(), and AudacityApp::OnInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadTheme()

void ThemeBase::LoadTheme ( teThemeType  Theme)

This function is called to load the initial Theme images. It does not though cause the GUI to refresh.

Definition at line 255 of file Theme.cpp.

256{
258
259 // Post-processing steps after loading of the cache
260
261 // Two always overwritten images
262 RotateImageInto( bmpRecordBeside, bmpRecordBelow, false );
263 RotateImageInto( bmpRecordBesideDisabled, bmpRecordBelowDisabled, false );
264
265 // Other modifications of images happening only when the setting
266 // GUIBlendThemes is true
267 if ( mpSet->bRecolourOnLoad ) {
269
270 wxColor Back = theTheme.Colour( clrTrackInfo );
271 wxColor CurrentText = theTheme.Colour( clrTrackPanelText );
272 wxColor DesiredText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
273
274 int TextColourDifference = ColourDistance( CurrentText, DesiredText );
275
276 // Theming is very accepting of alternative text colours. They just need to
277 // have decent contrast to the background colour, if we're blending themes.
278 if ( TextColourDifference != 0 ) {
279 int ContrastLevel = ColourDistance( Back, DesiredText );
280 if ( ContrastLevel > 250 )
281 Colour( clrTrackPanelText ) = DesiredText;
282 }
283 mpSet->bRecolourOnLoad = false;
284 }
285
286
287 // Next line is not required as we haven't yet built the GUI
288 // when this function is (or should be) called.
289 // AColor::ApplyUpdatedImages();
290
291 // The next step doesn't post-process the theme data. It only modifies
292 // system settings. So it is not necessary to make it conditional on
293 // preferences, for avoidance of errors in the use of Theme preferences.
294 // (See commit 2020217)
296}
CallbackReturn Publish(const ThemeChangeMessage &message)
Send a message to connected callbacks.
Definition: Observer.h:207
wxColour & Colour(int iIndex)
void RotateImageInto(int iTo, int iFrom, bool bClockwise)
int ColourDistance(wxColour &From, wxColour &To)
Definition: Theme.cpp:307
void RecolourTheme()
Definition: Theme.cpp:317
PreferredSystemAppearance mPreferredSystemAppearance
Definition: Theme.h:204
Based on ThemeBase, Theme manages image and icon resources.
Definition: Theme.h:211
bool bRecolourOnLoad
Definition: Theme.h:108

References ThemeSet::bRecolourOnLoad, Colour(), ColourDistance(), mPreferredSystemAppearance, mpSet, Observer::Publisher< ThemeChangeMessage >::Publish(), RecolourTheme(), RotateImageInto(), SwitchTheme(), and theTheme.

Referenced by LoadPreferredTheme().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadThemeComponents()

void ThemeBase::LoadThemeComponents ( bool  bOkIfNotFound = false)

Definition at line 1036 of file Theme.cpp.

1037{
1038 ValueRestorer cleanup{ mpSet };
1039 for (auto &[key, data] : GetThemeCacheLookup())
1040 LoadOneThemeComponents( key.Internal(), bOkIfNotFound );
1041}
void LoadOneThemeComponents(teThemeType id, bool bOkIfNotFound=false)
Definition: Theme.cpp:1043

References GetThemeCacheLookup(), key, LoadOneThemeComponents(), and mpSet.

Referenced by App::OnInit(), and ThemePrefs::OnLoadThemeComponents().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeImageWithAlpha()

wxImage ThemeBase::MakeImageWithAlpha ( wxBitmap &  Bmp)

◆ MaskedImage()

wxImage ThemeBase::MaskedImage ( char const **  pXpm,
char const **  pMask 
)

Definition at line 350 of file Theme.cpp.

351{
352 wxBitmap Bmp1( pXpm );
353 wxBitmap Bmp2( pMask );
354
355// wxLogDebug( wxT("Image 1: %i Image 2: %i"),
356// Bmp1.GetDepth(), Bmp2.GetDepth() );
357
358 // We want a 24-bit-depth bitmap if all is working, but on some
359 // platforms it might just return -1 (which means best available
360 // or not relevant).
361 // JKC: \todo check that we're not relying on 24 bit elsewhere.
362 wxASSERT( Bmp1.GetDepth()==-1 || Bmp1.GetDepth()==24);
363 wxASSERT( Bmp1.GetDepth()==-1 || Bmp2.GetDepth()==24);
364
365 int i,nBytes;
366 nBytes = Bmp1.GetWidth() * Bmp1.GetHeight();
367 wxImage Img1( Bmp1.ConvertToImage());
368 wxImage Img2( Bmp2.ConvertToImage());
369
370// unsigned char *src = Img1.GetData();
371 unsigned char *mk = Img2.GetData();
372 //wxImage::setAlpha requires memory allocated with malloc, not NEW
374 static_cast<unsigned char*>(malloc( nBytes )) };
375
376 // Extract alpha channel from second XPM.
377 for(i=0;i<nBytes;i++)
378 {
379 alpha[i] = mk[0];
380 mk+=3;
381 }
382
383 Img1.SetAlpha( alpha.release() );
384
385 //dmazzoni: the top line does not work on wxGTK
386 //wxBitmap Result( Img1, 32 );
387 //wxBitmap Result( Img1 );
388
389 return Img1;
390}
std::unique_ptr< Character[], freer > MallocString
Definition: MemoryX.h:146

◆ operator=()

ThemeBase & ThemeBase::operator= ( const ThemeBase )
delete

◆ ReadImageCache()

bool ThemeBase::ReadImageCache ( teThemeType  type = {},
bool  bOkIfNotFound = false 
)

Reads an image cache including images, cursors and colours.

Parameters
typeif empty means read from an external binary file. otherwise the data is taken from a block of memory.
bOkIfNotFoundif true means do not report absent file.
Returns
true iff we loaded the images.
Todo:
revisit this hack which makes adding NEW colours easier but which prevents a colour of (1,1,1) from being added. find an alternative way to make adding NEW colours easier. e.g. initialise the background to translucent, perhaps.

Definition at line 904 of file Theme.cpp.

905{
906 auto &resources = *mpSet;
908 wxImage ImageCache;
909
910 // Ensure we have an alpha channel...
911// if( !ImageCache.HasAlpha() )
912// {
913// ImageCache.InitAlpha();
914// }
915
917
918 using namespace BasicUI;
919
920 if( type.empty() || type == "custom" )
921 {
923
924 // Take the image cache file for the theme chosen in preferences
925 auto dir = ThemeSubdir(GetFilePath(), GUITheme().Read());
926 const auto &FileName =
927 wxFileName{ dir, ImageCacheFileName }.GetFullPath();
928 if( !wxFileExists( FileName ))
929 {
930 if( bOkIfNotFound )
931 return false; // did not load the images, so return false.
933 XO("Audacity could not find file:\n %s.\nTheme not loaded.")
934 .Format( FileName ));
935 return false;
936 }
937 if( !ImageCache.LoadFile( FileName, wxBITMAP_TYPE_PNG ))
938 {
940 /* i18n-hint: Do not translate png. It is the name of a file format.*/
941 XO("Audacity could not load file:\n %s.\nBad png format perhaps?")
942 .Format( FileName ));
943 return false;
944 }
945 }
946 // ELSE we are reading from internal storage.
947 else
948 {
949 size_t ImageSize = 0;
950 const unsigned char * pImage = nullptr;
951 auto &lookup = GetThemeCacheLookup();
952 auto iter = lookup.find({type, {}});
953 if (const auto end = lookup.end(); iter == end) {
954 iter = lookup.find({"classic", {}});
955 wxASSERT(iter != end);
956 }
957
958 mPreferredSystemAppearance = iter->second.preferredSystemAppearance;
959
960 ImageSize = iter->second.data.size();
961 if (ImageSize == 0)
962 // This must be the image compiler
963 return true;
964
965 pImage = iter->second.data.data();
966 //wxLogDebug("Reading ImageCache %p size %i", pImage, ImageSize );
967 wxMemoryInputStream InternalStream( pImage, ImageSize );
968
969 if( !ImageCache.LoadFile( InternalStream, wxBITMAP_TYPE_PNG ))
970 {
971 // If we get this message, it means that the data in file
972 // was not a valid png image.
973 // Most likely someone edited it by mistake,
974 // Or some experiment is being tried with NEW formats for it.
976 XO(
977"Audacity could not read its default theme.\nPlease report the problem."));
978 return false;
979 }
980 //wxLogDebug("Read %i by %i", ImageCache.GetWidth(), ImageCache.GetHeight() );
981 }
982
983 // Resize a large image down.
984 if( ImageCache.GetWidth() > ImageCacheWidth ){
985 int h = ImageCache.GetHeight() * ((1.0*ImageCacheWidth)/ImageCache.GetWidth());
986 ImageCache.Rescale( ImageCacheWidth, h );
987 }
988 FlowPacker context{ ImageCacheWidth };
989 // Load the bitmaps
990 for (size_t i = 0; i < resources.mImages.size(); ++i)
991 {
992 wxImage &Image = resources.mImages[i];
993 context.mFlags = mBitmapFlags[i];
994 if( !(mBitmapFlags[i] & resFlagInternal) )
995 {
996 context.GetNextPosition( Image.GetWidth(),Image.GetHeight() );
997 wxRect R = context.RectInner();
998 //wxLogDebug( "[%i, %i, %i, %i, \"%s\"], ", R.x, R.y, R.width, R.height, mBitmapNames[i].c_str() );
999 Image = GetSubImageWithAlpha( ImageCache, context.RectInner() );
1000 resources.mBitmaps[i] = wxBitmap(Image);
1001 }
1002 }
1003 if( !ImageCache.HasAlpha() )
1004 ImageCache.InitAlpha();
1005
1006// return true; //To not load colours..
1007 // Now load the colours.
1008 int x,y;
1009 context.SetColourGroup();
1010 wxColour TempColour;
1011 for (size_t i = 0; i < resources.mColours.size(); ++i)
1012 {
1013 context.GetNextPosition( iColSize, iColSize );
1014 context.RectMid( x, y );
1015 wxRect R = context.RectInner();
1016 //wxLogDebug( "[%i, %i, %i, %i, \"%s\"], ", R.x, R.y, R.width, R.height, mColourNames[i].c_str() );
1017 // Only change the colour if the alpha is opaque.
1018 // This allows us to add NEW colours more easily.
1019 if( ImageCache.GetAlpha(x,y ) > 128 )
1020 {
1021 TempColour = wxColour(
1022 ImageCache.GetRed( x,y),
1023 ImageCache.GetGreen( x,y),
1024 ImageCache.GetBlue(x,y));
1029 if( TempColour != wxColour(1,1,1) )
1030 resources.mColours[i] = TempColour;
1031 }
1032 }
1033 return true;
1034}
wxImage GetSubImageWithAlpha(const wxImage &Src, const wxRect &rect)
gPrefs Read(wxT("/GUI/VerticalZooming"), &bVZoom, false)
THEME_API BoolSetting GUIBlendThemes
bool empty() const
Definition: Identifier.h:61
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:185
wxImage & Image(int iIndex)
virtual void EnsureInitialised()=0
wxSize ImageSize(int iIndex)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159

References ThemeSet::bRecolourOnLoad, Identifier::empty(), PackedArray::end(), EnsureInitialised(), GetFilePath(), GetSubImageWithAlpha(), GetThemeCacheLookup(), GUIBlendThemes, GUITheme(), anonymous_namespace{Theme.cpp}::iColSize, Image(), anonymous_namespace{Theme.cpp}::ImageCacheFileName, ImageCacheWidth, ImageSize(), Light, mBitmapFlags, mPreferredSystemAppearance, mpSet, Setting< T >::Read(), Read(), resFlagInternal, BasicUI::ShowMessageBox(), anonymous_namespace{Theme.cpp}::ThemeSubdir(), and XO.

Referenced by SwitchTheme().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RecolourBitmap()

void ThemeBase::RecolourBitmap ( int  iIndex,
wxColour  From,
wxColour  To 
)

Definition at line 298 of file Theme.cpp.

299{
300 wxImage Image( Bitmap( iIndex ).ConvertToImage() );
301
302 std::unique_ptr<wxImage> pResult = ChangeImageColour(
303 &Image, From, To );
304 ReplaceImage( iIndex, pResult.get() );
305}
std::unique_ptr< wxImage > ChangeImageColour(wxImage *srcImage, wxColour &dstColour)
wxBitmap & Bitmap(int iIndex)
void ReplaceImage(int iIndex, wxImage *pImage)

References Bitmap(), ChangeImageColour(), Image(), and ReplaceImage().

Referenced by RecolourTheme().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RecolourTheme()

void ThemeBase::RecolourTheme ( )

Definition at line 317 of file Theme.cpp.

318{
319 wxColour From = Colour( clrMedium );
320#if defined( __WXGTK__ )
321 wxColour To = wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND );
322#else
323 wxColour To = wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE );
324#endif
325 // only recolour if recolouring is slight.
326 int d = ColourDistance( From, To );
327
328 // Don't recolour if difference is too big.
329 if( d > 120 )
330 return;
331
332 // A minor tint difference from standard does not need
333 // to be recouloured either. Includes case of d==0 which is nothing
334 // needs to be done.
335 if( d < 40 )
336 return;
337
338 Colour( clrMedium ) = To;
339 RecolourBitmap( bmpUpButtonLarge, From, To );
340 RecolourBitmap( bmpDownButtonLarge, From, To );
341 RecolourBitmap( bmpHiliteButtonLarge, From, To );
342 RecolourBitmap( bmpUpButtonSmall, From, To );
343 RecolourBitmap( bmpDownButtonSmall, From, To );
344 RecolourBitmap( bmpHiliteButtonSmall, From, To );
345
346 Colour( clrTrackInfo ) = To;
347 RecolourBitmap( bmpUpButtonExpand, From, To );
348}
void RecolourBitmap(int iIndex, wxColour From, wxColour To)
Definition: Theme.cpp:298

References Colour(), ColourDistance(), and RecolourBitmap().

Referenced by LoadTheme().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RegisterColour()

void ThemeBase::RegisterColour ( NameSet allNames,
int &  iIndex,
const wxColour &  Clr,
const wxString &  Name 
)

Definition at line 449 of file Theme.cpp.

451{
452 auto &resources = *mpSet;
453 resources.mColours.push_back( Clr );
454 auto index = resources.mColours.size() - 1;
455 if (iIndex == -1) {
456 // First time assignment of global variable identifying a colour
457 iIndex = index;
458 mColourNames.push_back( Name );
459 wxASSERT(allNames.insert(Name).second);
460 }
461 else {
462 // If revisiting for another theme set,
463 // colours should be re-done in the same sequence
464 wxASSERT(iIndex == index);
465 wxASSERT(mColourNames[index] == Name);
466 }
467}
std::vector< wxColour > mColours
Definition: Theme.h:105

References mColourNames, ThemeSet::mColours, and mpSet.

◆ RegisterImage() [1/2]

void ThemeBase::RegisterImage ( NameSet allNames,
int &  flags,
int &  iIndex,
char const **  pXpm,
const wxString &  Name 
)

Definition at line 396 of file Theme.cpp.

398{
399 wxBitmap Bmp( pXpm );
400 wxImage Img( Bmp.ConvertToImage() );
401 // The next line recommended by http://forum.audacityteam.org/viewtopic.php?f=50&t=96765
402 Img.SetMaskColour(0xDE, 0xDE, 0xDE);
403 Img.InitAlpha();
404
405 //dmazzoni: the top line does not work on wxGTK
406 //wxBitmap Bmp2( Img, 32 );
407 //wxBitmap Bmp2( Img );
408
409 RegisterImage( allNames, flags, iIndex, Img, Name );
410}
void RegisterImage(NameSet &allNames, int &flags, int &iIndex, char const **pXpm, const wxString &Name)
Definition: Theme.cpp:396

References RegisterImage().

Referenced by RegisterImage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RegisterImage() [2/2]

void ThemeBase::RegisterImage ( NameSet allNames,
int &  flags,
int &  iIndex,
const wxImage &  Image,
const wxString &  Name 
)

Definition at line 412 of file Theme.cpp.

414{
415 auto &resources = *mpSet;
416 resources.mImages.push_back( Image );
417
418#ifdef __APPLE__
419 // On Mac, bitmaps with alpha don't work.
420 // So we convert to a mask and use that.
421 // It isn't quite as good, as alpha gives smoother edges.
422 //[Does not affect the large control buttons, as for those we do
423 // the blending ourselves anyway.]
424 wxImage TempImage( Image );
425 TempImage.ConvertAlphaToMask();
426 resources.mBitmaps.push_back( wxBitmap( TempImage ) );
427#else
428 resources.mBitmaps.push_back( wxBitmap( Image ) );
429#endif
430
431 flags &= ~resFlagSkip;
432 auto index = resources.mBitmaps.size() - 1;
433 if (iIndex == -1) {
434 // First time assignment of global variable identifying an image
435 iIndex = index;
436 mBitmapNames.push_back( Name );
437 mBitmapFlags.push_back( flags );
438 wxASSERT(allNames.insert(Name).second);
439 }
440 else {
441 // If revisiting for another theme set,
442 // images should be re-done in the same sequence
443 wxASSERT(iIndex == index);
444 wxASSERT(mBitmapNames[index] == Name);
445 wxASSERT(mBitmapFlags[index] == flags);
446 }
447}
std::vector< wxImage > mImages
Definition: Theme.h:103

References Image(), mBitmapFlags, mBitmapNames, ThemeSet::mImages, and mpSet.

Here is the call graph for this function:

◆ ReplaceImage()

void ThemeBase::ReplaceImage ( int  iIndex,
wxImage *  pImage 
)

Referenced by ToolBar::MakeMacRecoloredImage(), and RecolourBitmap().

Here is the caller graph for this function:

◆ RotateImageInto()

void ThemeBase::RotateImageInto ( int  iTo,
int  iFrom,
bool  bClockwise 
)

Referenced by LoadTheme().

Here is the caller graph for this function:

◆ SaveOneThemeComponents()

bool ThemeBase::SaveOneThemeComponents ( teThemeType  id)

◆ SaveThemeAsCode()

void ThemeBase::SaveThemeAsCode ( )

Referenced by App::OnInit(), and ThemePrefs::OnSaveThemeAsCode().

Here is the caller graph for this function:

◆ SaveThemeComponents()

void ThemeBase::SaveThemeComponents ( )

Referenced by ThemePrefs::OnSaveThemeComponents().

Here is the caller graph for this function:

◆ SetBrushColour()

void ThemeBase::SetBrushColour ( wxBrush &  Brush,
int  iIndex 
)

Referenced by AColor::Init(), NumericTextCtrl::Layout(), NumericTextCtrl::OnPaint(), and TrackArtist::SetColours().

Here is the caller graph for this function:

◆ SetFilePath()

void ThemeBase::SetFilePath ( const FilePath path)

Definition at line 157 of file Theme.cpp.

158{
159 mThemeDir = path;
160}

References mThemeDir.

Referenced by GetFilePath(), and main().

Here is the caller graph for this function:

◆ SetPenColour()

void ThemeBase::SetPenColour ( wxPen &  Pen,
int  iIndex 
)

Referenced by AColor::Init(), NumericTextCtrl::OnPaint(), and TrackArtist::SetColours().

Here is the caller graph for this function:

◆ SwitchTheme()

void ThemeBase::SwitchTheme ( teThemeType  Theme)

Definition at line 217 of file Theme.cpp.

218{
219 // Switch the active theme set
220 mpSet = &mSets[Theme.empty() ? GUITheme().Read() : Theme];
221 auto &resources = *mpSet;
223
224 const bool cbOkIfNotFound = true;
225
226 if( !ReadImageCache( Theme, cbOkIfNotFound ) )
227 {
228 // THEN get the default set.
229 ReadImageCache( GetFallbackThemeType(), !cbOkIfNotFound );
230
231 // JKC: Now we could go on and load the individual images
232 // on top of the default images using the commented out
233 // code that follows...
234 //
235 // However, I think it is better to get the user to
236 // build a NEW image cache, which they can do easily
237 // from the Theme preferences tab.
238#if 0
239 // and now add any available component images.
240 LoadComponents( cbOkIfNotFound );
241
242 // JKC: I'm usure about doing this next step automatically.
243 // Suppose the disk is write protected?
244 // Is having the image cache created automatically
245 // going to confuse users? Do we need version specific names?
246 // and now save the combined image as a cache for later use.
247 // We should load the images a little faster in future as a result.
249#endif
250 }
251}
teThemeType GetFallbackThemeType()
Definition: Theme.cpp:889
std::map< Identifier, ThemeSet > mSets
Definition: Theme.h:206
bool ReadImageCache(teThemeType type={}, bool bOkIfNotFound=false)
Definition: Theme.cpp:904
void CreateImageCache()
Definition: Theme.cpp:614

References CreateImageCache(), EnsureInitialised(), GetFallbackThemeType(), GUITheme(), mpSet, mSets, ChoiceSetting::Read(), and ReadImageCache().

Referenced by CreateOneImageCache(), LoadOneThemeComponents(), LoadTheme(), ThemePrefs::OnLoadThemeCache(), ThemePrefs::OnReadThemeInternal(), and WriteOneImageMap().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteImageDefs()

void ThemeBase::WriteImageDefs ( )

Writes a series of Macro definitions that can be used in the include file.

Definition at line 847 of file Theme.cpp.

848{
849 // The generated image defs macro calls depend only on sizes of images,
850 // not contents, and so there is only one file good across all themes.
851
852 auto &resources = *mpSet;
854
855 wxFFile File( ThemeImageDefsAsCee(GetFilePath()), wxT("wb") );
856 if( !File.IsOpened() )
857 return;
858 teResourceFlags PrevFlags = (teResourceFlags)-1;
859 for (size_t i = 0; i < resources.mImages.size(); ++i)
860 {
861 wxImage &SrcImage = resources.mImages[i];
862 // No href in html. Uses title not alt.
863 if( PrevFlags != mBitmapFlags[i] )
864 {
865 PrevFlags = (teResourceFlags)mBitmapFlags[i];
866 int t = (int)PrevFlags;
867 wxString Temp;
868 if( t==0 ) Temp = wxT(" resFlagNone ");
869 if( t & resFlagPaired ) Temp += wxT(" resFlagPaired ");
870 if( t & resFlagCursor ) Temp += wxT(" resFlagCursor ");
871 if( t & resFlagNewLine ) Temp += wxT(" resFlagNewLine ");
872 if( t & resFlagInternal ) Temp += wxT(" resFlagInternal ");
873 Temp.Replace( wxT(" "), wxT(" | ") );
874
875 File.Write( wxString::Format( wxT("\r\n SET_THEME_FLAGS( %s );\r\n"),
876 Temp ));
877 }
878 File.Write( wxString::Format(
879 wxT(" DEFINE_IMAGE( bmp%s, wxImage( %i, %i ), wxT(\"%s\"));\r\n"),
880 mBitmapNames[i],
881 SrcImage.GetWidth(),
882 SrcImage.GetHeight(),
883 mBitmapNames[i]
884 ));
885 }
886}
teResourceFlags
Definition: Theme.h:59
@ resFlagNewLine
Definition: Theme.h:63
@ resFlagPaired
Definition: Theme.h:61
@ resFlagCursor
Definition: Theme.h:62
FilePath ThemeImageDefsAsCee(const FilePath &themeDir)
Definition: Theme.cpp:124

References EnsureInitialised(), GetFilePath(), mBitmapFlags, mBitmapNames, mpSet, resFlagCursor, resFlagInternal, resFlagNewLine, resFlagPaired, and anonymous_namespace{Theme.cpp}::ThemeImageDefsAsCee().

Referenced by ThemePrefs::OnSaveThemeAsCode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteImageMap()

void ThemeBase::WriteImageMap ( )

Definition at line 786 of file Theme.cpp.

787{
788 ValueRestorer cleanup{ mpSet };
789 for (auto &[key, data] : GetThemeCacheLookup())
790 WriteOneImageMap(key.Internal());
791}
void WriteOneImageMap(teThemeType id)
Definition: Theme.cpp:795

References GetThemeCacheLookup(), key, mpSet, and WriteOneImageMap().

Referenced by ThemePrefs::OnSaveThemeCache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteOneImageMap()

void ThemeBase::WriteOneImageMap ( teThemeType  id)

Writes an html file with an image map of the ImageCache Very handy for seeing what each part is for.

Definition at line 795 of file Theme.cpp.

796{
797 SwitchTheme( id );
798 auto &resources = *mpSet;
799
800 FlowPacker context{ ImageCacheWidth };
801
802 auto dir = ThemeSubdir(GetFilePath(), id);
803 auto FileName = wxFileName{ dir, ImageMapFileName }.GetFullPath();
804 wxFFile File( FileName, wxT("wb") );// I'll put in NEW lines explicitly.
805 if( !File.IsOpened() )
806 return;
807
808 File.Write( wxT("<html>\r\n"));
809 File.Write( wxT("<body bgcolor=\"303030\">\r\n"));
810 wxString Temp = wxString::Format( wxT("<img src=\"ImageCache.png\" width=\"%i\" usemap=\"#map1\">\r\n" ), ImageCacheWidth );
811 File.Write( Temp );
812 File.Write( wxT("<map name=\"map1\">\r\n") );
813
814 for (size_t i = 0; i < resources.mImages.size(); ++i)
815 {
816 wxImage &SrcImage = resources.mImages[i];
817 context.mFlags = mBitmapFlags[i];
818 if( !(mBitmapFlags[i] & resFlagInternal) )
819 {
820 context.GetNextPosition( SrcImage.GetWidth(), SrcImage.GetHeight());
821 // No href in html. Uses title not alt.
822 wxRect R( context.RectInner() );
823 File.Write( wxString::Format(
824 wxT("<area title=\"Bitmap:%s\" shape=rect coords=\"%i,%i,%i,%i\">\r\n"),
825 mBitmapNames[i],
826 R.GetLeft(), R.GetTop(), R.GetRight(), R.GetBottom()) );
827 }
828 }
829 // Now save the colours.
830 context.SetColourGroup();
831 for (size_t i = 0; i < resources.mColours.size(); ++i)
832 {
833 context.GetNextPosition( iColSize, iColSize );
834 // No href in html. Uses title not alt.
835 wxRect R( context.RectInner() );
836 File.Write( wxString::Format( wxT("<area title=\"Colour:%s\" shape=rect coords=\"%i,%i,%i,%i\">\r\n"),
837 mColourNames[i],
838 R.GetLeft(), R.GetTop(), R.GetRight(), R.GetBottom()) );
839 }
840 File.Write( wxT("</map>\r\n") );
841 File.Write( wxT("</body>\r\n"));
842 File.Write( wxT("</html>\r\n"));
843 // File will be closed automatically.
844}
constexpr auto ImageMapFileName
Definition: Theme.cpp:120

References GetFilePath(), anonymous_namespace{Theme.cpp}::iColSize, ImageCacheWidth, anonymous_namespace{Theme.cpp}::ImageMapFileName, mBitmapFlags, mBitmapNames, mColourNames, mpSet, resFlagInternal, SwitchTheme(), and anonymous_namespace{Theme.cpp}::ThemeSubdir().

Referenced by WriteImageMap().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mBitmapFlags

std::vector<int> ThemeBase::mBitmapFlags
protected

◆ mBitmapNames

wxArrayString ThemeBase::mBitmapNames
protected

◆ mColourNames

wxArrayString ThemeBase::mColourNames
protected

◆ mPreferredSystemAppearance

PreferredSystemAppearance ThemeBase::mPreferredSystemAppearance { PreferredSystemAppearance::Light }
protected

Definition at line 204 of file Theme.h.

Referenced by LoadTheme(), and ReadImageCache().

◆ mpSet

ThemeSet* ThemeBase::mpSet = nullptr
protected

◆ mSets

std::map<Identifier, ThemeSet> ThemeBase::mSets
protected

Definition at line 206 of file Theme.h.

Referenced by SwitchTheme().

◆ mThemeDir

FilePath ThemeBase::mThemeDir
protected

Definition at line 198 of file Theme.h.

Referenced by GetFilePath(), and SetFilePath().


The documentation for this class was generated from the following files: