📄 wxskinnableframe.cpp
字号:
/* * Roadnav * wxSkinnableFrame.cpp * * Copyright (c) 2004 - 2007 Richard L. Lynch <rllynch@users.sourceforge.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ ///////////////////////////////////////////////////////////////////////////////// \file////// Contains the wxSkinnableFrame class and its support code - easily /// converts a regular frame into a skinnable one./////////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifdef _MSC_VER#pragma warning(disable: 4786)#pragma warning(disable: 4800)#endif#ifdef HAVE_STDIO_H#include <stdio.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#include <wx/wx.h>#include <wx/filename.h>#include <wx/tokenzr.h>#include "wxSkinnableFrame.h"#include "libroadnav/MapRepresentations.h"#include "libroadnav/MapSupport.h"#include "wxBitmapButtonNoBackground.h"#include "wxBitmapControl.h"#include "wxStaticTextNoBackground.h"#include <vector>using namespace std;#define PWS_STYLE(s,a,l) if (s == wxT(#a)) l |= a;long ParseWindowStyle(const wxString & str){ long lStyle = 0; wxStringTokenizer tkz(str); while (tkz.HasMoreTokens()) { wxString strTok = tkz.GetNextToken(); PWS_STYLE(strTok, wxSIMPLE_BORDER, lStyle) PWS_STYLE(strTok, wxDOUBLE_BORDER, lStyle) PWS_STYLE(strTok, wxSUNKEN_BORDER, lStyle) PWS_STYLE(strTok, wxRAISED_BORDER, lStyle) PWS_STYLE(strTok, wxSTATIC_BORDER, lStyle) PWS_STYLE(strTok, wxNO_BORDER, lStyle) PWS_STYLE(strTok, wxTRANSPARENT_WINDOW, lStyle) PWS_STYLE(strTok, wxTAB_TRAVERSAL, lStyle) PWS_STYLE(strTok, wxWANTS_CHARS, lStyle) PWS_STYLE(strTok, wxNO_FULL_REPAINT_ON_RESIZE, lStyle) PWS_STYLE(strTok, wxVSCROLL, lStyle) PWS_STYLE(strTok, wxHSCROLL, lStyle) PWS_STYLE(strTok, wxALWAYS_SHOW_SB, lStyle) PWS_STYLE(strTok, wxCLIP_CHILDREN, lStyle) PWS_STYLE(strTok, wxFULL_REPAINT_ON_RESIZE, lStyle) PWS_STYLE(strTok, wxDEFAULT_FRAME_STYLE, lStyle) PWS_STYLE(strTok, wxICONIZE, lStyle) PWS_STYLE(strTok, wxCAPTION, lStyle) PWS_STYLE(strTok, wxMINIMIZE, lStyle) PWS_STYLE(strTok, wxMINIMIZE_BOX, lStyle) PWS_STYLE(strTok, wxMAXIMIZE, lStyle) PWS_STYLE(strTok, wxMAXIMIZE_BOX, lStyle) PWS_STYLE(strTok, wxCLOSE_BOX, lStyle) PWS_STYLE(strTok, wxSTAY_ON_TOP, lStyle) PWS_STYLE(strTok, wxSYSTEM_MENU, lStyle) PWS_STYLE(strTok, wxRESIZE_BORDER, lStyle) PWS_STYLE(strTok, wxFRAME_TOOL_WINDOW, lStyle) PWS_STYLE(strTok, wxFRAME_NO_TASKBAR, lStyle) PWS_STYLE(strTok, wxFRAME_FLOAT_ON_PARENT, lStyle) PWS_STYLE(strTok, wxFRAME_EX_CONTEXTHELP, lStyle) PWS_STYLE(strTok, wxFRAME_SHAPED, lStyle) PWS_STYLE(strTok, wxFRAME_EX_METAL, lStyle) } return lStyle;}//////////////////////////////////////////////////////////////////////////////////// \brief Make a vector of the names of the skins in the strDir directory./////////////////////////////////////////////////////////////////////////////////vector<wxString> EnumerateSkinsOneDir(wxString strDir){ vector<wxString> vRtn; wxFileName fnWildcard; wxString strFile; fnWildcard.AssignDir(strDir); fnWildcard.AppendDir(wxT("skins")); char szTmp[256]; strcpy(szTmp, fnWildcard.GetFullPath().mb_str(*wxConvCurrent)); if (!fnWildcard.DirExists()) return vRtn; fnWildcard.SetFullName(wxT("*")); strFile = wxFindFirstFile(fnWildcard.GetFullPath(), wxDIR); while (!strFile.IsEmpty() ) { wxFileName fnThis = strFile; vRtn.push_back(fnThis.GetName()); strFile = wxFindNextFile(); } return vRtn;}//////////////////////////////////////////////////////////////////////////////////// \brief Make a vector of the names of the skins in the common and user/// directory./////////////////////////////////////////////////////////////////////////////////vector<wxString> EnumerateSkins(){ vector<wxString> vRtn; vector<wxString> vTmp; vector<wxString>::iterator i; vRtn = EnumerateSkinsOneDir(GetCommonDataPath()); vTmp = EnumerateSkinsOneDir(GetLocalDataPath()); for (i = vTmp.begin(); i != vTmp.end(); i++) vRtn.push_back(*i); return vRtn;}//////////////////////////////////////////////////////////////////////////////////// \brief Map a skin name to its location./////////////////////////////////////////////////////////////////////////////////wxString ResolveSkinPath(wxString strName){ wxFileName fn; fn = strName; if (fn.DirExists()) return strName; fn.AssignDir(GetCommonDataPath()); fn.AppendDir(wxT("skins")); fn.AppendDir(strName); if (fn.DirExists()) return fn.GetFullPath(); fn.AssignDir(GetLocalDataPath()); fn.AppendDir(wxT("skins")); fn.AppendDir(strName); if (fn.DirExists()) return fn.GetFullPath(); return wxT("");}//////////////////////////////////////////////////////////////////////////////////// \brief Determine the amount of a space a multiline string would take up/// on a certain device context.////// strText is the text whose size is being measured////// dc is the device context////// w and h return the width and height of strText on the dc device context/////////////////////////////////////////////////////////////////////////////////void GetTextExtentMultiline(wxDC * dc, wxString strText, wxCoord * w, wxCoord * h){ wxString strLine; vector<wxString> vLines; int x, y; int iLineHeight; unsigned int iLine; *w = 0; *h = 0; if (strText == wxT("")) return; strLine = strText.BeforeFirst('\n'); strText = strText.AfterFirst('\n'); while (strLine != wxT("")) { vLines.push_back(strLine); strLine = strText.BeforeFirst('\n'); strText = strText.AfterFirst('\n'); } iLineHeight = 0; for (iLine = 0; iLine < vLines.size(); iLine++) { dc->GetTextExtent(vLines[iLine], &x, &y); if (x > *w) *w = x; if (y > iLineHeight) iLineHeight = y; } *h = iLineHeight * vLines.size();}//////////////////////////////////////////////////////////////////////////////////// \brief Loads a font from an XML element/////////////////////////////////////////////////////////////////////////////////wxFont LoadFont(TiXmlElement * root){ int iDefaultFontSize = -1; wxString strDefaultFontName; wxFont fntRtn; TiXmlElement * element; element = root->FirstChildElement(); while (element) { const char * pszName = element->Value(); const char * pszContents = NULL; TiXmlNode * node; for (node = element->FirstChild(); node && node->Type() != TiXmlNode::TEXT; node = node->NextSibling()); if (node) pszContents = node->Value(); if (!strcmp(pszName, "size") && pszContents) iDefaultFontSize = atoi(pszContents); if (!strcmp(pszName, "name") && pszContents) strDefaultFontName = wxString(pszContents, *wxConvCurrent); element = element->NextSiblingElement(); } fntRtn = *wxNORMAL_FONT; if (strDefaultFontName != wxT("")) fntRtn.SetFaceName(strDefaultFontName); if (iDefaultFontSize > 0) fntRtn.SetPointSize(iDefaultFontSize); return fntRtn;}//////////////////////////////////////////////////////////////////////////////////// \brief wxSkinnableFrame_ProportionalCoordinate constructor - initialize everything to zero/////////////////////////////////////////////////////////////////////////////////wxSkinnableFrame_ProportionalCoordinate::wxSkinnableFrame_ProportionalCoordinate(){ m_fMultiplier = 0; m_iOffset1 = 0; m_iOffset2 = 0;}//////////////////////////////////////////////////////////////////////////////////// \brief Loads a proportional position from an XML element/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame_ProportionalCoordinate::Load(TiXmlElement * root){ root->QueryIntAttribute("offset1", &m_iOffset1); root->QueryIntAttribute("offset2", &m_iOffset2); root->QueryDoubleAttribute("multiplier", &m_fMultiplier);}//////////////////////////////////////////////////////////////////////////////////// \brief Loads a pair of coordinates from an XML element/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame_ProportionalPoint::Load(TiXmlElement * root){ TiXmlElement * element; element = root->FirstChildElement("x"); if (!element) return; m_cX.Load(element); element = root->FirstChildElement("y"); if (!element) return; m_cY.Load(element); return;}//////////////////////////////////////////////////////////////////////////////////// \brief Resolve this coordinate given the size of the control/////////////////////////////////////////////////////////////////////////////////int wxSkinnableFrame_ProportionalCoordinate::Resolve(int iMax){ return (int) (m_iOffset1 + (m_iOffset2 + iMax) * m_fMultiplier);}//////////////////////////////////////////////////////////////////////////////////// \brief Resolve this point given the size of the control/////////////////////////////////////////////////////////////////////////////////wxPoint wxSkinnableFrame_ProportionalPoint::Resolve(wxPoint cMax){ return wxPoint(m_cX.Resolve(cMax.x), m_cY.Resolve(cMax.y));}//////////////////////////////////////////////////////////////////////////////////// \brief wxSkinnableFrame_LayoutControl constructor/////////////////////////////////////////////////////////////////////////////////wxSkinnableFrame_LayoutControl::wxSkinnableFrame_LayoutControl(){ m_cCenterWidth = -1; m_iShowMinHeight = 0; m_iShowMinWidth = 0;}//////////////////////////////////////////////////////////////////////////////////// \brief Position this control according to m_coTopLeft and m_coBottomRight/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame_LayoutControl::Position(wxSize szParent){ wxPoint ptTopLeft;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -