in ID@XboxSDK/Clubs/Xbox/Cpp/SampleGUI.cpp [466:1220]
void LoadLayout(const wchar_t* layoutFile, const wchar_t* imageDir, unsigned offset)
{
static const wchar_t* s_seps = L" ,;|";
static wchar_t s_text[4096] = {};
DX::CSVReader reader(layoutFile, DX::CSVReader::Encoding::ANSI, true);
IPanel* currentPanel = nullptr;
if (imageDir)
m_layoutImageDir = imageDir;
else
m_layoutImageDir.clear();
while (!reader.EndOfFile())
{
// Each record starts with ITEM,ID,RECTX,RECTY,DX,DY
wchar_t item[1024] = {};
if (!reader.NextItem(item))
{
reader.NextRecord();
continue;
}
TrimTrailingWhitespace(item);
unsigned id;
{
// IPanel object ids need to be globally unique
wchar_t tmp[16] = {};
if (!reader.NextItem(tmp))
{
DebugTrace("ERROR: Expected an id for record %zu\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
id = _wtoi(tmp);
}
RECT rct = { 0, 0, 0, 0 };
{
wchar_t tmp[16] = {};
if (!reader.NextItem(tmp))
{
DebugTrace("ERROR: Expected an rectx for record %zu\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
rct.left = _wtoi(tmp);
if (!reader.NextItem(tmp))
{
DebugTrace("ERROR: Expected an recty for record %zu\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
rct.top = _wtoi(tmp);
if (!reader.NextItem(tmp))
{
DebugTrace("ERROR: Expected an dx for record %zu\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
rct.right = rct.left + _wtoi(tmp);
if (!reader.NextItem(tmp))
{
DebugTrace("ERROR: Expected an dy for record %zu\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
rct.bottom = rct.top + _wtoi(tmp);
}
// Create item
if (_wcsicmp(item, L"POPUP") == 0)
{
id += offset;
auto it = m_panels.find(id);
if (it != m_panels.end())
{
DebugTrace("ERROR: Duplicate panel id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
currentPanel = new Popup(rct);
m_panels[id] = currentPanel;
}
else if (_wcsicmp(item, L"HUD") == 0)
{
id += offset;
auto it = m_panels.find(id);
if (it != m_panels.end())
{
DebugTrace("ERROR: Duplicate panel id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
currentPanel = new HUD(rct);
m_panels[id] = currentPanel;
if (!m_hudPanel)
{
currentPanel->Show();
}
}
else if (_wcsicmp(item, L"OVERLAY") == 0)
{
id += offset;
auto it = m_panels.find(id);
if (it != m_panels.end())
{
DebugTrace("ERROR: Duplicate panel id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
currentPanel = new Overlay(rct);
m_panels[id] = currentPanel;
}
else if (_wcsicmp(item, L"LABEL") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: LABEL found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
if (!reader.NextItem(s_text))
{
DebugTrace("ERROR: LABEL missing text string [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
HandleEscapeCharacters(s_text);
unsigned style = 0;
XMVECTOR color = Colors::White;
{
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"LEFT") == 0)
{
style |= TextLabel::c_StyleAlignLeft | TextLabel::c_StyleAlignMiddle;
}
else if (wcscmp(tok, L"CENTER") == 0)
{
style |= TextLabel::c_StyleAlignCenter | TextLabel::c_StyleAlignMiddle;
}
else if (wcscmp(tok, L"RIGHT") == 0)
{
style |= TextLabel::c_StyleAlignRight | TextLabel::c_StyleAlignMiddle;
}
else if (wcscmp(tok, L"LARGE") == 0)
{
style |= TextLabel::c_StyleFontLarge;
}
else if (wcscmp(tok, L"SMALL") == 0)
{
style |= TextLabel::c_StyleFontSmall;
}
else if (wcscmp(tok, L"BOLD") == 0)
{
style |= TextLabel::c_StyleFontBold;
}
else if (wcscmp(tok, L"ITALIC") == 0)
{
style |= TextLabel::c_StyleFontItalic;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= TextLabel::c_StyleTransparent;
}
else if (wcscmp(tok, L"WORDWRAP") == 0)
{
style |= TextLabel::c_StyleWordWrap;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
wchar_t colorStr[32] = {};
if (reader.NextItem(colorStr))
{
_wcsupr_s(colorStr);
color = LoadColorItem(colorStr, reader.RecordIndex());
}
}
}
if (id)
{
// check for duplicates if nonzero ids used
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
}
auto label = new TextLabel(id, s_text, rct, style);
label->SetForegroundColor(color);
currentPanel->Add(label);
}
else if (_wcsicmp(item, L"LEGEND") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: LEGEND found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
if (!reader.NextItem(s_text))
{
DebugTrace("ERROR: LEGEND missing text string [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
HandleEscapeCharacters(s_text);
unsigned style = 0;
XMVECTOR color = Colors::White;
{
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"LEFT") == 0)
{
style |= Legend::c_StyleAlignLeft | Legend::c_StyleAlignMiddle;
}
else if (wcscmp(tok, L"CENTER") == 0)
{
style |= Legend::c_StyleAlignCenter | Legend::c_StyleAlignMiddle;
}
else if (wcscmp(tok, L"RIGHT") == 0)
{
style |= Legend::c_StyleAlignRight | Legend::c_StyleAlignMiddle;
}
else if (wcscmp(tok, L"LARGE") == 0)
{
style |= Legend::c_StyleFontLarge;
}
else if (wcscmp(tok, L"SMALL") == 0)
{
style |= Legend::c_StyleFontSmall;
}
else if (wcscmp(tok, L"BOLD") == 0)
{
style |= Legend::c_StyleFontBold;
}
else if (wcscmp(tok, L"ITALIC") == 0)
{
style |= Legend::c_StyleFontItalic;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= Legend::c_StyleTransparent;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
wchar_t colorStr[32] = {};
if (reader.NextItem(colorStr))
{
_wcsupr_s(colorStr);
color = LoadColorItem(colorStr, reader.RecordIndex());
}
}
}
if (id)
{
// check for duplicates if nonzero ids used
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
}
auto legend = new Legend(id, s_text, rct, style);
legend->SetForegroundColor(color);
currentPanel->Add(legend);
}
else if (_wcsicmp(item, L"IMAGE") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: IMAGE found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
unsigned imageId = 0;
wchar_t imageFile[MAX_PATH] = {};
if (reader.NextItem(imageFile))
{
TrimTrailingWhitespace(imageFile);
imageId = LoadImageItem(imageFile);
}
else
{
DebugTrace("ERROR: IMAGE missing image file name [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
if (id)
{
// check for duplicates if nonzero ids used
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
}
currentPanel->Add(new Image(id, imageId, rct));
}
else if (_wcsicmp(item, L"BUTTON") == 0 || _wcsicmp(item, L"EXITBUTTON") == 0 || _wcsicmp(item, L"DEFBUTTON") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: BUTTON found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
if (!reader.NextItem(s_text))
{
DebugTrace("ERROR: BUTTON missing text string [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
unsigned hotkey = 0;
wchar_t hotkeyStr[64] = {};
unsigned style = 0;
if (reader.NextItem(hotkeyStr))
{
TrimTrailingWhitespace(hotkeyStr);
hotkey = HandleVirtualKeys(hotkeyStr);
// Optional style
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"LARGE") == 0)
{
style |= Button::c_StyleFontLarge;
}
else if (wcscmp(tok, L"SMALL") == 0)
{
style |= Button::c_StyleFontSmall;
}
else if (wcscmp(tok, L"BOLD") == 0)
{
style |= Button::c_StyleFontBold;
}
else if (wcscmp(tok, L"ITALIC") == 0)
{
style |= Button::c_StyleFontItalic;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= Button::c_StyleTransparent;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
}
}
if (_wcsicmp(item, L"EXITBUTTON") == 0)
{
style |= Button::c_StyleExit;
}
else if (_wcsicmp(item, L"DEFBUTTON") == 0)
{
style |= Button::c_StyleExit | Button::c_StyleDefault;
}
// check for duplicate id
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
auto *butn = new Button(id, s_text, rct);
butn->SetStyle(style);
butn->SetHotKey(hotkey);
currentPanel->Add(butn);
}
else if (_wcsicmp(item, L"IMAGEBUTTON") == 0 || _wcsicmp(item, L"EXITIMAGEBUTTON") == 0 || _wcsicmp(item, L"DEFIMAGEBUTTON") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: IMAGEBUTTON found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
unsigned imageId = 0;
wchar_t imageFile[MAX_PATH] = {};
if (reader.NextItem(imageFile))
{
TrimTrailingWhitespace(imageFile);
imageId = LoadImageItem(imageFile);
}
else
{
DebugTrace("ERROR: IMAGEBUTTON missing image file name [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
unsigned hotkey = 0;
wchar_t hotkeyStr[64] = {};
unsigned style = 0;
if (reader.NextItem(hotkeyStr))
{
TrimTrailingWhitespace(hotkeyStr);
hotkey = HandleVirtualKeys(hotkeyStr);
// Optional style
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"BACKGROUND") == 0)
{
style |= ImageButton::c_StyleBackground;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= ImageButton::c_StyleTransparent | ImageButton::c_StyleBackground;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
}
}
if (_wcsicmp(item, L"EXITIMAGEBUTTON") == 0)
{
style |= ImageButton::c_StyleExit;
}
else if (_wcsicmp(item, L"DEFIMAGEBUTTON") == 0)
{
style |= ImageButton::c_StyleExit | ImageButton::c_StyleDefault;
}
// check for duplicate id
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
auto *butn = new ImageButton(id, imageId, rct);
butn->SetStyle(style);
butn->SetHotKey(hotkey);
currentPanel->Add(butn);
}
else if (_wcsicmp(item, L"CHECKBOX") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: CHECKBOX found outside of panel [record %zu]", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
if (!reader.NextItem(s_text))
{
DebugTrace("ERROR: CHECKBOX missing text string [record %zu]", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
unsigned style = 0;
bool checked = false;
{
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"LARGE") == 0)
{
style |= CheckBox::c_StyleFontLarge;
}
else if (wcscmp(tok, L"SMALL") == 0)
{
style |= CheckBox::c_StyleFontSmall;
}
else if (wcscmp(tok, L"BOLD") == 0)
{
style |= CheckBox::c_StyleFontBold;
}
else if (wcscmp(tok, L"ITALIC") == 0)
{
style |= CheckBox::c_StyleFontItalic;
}
else if (wcscmp(tok, L"CHECKED") == 0)
{
checked = true;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= CheckBox::c_StyleTransparent;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
}
}
// check for duplicate id
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
auto *box = new CheckBox(id, s_text, rct, checked);
box->SetStyle(style);
currentPanel->Add(box);
}
else if (_wcsicmp(item, L"SLIDER") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: SLIDER found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
// check for duplicate id
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
unsigned style = 0;
{
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= Slider::c_StyleTransparent;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
}
}
auto slider = new Slider(id, rct);
slider->SetStyle(style);
currentPanel->Add(slider);
}
else if (_wcsicmp(item, L"PROGRESSBAR") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: PROGRESSBAR found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
// check for duplicate id
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
currentPanel->Add(new ProgressBar(id, rct));
}
else if (_wcsicmp(item, L"LISTBOX") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: LISTBOX found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
// check for duplicate id
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
int itemHeight = 0;
wchar_t itemHeightStr[64] = {};
unsigned style = 0;
if (reader.NextItem(itemHeightStr))
{
itemHeight = _wtoi(itemHeightStr);
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"MULTISELECT") == 0)
{
style |= ListBox::c_StyleMultiSelection;
}
else if (wcscmp(tok, L"LARGE") == 0)
{
style |= ListBox::c_StyleFontLarge;
}
else if (wcscmp(tok, L"SMALL") == 0)
{
style |= ListBox::c_StyleFontSmall;
}
else if (wcscmp(tok, L"BOLD") == 0)
{
style |= ListBox::c_StyleFontBold;
}
else if (wcscmp(tok, L"ITALIC") == 0)
{
style |= ListBox::c_StyleFontItalic;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= ListBox::c_StyleTransparent;
}
else if (wcscmp(tok, L"SCROLLBAR") == 0)
{
style |= ListBox::c_StyleScrollBar;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
}
}
currentPanel->Add(new ListBox(id, rct, style, itemHeight));
}
else if (_wcsicmp(item, L"TEXTBOX") == 0)
{
if (!currentPanel)
{
DebugTrace("ERROR: TEXTBOX found outside of panel [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
if (id)
{
// check for duplicates if nonzero ids used
if (currentPanel->Find(id))
{
DebugTrace("ERROR: Duplicate control id found [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
}
if (!reader.NextItem(s_text))
{
DebugTrace("ERROR: TEXTBOX missing text string [record %zu]\n", reader.RecordIndex() + 1);
throw std::exception("LoadLayout");
}
HandleEscapeCharacters(s_text);
unsigned style = 0;
{
wchar_t styleStr[128] = {};
if (reader.NextItem(styleStr))
{
_wcsupr_s(styleStr);
wchar_t* context = nullptr;
const wchar_t* tok = wcstok_s(styleStr, s_seps, &context);
while (tok)
{
if (wcscmp(tok, L"LARGE") == 0)
{
style |= TextBox::c_StyleFontLarge;
}
else if (wcscmp(tok, L"SMALL") == 0)
{
style |= TextBox::c_StyleFontSmall;
}
else if (wcscmp(tok, L"BOLD") == 0)
{
style |= TextBox::c_StyleFontBold;
}
else if (wcscmp(tok, L"ITALIC") == 0)
{
style |= TextBox::c_StyleFontItalic;
}
else if (wcscmp(tok, L"TRANSPARENT") == 0)
{
style |= TextBox::c_StyleTransparent;
}
else if (wcscmp(tok, L"SCROLLBAR") == 0)
{
style |= TextBox::c_StyleScrollBar;
}
tok = wcstok_s(nullptr, s_seps, &context);
}
}
}
currentPanel->Add(new TextBox(id, s_text, rct, style));
}
reader.NextRecord();
}
}