void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer, const wxChar* param, bool rows) { int nrows, ncols; sizer->CalcRowsCols(nrows, ncols); const int nslots = rows ? nrows : ncols; wxStringTokenizer tkn; tkn.SetString(GetParamValue(param), wxT(",")); while (tkn.HasMoreTokens()) { unsigned long l; if (!tkn.GetNextToken().ToULong(&l)) { ReportParamError ( param, "value must be comma-separated list of row numbers" ); break; } if ( (int)l >= nslots ) { ReportParamError ( param, wxString::Format ( "invalid %s index %d: must be less than %d", rows ? "row" : "column", l, nslots ) ); // ignore incorrect value, still try to process the rest continue; } if (rows) sizer->AddGrowableRow(l); else sizer->AddGrowableCol(l); } }
wxObject *wxCollapsiblePaneXmlHandler::DoCreateResource() { if (m_class == wxT("panewindow")) // read the XRC for the pane window { wxXmlNode *n = GetParamNode(wxT("object")); if ( !n ) n = GetParamNode(wxT("object_ref")); if (n) { bool old_ins = m_isInside; m_isInside = false; wxObject *item = CreateResFromNode(n, m_collpane->GetPane(), NULL); m_isInside = old_ins; return item; } else { ReportError("no control within panewindow"); return NULL; } } else { XRC_MAKE_INSTANCE(ctrl, wxCollapsiblePane) wxString label = GetText(wxT("label")); if (label.empty()) { ReportParamError("label", "label cannot be empty"); return NULL; } ctrl->Create(m_parentAsWindow, GetID(), label, GetPosition(), GetSize(), GetStyle(wxT("style"), wxCP_DEFAULT_STYLE), wxDefaultValidator, GetName()); ctrl->Collapse(GetBool(wxT("collapsed"))); SetupWindow(ctrl); wxCollapsiblePane *old_par = m_collpane; m_collpane = ctrl; bool old_ins = m_isInside; m_isInside = true; CreateChildren(m_collpane, true/*only this handler*/); m_isInside = old_ins; m_collpane = old_par; return ctrl; } }
void wxSizerXmlHandler::SetFlexibleMode(wxFlexGridSizer* fsizer) { if (HasParam(wxT("flexibledirection"))) { wxString dir = GetParamValue(wxT("flexibledirection")); if (dir == wxT("wxVERTICAL")) fsizer->SetFlexibleDirection(wxVERTICAL); else if (dir == wxT("wxHORIZONTAL")) fsizer->SetFlexibleDirection(wxHORIZONTAL); else if (dir == wxT("wxBOTH")) fsizer->SetFlexibleDirection(wxBOTH); else { ReportParamError ( wxT("flexibledirection"), wxString::Format("unknown direction \"%s\"", dir) ); } } if (HasParam(wxT("nonflexiblegrowmode"))) { wxString mode = GetParamValue(wxT("nonflexiblegrowmode")); if (mode == wxT("wxFLEX_GROWMODE_NONE")) fsizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE); else if (mode == wxT("wxFLEX_GROWMODE_SPECIFIED")) fsizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); else if (mode == wxT("wxFLEX_GROWMODE_ALL")) fsizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL); else { ReportParamError ( wxT("nonflexiblegrowmode"), wxString::Format("unknown grow mode \"%s\"", mode) ); } } }
wxObject *wxMenuXmlHandler::DoCreateResource() { if (m_class == wxT("wxMenu")) { wxMenu *menu = m_instance ? wxStaticCast(m_instance, wxMenu) : new wxMenu(GetStyle()); wxString title = GetText(wxT("label")); wxString help = GetText(wxT("help")); bool oldins = m_insideMenu; m_insideMenu = true; CreateChildren(menu, true/*only this handler*/); m_insideMenu = oldins; wxMenuBar *p_bar = wxDynamicCast(m_parent, wxMenuBar); if (p_bar) { p_bar->Append(menu, title); } else { wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu); if (p_menu) { p_menu->Append(GetID(), title, menu, help); if (HasParam(wxT("enabled"))) p_menu->Enable(GetID(), GetBool(wxT("enabled"))); } } return menu; } else { wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu); if (m_class == wxT("separator")) p_menu->AppendSeparator(); else if (m_class == wxT("break")) p_menu->Break(); else /*wxMenuItem*/ { int id = GetID(); wxString label = GetText(wxT("label")); wxString accel = GetText(wxT("accel"), false); wxString fullLabel = label; if (!accel.empty()) fullLabel << wxT("\t") << accel; wxItemKind kind = wxITEM_NORMAL; if (GetBool(wxT("radio"))) kind = wxITEM_RADIO; if (GetBool(wxT("checkable"))) { if ( kind != wxITEM_NORMAL ) { ReportParamError ( "checkable", "menu item can't have both <radio> and <checkable> properties" ); } kind = wxITEM_CHECK; } wxMenuItem *mitem = new wxMenuItem(p_menu, id, fullLabel, GetText(wxT("help")), kind); #if (!defined(__WXMSW__) && !defined(__WXPM__)) || wxUSE_OWNER_DRAWN if (HasParam(wxT("bitmap"))) { // currently only wxMSW has support for using different checked // and unchecked bitmaps for menu items #ifdef __WXMSW__ if (HasParam(wxT("bitmap2"))) mitem->SetBitmaps(GetBitmap(wxT("bitmap2"), wxART_MENU), GetBitmap(wxT("bitmap"), wxART_MENU)); else #endif // __WXMSW__ mitem->SetBitmap(GetBitmap(wxT("bitmap"), wxART_MENU)); } #endif p_menu->Append(mitem); mitem->Enable(GetBool(wxT("enabled"), true)); if (kind == wxITEM_CHECK) mitem->Check(GetBool(wxT("checked"))); } return NULL; } }
wxObject *wxToolBarXmlHandlerEx::DoCreateResource() { if (m_class == wxT("tool")) { if (!m_toolbar) { ReportError("tool only allowed inside a wxToolBar"); return NULL; } wxItemKind kind = wxITEM_NORMAL; if (GetBool(wxT("radio"))) kind = wxITEM_RADIO; if (GetBool(wxT("toggle"))) { if (kind != wxITEM_NORMAL) { ReportParamError ( "toggle", "tool can't have both <radio> and <toggle> properties" ); } kind = wxITEM_CHECK; } #if wxUSE_MENUS // check whether we have dropdown tag inside wxMenu *menu = NULL; // menu for drop down items wxXmlNode * const nodeDropdown = GetParamNode("dropdown"); if (nodeDropdown) { if (kind != wxITEM_NORMAL) { ReportParamError ( "dropdown", "drop-down tool can't have neither <radio> nor <toggle> properties" ); } kind = wxITEM_DROPDOWN; // also check for the menu specified inside dropdown (it is // optional and may be absent for e.g. dynamically-created // menus) wxXmlNode * const nodeMenu = nodeDropdown->GetChildren(); if (nodeMenu) { wxObject *res = CreateResFromNode(nodeMenu, NULL); menu = dynamic_cast<wxMenu*>(res); if (!menu) { ReportError ( nodeMenu, "drop-down tool contents can only be a wxMenu" ); } if (nodeMenu->GetNext()) { ReportError ( nodeMenu->GetNext(), "unexpected extra contents under drop-down tool" ); } } } #endif wxBitmap bitmap = GetBitmap(wxT("bitmap"), wxART_TOOLBAR, m_iconSize); wxBitmap bitmap2 = GetBitmap(wxT("bitmap2"), wxART_TOOLBAR, m_iconSize); #ifdef __WXMAC__ if( bitmap.IsOk() ) { if( bitmap.GetSize().x < 24 ) { bitmap = wxBitmap(bitmap.ConvertToImage().Size(wxSize(24, 24), wxPoint(4, 4))); } } if( bitmap2.IsOk() ) { if( bitmap2.GetSize().x < 24 ) { bitmap2 = wxBitmap(bitmap2.ConvertToImage().Size(wxSize(24, 24), wxPoint(4, 4))); } } #endif #ifdef __WXGTK3__ // We need to provide a disabled bitmap. if( !bitmap2.IsOk() && bitmap.IsOk() ) { bitmap2 = wxBitmap(bitmap.ConvertToImage().ConvertToGreyscale()); } #endif wxToolBarToolBase * const tool = m_toolbar->AddTool ( GetID(), GetText(wxT("label")), bitmap, bitmap2, kind, GetText(wxT("tooltip")), GetText(wxT("longhelp")) ); if (GetBool(wxT("disabled"))) m_toolbar->EnableTool(tool->GetId(), false); if (GetBool(wxS("checked"))) { if (kind == wxITEM_NORMAL) { ReportParamError ( "checked", "only <radio> nor <toggle> tools can be checked" ); } else { m_toolbar->ToggleTool(tool->GetId(), true); } } #if wxUSE_MENUS if (menu) tool->SetDropdownMenu(menu); #endif return m_toolbar; // must return non-NULL } else if (m_class == wxT("separator") || m_class == wxT("space")) { if (!m_toolbar) { ReportError("separators only allowed inside wxToolBar"); return NULL; } if (m_class == wxT("separator")) m_toolbar->AddSeparator(); else m_toolbar->AddStretchableSpace(); return m_toolbar; // must return non-NULL } else /*<object class="wxToolBar">*/ { int style = GetStyle(wxT("style"), wxNO_BORDER | wxTB_HORIZONTAL); #ifdef __WXMSW__ if (!(style & wxNO_BORDER)) style |= wxNO_BORDER; #endif XRC_MAKE_INSTANCE(toolbar, wxToolBar) toolbar->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), style, GetName()); SetupWindow(toolbar); toolbar->SetToolBitmapSize(m_iconSize); wxSize margins = GetSize(wxT("margins")); if (!(margins == wxDefaultSize)) toolbar->SetMargins(margins.x, margins.y); long packing = GetLong(wxT("packing"), -1); if (packing != -1) toolbar->SetToolPacking(packing); long separation = GetLong(wxT("separation"), -1); if (separation != -1) toolbar->SetToolSeparation(separation); wxXmlNode *children_node = GetParamNode(wxT("object")); if (!children_node) children_node = GetParamNode(wxT("object_ref")); if (children_node == NULL) return toolbar; m_isInside = true; m_toolbar = toolbar; wxXmlNode *n = children_node; while (n) { if ((n->GetType() == wxXML_ELEMENT_NODE) && (n->GetName() == wxT("object") || n->GetName() == wxT("object_ref"))) { wxObject *created = CreateResFromNode(n, toolbar, NULL); wxControl *control = dynamic_cast<wxControl*>(created); if (!IsOfClass(n, wxT("tool")) && !IsOfClass(n, wxT("separator")) && !IsOfClass(n, wxT("space")) && control != NULL) toolbar->AddControl(control); } n = n->GetNext(); } m_isInside = false; m_toolbar = NULL; if (m_parentAsWindow && !GetBool(wxT("dontattachtoframe"))) { wxFrame *parentFrame = dynamic_cast<wxFrame*>(m_parent); if (parentFrame) parentFrame->SetToolBar(toolbar); } toolbar->Realize(); return toolbar; } }
wxObject *wxAuiToolBarXmlHandler::DoCreateResource() { if (m_class == wxS("tool")) { if ( !m_toolbar ) { ReportError("tool only allowed inside a wxAuiToolBar"); return NULL; } wxItemKind kind = wxITEM_NORMAL; if (GetBool(wxS("radio"))) kind = wxITEM_RADIO; if (GetBool(wxS("toggle"))) { if ( kind != wxITEM_NORMAL ) { ReportParamError ( "toggle", "tool can't have both <radio> and <toggle> properties" ); } kind = wxITEM_CHECK; } #if wxUSE_MENUS // check whether we have dropdown tag inside wxMenu *menu = NULL; // menu for drop down items wxXmlNode * const nodeDropdown = GetParamNode("dropdown"); if ( nodeDropdown ) { // also check for the menu specified inside dropdown (it is // optional and may be absent for e.g. dynamically-created // menus) wxXmlNode * const nodeMenu = GetNodeChildren(nodeDropdown); if ( nodeMenu ) { wxObject *res = CreateResFromNode(nodeMenu, NULL); menu = wxDynamicCast(res, wxMenu); if ( !menu ) { ReportError ( nodeMenu, "drop-down tool contents can only be a wxMenu" ); } if ( GetNodeNext(nodeMenu) ) { ReportError ( GetNodeNext(nodeMenu), "unexpected extra contents under drop-down tool" ); } } } #endif wxAuiToolBarItem * const tool = m_toolbar->AddTool ( GetID(), GetText(wxS("label")), GetBitmap(wxS("bitmap"), wxART_TOOLBAR, m_toolSize), GetBitmap(wxS("bitmap2"), wxART_TOOLBAR, m_toolSize), kind, GetText(wxS("tooltip")), GetText(wxS("longhelp")), NULL ); if ( GetBool(wxS("disabled")) ) m_toolbar->EnableTool(GetID(), false); #if wxUSE_MENUS if (menu) { tool->SetHasDropDown(true); tool->SetUserData(m_menuHandler.RegisterMenu(m_toolbar, GetID(), menu)); } #endif return m_toolbar; // must return non-NULL } else if (m_class == wxS("separator") || m_class == wxS("space") || m_class == wxS("label")) { if ( !m_toolbar ) { ReportError("separators only allowed inside wxAuiToolBar"); return NULL; } if ( m_class == wxS("separator") ) m_toolbar->AddSeparator(); else if (m_class == wxS("space")) { // This may be a stretch spacer (the default) or a non-stretch one bool hasProportion = HasParam(wxS("proportion")); bool hasWidth = HasParam(wxS("width")); if (hasProportion && hasWidth) { ReportError("A space can't both stretch and have width"); return NULL; } if (hasWidth) { m_toolbar->AddSpacer ( GetLong(wxS("width")) ); } else { m_toolbar->AddStretchSpacer ( GetLong(wxS("proportion"), 1l) ); } } else if (m_class == wxS("label")) { m_toolbar->AddLabel ( GetID(), GetText(wxS("label")), GetLong(wxS("width"), -1l) ); } return m_toolbar; // must return non-NULL } else /*<object class="wxAuiToolBar">*/ { int style = GetStyle(wxS("style"), wxNO_BORDER | wxTB_HORIZONTAL); #ifdef __WXMSW__ if (!(style & wxNO_BORDER)) style |= wxNO_BORDER; #endif XRC_MAKE_INSTANCE(toolbar, wxAuiToolBar) toolbar->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), style); toolbar->SetName(GetName()); SetupWindow(toolbar); m_toolSize = GetSize(wxS("bitmapsize")); if (!(m_toolSize == wxDefaultSize)) toolbar->SetToolBitmapSize(m_toolSize); wxSize margins = GetSize(wxS("margins")); if (!(margins == wxDefaultSize)) toolbar->SetMargins(margins.x, margins.y); long packing = GetLong(wxS("packing"), -1); if (packing != -1) toolbar->SetToolPacking(packing); long separation = GetLong(wxS("separation"), -1); if (separation != -1) toolbar->SetToolSeparation(separation); wxXmlNode *children_node = GetParamNode(wxS("object")); if (!children_node) children_node = GetParamNode(wxS("object_ref")); if (children_node == NULL) return toolbar; m_isInside = true; m_toolbar = toolbar; wxXmlNode *n = children_node; while (n) { if (IsObjectNode(n)) { wxObject *created = CreateResFromNode(n, toolbar, NULL); wxControl *control = wxDynamicCast(created, wxControl); if (!IsOfClass(n, wxS("tool")) && !IsOfClass(n, wxS("separator")) && !IsOfClass(n, wxS("label")) && !IsOfClass(n, wxS("space")) && control != NULL) toolbar->AddControl(control); } n = GetNodeNext(n); } m_isInside = false; m_toolbar = NULL; toolbar->Realize(); return toolbar; } }
wxObject *wxTreebookXmlHandler::DoCreateResource() { if (m_class == wxT("wxTreebook")) { XRC_MAKE_INSTANCE(tbk, wxTreebook) tbk->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle(wxT("style")), GetName()); wxImageList *imagelist = GetImageList(); if ( imagelist ) tbk->AssignImageList(imagelist); wxTreebook * old_par = m_tbk; m_tbk = tbk; bool old_ins = m_isInside; m_isInside = true; wxArrayTbkPageIndexes old_treeContext = m_treeContext; m_treeContext.Clear(); CreateChildren(m_tbk, true/*only this handler*/); wxXmlNode *node = GetParamNode("object"); int pageIndex = 0; for (unsigned int i = 0; i < m_tbk->GetPageCount(); i++) { if ( m_tbk->GetPage(i) ) { wxXmlNode *child = node->GetChildren(); while (child) { if (child->GetName() == "expanded" && child->GetNodeContent() == "1") m_tbk->ExpandNode(pageIndex, true); child = child->GetNext(); } pageIndex++; } } m_treeContext = old_treeContext; m_isInside = old_ins; m_tbk = old_par; return tbk; } // else ( m_class == wxT("treebookpage") ) wxXmlNode *n = GetParamNode(wxT("object")); wxWindow *wnd = NULL; if ( !n ) n = GetParamNode(wxT("object_ref")); if (n) { bool old_ins = m_isInside; m_isInside = false; wxObject *item = CreateResFromNode(n, m_tbk, NULL); m_isInside = old_ins; wnd = wxDynamicCast(item, wxWindow); if (wnd == NULL && item != NULL) { ReportError(n, "treebookpage child must be a window"); } } size_t depth = GetLong( wxT("depth") ); if( depth <= m_treeContext.GetCount() ) { // first prepare the icon int imgIndex = wxNOT_FOUND; if ( HasParam(wxT("bitmap")) ) { wxBitmap bmp = GetBitmap(wxT("bitmap"), wxART_OTHER); wxImageList *imgList = m_tbk->GetImageList(); if ( imgList == NULL ) { imgList = new wxImageList( bmp.GetWidth(), bmp.GetHeight() ); m_tbk->AssignImageList( imgList ); } imgIndex = imgList->Add(bmp); } else if ( HasParam(wxT("image")) ) { if ( m_tbk->GetImageList() ) { imgIndex = GetLong(wxT("image")); } else // image without image list? { ReportError(n, "image can only be used in conjunction " "with imagelist"); } } // then add the page to the corresponding parent if( depth < m_treeContext.GetCount() ) m_treeContext.RemoveAt(depth, m_treeContext.GetCount() - depth ); if( depth == 0) { m_tbk->AddPage(wnd, GetText(wxT("label")), GetBool(wxT("selected")), imgIndex); } else { m_tbk->InsertSubPage(m_treeContext.Item(depth - 1), wnd, GetText(wxT("label")), GetBool(wxT("selected")), imgIndex); } m_treeContext.Add( m_tbk->GetPageCount() - 1); } else { ReportParamError("depth", "invalid depth"); } return wnd; }
wxObject *wxStatusBarXmlHandler::DoCreateResource() { XRC_MAKE_INSTANCE(statbar, wxStatusBar) statbar->Create(m_parentAsWindow, GetID(), GetStyle(), GetName()); int fields = GetLong(wxT("fields"), 1); wxString widths = GetParamValue(wxT("widths")); wxString styles = GetParamValue(wxT("styles")); if (fields > 1 && !widths.IsEmpty()) { int *width = new int[fields]; for (int i = 0; i < fields; ++i) { width[i] = wxAtoi(widths.BeforeFirst(wxT(','))); if(widths.Find(wxT(','))) widths.Remove(0, widths.Find(wxT(',')) + 1); } statbar->SetFieldsCount(fields, width); delete[] width; } else statbar->SetFieldsCount(fields); if (!styles.empty()) { int *style = new int[fields]; for (int i = 0; i < fields; ++i) { style[i] = wxSB_NORMAL; wxString first = styles.BeforeFirst(wxT(',')); if (first == wxT("wxSB_NORMAL")) style[i] = wxSB_NORMAL; else if (first == wxT("wxSB_FLAT")) style[i] = wxSB_FLAT; else if (first == wxT("wxSB_RAISED")) style[i] = wxSB_RAISED; else if (!first.empty()) { ReportParamError ( "styles", wxString::Format ( "unknown status bar field style \"%s\"", first ) ); } if(styles.Find(wxT(','))) styles.Remove(0, styles.Find(wxT(',')) + 1); } statbar->SetStatusStyles(fields, style); delete [] style; } CreateChildren(statbar); if (m_parentAsWindow) { wxFrame *parentFrame = wxDynamicCast(m_parent, wxFrame); if (parentFrame) parentFrame->SetStatusBar(statbar); } return statbar; }
void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer, const wxChar* param, bool rows) { int nrows, ncols; sizer->CalcRowsCols(nrows, ncols); const int nslots = rows ? nrows : ncols; wxStringTokenizer tkn; tkn.SetString(GetParamValue(param), wxT(",")); while (tkn.HasMoreTokens()) { wxString propStr; wxString idxStr = tkn.GetNextToken().BeforeFirst(wxT(':'), &propStr); unsigned long li; if (!idxStr.ToULong(&li)) { ReportParamError ( param, "value must be a comma-separated list of numbers" ); break; } unsigned long lp = 0; if (!propStr.empty()) { if (!propStr.ToULong(&lp)) { ReportParamError ( param, "value must be a comma-separated list of numbers" ); break; } } const int n = static_cast<int>(li); if ( n >= nslots ) { ReportParamError ( param, wxString::Format ( "invalid %s index %d: must be less than %d", rows ? "row" : "column", n, nslots ) ); // ignore incorrect value, still try to process the rest continue; } if (rows) sizer->AddGrowableRow(n, static_cast<int>(lp)); else sizer->AddGrowableCol(n, static_cast<int>(lp)); } }
int wxSizerXmlHandler::GetSizerFlags() { const wxString s = GetParamValue(wxS("flag")); if ( s.empty() ) return 0; // Parse flags keeping track of invalid combinations. This is somewhat // redundant with the checks performed in wxSizer subclasses themselves but // doing it here allows us to give the exact line number at which the // offending line numbers are given, which is very valuable. // // We also can detect invalid flags combinations involving wxALIGN_LEFT and // wxALIGN_TOP here, while this is impossible at wxSizer level as both of // these flags have value of 0. // As the logic is exactly the same in horizontal and vertical // orientations, use arrays and loops to avoid duplicating the code. enum Orient { Orient_Horz, Orient_Vert, Orient_Max }; const char* const orientName[] = { "horizontal", "vertical" }; // The already seen alignment flag in the given orientation or empty if // none have been seen yet. wxString alignFlagIn[] = { wxString(), wxString() }; // Either "wxEXPAND" or "wxGROW" depending on the string used in the input, // or empty string if none is specified. wxString expandFlag; // Either "wxALIGN_CENTRE" or "wxALIGN_CENTER" if either flag was found or // empty string. wxString centreFlag; // Indicates whether we can use alignment in the given orientation at all. bool alignAllowedIn[] = { true, true }; // Find out the sizer orientation: it is the principal/major size direction // for the 1D sizers and undefined/invalid for the 2D ones. Orient orientSizer; if ( wxBoxSizer* const boxSizer = wxDynamicCast(m_parentSizer, wxBoxSizer) ) { orientSizer = boxSizer->GetOrientation() == wxHORIZONTAL ? Orient_Horz : Orient_Vert; // Alignment can be only used in the transversal/minor direction. alignAllowedIn[orientSizer] = false; } else { orientSizer = Orient_Max; } int flags = 0; wxStringTokenizer tkn(s, wxS("| \t\n"), wxTOKEN_STRTOK); while ( tkn.HasMoreTokens() ) { const wxString flagName = tkn.GetNextToken(); const int n = m_styleNames.Index(flagName); if ( n == wxNOT_FOUND ) { ReportParamError ( "flag", wxString::Format("unknown sizer flag \"%s\"", flagName) ); continue; } // Flag description is the string that appears in the error messages, // the main difference from the flag name is that it can indicate that // wxALIGN_CENTRE_XXX flag could have been encountered as part of // wxALIGN_CENTRE which should make the error message more clear as // seeing references to e.g. wxALIGN_CENTRE_VERTICAL when it's never // used could be confusing. wxString flagDesc = wxS('"') + flagName + wxS('"'); int flag = m_styleValues[n]; bool flagSpecifiesAlignIn[] = { false, false }; switch ( flag ) { case wxALIGN_CENTRE_HORIZONTAL: case wxALIGN_RIGHT: flagSpecifiesAlignIn[Orient_Horz] = true; break; case wxALIGN_CENTRE_VERTICAL: case wxALIGN_BOTTOM: flagSpecifiesAlignIn[Orient_Vert] = true; break; case wxEXPAND: expandFlag = flagName; break; case wxALIGN_CENTRE: // wxALIGN_CENTRE is a combination of wxALIGN_CENTRE_HORIZONTAL // and wxALIGN_CENTRE_VERTICAL but we also handle it as just // one of those flags if alignment in the other direction is // not allowed for both compatibility and convenience reasons. switch ( orientSizer ) { case Orient_Horz: flagSpecifiesAlignIn[Orient_Vert] = true; flagDesc.Printf ( "\"wxALIGN_CENTRE_VERTICAL\" (as part of %s)", flagName ); flag = wxALIGN_CENTRE_VERTICAL; break; case Orient_Vert: flagSpecifiesAlignIn[Orient_Horz] = true; flagDesc.Printf ( "\"wxALIGN_CENTRE_HORIZONTAL\" (as part of %s)", flagName ); flag = wxALIGN_CENTRE_HORIZONTAL; break; case Orient_Max: // For 2D sizers we need to deal with this flag at the // end, so just remember that we had it for now. centreFlag = flagName; flag = 0; break; } break; case 0: // This is a special case: both wxALIGN_LEFT and wxALIGN_TOP // have value of 0, so we need to examine the name of the flag // and not just its value. if ( flagName == wxS("wxALIGN_LEFT") ) flagSpecifiesAlignIn[Orient_Horz] = true; else if ( flagName == wxS("wxALIGN_TOP") ) flagSpecifiesAlignIn[Orient_Vert] = true; break; } for ( int orient = 0; orient < Orient_Max; orient++ ) { if ( !flagSpecifiesAlignIn[orient] ) continue; if ( !alignAllowedIn[orient] ) { ReportParamError ( "flag", wxString::Format ( "%s alignment flag %s has no effect inside " "a %s box sizer, remove it and consider inserting " "a spacer instead", orientName[orient], flagDesc, orientName[orient] ) ); // Notice that we take care to not add this invalid flag to the // flags we will actually use with wxSizer: they would just // trigger an assert there which wouldn't be very useful as // we've already given an error about this. flag = 0; } else if ( alignFlagIn[orient].empty() ) { alignFlagIn[orient] = flagDesc; } else { ReportParamError ( "flag", wxString::Format ( "both %s and %s specify %s alignment " "and can't be used together", alignFlagIn[orient], flagDesc, orientName[orient] ) ); flag = 0; } } flags |= flag; } // Now that we know all the alignment flags we can interpret wxALIGN_CENTRE // for the 2D sizers ("centreFlag" is only set in the 2D case). if ( !centreFlag.empty() ) { if ( !expandFlag.empty() ) { ReportParamError ( "flag", wxString::Format ( "\"%s\" has no effect when combined with \"%s\"", centreFlag, expandFlag ) ); } else // !wxEXPAND { int flagsCentre = 0; if ( alignFlagIn[Orient_Horz].empty() ) flagsCentre |= wxALIGN_CENTRE_HORIZONTAL; if ( alignFlagIn[Orient_Vert].empty() ) flagsCentre |= wxALIGN_CENTRE_VERTICAL; if ( !flagsCentre ) { ReportParamError ( "flag", wxString::Format ( "\"%s\" flag has no effect when combined " "with both %s and %s horizontal and " "vertical alignment flags", centreFlag, alignFlagIn[Orient_Horz], alignFlagIn[Orient_Vert] ) ); } flags |= flagsCentre; } } // Finally check that the alignment flags are compatible with wxEXPAND. if ( !expandFlag.empty() ) { if ( orientSizer != Orient_Max ) { const Orient orientOther = orientSizer == Orient_Horz ? Orient_Vert : Orient_Horz; if ( !alignFlagIn[orientOther].empty() ) { ReportParamError ( "flag", wxString::Format ( "\"%s\" is incompatible with %s alignment flag " "\"%s\" in a %s box sizer", expandFlag, orientName[orientOther], alignFlagIn[orientOther], orientName[orientSizer] ) ); // Just as with the alignment flags above, ignore wxEXPAND // completely to avoid asserts from wxSizer code. flags &= ~wxEXPAND; } } else // 2D sizer { if ( !alignFlagIn[Orient_Horz].empty() && !alignFlagIn[Orient_Vert].empty() ) { ReportParamError ( "flag", wxString::Format ( "\"%s\" flag has no effect when combined " "with both %s and %s horizontal and " "vertical alignment flags", expandFlag, alignFlagIn[Orient_Horz], alignFlagIn[Orient_Vert] ) ); flags &= ~wxEXPAND; } } } return flags; }