void CheckBox::DrawElement(C4FacetEx &cgo) { // left side: check facet (squared) int x0 = rcBounds.x + cgo.TargetX; int y0 = rcBounds.y + cgo.TargetY; GetRes()->fctCheckbox.GetPhase(fChecked + 2*!fEnabled).DrawX(cgo.Surface, x0, y0, rcBounds.Hgt, rcBounds.Hgt); // right of it: checkbox text CStdFont *pUseFont = pFont ? pFont : &(GetRes()->TextFont); int32_t yOff; float fZoom; if (pUseFont->GetLineHeight() <= rcBounds.Hgt) { yOff = Max<int32_t>(rcBounds.Hgt - pUseFont->GetLineHeight(), 0)/2; fZoom = 1.0f; } else { yOff = 0; fZoom = (float) rcBounds.Hgt / Max(pUseFont->GetLineHeight(), 1); } lpDDraw->TextOut(sCaption.getData(), *pUseFont, fZoom, cgo.Surface, x0 + rcBounds.Hgt + C4GUI_CheckBoxLabelSpacing, y0 + yOff, fEnabled ? dwEnabledClr : dwDisabledClr, ALeft, true); // selection marker if ((fMouseOn && IsInActiveDlg(false)) || HasDrawFocus()) { lpDDraw->SetBlitMode(C4GFXBLIT_ADDITIVE); GetRes()->fctButtonHighlight.DrawX(cgo.Surface, x0+rcBounds.Hgt*1/4, y0+rcBounds.Hgt*1/4, rcBounds.Hgt*1/2, rcBounds.Hgt*1/2); lpDDraw->ResetBlitMode(); } }
void MultilineLabel::DrawElement(C4TargetFacet &cgo) { // get clipping int iClipX, iClipY, iClipX2, iClipY2; pDraw->GetPrimaryClipper(iClipX, iClipY, iClipX2, iClipY2); // draw all lines int32_t iIndex = 0; const char *szLine; int32_t iY = rcBounds.y + cgo.TargetY; CStdFont *pLineFont; DWORD dwLineClr; bool fNewParagraph; while ((szLine = Lines.GetLine(iIndex, &pLineFont, &dwLineClr, &fNewParagraph))) { int32_t iFontLineHeight = pLineFont->GetLineHeight(); // indents between paragraphs if (fNewParagraph && iIndex) iY += iFontLineHeight/3; // clip if (iY > iClipY2) break; if (iY >= iClipY-iFontLineHeight) { // draw line pDraw->TextOut(szLine, *pLineFont, 1.0f, cgo.Surface, rcBounds.x + cgo.TargetX, iY, dwLineClr, ALeft, fMarkup); } // advance line iY += iFontLineHeight; ++iIndex; } }
C4ChatControl::ChatSheet::NickItem::NickItem(class C4Network2IRCUser *pByUser) : pStatusIcon(NULL), pNameLabel(NULL), fFlaggedExisting(false), iStatus(0) { // create elements - will be positioned when resized C4Rect rcDefault(0, 0, 10, 10); AddElement(pStatusIcon = new C4GUI::Icon(rcDefault, C4GUI::Ico_None)); AddElement(pNameLabel = new C4GUI::Label("", rcDefault, ALeft, C4GUI_CaptionFontClr, NULL, false, false, false)); // set height (pos and width set when added to the list) CStdFont *pUseFont = &C4GUI::GetRes()->TextFont; rcBounds.Set(0, 0, 100, pUseFont->GetLineHeight()); // initial update Update(pByUser); }
void MultilineLabel::UpdateHeight() { // size by line count int32_t iIndex = 0; const char *szLine; int32_t iHgt = 0; CStdFont *pLineFont; bool fNewPar; while ((szLine = Lines.GetLine(iIndex, &pLineFont, NULL, &fNewPar))) { int32_t iFontLineHeight = pLineFont->GetLineHeight(); // indents between separate messages if (fNewPar && iIndex) iHgt += iFontLineHeight/3; // text line height iHgt += iFontLineHeight; ++iIndex; } rcBounds.Hgt = std::max<int32_t>(iHgt, 5); // update parent container Element::UpdateSize(); }
C4StartupNetListEntry::C4StartupNetListEntry(C4GUI::ListBox *pForListBox, C4GUI::Element *pInsertBefore, C4StartupNetDlg *pNetDlg) : pNetDlg(pNetDlg), pList(pForListBox), pRefClient(nullptr), pRef(nullptr), fError(false), eQueryType(NRQT_Unknown), iTimeout(0), iInfoIconCount(0), iSortOrder(0), fIsSmall(false), fIsCollapsed(false), fIsEnabled(true), fIsImportant(false) { // calc height int32_t iLineHgt = ::GraphicsResource.TextFont.GetLineHeight(), iHeight = iLineHgt * 2 + 4; // add icons - normal icons use small size, only animated netgetref uses full size rctIconLarge.Set(0, 0, iHeight, iHeight); int32_t iSmallIcon = iHeight * 2 / 3; rctIconSmall.Set((iHeight - iSmallIcon)/2, (iHeight - iSmallIcon)/2, iSmallIcon, iSmallIcon); pIcon = new C4GUI::Icon(rctIconSmall, C4GUI::Ico_Host); AddElement(pIcon); SetBounds(pIcon->GetBounds()); // add to listbox (will get resized horizontally and moved) pForListBox->InsertElement(this, pInsertBefore); // add status icons and text labels now that width is known CStdFont *pUseFont = &(::GraphicsResource.TextFont); int32_t iIconSize = pUseFont->GetLineHeight(); C4Rect rcIconRect = GetContainedClientRect(); int32_t iThisWdt = rcIconRect.Wdt; rcIconRect.x = iThisWdt - iIconSize * (iInfoIconCount + 1); rcIconRect.Wdt = rcIconRect.Hgt = iIconSize; for (auto & pInfoIcon : pInfoIcons) { AddElement(pInfoIcon = new C4GUI::Icon(rcIconRect, C4GUI::Ico_None)); rcIconRect.x -= rcIconRect.Wdt; } C4Rect rcLabelBounds; rcLabelBounds.x = iHeight+3; rcLabelBounds.Hgt = iLineHgt; for (int i=0; i<InfoLabelCount; ++i) { C4GUI::Label *pLbl; rcLabelBounds.y = 1+i*(iLineHgt+2); rcLabelBounds.Wdt = iThisWdt - rcLabelBounds.x - 1; if (!i) rcLabelBounds.Wdt -= iLineHgt; // leave space for topright extra icon AddElement(pLbl = pInfoLbl[i] = new C4GUI::Label("", rcLabelBounds, ALeft, C4GUI_CaptionFontClr)); // label will have collapsed due to no text: Repair it pLbl->SetAutosize(false); pLbl->SetBounds(rcLabelBounds); } // update small state, which will resize this to a small entry UpdateSmallState(); // Set*-function will fill icon and text and calculate actual size }
CStdFont &C4StartupGraphics::GetBlackFontByHeight(int32_t iHgt, float *pfZoom) { // get optimal font for given control size CStdFont *pUseFont; if (iHgt <= BookSmallFont.GetLineHeight()) pUseFont = &BookSmallFont; else if (iHgt <= BookFont.GetLineHeight()) pUseFont = &BookFont; else if (iHgt <= BookFontCapt.GetLineHeight()) pUseFont = &BookFontCapt; else pUseFont = &BookFontTitle; // determine zoom if (pfZoom) { int32_t iLineHgt = pUseFont->GetLineHeight(); if (iLineHgt) *pfZoom = (float) iHgt / (float) iLineHgt; else *pfZoom = 1.0f; // error } return *pUseFont; }
C4PortraitSelDlg::ListItem::ListItem(const char *szFilename) : C4FileSelDlg::ListItem(szFilename), fError(false), fLoaded(false) { CStdFont *pUseFont = &(C4GUI::GetRes()->MiniFont); // determine label text StdStrBuf sDisplayLabel; if (szFilename) { sDisplayLabel.Copy(::GetFilename(szFilename)); ::RemoveExtension(&sDisplayLabel); } else { sDisplayLabel.Ref(LoadResStr("IDS_MSG_NOPORTRAIT")); } // insert linebreaks into label text int32_t iLineHgt = Max<int32_t>( pUseFont->BreakMessage(sDisplayLabel.getData(), ImagePreviewSize - 6, &sFilenameLabelText, false), 1); // set size SetBounds(C4Rect(0, 0, ImagePreviewSize, ImagePreviewSize + iLineHgt)); }
CStdFont &Resource::GetFontByHeight(int32_t iHgt, float *pfZoom) { // get optimal font for given control size CStdFont *pUseFont; if (iHgt <= MiniFont.GetLineHeight()) pUseFont = &MiniFont; else if (iHgt <= TextFont.GetLineHeight()) pUseFont = &TextFont; else if (iHgt <= CaptionFont.GetLineHeight()) pUseFont = &CaptionFont; else pUseFont = &TitleFont; // determine zoom if (pfZoom) { int32_t iLineHgt = pUseFont->GetLineHeight(); if (iLineHgt) *pfZoom = (float) iHgt / (float) iLineHgt; else *pfZoom = 1.0f; // error } return *pUseFont; }
void C4PortraitSelDlg::AddExtraOptions(const C4Rect &rcOptionsRect) { C4GUI::ComponentAligner caOptions(rcOptionsRect, C4GUI_DefDlgIndent, C4GUI_DefDlgSmallIndent, false); CStdFont *pUseFont = &(C4GUI::GetRes()->TextFont); AddElement(new C4GUI::Label( LoadResStr("IDS_CTL_IMPORTIMAGEAS"), caOptions.GetGridCell(0, 3, 0, 1, -1, pUseFont->GetLineHeight(), true), ALeft)); AddElement(pCheckSetPicture = new C4GUI::CheckBox( caOptions.GetGridCell(1, 3, 0, 1, -1, pUseFont->GetLineHeight(), true), LoadResStr("IDS_TEXT_PLAYERIMAGE"), fDefSetPicture)); pCheckSetPicture->SetToolTip( LoadResStr("IDS_DESC_CHANGESTHEIMAGEYOUSEEINTH")); AddElement(pCheckSetBigIcon = new C4GUI::CheckBox( caOptions.GetGridCell(2, 3, 0, 1, -1, pUseFont->GetLineHeight(), true), LoadResStr("IDS_TEXT_LOBBYICON"), fDefSetPicture)); pCheckSetBigIcon->SetToolTip( LoadResStr("IDS_DESC_CHANGESTHEIMAGEYOUSEEINTH2")); }
void Screen::DrawToolTip(const char *szTip, C4FacetEx &cgo, int32_t x, int32_t y) { CStdFont *pUseFont = &(GetRes()->TooltipFont); StdStrBuf sText; pUseFont->BreakMessage(szTip, Min<int32_t>(C4GUI_MaxToolTipWdt, Max<int32_t>(cgo.Wdt, 50)), &sText, true); // get tooltip rect int32_t tWdt,tHgt; if (pUseFont->GetTextExtent(sText.getData(), tWdt, tHgt, true)) { tWdt+=6; tHgt+=4; int32_t tX, tY; if (y < cgo.Y+cgo.TargetY+tHgt+5) tY = Min<int32_t>(y+5, cgo.TargetY+cgo.Hgt-tHgt); else tY = y-tHgt-5; tX = BoundBy<int32_t>(x-tWdt/2, cgo.TargetX+cgo.X, cgo.TargetX+cgo.Wdt-tWdt); // draw tooltip box lpDDraw->DrawBoxDw(cgo.Surface, tX,tY,tX+tWdt-1,tY+tHgt-2, C4GUI_ToolTipBGColor); lpDDraw->DrawFrameDw(cgo.Surface, tX,tY,tX+tWdt-1,tY+tHgt-1, C4GUI_ToolTipFrameColor); // draw tooltip lpDDraw->TextOut(sText.getData(), *pUseFont, 1.0f, cgo.Surface, tX+3,tY+1, C4GUI_ToolTipColor, ALeft); // while there's a tooltip, redraw the bg, because it might overlap Game.GraphicsSystem.InvalidateBg(); } }
void C4StartupNetListEntry::UpdateText() { bool fRestackElements=false; CStdFont *pUseFont = &(::GraphicsResource.TextFont); // adjust icons int32_t sx=iInfoIconCount*pUseFont->GetLineHeight(); int32_t i; for (i=iInfoIconCount; i<MaxInfoIconCount; ++i) { pInfoIcons[i]->SetIcon(C4GUI::Ico_None); pInfoIcons[i]->SetToolTip(nullptr); } // text to labels for (i=0; i<InfoLabelCount; ++i) { int iAvailableWdt = GetClientRect().Wdt - pInfoLbl[i]->GetBounds().x - 1; if (!i) iAvailableWdt -= sx; StdStrBuf BrokenText; pUseFont->BreakMessage(sInfoText[i].getData(), iAvailableWdt, &BrokenText, true); int32_t iHgt, iWdt; if (pUseFont->GetTextExtent(BrokenText.getData(), iWdt, iHgt, true)) { if ((pInfoLbl[i]->GetBounds().Hgt != iHgt) || (pInfoLbl[i]->GetBounds().Wdt != iAvailableWdt)) { C4Rect rcBounds = pInfoLbl[i]->GetBounds(); rcBounds.Wdt = iAvailableWdt; rcBounds.Hgt = iHgt; pInfoLbl[i]->SetBounds(rcBounds); fRestackElements = true; } } pInfoLbl[i]->SetText(BrokenText.getData()); pInfoLbl[i]->SetColor(fIsEnabled ? C4GUI_MessageFontClr : C4GUI_InactMessageFontClr); } if (fRestackElements) UpdateEntrySize(); }
C4Network2ClientListDlg::C4Network2ClientListDlg() : Dialog(::pGUI->GetPreferredDlgRect().Wdt*3/4, ::pGUI->GetPreferredDlgRect().Hgt*3/4, LoadResStr("IDS_NET_CAPTION"), false) { // component layout CStdFont *pUseFont = &::GraphicsResource.TextFont; C4GUI::ComponentAligner caAll(GetContainedClientRect(), 0,0); C4Rect rcStatus = caAll.GetFromBottom(pUseFont->GetLineHeight()); // create game options; max 1/2 of dialog height pGameOptions = new C4GameOptionsList(caAll.GetFromTop(caAll.GetInnerHeight()/2), true, C4GameOptionsList::GOLS_Runtime); pGameOptions->SetDecoration(false, nullptr, true, false); pGameOptions->SetSelectionDiabled(); // but resize to actually used height int32_t iFreedHeight = pGameOptions->ContractToElementHeight(); caAll.ExpandTop(iFreedHeight); AddElement(pGameOptions); // create client list box AddElement(pListBox = new C4Network2ClientListBox(caAll.GetAll(), false)); // create status label AddElement(pStatusLabel = new C4GUI::Label("", rcStatus)); // add timer Application.Add(this); // initial update Update(); }
bool C4FontLoader::InitFont(CStdFont &rFont, C4VectorFont * pFont, int32_t iSize, uint32_t dwWeight, bool fDoShadow) { if (!pFont->pFont) { #ifdef HAVE_FREETYPE // Creation from binary font data if (!pFont->Data.isNull()) pFont->pFont = CStdFont::CreateFont(pFont->Data); // creation from filename if (!pFont->pFont) pFont->pFont = CStdFont::CreateFont(pFont->FileName); #endif // WinGDI: Try creation from font face name only if (!pFont->pFont) pFont->pFont = CStdFont::CreateFont(pFont->Name.getData()); if (!pFont->pFont) return false; // this font can't be used } rFont.Init(*(pFont->pFont), iSize, dwWeight, Config.General.LanguageCharset, fDoShadow); // throws exception on error return true; }
void C4ChatControl::UpdateSize() { // parent update typedef C4GUI::Window ParentClass; ParentClass::UpdateSize(); // position child elements pTabMain->SetBounds(GetContainedClientRect()); pTabChats->SetBounds(pTabChats->GetParent()->GetContainedClientRect()); C4GUI::Tabular::Sheet *pSheetLogin = pTabMain->GetSheet(0); C4GUI::ComponentAligner caLoginSheet(pSheetLogin->GetContainedClientRect(), 0, 0, false); CStdFont *pUseFont = &C4GUI::GetRes()->TextFont; int32_t iIndent1 = C4GUI_DefDlgSmallIndent / 2, iIndent2 = C4GUI_DefDlgIndent / 2; int32_t iLoginHgt = pUseFont->GetLineHeight() * 8 + iIndent1 * 10 + iIndent2 * 10 + C4GUI_ButtonHgt + 20; int32_t iLoginWdt = iLoginHgt * 2 / 3; C4GUI::ComponentAligner caLogin( caLoginSheet.GetCentered( Min<int32_t>(iLoginWdt, caLoginSheet.GetInnerWidth()), Min<int32_t>(iLoginHgt, caLoginSheet.GetInnerHeight())), iIndent1, iIndent1); pLblLoginNick->SetBounds(caLogin.GetFromTop(pUseFont->GetLineHeight())); pEdtLoginNick->SetBounds( caLogin.GetFromTop(C4GUI::Edit::GetDefaultEditHeight())); caLogin.ExpandTop(2 * (iIndent1 - iIndent2)); pLblLoginPass->SetBounds(caLogin.GetFromTop(pUseFont->GetLineHeight())); pEdtLoginPass->SetBounds( caLogin.GetFromTop(C4GUI::Edit::GetDefaultEditHeight())); caLogin.ExpandTop(2 * (iIndent1 - iIndent2)); pLblLoginRealName->SetBounds(caLogin.GetFromTop(pUseFont->GetLineHeight())); pEdtLoginRealName->SetBounds( caLogin.GetFromTop(C4GUI::Edit::GetDefaultEditHeight())); caLogin.ExpandTop(2 * (iIndent1 - iIndent2)); pLblLoginChannel->SetBounds(caLogin.GetFromTop(pUseFont->GetLineHeight())); pEdtLoginChannel->SetBounds( caLogin.GetFromTop(C4GUI::Edit::GetDefaultEditHeight())); caLogin.ExpandTop(2 * (iIndent1 - iIndent2)); pBtnLogin->SetBounds(caLogin.GetFromTop(C4GUI_ButtonHgt, C4GUI_DefButtonWdt)); }
bool C4FontLoader::InitFont(CStdFont &rFont, const char *szFontName, FontType eType, int32_t iSize, C4GroupSet *pGfxGroups, bool fDoShadow) { // safety if (!szFontName || !*szFontName) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // get font to load // pFontDefs may be NULL if no fonts are loaded; but then iFontDefCount is zero as well // the function must not be aborted, because a standard windows font may be loaded std::vector<C4FontDef>::iterator pFontDefC = FontDefs.begin(), pFontDef = FontDefs.end(); while (pFontDefC != FontDefs.end()) { // check font if (pFontDefC->Name == szFontName) { int32_t iSizeDiff = Abs(pFontDefC->iSize - iSize); // better match than last font? if (pFontDef == FontDefs.end() || Abs(pFontDef->iSize - iSize) >= iSizeDiff) pFontDef = pFontDefC; } // check next one ++pFontDefC; } // if def has not been found, use the def as font name // determine font def string const char *szFontString = szFontName; // special: Fonts without shadow are always newly rendered if (!fDoShadow) { pFontDef=FontDefs.end(); } if (pFontDef!=FontDefs.end()) switch (eType) { case C4FT_Log: szFontString = pFontDef->LogFont.getData(); break; case C4FT_MainSmall:szFontString = pFontDef->SmallFont.getData(); break; case C4FT_Main: szFontString = pFontDef->Font.getData(); break; case C4FT_Caption: szFontString = pFontDef->CaptionFont.getData(); break; case C4FT_Title: szFontString = pFontDef->TitleFont.getData(); break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } // font not assigned? if (!*szFontString) { // invalid call or spec LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // get font name char FontFaceName[C4MaxName+1], FontParam[C4MaxName+1]; SCopyUntil(szFontString, FontFaceName, ',', C4MaxName); // is it an image file? const char *szExt = GetExtension(FontFaceName); if (SEqualNoCase(szExt, "png") || SEqualNoCase(szExt, "bmp")) { // image file name: load bitmap font from image file // if no graphics group is given, do not load yet if (!pGfxGroups) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // indent given? int32_t iIndent = 0; if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &iIndent); // load font face from gfx group int32_t iGrpId; C4Group *pGrp = pGfxGroups->FindEntry(FontFaceName, NULL, &iGrpId); if (!pGrp) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // check if it's already loaded from that group with that parameters if (!rFont.IsSameAsID(FontFaceName, iGrpId, iIndent)) { // it's not; so (re-)load it now! if (rFont.IsInitialized()) { // reloading rFont.Clear(); LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iIndent, 0); } C4Surface sfc; if (!sfc.Load(*pGrp, FontFaceName)) { LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } // init font from face try { rFont.Init(GetFilenameOnly(FontFaceName), &sfc, iIndent); } catch (std::runtime_error & e) { LogFatal(e.what()); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } rFont.id = iGrpId; } } else { int32_t iDefFontSize; DWORD dwDefWeight=FW_NORMAL; #if defined(_WIN32) && !defined(HAVE_FREETYPE) switch (eType) { case C4FT_Log: iDefFontSize = 8; break; case C4FT_MainSmall:iDefFontSize = iSize+1; break; case C4FT_Main: iDefFontSize = iSize+4; break; case C4FT_Caption: iDefFontSize = iSize+6; dwDefWeight = FW_BOLD; break; case C4FT_Title: iDefFontSize = iSize*3; break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } #else switch (eType) { case C4FT_Log: iDefFontSize = iSize*12/14; break; case C4FT_MainSmall:iDefFontSize = iSize*13/14; break; case C4FT_Main: iDefFontSize = iSize; break; case C4FT_Caption: iDefFontSize = iSize*16/14; /*dwDefWeight = FW_MEDIUM;*/ break; case C4FT_Title: iDefFontSize = iSize*22/14; /*dwDefWeight = FW_MEDIUM;*/ break; default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call } #endif // regular font name: let WinGDI or Freetype draw a font with the given parameters // font size given? if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &iDefFontSize); // font weight given? if (SCopySegment(szFontString, 2, FontParam, ',', C4MaxName)) sscanf(FontParam, "%i", &dwDefWeight); // check if it's already loaded from that group with that parameters if (!rFont.IsSameAs(FontFaceName, iDefFontSize, dwDefWeight)) { // it's not; so (re-)load it now! if (rFont.IsInitialized()) { // reloading rFont.Clear(); LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iDefFontSize, dwDefWeight); } // init with given font name try { // check if one of the internally listed fonts should be used C4VectorFont * pFont = pVectorFonts; while (pFont) { if (SEqual(pFont->Name.getData(), FontFaceName)) { if (InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) break; } pFont = pFont->pNext; } // no internal font matching? Then create one using the given face/filename (using a system font) if (!pFont) { pFont = new C4VectorFont(); if (pFont->Init(FontFaceName, iDefFontSize, dwDefWeight, Config.General.LanguageCharset)) { AddVectorFont(pFont); if (!InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) throw std::runtime_error(FormatString("Error initializing font %s", FontFaceName).getData()); } else { delete pFont; // no match for font face found throw std::runtime_error(FormatString("Font face %s undefined", FontFaceName).getData()); } } } catch (std::runtime_error & e) { LogFatal(e.what()); LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; } rFont.id = 0; } } // done, success return true; }
void C4FileSelDlg::InitElements() { UpdateSize(); CStdFont *pUseFont = &(C4GUI::GetRes()->TextFont); // main calcs bool fHasOptions = HasExtraOptions(); C4GUI::ComponentAligner caMain(GetClientRect(), 0, 0, true); C4Rect rcOptions; C4GUI::ComponentAligner caButtonArea( caMain.GetFromBottom(C4GUI_ButtonAreaHgt, 2 * C4GUI_DefButton2Wdt + 4 * C4GUI_DefButton2HSpace), C4GUI_DefButton2HSpace, (C4GUI_ButtonAreaHgt - C4GUI_ButtonHgt) / 2); if (fHasOptions) rcOptions = caMain.GetFromBottom(pUseFont->GetLineHeight() + 2 * C4GUI_DefDlgSmallIndent); C4GUI::ComponentAligner caUpperArea(caMain.GetAll(), C4GUI_DefDlgIndent, C4GUI_DefDlgIndent, true); // create file selection area if (iLocationCount) { C4GUI::ComponentAligner caLocations( caUpperArea.GetFromTop(C4GUI::ComboBox::GetDefaultHeight() + 2 * C4GUI_DefDlgSmallIndent), C4GUI_DefDlgIndent, C4GUI_DefDlgSmallIndent, false); StdStrBuf sText(LoadResStr("IDS_TEXT_LOCATION")); AddElement(new C4GUI::Label( sText.getData(), caLocations.GetFromLeft(pUseFont->GetTextWidth(sText.getData())), ALeft)); pLocationComboBox = new C4GUI::ComboBox(caLocations.GetAll()); pLocationComboBox->SetComboCB( new C4GUI::ComboBox_FillCallback<C4FileSelDlg>( this, &C4FileSelDlg::OnLocationComboFill, &C4FileSelDlg::OnLocationComboSelChange)); pLocationComboBox->SetText(pLocations[0].sName.getData()); } // create file selection area bool fHasPreview = HasPreviewArea(); pFileListBox = new C4GUI::ListBox( fHasPreview ? caUpperArea.GetFromLeft(caUpperArea.GetWidth() / 2) : caUpperArea.GetAll(), GetFileSelColWidth()); pFileListBox->SetSelectionChangeCallbackFn( new C4GUI::CallbackHandler<C4FileSelDlg>(this, &C4FileSelDlg::OnSelChange)); pFileListBox->SetSelectionDblClickFn(new C4GUI::CallbackHandler<C4FileSelDlg>( this, &C4FileSelDlg::OnSelDblClick)); if (fHasPreview) { caUpperArea.ExpandLeft(C4GUI_DefDlgIndent); pSelectionInfoBox = new C4GUI::TextWindow(caUpperArea.GetAll()); pSelectionInfoBox->SetDecoration(true, true, NULL, true); } // create button area C4GUI::Button *btnAbort = new C4GUI::CancelButton(caButtonArea.GetFromRight(C4GUI_DefButton2Wdt)); btnOK = new C4GUI::OKButton(caButtonArea.GetFromRight(C4GUI_DefButton2Wdt)); // add components in tab order if (pLocationComboBox) AddElement(pLocationComboBox); AddElement(pFileListBox); if (pSelectionInfoBox) AddElement(pSelectionInfoBox); if (fHasOptions) AddExtraOptions(rcOptions); AddElement(btnOK); AddElement(btnAbort); SetFocus(pFileListBox, false); // no selection yet UpdateSelection(); }