📄 theme.cpp
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Copyright (C) 1999 EMusic
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: Theme.cpp,v 1.24 2000/01/15 01:55:02 robert Exp $
____________________________________________________________________________*/
// The debugger can't handle symbols more than 255 characters long.
// STL often creates symbols longer than that.
// When symbols are longer than 255 characters, the warning is disabled.
#ifdef WIN32
#pragma warning(disable:4786)
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#define _S_IFDIR S_IFDIR
#define _stat stat
#endif
#include <map>
#include <algorithm>
#include <assert.h>
#include "Theme.h"
#include "ButtonControl.h"
#include "DialControl.h"
#include "SliderControl.h"
#include "VSliderControl.h"
#include "TextControl.h"
#include "MultiStateControl.h"
#include "ThemeZip.h"
#include "MessageDialog.h"
#include "debug.h"
#include "config.h"
#define DB Debug_v("%s:%d\n", __FILE__, __LINE__);
#ifdef WIN32
#include <direct.h>
//#define stat(a,b) _stat(a,b)
#define rmdir(a) _rmdir(a)
#define MKDIR(z) mkdir(z)
#else
#define MKDIR(z) mkdir(z, 0755)
#endif
#ifdef WIN32
#include "Win32Window.h"
#include "Win32Bitmap.h"
#include "Win32Font.h"
#elif defined(HAVE_GTK)
#include "GTKWindow.h"
#include "GTKBitmap.h"
#include "GTKFont.h"
#include "GTKUtility.h"
#elif defined(__BEOS__)
#include "BeOSWindow.h"
#include "BeOSBitmap.h"
#include "BeOSFont.h"
#endif
const int iThemeVersionMajor = 1;
const int iThemeVersionMinor = 0;
const char *szThemeNotFoundError = "Cannot open the theme specified in the preferences. Using default theme instead.";
const char *szThemeUnzipError = "Cannot unzip the specified theme. Using default theme instead.";
const char *szCannotCreateTempDirError = "Cannot create a temporary directory to unzip theme.";
Theme::Theme(FAContext *context)
{
m_pContext = context;
m_pCurrentWindow = NULL;
m_pCurrentControl = NULL;
m_pParsedWindows = m_pWindows = NULL;
m_pParsedBitmaps = m_pBitmaps = NULL;
m_pParsedFonts = m_pFonts = NULL;
m_bReloadTheme = false;
m_bReloadWindow = false;
m_oReloadWindow = string("");
m_eCurrentControl = eUndefinedControl;
m_pThemeMan = new ThemeManager(m_pContext);
m_bThemeLoaded = false;
m_bCreditsShown = false;
string funkyName = "Frunobulax";
#ifdef WIN32
m_pWindow = new Win32Window(this, funkyName);
#elif defined(HAVE_GTK)
InitializeGTK(context);
m_pWindow = new GTKWindow(this, funkyName);
#elif defined(__BEOS__)
m_pWindow = new BeOSWindow(this, funkyName);
#endif
m_pWindow->VulcanMindMeldHost(true);
}
Theme::~Theme(void)
{
delete m_pCurrentWindow;
delete m_pCurrentControl;
delete m_pThemeMan;
delete m_pWindow;
ClearWindows();
ClearBitmaps();
ClearFonts();
#ifdef HAVE_GTK
ShutdownGTK();
#endif
}
void Theme::ClearWindows(void)
{
if (m_pWindows)
{
while(m_pWindows->size() > 0)
{
delete (*m_pWindows)[0];
m_pWindows->erase(m_pWindows->begin());
}
delete m_pWindows;
m_pWindows = NULL;
}
}
void Theme::ClearBitmaps(void)
{
if (m_pBitmaps)
{
while(m_pBitmaps->size() > 0)
{
delete (*m_pBitmaps)[0];
m_pBitmaps->erase(m_pBitmaps->begin());
}
delete m_pBitmaps;
m_pBitmaps = NULL;
}
}
void Theme::ClearFonts(void)
{
if (m_pFonts)
{
while(m_pFonts->size() > 0)
{
delete (*m_pFonts)[0];
m_pFonts->erase(m_pFonts->begin());
}
delete m_pFonts;
m_pFonts = NULL;
}
}
void Theme::SetThemePath(string &oThemePath)
{
m_oThemePath = oThemePath + string(DIR_MARKER_STR);
}
Error Theme::LoadTheme(string &oFile, string &oWindowName)
{
char *pTemp;
ThemeZip oZip;
string oCompleteFile, oTempPath, oDefaultPath;
Error eRet;
struct _stat buf;
if (_stat(oFile.c_str(), &buf) == 0 && (buf.st_mode & _S_IFDIR))
{
SetThemePath(oFile);
oCompleteFile = oFile + string(DIR_MARKER_STR) + string("theme.xml");
eRet = Parse::ParseFile(oCompleteFile);
}
else
{
pTemp = tempnam(NULL, "fat");
oTempPath = pTemp;
free(pTemp);
if (MKDIR(oTempPath.c_str()))
{
MessageDialog oBox(m_pContext);
string oErr, oMessage(szCannotCreateTempDirError);
oBox.Show(oMessage.c_str(), string(BRANDING), kMessageOk);
return kError_InvalidParam;
}
SetThemePath(oTempPath);
eRet = oZip.DecompressThemeZip(oFile, oTempPath);
if (eRet == kError_FileNotFound)
{
string oDefaultPath;
if (oFile.length() > 0)
{
MessageDialog oBox(m_pContext);
string oErr, oMessage(szThemeNotFoundError);
oBox.Show(oMessage.c_str(), string(BRANDING), kMessageOk);
}
m_pThemeMan->GetDefaultTheme(oFile);
eRet = oZip.DecompressThemeZip(oFile, oTempPath);
if (IsError(eRet))
{
m_oLastError = "Cannot find default theme";
rmdir(oTempPath.c_str());
return kError_InvalidParam;
}
}
if (IsError(eRet))
{
MessageDialog oBox(m_pContext);
string oErr, oMessage(szThemeUnzipError);
oBox.Show(oMessage.c_str(), string(BRANDING), kMessageOk);
m_pThemeMan->GetDefaultTheme(oFile);
eRet = oZip.DecompressThemeZip(oFile, oTempPath);
if (IsError(eRet))
{
m_oLastError = "Cannot find default theme";
rmdir(oTempPath.c_str());
return kError_InvalidParam;
}
}
oCompleteFile = oTempPath + string(DIR_MARKER_STR)
+ string("theme.xml");
eRet = Parse::ParseFile(oCompleteFile);
oZip.CleanupThemeZip();
rmdir(oTempPath.c_str());
}
if (!IsError(eRet))
{
string oTemp;
vector<Window *>::iterator i;
Window *pMainWindow, *pNewWindow = NULL;
// Is this a reload, as opposed to a new load?
if (m_pWindows)
{
// Clear the current window list
ClearWindows();
// Adopt the new window vector
m_pWindows = m_pParsedWindows;
// Select the new window, based on the passed in name
for(i = m_pWindows->begin(); i != m_pWindows->end(); i++)
{
(*i)->GetName(oTemp);
if (oTemp == oWindowName)
{
pNewWindow = *i;
break;
}
if (oTemp == string("MainWindow"))
pMainWindow = *i;
}
// If we can't find the proper mode, switch to mainwindow
if (!pNewWindow)
pNewWindow = pMainWindow;
// Clear out all the old bitmaps and fonts
ClearBitmaps();
ClearFonts();
// Accept the new bitmaps and font.
m_pBitmaps = m_pParsedBitmaps;
m_pFonts = m_pParsedFonts;
m_pParsedWindows = NULL;
m_pParsedBitmaps = NULL;
m_pParsedFonts = NULL;
#ifdef WIN32
((Win32Window *)m_pWindow)->ConvertTo256Color(m_pBitmaps);
#endif
// Now the window lists have been properly adjusted, so
// adopt all the info from the new window into the existing
// window via the VulcanMindLink
m_pWindow->VulcanMindMeld(pNewWindow);
// And if god doesn't stike me down right now,
// everything *should* be fine.
}
else
{
// Its a new load -- just take things verbatim and run
m_pWindows = m_pParsedWindows;
m_pBitmaps = m_pParsedBitmaps;
m_pFonts = m_pParsedFonts;
m_pParsedWindows = NULL;
m_pParsedBitmaps = NULL;
m_pParsedFonts = NULL;
for(i = m_pWindows->begin(); i != m_pWindows->end(); i++)
{
(*i)->GetName(oTemp);
if (oTemp == oWindowName)
{
pNewWindow = *i;
break;
}
if (oTemp == string("MainWindow"))
pMainWindow = *i;
}
if (!pNewWindow)
pNewWindow = pMainWindow;
#ifdef WIN32
((Win32Window *)m_pWindow)->ConvertTo256Color(m_pBitmaps);
#endif
m_pWindow->VulcanMindMeld(pNewWindow);
}
m_bThemeLoaded = true;
}
return eRet;
}
Error Theme::SwitchWindow(const string &oWindowName)
{
string oTemp;
vector<Window *>::iterator i;
Window *pMainWindow, *pNewWindow = NULL;
for(i = m_pWindows->begin(); i != m_pWindows->end(); i++)
{
(*i)->GetName(oTemp);
if (oTemp == oWindowName)
{
pNewWindow = *i;
break;
}
if (oTemp == string("MainWindow"))
pMainWindow = *i;
}
if (!pNewWindow)
pNewWindow = pMainWindow;
return m_pWindow->VulcanMindMeld(pNewWindow);
}
Error Theme::Run(Pos &oWindowPos)
{
if (!m_bThemeLoaded)
return kError_YouScrewedUp;
InitWindow();
return m_pWindow->Run(oWindowPos);
}
Error Theme::Close(void)
{
if (m_pWindow)
return m_pWindow->Close();
else
return kError_NoErr;
}
Error Theme::BeginElement(string &oElement, AttrMap &oAttrMap)
{
Error eRet;
string oCompleteFile;
if (oElement == string("Version"))
{
int iRet, iVersionMajor, iVersionMinor;
iRet = sscanf(oAttrMap["Version"].c_str(), " %d.%d", &iVersionMajor,
&iVersionMinor);
if (iRet != 2)
{
m_oLastError = string("Improperly formatted version number "
"in the <Version> tag");
return kError_ParseError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -