diff --git a/clientgui/SkinManager.cpp b/clientgui/SkinManager.cpp new file mode 100644 index 0000000000..44cf6c707c --- /dev/null +++ b/clientgui/SkinManager.cpp @@ -0,0 +1,924 @@ +// Berkeley Open Infrastructure for Network Computing +// http://boinc.berkeley.edu +// Copyright (C) 2005 University of California +// +// This is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any later version. +// +// This software 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 Lesser General Public License for more details. +// +// To view the GNU Lesser General Public License visit +// http://www.gnu.org/copyleft/lesser.html +// or write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma implementation "SkinManager.h" +#endif + +#include "stdwx.h" +#include "BOINCGUIApp.h" +#include "diagnostics.h" +#include "parse.h" +#include "util.h" +#include "error_numbers.h" +#include "miofile.h" +#include "SkinManager.h" + + +////@begin XPM images +#include "res/skins/default/graphic/background_image.xpm" +#include "res/skins/default/graphic/spacer_image.xpm" +#include "res/skins/default/graphic/state_indicator_background_image.xpm" +#include "res/skins/default/graphic/connecting_indicator_image.xpm" +#include "res/skins/default/graphic/error_indicator_image.xpm" +#include "res/skins/default/graphic/workunit_active_image.xpm" +#include "res/skins/default/graphic/workunit_suspended_image.xpm" +#include "res/skins/default/graphic/workunit_tab_area_background_image.xpm" +#include "res/skins/default/graphic/workunit_area_background_image.xpm" +#include "res/skins/default/graphic/workunit_animation_background_image.xpm" +#include "res/skins/default/graphic/workunit_animation_image.xpm" +#include "res/skins/default/graphic/workunit_gauge_background_image.xpm" +#include "res/skins/default/graphic/workunit_gauge_progress_indicator_image.xpm" +#include "res/skins/default/graphic/project_area_background_image.xpm" +#include "res/skins/default/graphic/project_image.xpm" +#include "res/skins/default/graphic/attach_project_button.xpm" +#include "res/skins/default/graphic/attach_project_clicked_button.xpm" +#include "res/skins/default/graphic/right_arrow_button.xpm" +#include "res/skins/default/graphic/right_arrow_clicked_button.xpm" +#include "res/skins/default/graphic/left_arrow_button.xpm" +#include "res/skins/default/graphic/left_arrow_clicked_button.xpm" +#include "res/skins/default/graphic/save_button.xpm" +#include "res/skins/default/graphic/save_clicked_button.xpm" +#include "res/skins/default/graphic/cancel_button.xpm" +#include "res/skins/default/graphic/cancel_clicked_button.xpm" +#include "res/skins/default/graphic/close_button.xpm" +#include "res/skins/default/graphic/close_clicked_button.xpm" +#include "res/skins/default/graphic/clear_button.xpm" +#include "res/skins/default/graphic/clear_clicked_button.xpm" +#include "res/skins/default/graphic/messages_link_image.xpm" +#include "res/skins/default/graphic/messages_alert_link_image.xpm" +#include "res/skins/default/graphic/suspend_link_image.xpm" +#include "res/skins/default/graphic/resume_link_image.xpm" +#include "res/skins/default/graphic/preferences_link_image.xpm" +#include "res/skins/default/graphic/advanced_link_image.xpm" +#include "res/skins/default/graphic/preferences_dialog_background_image.xpm" +#include "res/skins/default/graphic/messages_dialog_background_image.xpm" +#ifdef __APPLE__ +#include "res/boinc_mac.xpm" +#else +#include "res/boinc.xpm" +#endif +#include "res/boincdisconnect.xpm" +#include "res/boincsnooze.xpm" +#include "res/boincsm.xpm" +////@end XPM images + + +IMPLEMENT_DYNAMIC_CLASS(CSkinItem, wxObject) + + +CSkinItem::CSkinItem() { +} + + +CSkinItem::~CSkinItem() { +} + + +wxColour CSkinItem::ParseColor(wxString strColor) { + wxStringTokenizer tkz(strColor, wxT(":"), wxTOKEN_RET_EMPTY); + unsigned char red = (unsigned char)tkz.GetNextToken().mb_str(); + unsigned char green = (unsigned char)tkz.GetNextToken().mb_str(); + unsigned char blue = (unsigned char)tkz.GetNextToken().mb_str(); + return wxColour(red, green, blue); +} + + +IMPLEMENT_DYNAMIC_CLASS(CSkinImage, CSkinItem) + + +CSkinImage::CSkinImage() { + Clear(); +} + + +CSkinImage::~CSkinImage() { + Clear(); +} + + +void CSkinImage::Clear() { + m_bmpBitmap = wxNullBitmap; + m_colBackgroundColor = wxNullColour; + m_colTransparencyMask = wxNullColour; +} + + +bool CSkinImage::Ok() { + return m_bmpBitmap.Ok(); +} + + +int CSkinImage::Parse(MIOFILE& in) { + char buf[256]; + std::string strBuffer; + + while (in.fgets(buf, 256)) { + if (match_tag(buf, "")) break; + else if (parse_str(buf, "", strBuffer)) { + m_bmpBitmap = wxBitmap(wxImage(wxString(strBuffer.c_str(), wxConvUTF8), wxBITMAP_TYPE_ANY)); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_colBackgroundColor = ParseColor(wxString(strBuffer.c_str(), wxConvUTF8)); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_colTransparencyMask = ParseColor(wxString(strBuffer.c_str(), wxConvUTF8)); + continue; + } + } + + if (Ok()) { + return 0; + } + + return ERR_XML_PARSE; +} + + +bool CSkinImage::SetDefaults(const char** default_image) { + m_bmpBitmap = wxBitmap(default_image); + return true; +} + + +bool CSkinImage::SetDefaults(const char** default_image, wxString strBackgroundColor, wxString strTransparenyMask) { + m_bmpBitmap = wxBitmap(default_image); + m_colBackgroundColor = ParseColor(strBackgroundColor); + m_colTransparencyMask = ParseColor(strTransparenyMask); + return true; +} + + +IMPLEMENT_DYNAMIC_CLASS(CSkinSimpleButton, CSkinItem) + + +CSkinSimpleButton::CSkinSimpleButton() { + Clear(); +} + + +CSkinSimpleButton::~CSkinSimpleButton() { + Clear(); +} + + +void CSkinSimpleButton::Clear() { + m_bmpBitmap = wxNullBitmap; + m_bmpBitmapClicked = wxNullBitmap; +} + + +bool CSkinSimpleButton::Ok() { + return m_bmpBitmap.Ok() && m_bmpBitmapClicked.Ok(); +} + + +int CSkinSimpleButton::Parse(MIOFILE& in) { + char buf[256]; + std::string strBuffer; + + while (in.fgets(buf, 256)) { + if (match_tag(buf, "")) break; + else if (parse_str(buf, "", strBuffer)) { + m_bmpBitmap = wxBitmap(wxImage(wxString(strBuffer.c_str(), wxConvUTF8), wxBITMAP_TYPE_ANY)); + continue; + } + else if (parse_str(buf, "", strBuffer)) { + m_bmpBitmapClicked = wxBitmap(wxImage(wxString(strBuffer.c_str(), wxConvUTF8), wxBITMAP_TYPE_ANY)); + continue; + } + } + + if (Ok()) { + return 0; + } + + return ERR_XML_PARSE; +} + + +bool CSkinSimpleButton::SetDefaults(const char** default_image, const char** default_clicked_image) { + m_bmpBitmap = wxBitmap(default_image); + m_bmpBitmapClicked = wxBitmap(default_clicked_image); + return true; +} + + +IMPLEMENT_DYNAMIC_CLASS(CSkinSimpleTab, CSkinItem) + + +CSkinSimpleTab::CSkinSimpleTab() { + Clear(); +} + + +CSkinSimpleTab::~CSkinSimpleTab() { + Clear(); +} + + +void CSkinSimpleTab::Clear() { + m_bmpBitmap = wxNullBitmap; + m_colBorderColor = wxNullColour; + m_colGradientFromColor = wxNullColour; + m_colGradientToColor = wxNullColour; +} + + +bool CSkinSimpleTab::Ok() { + return m_bmpBitmap.Ok() && m_colBorderColor.Ok() && m_colGradientFromColor.Ok() && m_colGradientToColor.Ok(); +} + + +int CSkinSimpleTab::Parse(MIOFILE& in) { + char buf[256]; + std::string strBuffer; + + while (in.fgets(buf, 256)) { + if (match_tag(buf, "")) break; + else if (parse_str(buf, "", strBuffer)) { + m_bmpBitmap = wxBitmap(wxImage(wxString(strBuffer.c_str(), wxConvUTF8), wxBITMAP_TYPE_ANY)); + continue; + } + else if (parse_str(buf, "", strBuffer)) { + m_colBorderColor = ParseColor(wxString(strBuffer.c_str(), wxConvUTF8)); + continue; + } + else if (parse_str(buf, "", strBuffer)) { + m_colGradientFromColor = ParseColor(wxString(strBuffer.c_str(), wxConvUTF8)); + continue; + } + else if (parse_str(buf, "", strBuffer)) { + m_colGradientToColor = ParseColor(wxString(strBuffer.c_str(), wxConvUTF8)); + continue; + } + } + + if (Ok()) { + return 0; + } + + return ERR_XML_PARSE; +} + + +bool CSkinSimpleTab::SetDefaults( + const char** default_image, wxString strBorderColor, wxString strGradientFromColor, wxString strGradientToColor +) { + m_bmpBitmap = wxBitmap(default_image); + m_colBorderColor = ParseColor(strBorderColor); + m_colGradientFromColor = ParseColor(strGradientFromColor); + m_colGradientToColor = ParseColor(strGradientToColor); + return true; +} + + +IMPLEMENT_DYNAMIC_CLASS(CSkinSimple, CSkinItem) + + +CSkinSimple::CSkinSimple() { + Clear(); +} + + +CSkinSimple::~CSkinSimple() { + Clear(); +} + + +void CSkinSimple::Clear() { + m_BackgroundImage.Clear(); + m_SpacerImage.Clear(); + m_StaticLineColor = wxNullColour; + + m_StateIndicatorBackgroundImage.Clear(); + m_ConnectingIndicatorImage.Clear(); + m_ErrorIndicatorImage.Clear(); + + m_WorkunitActiveTab.Clear(); + m_WorkunitSuspendedTab.Clear(); + m_WorkunitTabAreaBackgroundImage.Clear(); + m_WorkunitAreaBackgroundImage.Clear(); + m_WorkunitAnimationBackgroundImage.Clear(); + m_WorkunitAnimationImage.Clear(); + m_WorkunitGaugeBackgroundImage.Clear(); + m_WorkunitGaugeProgressIndicatorImage.Clear(); + + m_ProjectAreaBackgroundImage.Clear(); + m_ProjectImage.Clear(); + + m_AttachProjectButton.Clear(); + m_RightArrowButton.Clear(); + m_LeftArrowButton.Clear(); + m_SaveButton.Clear(); + m_CancelButton.Clear(); + m_CloseButton.Clear(); + m_ClearButton.Clear(); + + m_PreferencesDialogBackgroundImage.Clear(); + m_MessagesDialogBackgroundImage.Clear(); + + m_MessagesLink.Clear(); + m_MessagesAlertLink.Clear(); + m_SuspendLink.Clear(); + m_ResumeLink.Clear(); + m_PreferencesLink.Clear(); + m_AdvancedLink.Clear(); +} + + +bool CSkinSimple::Ok() { + if (!m_BackgroundImage.Ok()) return false; + if (!m_SpacerImage.Ok()) return false; + if (!m_StaticLineColor.Ok()) return false; + if (!m_StateIndicatorBackgroundImage.Ok()) return false; + if (!m_ConnectingIndicatorImage.Ok()) return false; + if (!m_ErrorIndicatorImage.Ok()) return false; + if (!m_WorkunitActiveTab.Ok()) return false; + if (!m_WorkunitSuspendedTab.Ok()) return false; + if (!m_WorkunitTabAreaBackgroundImage.Ok()) return false; + if (!m_WorkunitAreaBackgroundImage.Ok()) return false; + if (!m_WorkunitAnimationBackgroundImage.Ok()) return false; + if (!m_WorkunitAnimationImage.Ok()) return false; + if (!m_WorkunitGaugeBackgroundImage.Ok()) return false; + if (!m_WorkunitGaugeProgressIndicatorImage.Ok()) return false; + if (!m_ProjectAreaBackgroundImage.Ok()) return false; + if (!m_ProjectImage.Ok()) return false; + if (!m_AttachProjectButton.Ok()) return false; + if (!m_RightArrowButton.Ok()) return false; + if (!m_LeftArrowButton.Ok()) return false; + if (!m_SaveButton.Ok()) return false; + if (!m_CancelButton.Ok()) return false; + if (!m_CloseButton.Ok()) return false; + if (!m_ClearButton.Ok()) return false; + if (!m_MessagesLink.Ok()) return false; + if (!m_MessagesAlertLink.Ok()) return false; + if (!m_SuspendLink.Ok()) return false; + if (!m_ResumeLink.Ok()) return false; + if (!m_PreferencesLink.Ok()) return false; + if (!m_AdvancedLink.Ok()) return false; + if (!m_PreferencesDialogBackgroundImage.Ok()) return false; + if (!m_MessagesDialogBackgroundImage.Ok()) return false; + return true; +} + + +int CSkinSimple::Parse(MIOFILE& in) { + char buf[256]; + std::string strBuffer; + + while (in.fgets(buf, 256)) { + if (match_tag(buf, "")) break; + else if (match_tag(buf, "")) { + m_BackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_SpacerImage.Parse(in); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_StaticLineColor = ParseColor(wxString(strBuffer.c_str(), wxConvUTF8)); + continue; + } else if (match_tag(buf, "")) { + m_StateIndicatorBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_ConnectingIndicatorImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_ErrorIndicatorImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitActiveTab.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitSuspendedTab.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitTabAreaBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitAreaBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitAnimationBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitAnimationImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitGaugeBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_WorkunitGaugeProgressIndicatorImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_ProjectAreaBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_ProjectImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_AttachProjectButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_RightArrowButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_LeftArrowButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_SaveButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_CancelButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_CloseButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_ClearButton.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_MessagesLink.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_MessagesAlertLink.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_SuspendLink.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_ResumeLink.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_PreferencesLink.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_AdvancedLink.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_PreferencesDialogBackgroundImage.Parse(in); + continue; + } else if (match_tag(buf, "")) { + m_MessagesDialogBackgroundImage.Parse(in); + continue; + } + } + + // Make sure all of our parts and pieces are going to work if not replace them + // with the defaults. + ValidateSkin(); + + // Check one last time to make sure everything is good to go. + // + if (Ok()) { + return 0; + } + + return ERR_XML_PARSE; +} + + +bool CSkinSimple::ValidateSkin() { + if (!m_BackgroundImage.Ok()) { + if (!m_BackgroundImage.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load background image. Using default.\n")); + } + if (!m_BackgroundImage.GetBackgroundColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse background color. Using default.\n")); + } + m_BackgroundImage.SetDefaults((const char**)background_image_xpm, wxString(wxT("133:181:178")), wxEmptyString); + wxASSERT(m_BackgroundImage.Ok()); + } + if (!m_SpacerImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load spacer image. Using default.\n")); + m_SpacerImage.SetDefaults((const char**)spacer_image_xpm); + wxASSERT(m_SpacerImage.Ok()); + } + if (!m_StaticLineColor.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse static line color. Using default.\n")); + m_StaticLineColor = ParseColor(wxString(wxT("204:102:51"))); + wxASSERT(m_StaticLineColor.Ok()); + } + if (!m_StateIndicatorBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load state indicator background image. Using default.\n")); + m_StateIndicatorBackgroundImage.SetDefaults((const char**)state_indicator_background_image_xpm); + wxASSERT(m_StateIndicatorBackgroundImage.Ok()); + } + if (!m_ConnectingIndicatorImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load connecting indicator image. Using default.\n")); + m_ConnectingIndicatorImage.SetDefaults((const char**)connecting_indicator_image_xpm); + wxASSERT(m_ConnectingIndicatorImage.Ok()); + } + if (!m_ErrorIndicatorImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load error indicator image. Using default.\n")); + m_ErrorIndicatorImage.SetDefaults((const char**)error_indicator_image_xpm); + wxASSERT(m_ErrorIndicatorImage.Ok()); + } + if (!m_WorkunitActiveTab.Ok()) { + if (!m_WorkunitActiveTab.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load active tab image. Using default.\n")); + } + if (!m_WorkunitActiveTab.GetBorderColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse active tab border color. Using default.\n")); + } + if (!m_WorkunitActiveTab.GetGradientFromColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse active tab gradient from color. Using default.\n")); + } + if (!m_WorkunitActiveTab.GetGradientToColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse active tab gradient to color. Using default.\n")); + } + m_WorkunitActiveTab.SetDefaults( + (const char**)workunit_active_image_xpm, + wxString(wxT("20:82:82")), + wxString(wxT("134:179:176")), + wxString(wxT("51:102:102")) + ); + wxASSERT(m_WorkunitActiveTab.Ok()); + } + if (!m_WorkunitSuspendedTab.Ok()) { + if (!m_WorkunitSuspendedTab.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load suspended tab image. Using default.\n")); + } + if (!m_WorkunitSuspendedTab.GetBorderColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse suspended tab border color. Using default.\n")); + } + if (!m_WorkunitSuspendedTab.GetGradientFromColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse suspended tab gradient from color. Using default.\n")); + } + if (!m_WorkunitSuspendedTab.GetGradientToColor()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to parse suspended tab gradient to color. Using default.\n")); + } + m_WorkunitSuspendedTab.SetDefaults( + (const char**)workunit_active_image_xpm, + wxString(wxT("102:153:153")), + wxString(wxT("134:179:176")), + wxString(wxT("84:175:175")) + ); + wxASSERT(m_WorkunitSuspendedTab.Ok()); + } + if (!m_WorkunitTabAreaBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load workunit tab area background image. Using default.\n")); + m_WorkunitTabAreaBackgroundImage.SetDefaults((const char**)workunit_tab_area_background_image_xpm); + wxASSERT(m_WorkunitTabAreaBackgroundImage.Ok()); + } + if (!m_WorkunitAreaBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load workunit area background image. Using default.\n")); + m_WorkunitAreaBackgroundImage.SetDefaults((const char**)workunit_area_background_image_xpm); + wxASSERT(m_WorkunitAreaBackgroundImage.Ok()); + } + if (!m_WorkunitAnimationBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load workunit animation background image. Using default.\n")); + m_WorkunitAnimationBackgroundImage.SetDefaults((const char**)workunit_animation_background_image_xpm); + wxASSERT(m_WorkunitAnimationBackgroundImage.Ok()); + } + if (!m_WorkunitAnimationImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load workunit animation image. Using default.\n")); + m_WorkunitAnimationImage.SetDefaults((const char**)workunit_animation_image_xpm); + wxASSERT(m_WorkunitAnimationImage.Ok()); + } + if (!m_WorkunitGaugeBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load gauge background image. Using default.\n")); + m_WorkunitGaugeBackgroundImage.SetDefaults((const char**)workunit_gauge_background_image_xpm); + wxASSERT(m_WorkunitGaugeBackgroundImage.Ok()); + } + if (!m_WorkunitGaugeProgressIndicatorImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load gauge progress indicator image. Using default.\n")); + m_WorkunitGaugeProgressIndicatorImage.SetDefaults((const char**)workunit_gauge_progress_indicator_image_xpm); + wxASSERT(m_WorkunitGaugeProgressIndicatorImage.Ok()); + } + if (!m_ProjectAreaBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load project area background image. Using default.\n")); + m_ProjectAreaBackgroundImage.SetDefaults((const char**)project_area_background_image_xpm); + wxASSERT(m_ProjectAreaBackgroundImage.Ok()); + } + if (!m_ProjectImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load project image. Using default.\n")); + m_ProjectImage.SetDefaults((const char**)project_image_xpm); + wxASSERT(m_ProjectImage.Ok()); + } + if (!m_AttachProjectButton.Ok()) { + if (!m_AttachProjectButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load attach project button. Using default.\n")); + } + if (!m_AttachProjectButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load attach project clicked button. Using default.\n")); + } + m_AttachProjectButton.SetDefaults( + (const char**)attach_project_button_xpm, + (const char**)attach_project_clicked_button_xpm + ); + wxASSERT(m_AttachProjectButton.Ok()); + } + if (!m_RightArrowButton.Ok()) { + if (!m_RightArrowButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load right arrow button. Using default.\n")); + } + if (!m_RightArrowButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load right arrow clicked button. Using default.\n")); + } + m_RightArrowButton.SetDefaults( + (const char**)right_arrow_button_xpm, + (const char**)right_arrow_clicked_button_xpm + ); + wxASSERT(m_RightArrowButton.Ok()); + } + if (!m_LeftArrowButton.Ok()) { + if (!m_LeftArrowButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load left arrow button. Using default.\n")); + } + if (!m_LeftArrowButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load left arrow clicked button. Using default.\n")); + } + m_LeftArrowButton.SetDefaults( + (const char**)left_arrow_button_xpm, + (const char**)left_arrow_clicked_button_xpm + ); + wxASSERT(m_LeftArrowButton.Ok()); + } + if (!m_SaveButton.Ok()) { + if (!m_SaveButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load save button. Using default.\n")); + } + if (!m_SaveButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load save clicked button. Using default.\n")); + } + m_SaveButton.SetDefaults( + (const char**)save_button_xpm, + (const char**)save_clicked_button_xpm + ); + wxASSERT(m_SaveButton.Ok()); + } + if (!m_CancelButton.Ok()) { + if (!m_CancelButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load cancel button. Using default.\n")); + } + if (!m_CancelButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load cancel clicked button. Using default.\n")); + } + m_CancelButton.SetDefaults( + (const char**)cancel_button_xpm, + (const char**)cancel_clicked_button_xpm + ); + wxASSERT(m_CancelButton.Ok()); + } + if (!m_CloseButton.Ok()) { + if (!m_CloseButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load close button. Using default.\n")); + } + if (!m_CloseButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load close clicked button. Using default.\n")); + } + m_CloseButton.SetDefaults( + (const char**)close_button_xpm, + (const char**)close_clicked_button_xpm + ); + wxASSERT(m_CloseButton.Ok()); + } + if (!m_ClearButton.Ok()) { + if (!m_ClearButton.GetBitmap()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load clear button. Using default.\n")); + } + if (!m_ClearButton.GetBitmapClicked()->Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load clear clicked button. Using default.\n")); + } + m_ClearButton.SetDefaults( + (const char**)clear_button_xpm, + (const char**)clear_clicked_button_xpm + ); + wxASSERT(m_ClearButton.Ok()); + } + if (!m_MessagesLink.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load messages link image. Using default.\n")); + m_MessagesLink.SetDefaults((const char**)messages_link_image_xpm); + wxASSERT(m_MessagesLink.Ok()); + } + if (!m_MessagesAlertLink.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load messages alert link image. Using default.\n")); + m_MessagesAlertLink.SetDefaults((const char**)messages_alert_link_image_xpm); + wxASSERT(m_MessagesAlertLink.Ok()); + } + if (!m_SuspendLink.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load suspend link image. Using default.\n")); + m_SuspendLink.SetDefaults((const char**)suspend_link_image_xpm); + wxASSERT(m_SuspendLink.Ok()); + } + if (!m_ResumeLink.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load resume link image. Using default.\n")); + m_ResumeLink.SetDefaults((const char**)resume_link_image_xpm); + wxASSERT(m_ResumeLink.Ok()); + } + if (!m_PreferencesLink.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load preferences link image. Using default.\n")); + m_PreferencesLink.SetDefaults((const char**)preferences_link_image_xpm); + wxASSERT(m_PreferencesLink.Ok()); + } + if (!m_AdvancedLink.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load advanced link image. Using default.\n")); + m_AdvancedLink.SetDefaults((const char**)advanced_link_image_xpm); + wxASSERT(m_AdvancedLink.Ok()); + } + if (!m_PreferencesDialogBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load preferences dialog background image. Using default.\n")); + m_PreferencesDialogBackgroundImage.SetDefaults((const char**)preferences_dialog_background_image_xpm); + wxASSERT(m_PreferencesDialogBackgroundImage.Ok()); + } + if (!m_MessagesDialogBackgroundImage.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load messages dialog background image. Using default.\n")); + m_MessagesDialogBackgroundImage.SetDefaults((const char**)messages_dialog_background_image_xpm); + wxASSERT(m_MessagesDialogBackgroundImage.Ok()); + } + return true; +} + + +IMPLEMENT_DYNAMIC_CLASS(CSkinAdvanced, CSkinItem) + + +CSkinAdvanced::CSkinAdvanced() { + Clear(); +} + + +CSkinAdvanced::~CSkinAdvanced() { + Clear(); +} + + +void CSkinAdvanced::Clear() { + m_strApplicationName = wxEmptyString; + m_iconApplicationIcon = wxNullIcon; + m_iconApplicationDisconnectedIcon = wxNullIcon; + m_iconApplicationSnoozeIcon = wxNullIcon; + m_bitmapApplicationLogo = wxNullBitmap; + m_strCompanyName = wxEmptyString; + m_strCompanyWebsite = wxEmptyString; + m_strProjectName = wxEmptyString; + m_bDefaultTabSpecified = false; + m_iDefaultTab = 0; + m_strExitMessage = wxEmptyString; +} + + +bool CSkinAdvanced::Ok() { + if (m_strApplicationName.IsEmpty()) return false; + if (!m_iconApplicationIcon.Ok()) return false; + if (!m_iconApplicationDisconnectedIcon.Ok()) return false; + if (!m_iconApplicationSnoozeIcon.Ok()) return false; + if (!m_bitmapApplicationLogo.Ok()) return false; + if (m_strCompanyName.IsEmpty()) return false; + if (m_strCompanyWebsite.IsEmpty()) return false; + if (m_strProjectName.IsEmpty()) return false; + if (!m_bDefaultTabSpecified) return false; + return true; +} + + +int CSkinAdvanced::Parse(MIOFILE& in) { + char buf[256]; + std::string strBuffer; + + while (in.fgets(buf, 256)) { + if (match_tag(buf, "")) break; + else if (parse_str(buf, "", strBuffer)) { + m_strApplicationName = wxString(strBuffer.c_str(), wxConvUTF8); + continue; + } else if (match_tag(buf, "")) { + // Parse out the bitmap information and transparency mask + CSkinImage img; + img.Parse(in); + + // Configure bitmap object with transparency mask + wxBitmap bmp = wxBitmap(*img.GetBitmap()); + bmp.SetMask(new wxMask(*img.GetBitmap(), *img.GetTransparencyMask())); + + // Not set the icon object using the newly created bitmap + m_iconApplicationIcon.CopyFromBitmap(bmp); + continue; + } else if (match_tag(buf, "")) { + // Parse out the bitmap information and transparency mask + CSkinImage img; + img.Parse(in); + + // Configure bitmap object with transparency mask + wxBitmap bmp = wxBitmap(*img.GetBitmap()); + bmp.SetMask(new wxMask(*img.GetBitmap(), *img.GetTransparencyMask())); + + // Not set the icon object using the newly created bitmap + m_iconApplicationDisconnectedIcon.CopyFromBitmap(bmp); + continue; + } else if (match_tag(buf, "")) { + // Parse out the bitmap information and transparency mask + CSkinImage img; + img.Parse(in); + + // Configure bitmap object with transparency mask + wxBitmap bmp = wxBitmap(*img.GetBitmap()); + bmp.SetMask(new wxMask(*img.GetBitmap(), *img.GetTransparencyMask())); + + // Not set the icon object using the newly created bitmap + m_iconApplicationSnoozeIcon.CopyFromBitmap(bmp); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_bitmapApplicationLogo = wxBitmap(wxImage(wxString(strBuffer.c_str(), wxConvUTF8), wxBITMAP_TYPE_ANY)); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_strCompanyName = wxString(strBuffer.c_str(), wxConvUTF8); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_strCompanyWebsite = wxString(strBuffer.c_str(), wxConvUTF8); + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_strProjectName = wxString(strBuffer.c_str(), wxConvUTF8); + continue; + } else if (parse_int(buf, "", m_iDefaultTab)) { + m_bDefaultTabSpecified = true; + continue; + } else if (parse_str(buf, "", strBuffer)) { + m_strExitMessage = wxString(strBuffer.c_str(), wxConvUTF8); + continue; + } + } + + // Make sure all of our parts and pieces are going to work if not replace them + // with the defaults. + ValidateSkin(); + + // Check one last time to make sure everything is good to go. + // + if (Ok()) { + return 0; + } + + return ERR_XML_PARSE; +} + + +bool CSkinAdvanced::ValidateSkin() { + if (m_strApplicationName.IsEmpty()) { + fprintf(stderr, wxT("Skin Manager: Application name was not defined. Using default.\n")); + m_strApplicationName = wxT("BOINC Manager"); + wxASSERT(!m_strApplicationName.IsEmpty()); + } + if (!m_iconApplicationIcon.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load application icon. Using default.\n")); + m_iconApplicationIcon = wxIcon((const char**)boinc_xpm); + wxASSERT(m_iconApplicationIcon.Ok()); + } + if (!m_iconApplicationDisconnectedIcon.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load application disconnected icon. Using default.\n")); + m_iconApplicationDisconnectedIcon = wxIcon((const char**)boincdisconnect_xpm); + wxASSERT(m_iconApplicationDisconnectedIcon.Ok()); + } + if (!m_iconApplicationSnoozeIcon.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load application snooze icon. Using default.\n")); + m_iconApplicationDisconnectedIcon = wxIcon((const char**)boincsnooze_xpm); + wxASSERT(m_iconApplicationDisconnectedIcon.Ok()); + } + if (!m_bitmapApplicationLogo.Ok()) { + fprintf(stderr, wxT("Skin Manager: Failed to load application logo. Using default.\n")); + m_bitmapApplicationLogo = wxBitmap((const char**)boincsm_xpm); + wxASSERT(m_bitmapApplicationLogo.Ok()); + } + if (m_strCompanyName.IsEmpty()) { + fprintf(stderr, wxT("Skin Manager: Company name was not defined. Using default.\n")); + m_strCompanyName = wxT("Space Sciences Laboratory, U.C. Berkeley"); + wxASSERT(!m_strCompanyName.IsEmpty()); + } + if (m_strCompanyWebsite.IsEmpty()) { + fprintf(stderr, wxT("Skin Manager: Company web site was not defined. Using default.\n")); + m_strCompanyWebsite = wxT("Space Sciences Laboratory, U.C. Berkeley"); + wxASSERT(!m_strCompanyWebsite.IsEmpty()); + } + if (m_strProjectName.IsEmpty()) { + fprintf(stderr, wxT("Skin Manager: Project name was not defined. Using default.\n")); + m_strProjectName = wxT("BOINC"); + wxASSERT(!m_strProjectName.IsEmpty()); + } + if (!m_bDefaultTabSpecified) { + fprintf(stderr, wxT("Skin Manager: Default tab was not defined. Using default.\n")); + m_bDefaultTabSpecified = true; + m_iDefaultTab = 0; + } + return true; +} + + + + diff --git a/clientgui/SkinManager.h b/clientgui/SkinManager.h new file mode 100644 index 0000000000..4bcc842ba5 --- /dev/null +++ b/clientgui/SkinManager.h @@ -0,0 +1,221 @@ +// Berkeley Open Infrastructure for Network Computing +// http://boinc.berkeley.edu +// Copyright (C) 2005 University of California +// +// This is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any later version. +// +// This software 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 Lesser General Public License for more details. +// +// To view the GNU Lesser General Public License visit +// http://www.gnu.org/copyleft/lesser.html +// or write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef _SKINMANAGER_H_ +#define _SKINMANAGER_H_ + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma interface "SkinManager.cpp" +#endif + + +class CSkinItem : public wxObject +{ + DECLARE_DYNAMIC_CLASS( CSkinItem ) + +public: + CSkinItem(); + ~CSkinItem(); + + static wxColour ParseColor(wxString strColor); +}; + + +class CSkinImage : public CSkinItem +{ + DECLARE_DYNAMIC_CLASS( CSkinImage ) + +public: + CSkinImage(); + ~CSkinImage(); + + void Clear(); + bool Ok(); + int Parse(MIOFILE& in); + + wxBitmap* GetBitmap() { return &m_bmpBitmap; }; + wxColour* GetBackgroundColor() { return &m_colBackgroundColor; }; + wxColour* GetTransparencyMask() { return &m_colTransparencyMask; }; + + bool SetDefaults(const char** default_image); + bool SetDefaults(const char** default_image, wxString strBackgroundColor, wxString strTransparenyMask); + +private: + wxBitmap m_bmpBitmap; + wxColour m_colBackgroundColor; + wxColor m_colTransparencyMask; +}; + + +class CSkinSimpleButton : public CSkinItem +{ + DECLARE_DYNAMIC_CLASS( CSkinSimpleButton ) + +public: + CSkinSimpleButton(); + ~CSkinSimpleButton(); + + void Clear(); + bool Ok(); + int Parse(MIOFILE& in); + + wxBitmap* GetBitmap() { return &m_bmpBitmap; }; + wxBitmap* GetBitmapClicked() { return &m_bmpBitmapClicked; }; + + bool SetDefaults(const char** default_image, const char** default_clicked_image); + +private: + wxBitmap m_bmpBitmap; + wxBitmap m_bmpBitmapClicked; +}; + + +class CSkinSimpleTab : public CSkinItem +{ + DECLARE_DYNAMIC_CLASS( CSkinSimpleTab ) + +public: + CSkinSimpleTab(); + ~CSkinSimpleTab(); + + void Clear(); + bool Ok(); + int Parse(MIOFILE& in); + + wxBitmap* GetBitmap() { return &m_bmpBitmap; }; + wxColour* GetBorderColor() { return &m_colBorderColor; }; + wxColour* GetGradientFromColor() { return &m_colGradientFromColor; }; + wxColour* GetGradientToColor() { return &m_colGradientToColor; }; + + bool SetDefaults( + const char** default_image, + wxString strBorderColor, + wxString strGradientFromColor, + wxString strGradientToColor + ); + +private: + wxBitmap m_bmpBitmap; + wxColour m_colBorderColor; + wxColour m_colGradientFromColor; + wxColour m_colGradientToColor; +}; + + +class CSkinSimple : public CSkinItem +{ + DECLARE_DYNAMIC_CLASS( CSkinSimple ) + +public: + CSkinSimple(); + ~CSkinSimple(); + + void Clear(); + int Parse(MIOFILE& in); + + bool Ok(); + + bool ValidateSkin(); + +private: + CSkinImage m_BackgroundImage; + CSkinImage m_SpacerImage; + wxColour m_StaticLineColor; + + CSkinImage m_StateIndicatorBackgroundImage; + CSkinImage m_ConnectingIndicatorImage; + CSkinImage m_ErrorIndicatorImage; + + CSkinSimpleTab m_WorkunitActiveTab; + CSkinSimpleTab m_WorkunitSuspendedTab; + CSkinImage m_WorkunitTabAreaBackgroundImage; + CSkinImage m_WorkunitAreaBackgroundImage; + CSkinImage m_WorkunitAnimationBackgroundImage; + CSkinImage m_WorkunitAnimationImage; + CSkinImage m_WorkunitGaugeBackgroundImage; + CSkinImage m_WorkunitGaugeProgressIndicatorImage; + + CSkinImage m_ProjectAreaBackgroundImage; + CSkinImage m_ProjectImage; + + CSkinSimpleButton m_AttachProjectButton; + CSkinSimpleButton m_RightArrowButton; + CSkinSimpleButton m_LeftArrowButton; + CSkinSimpleButton m_SaveButton; + CSkinSimpleButton m_CancelButton; + CSkinSimpleButton m_CloseButton; + CSkinSimpleButton m_ClearButton; + + CSkinImage m_MessagesLink; + CSkinImage m_MessagesAlertLink; + CSkinImage m_SuspendLink; + CSkinImage m_ResumeLink; + CSkinImage m_PreferencesLink; + CSkinImage m_AdvancedLink; + + CSkinImage m_PreferencesDialogBackgroundImage; + CSkinImage m_MessagesDialogBackgroundImage; +}; + + +class CSkinAdvanced : public CSkinItem +{ + DECLARE_DYNAMIC_CLASS( CSkinAdvanced ) + +public: + CSkinAdvanced(); + ~CSkinAdvanced(); + + void Clear(); + bool Ok(); + int Parse(MIOFILE& in); + + bool ValidateSkin(); + + wxString GetApplicationName() { return m_strApplicationName; } + wxIcon* GetApplicationIcon() { return &m_iconApplicationIcon; } + wxIcon* GetApplicationDisconnectedIcon() { return &m_iconApplicationDisconnectedIcon; } + wxIcon* GetApplicationSnoozeIcon() { return &m_iconApplicationSnoozeIcon; } + wxBitmap* GetApplicationLogo() { return &m_bitmapApplicationLogo; } + wxString GetCompanyName() { return m_strCompanyName; } + wxString GetCompanyWebsite() { return m_strCompanyWebsite; } + wxString GetProjectName() { return m_strProjectName; } + int GetDefaultTab() { return m_iDefaultTab; } + wxString GetExitMessage() { return m_strExitMessage; } + bool IsBranded() { return m_bIsBranded; } + bool IsDefaultTabSpecified() { return m_bDefaultTabSpecified; } + +private: + bool m_bIsBranded; + wxString m_strApplicationName; + wxIcon m_iconApplicationIcon; + wxIcon m_iconApplicationDisconnectedIcon; + wxIcon m_iconApplicationSnoozeIcon; + wxBitmap m_bitmapApplicationLogo; + wxString m_strCompanyName; + wxString m_strCompanyWebsite; + wxString m_strProjectName; + bool m_bDefaultTabSpecified; + int m_iDefaultTab; + wxString m_strExitMessage; +}; + + + +#endif