mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
415 lines
14 KiB
C++
415 lines
14 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2015 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
|
* This project is released under the MIT License.
|
|
*/
|
|
#if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI)
|
|
#include <iostream>
|
|
#include "SkinHelper.h"
|
|
#include "GDCore/IDE/wxTools/AuiTabArt.h"
|
|
#include "GDCore/IDE/wxTools/FlatAuiTabArt.h"
|
|
#include "GDCore/CommonTools.h"
|
|
#include "GDCore/IDE/wxTools/RibbonMetroArtProvider.h"
|
|
#include <wx/ribbon/bar.h>
|
|
#include <wx/ribbon/art.h>
|
|
#include <wx/aui/aui.h>
|
|
#include <wx/aui/auibar.h>
|
|
#include <wx/propgrid/propgrid.h>
|
|
#include <wx/config.h>
|
|
#include <wx/dcbuffer.h>
|
|
#include <wx/settings.h>
|
|
#include "GDCore/Tools/Log.h"
|
|
|
|
namespace gd
|
|
{
|
|
|
|
std::map<gd::String, wxBitmap*> SkinHelper::cachedIcons;
|
|
|
|
/** \brief Internal art provider providing a nice help button instead of the default one.
|
|
*/
|
|
class gdRibbonMSWArtProvider : public wxRibbonMSWArtProvider
|
|
{
|
|
public:
|
|
gdRibbonMSWArtProvider() : wxRibbonMSWArtProvider(), helpBitmap(gd::SkinHelper::GetIcon("help", 16)) {};
|
|
virtual ~gdRibbonMSWArtProvider() {};
|
|
wxRibbonArtProvider* Clone() const { return new gdRibbonMSWArtProvider(*this); };
|
|
|
|
/** A mere copy of the original implementation, with a custom bitmap used instead of the default one.
|
|
*/
|
|
void DrawHelpButton(wxDC& dc, wxRibbonBar* wnd, const wxRect& rect)
|
|
{
|
|
DrawPartialPageBackground(dc, wnd, rect, false);
|
|
|
|
dc.DestroyClippingRegion();
|
|
dc.SetClippingRegion(rect);
|
|
|
|
if ( wnd->IsHelpButtonHovered() )
|
|
{
|
|
dc.SetPen(m_ribbon_toggle_pen);
|
|
dc.SetBrush(m_ribbon_toggle_brush);
|
|
dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 20, 20, 1.0);
|
|
dc.DrawBitmap(helpBitmap, rect.GetX ()+2, rect.GetY()+2, true);
|
|
}
|
|
else
|
|
{
|
|
dc.DrawBitmap(helpBitmap, rect.GetX ()+2, rect.GetY()+2, true);
|
|
}
|
|
|
|
}
|
|
|
|
wxBitmap helpBitmap;
|
|
};
|
|
|
|
/** \brief Internal art provider providing a nice help button instead of the default one.
|
|
*/
|
|
class gdRibbonAUIArtProvider : public wxRibbonAUIArtProvider
|
|
{
|
|
public:
|
|
gdRibbonAUIArtProvider() : wxRibbonAUIArtProvider(), helpBitmap(gd::SkinHelper::GetIcon("help", 16)) {};
|
|
virtual ~gdRibbonAUIArtProvider() {};
|
|
wxRibbonArtProvider* Clone() const { return new gdRibbonAUIArtProvider(*this); };
|
|
|
|
/** A mere copy of the original implementation, with a custom bitmap used instead of the default one.
|
|
*/
|
|
void DrawHelpButton(wxDC& dc, wxRibbonBar* wnd, const wxRect& rect)
|
|
{
|
|
DrawPartialPageBackground(dc, wnd, rect, false);
|
|
|
|
dc.DestroyClippingRegion();
|
|
dc.SetClippingRegion(rect);
|
|
|
|
if ( wnd->IsHelpButtonHovered() )
|
|
{
|
|
dc.SetPen(m_ribbon_toggle_pen);
|
|
dc.SetBrush(m_ribbon_toggle_brush);
|
|
dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 20, 20, 1.0);
|
|
dc.DrawBitmap(helpBitmap, rect.GetX ()+2, rect.GetY()+2, true);
|
|
}
|
|
else
|
|
{
|
|
dc.DrawBitmap(helpBitmap, rect.GetX ()+2, rect.GetY()+2, true);
|
|
}
|
|
|
|
}
|
|
|
|
wxBitmap helpBitmap;
|
|
};
|
|
|
|
void SkinHelper::ApplyCurrentSkin(wxRibbonBar & bar)
|
|
{
|
|
wxConfigBase *pConfig = wxConfigBase::Get();
|
|
wxString result;
|
|
pConfig->Read( _T( "/Skin/RDefined" ), &result );
|
|
|
|
//Ribbon skin
|
|
if ( result == "true" )
|
|
{
|
|
int r = 120, v = 120, b = 120;
|
|
int r2 = 120, v2 = 120, b2 = 120;
|
|
|
|
wxRibbonArtProvider * ribbonArtProvider = NULL;
|
|
pConfig->Read( _T( "/Skin/RibbonStyle" ), &result );
|
|
|
|
//Style
|
|
if ( result == "AUI" )
|
|
ribbonArtProvider = new gdRibbonAUIArtProvider;
|
|
else if ( result == "Metro" )
|
|
ribbonArtProvider = new RibbonMetroArtProvider;
|
|
else
|
|
ribbonArtProvider = new gdRibbonMSWArtProvider;
|
|
|
|
bar.SetArtProvider(ribbonArtProvider);
|
|
|
|
//Colors
|
|
pConfig->Read( _T( "/Skin/Ribbon1R" ), &r );
|
|
pConfig->Read( _T( "/Skin/Ribbon1G" ), &v );
|
|
pConfig->Read( _T( "/Skin/Ribbon1B" ), &b );
|
|
|
|
pConfig->Read( _T( "/Skin/Ribbon2R" ), &r2 );
|
|
pConfig->Read( _T( "/Skin/Ribbon2G" ), &v2 );
|
|
pConfig->Read( _T( "/Skin/Ribbon2B" ), &b2 );
|
|
|
|
wxColour colour, secondary, tertiary;
|
|
bar.GetArtProvider()->GetColourScheme(&colour, &secondary, &tertiary);
|
|
bar.GetArtProvider()->SetColourScheme(wxColour(r, v, b), wxColour(r2, v2, b2), wxColour(0, 0, 0));
|
|
|
|
}
|
|
else
|
|
{
|
|
bar.SetArtProvider(new RibbonMetroArtProvider);
|
|
bar.GetArtProvider()->SetColourScheme(wxColour(245, 245, 245), wxColour(196, 203, 255), wxColour(0, 0, 0));
|
|
}
|
|
}
|
|
|
|
void SkinHelper::ApplyCurrentSkin(wxAuiManager & auiManager)
|
|
{
|
|
wxConfigBase *pConfig = wxConfigBase::Get();
|
|
wxString result;
|
|
|
|
//DockArt skin
|
|
wxAuiDefaultDockArt *dockArt = new wxAuiDefaultDockArt();
|
|
pConfig->Read( _T( "/Skin/Defined" ), &result );
|
|
dockArt->SetFont(wxAUI_DOCKART_CAPTION_FONT, wxFont(10, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE));
|
|
if ( result == "true" )
|
|
{
|
|
int r = 120, v = 120, b = 120;
|
|
|
|
pConfig->Read( _T( "/Skin/PaneA1R" ), &r );
|
|
pConfig->Read( _T( "/Skin/PaneA1G" ), &v );
|
|
pConfig->Read( _T( "/Skin/PaneA1B" ), &b );
|
|
dockArt->SetColour( 7, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/PaneA2R" ), &r );
|
|
pConfig->Read( _T( "/Skin/PaneA2G" ), &v );
|
|
pConfig->Read( _T( "/Skin/PaneA2B" ), &b );
|
|
dockArt->SetColour( 8, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/PaneI1R" ), &r );
|
|
pConfig->Read( _T( "/Skin/PaneI1G" ), &v );
|
|
pConfig->Read( _T( "/Skin/PaneI1B" ), &b );
|
|
dockArt->SetColour( 9, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/PaneI2R" ), &r );
|
|
pConfig->Read( _T( "/Skin/PaneI2G" ), &v );
|
|
pConfig->Read( _T( "/Skin/PaneI2B" ), &b );
|
|
dockArt->SetColour( 10, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/BorderR" ), &r );
|
|
pConfig->Read( _T( "/Skin/BorderG" ), &v );
|
|
pConfig->Read( _T( "/Skin/BorderB" ), &b );
|
|
dockArt->SetColour( 13, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/BackR" ), &r );
|
|
pConfig->Read( _T( "/Skin/BackG" ), &v );
|
|
pConfig->Read( _T( "/Skin/BackB" ), &b );
|
|
dockArt->SetColour( 6, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/ATextR" ), &r );
|
|
pConfig->Read( _T( "/Skin/ATextG" ), &v );
|
|
pConfig->Read( _T( "/Skin/ATextB" ), &b );
|
|
dockArt->SetColour( 11, wxColour( r, v, b ) );
|
|
|
|
pConfig->Read( _T( "/Skin/ITextR" ), &r );
|
|
pConfig->Read( _T( "/Skin/ITextG" ), &v );
|
|
pConfig->Read( _T( "/Skin/ITextB" ), &b );
|
|
dockArt->SetColour( 12, wxColour( r, v, b ) );
|
|
}
|
|
else
|
|
{
|
|
dockArt->SetColour(7, wxColour(145,0,206)); //Active tab
|
|
dockArt->SetColour(8, wxColour(145,0,206));
|
|
dockArt->SetColour(9, wxColour(145,0,206)); //Inactive tab
|
|
dockArt->SetColour(10, wxColour(145,0,206));
|
|
dockArt->SetColour(13, wxColour(236,236,236)); //Border
|
|
dockArt->SetColour(6, wxColour(236,236,236)); //Background color
|
|
dockArt->SetColour(11, wxColour(255,255,255)); //Active text color
|
|
dockArt->SetColour(12, wxColour(255,255,255)); //Inactive text color
|
|
}
|
|
dockArt->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxSystemSettings::GetColour(wxSYS_COLOUR_MENU));
|
|
|
|
auiManager.SetArtProvider(dockArt);
|
|
}
|
|
|
|
void SkinHelper::ApplyCurrentSkin(wxAuiNotebook & notebook, bool subnotebook)
|
|
{
|
|
wxConfigBase *pConfig = wxConfigBase::Get();
|
|
wxString result;
|
|
|
|
wxAuiTabArt * tabArt = NULL;
|
|
pConfig->Read( _T( "/Skin/TabStyle" ), &result );
|
|
if ( result == "Classic" )
|
|
{
|
|
gd::AuiTabArt * art = new gd::AuiTabArt();
|
|
art->DisableBackgroundGradient(subnotebook);
|
|
tabArt = art;
|
|
}
|
|
else
|
|
{
|
|
gd::FlatAuiTabArt * art = new gd::FlatAuiTabArt();
|
|
art->DisableBackgroundGradient(subnotebook);
|
|
tabArt = art;
|
|
}
|
|
|
|
pConfig->Read( _T( "/Skin/Defined" ), &result );
|
|
if ( result == "true" )
|
|
{
|
|
wxColor tabColor;
|
|
pConfig->Read( _T( "/Skin/TabColor" ), &tabColor );
|
|
tabArt->SetColour(tabColor);
|
|
|
|
wxColor activeTabColor;
|
|
pConfig->Read( _T( "/Skin/ActiveTabColor" ), &activeTabColor );
|
|
tabArt->SetActiveColour(activeTabColor);
|
|
}
|
|
else
|
|
{
|
|
tabArt->SetColour(wxColour(239,239,239));
|
|
tabArt->SetActiveColour(wxColour(255, 255, 255));
|
|
}
|
|
|
|
notebook.SetArtProvider(tabArt);
|
|
}
|
|
|
|
class AuiToolBarArt : public wxAuiDefaultToolBarArt
|
|
{
|
|
public:
|
|
|
|
AuiToolBarArt() : wxAuiDefaultToolBarArt() {};
|
|
virtual ~AuiToolBarArt() {};
|
|
|
|
virtual wxAuiToolBarArt* Clone() { return static_cast<wxAuiToolBarArt*>(new AuiToolBarArt); };
|
|
|
|
void SetBaseColour(wxColour baseColour)
|
|
{
|
|
m_baseColour = baseColour;
|
|
}
|
|
|
|
virtual void DrawBackground( wxDC& dc, wxWindow* wnd, const wxRect& rect_)
|
|
{
|
|
//Defines the two rectangles for gradient
|
|
wxRect rect1 = rect_;
|
|
rect1.height /= 3;
|
|
wxRect rect2 = rect_;
|
|
rect2.y += rect1.height;
|
|
rect2.height = rect2.height*2.0/3.0+1;
|
|
|
|
wxColour startColour = m_baseColour.ChangeLightness(165);
|
|
wxColour intermediateColour = m_baseColour.ChangeLightness(140);
|
|
wxColour endColour = m_baseColour.ChangeLightness(125);
|
|
intermediateColour.Set(intermediateColour.Red()-10,intermediateColour.Green()-10, intermediateColour.Blue()+10);
|
|
|
|
dc.GradientFillLinear(rect1, startColour, intermediateColour, wxSOUTH);
|
|
dc.GradientFillLinear(rect2, intermediateColour, endColour, wxSOUTH);
|
|
}
|
|
};
|
|
|
|
class FlatAuiToolBarArt : public wxAuiDefaultToolBarArt
|
|
{
|
|
public:
|
|
|
|
FlatAuiToolBarArt() : wxAuiDefaultToolBarArt() {};
|
|
virtual ~FlatAuiToolBarArt() {};
|
|
|
|
virtual wxAuiToolBarArt* Clone() { return static_cast<wxAuiToolBarArt*>(new FlatAuiToolBarArt); };
|
|
|
|
void SetBaseColour(wxColour baseColour)
|
|
{
|
|
m_baseColour = baseColour;
|
|
}
|
|
|
|
virtual void DrawBackground( wxDC& dc, wxWindow* wnd, const wxRect& rect_)
|
|
{
|
|
wxColour startColour = m_baseColour.ChangeLightness(165);
|
|
dc.GradientFillLinear(rect_, startColour, startColour, wxSOUTH);
|
|
}
|
|
};
|
|
|
|
void SkinHelper::ApplyCurrentSkin(wxAuiToolBar & toolbar)
|
|
{
|
|
wxConfigBase *pConfig = wxConfigBase::Get();
|
|
wxString result = "Flat";
|
|
|
|
//DockArt skin
|
|
pConfig->Read( _T( "/Skin/ToolbarStyle" ), &result );
|
|
wxColor baseColor;
|
|
pConfig->Read( _T( "/Skin/ToolbarCustomColor" ), &baseColor );
|
|
|
|
bool toolbarCustomColor = false;
|
|
pConfig->Read( _T( "/Skin/ToolbarHasCustomColor" ), &toolbarCustomColor );
|
|
|
|
if ( result == "Flat" )
|
|
{
|
|
FlatAuiToolBarArt * art = new FlatAuiToolBarArt;
|
|
if ( toolbarCustomColor ) art->SetBaseColour(baseColor);
|
|
toolbar.SetArtProvider(art);
|
|
}
|
|
else
|
|
{
|
|
AuiToolBarArt * art = new AuiToolBarArt;
|
|
if ( toolbarCustomColor ) art->SetBaseColour(baseColor);
|
|
toolbar.SetArtProvider(art);
|
|
}
|
|
}
|
|
|
|
void SkinHelper::ApplyCurrentSkin(wxPropertyGrid & propertyGrid)
|
|
{
|
|
#if defined(WINDOWS)
|
|
propertyGrid.SetMarginColour( wxSystemSettings::GetColour(wxSYS_COLOUR_MENU) );
|
|
propertyGrid.SetCaptionBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_MENU) );
|
|
propertyGrid.SetEmptySpaceColour( wxSystemSettings::GetColour(wxSYS_COLOUR_MENU) );
|
|
propertyGrid.SetCellBackgroundColour( *wxWHITE );
|
|
propertyGrid.SetCellTextColour( *wxBLACK );
|
|
propertyGrid.SetLineColour( wxColour(212,208,200) );
|
|
#else
|
|
propertyGrid.SetEmptySpaceColour(propertyGrid.GetMarginColour());
|
|
#endif
|
|
}
|
|
|
|
wxBitmap SkinHelper::GetRibbonIcon(wxString iconName)
|
|
{
|
|
wxLogNull noLogPlease;
|
|
wxString skinName;
|
|
wxString size;
|
|
wxConfigBase::Get()->Read( _T( "/Skin/RibbonIcons" ), &skinName, "default" );
|
|
wxConfigBase::Get()->Read( _T( "/Skin/RibbonIconsSize" ), &size, "32" );
|
|
|
|
if ( !wxFileExists("res/ribbon_"+skinName+"/"+iconName+size+".png") )
|
|
skinName = "default";
|
|
if ( !wxFileExists("res/ribbon_"+skinName+"/"+iconName+size+".png") )
|
|
size = "32";
|
|
|
|
return wxBitmap("res/ribbon_"+skinName+"/"+iconName+size+".png", wxBITMAP_TYPE_ANY);
|
|
}
|
|
|
|
wxBitmap SkinHelper::GetIcon(wxString name, unsigned int size)
|
|
{
|
|
wxLogNull noLogPlease;
|
|
wxString skinName;
|
|
gd::String iconName = name;
|
|
gd::String sizeStr = gd::String::From(size);
|
|
wxConfigBase::Get()->Read( _T( "/Skin/Icons" ), &skinName, "default" );
|
|
gd::String identifier = "res/icons_" + gd::String(skinName) + "/" + iconName + sizeStr + ".png";
|
|
|
|
if ( cachedIcons.find(identifier) != cachedIcons.end() && cachedIcons.find(identifier)->second != NULL )
|
|
return *cachedIcons.find(identifier)->second;
|
|
|
|
//No cached icon, load it from the file
|
|
if ( !wxFileExists("res/icons_"+skinName+"/"+iconName+sizeStr+".png") )
|
|
skinName = "default";
|
|
|
|
wxBitmap * bmp = new wxBitmap("res/icons_"+skinName+"/"+iconName+sizeStr+".png", wxBITMAP_TYPE_ANY);
|
|
cachedIcons[identifier] = bmp;
|
|
return *bmp;
|
|
}
|
|
|
|
bool SkinHelper::IconExists(wxString name, unsigned int size)
|
|
{
|
|
wxLogNull noLogPlease;
|
|
wxString skinName;
|
|
gd::String iconName = name;
|
|
gd::String sizeStr = gd::String::From(size);
|
|
wxConfigBase::Get()->Read( _T( "/Skin/Icons" ), &skinName, "default" );
|
|
gd::String identifier = "res/icons_"+skinName+"/"+iconName+sizeStr+".png";
|
|
|
|
if ( cachedIcons.find(identifier) != cachedIcons.end() && cachedIcons.find(identifier)->second != NULL )
|
|
return true;
|
|
|
|
//No cached icon, check if the file exists
|
|
return wxFileExists("res/icons_"+skinName+"/"+iconName+sizeStr+".png")
|
|
|| wxFileExists("res/icons_default/"+iconName+sizeStr+".png");
|
|
}
|
|
|
|
void SkinHelper::ClearIconCache()
|
|
{
|
|
for(std::map<gd::String, wxBitmap*>::iterator it = cachedIcons.begin(); it != cachedIcons.end();++it)
|
|
{
|
|
if (it->second != NULL)
|
|
delete it->second;
|
|
}
|
|
|
|
cachedIcons.clear();
|
|
}
|
|
|
|
}
|
|
#endif
|