📄 wxskinnableframe.cpp
字号:
if (ApplyControlCommonAttributes(root, &sLayoutControl, sLayoutControl.m_pControl)) { delete pCtl; return true; } // store in vector m_vPositionedControls.push_back(sLayoutControl); SetNamedText(wxString(pszName, *wxConvCurrent), wxString(pszLabel, *wxConvCurrent), false); return false;}//////////////////////////////////////////////////////////////////////////////////// \brief Process the mainwindow element/////////////////////////////////////////////////////////////////////////////////bool wxSkinnableFrame::LoadSkinMainWindow(TiXmlElement * root){ ApplyWindowCommonAttributes(root, this); return false; }//////////////////////////////////////////////////////////////////////////////////// \brief Process the layout element/////////////////////////////////////////////////////////////////////////////////bool wxSkinnableFrame::LoadSkinLayout(TiXmlElement * root){ TiXmlElement * element; element = root->FirstChildElement(); while (element) { const char * pszName = element->Value(); if (!strcmp(pszName, "control")) LoadSkinLayoutControl(element); if (!strcmp(pszName, "button")) LoadSkinLayoutButton(element); if (!strcmp(pszName, "image")) LoadSkinLayoutImage(element); if (!strcmp(pszName, "text")) LoadSkinLayoutText(element); element = element->NextSiblingElement(); } return true; }//////////////////////////////////////////////////////////////////////////////////// \brief Process the global element. Contains various application wide/// settings like min window size, default font size, etc./////////////////////////////////////////////////////////////////////////////////bool wxSkinnableFrame::LoadSkinGlobal(TiXmlElement * root){ TiXmlElement * element; element = root->FirstChildElement(); while (element) { const char * pszName = element->Value(); if (!strcmp(pszName, "font")) { m_fntDefault = LoadFont(element); SetFont(m_fntDefault); } if (!strcmp(pszName, "minsize")) { int iWidth = 0; int iHeight = 0; const char * pszTmp; pszTmp = element->Attribute("width"); if (pszTmp) iWidth = atoi(pszTmp); pszTmp = element->Attribute("height"); if (pszTmp) iHeight = atoi(pszTmp); if (iWidth && iHeight) { wxSize szThis; wxSize szMargin; bool bSizeChanged = false; // figure out how big the status bar, menu bar, etc. are szMargin = GetSize() - GetClientSize(); // convert minsize from client size to window size iWidth += szMargin.x; iHeight += szMargin.y; // set min size SetSizeHints(iWidth, iHeight); // grow window if necessary szThis = GetSize(); if (szThis.x < iWidth) { szThis.x = iWidth; bSizeChanged = true; } if (szThis.y < iHeight) { szThis.y = iHeight; bSizeChanged = true; } if (bSizeChanged) SetSize(szThis); } } element = element->NextSiblingElement(); } return true; }//////////////////////////////////////////////////////////////////////////////////// \brief Load the skin in the specified directory/////////////////////////////////////////////////////////////////////////////////bool wxSkinnableFrame::LoadSkin(wxString strPath, bool bIsFilename){ wxMutexLocker lock(m_mxSkin); TiXmlDocument doc; if (m_strCurrentSkin == strPath) return false; UnloadSkin(); if (bIsFilename) { m_strSkinPath = ResolveSkinPath(strPath); doc.SetValue(GetDataFilename(wxT("skin.xml")).mb_str(*wxConvCurrent)); doc.LoadFile(); } else { m_strSkinPath = wxT(""); doc.Parse(strPath.mb_str(*wxConvCurrent)); } TiXmlElement * element; element = doc.RootElement(); if (!element) return true; element = element->FirstChildElement(); while (element) { const char * pszName = element->Value(); if (!strcmp(pszName, "layout")) LoadSkinLayout(element); if (!strcmp(pszName, "global")) LoadSkinGlobal(element); if (!strcmp(pszName, "mainwindow")) LoadSkinMainWindow(element); element = element->NextSiblingElement(); } map<std::string,wxControl *>::iterator i; for (i = m_mapUnassignedControls.begin(); i != m_mapUnassignedControls.end(); i++) { if ((*i).second) (*i).second->Show(false); } wxTimerEvent event; OnTimerRefresh(event); m_strCurrentSkin = strPath; return false;}//////////////////////////////////////////////////////////////////////////////////// \brief Handle the window being resized/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::OnSize(wxSizeEvent & evEvent){ if (m_vPositionedControls.size() == 0) { wxFrame::OnSize(evEvent); return; } m_pTimerRefresh->Start(100, TRUE);}//////////////////////////////////////////////////////////////////////////////////// \brief Add a named control - one that can be positioned by the skin/// using the control element./////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::AddNamedControl(wxControl * pCtl, wxString strName){ m_mapUnassignedControls[static_cast<const char *>(strName.mb_str(*wxConvCurrent))] = pCtl;}//////////////////////////////////////////////////////////////////////////////////// \brief This function should be overriden by derived classes to produce/// the class called strName, and then call AddNamedControl.////// Such controls cannot be created before LoadSkin, since they'd appear/// in the wrong z-order (beneath all of the skin controls)./////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::CreateNamedControl(wxString strName){}//////////////////////////////////////////////////////////////////////////////////// \brief This function should be overriden by derived classes to/// delete the object called strName that was created in CreateNamedControl////// If the control was created on the stack and added during the frame/// constructor, AddNamedControl should be called again./////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::DeleteNamedControl(wxString strName, wxControl * pControl){}//////////////////////////////////////////////////////////////////////////////////// \brief Update the text in the text field called strName with text /// strNewLabel/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::SetNamedText(wxString strName, wxString strNewLabel, bool bNeedLock){ if (bNeedLock) m_mxSkin.Lock(); std::vector<wxSkinnableFrame_LayoutControl>::iterator i; for (i = m_vPositionedControls.begin(); i != m_vPositionedControls.end(); i++) { if ((*i).m_strName == strName && (*i).m_eType == wxSkinnableFrame_LayoutControl::ctText) { wxString strCompleteLabel = (*i).m_strPrepend + strNewLabel + (*i).m_strAppend; if ((*i).m_pControl->GetLabel() != strCompleteLabel) { // restore the static text to its original size wxSize szCli = GetClientSize(); wxScreenDC dcScr; wxCoord w, h; dcScr.SetFont((*i).m_pControl->GetFont()); GetTextExtentMultiline(&dcScr, strCompleteLabel, &w, &h); (*i).m_cCenterWidth = w; (*i).Position(szCli); (*i).m_pControl->SetLabel(strCompleteLabel); } } } if (bNeedLock) m_mxSkin.Unlock();}//////////////////////////////////////////////////////////////////////////////////// \brief Update the active state on controls with activation key/// strActiveKey/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::SetActive(wxString strActiveKey, bool bActive, bool bNeedLock){ if (bNeedLock) m_mxSkin.Lock(); std::vector<wxSkinnableFrame_LayoutControl>::iterator i; for (i = m_vPositionedControls.begin(); i != m_vPositionedControls.end(); i++) { if ((*i).m_strActiveKey == strActiveKey && (*i).m_eType == wxSkinnableFrame_LayoutControl::ctButton) { wxBitmapButtonNoBackground * pCtl = wxDynamicCast((*i).m_pControl, wxBitmapButtonNoBackground); if (pCtl) pCtl->SetActive(bActive); } } if (bNeedLock) m_mxSkin.Unlock();}//////////////////////////////////////////////////////////////////////////////////// \brief Unload the skin/////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::UnloadSkin(){ vector<wxSkinnableFrame_LayoutControl>::iterator i; for (i = m_vPositionedControls.begin(); i != m_vPositionedControls.end(); i++) { if ((*i).m_eType == wxSkinnableFrame_LayoutControl::ctControl) DeleteNamedControl((*i).m_strName, (*i).m_pControl); else delete (*i).m_pControl; } m_vPositionedControls.clear(); m_strSkinPath = wxT(""); m_fntDefault = *wxNORMAL_FONT; SetFont(m_fntDefault);}//////////////////////////////////////////////////////////////////////////////////// \brief Timer event triggered 100ms after the user stops resizing the/// window. May also schedule itself to be triggered later if it can't get/// a lock on m_mxSkin./////////////////////////////////////////////////////////////////////////////////void wxSkinnableFrame::OnTimerRefresh(wxTimerEvent& event){ // somehow, there's potential for a deadlock here if we just use a regular // mutex locker. Instead, try to get the lock, and if it's not available, // schedule a timer to try again later. if (m_mxSkin.TryLock() != wxMUTEX_NO_ERROR) { m_pTimerRefresh->Start(1, TRUE); return; } vector<wxSkinnableFrame_LayoutControl>::iterator i; wxSize szCli = GetClientSize(); for (i = m_vPositionedControls.begin(); i != m_vPositionedControls.end(); i++) (*i).Position(szCli); Refresh(); m_mxSkin.Unlock();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -