ddnet/src/game/client/components/menus_demo.cpp

568 lines
16 KiB
C++
Raw Normal View History

2010-05-29 07:25:38 +00:00
#include <base/math.h>
2010-05-29 07:25:38 +00:00
#include <engine/demo.h>
#include <engine/keys.h>
#include <engine/graphics.h>
#include <engine/storage.h>
2010-05-29 07:25:38 +00:00
#include <game/client/render.h>
#include <game/client/gameclient.h>
#include <game/localization.h>
2010-05-29 07:25:38 +00:00
#include <game/client/ui.h>
#include <game/generated/client_data.h>
2010-05-29 07:25:38 +00:00
#include "menus.h"
2010-05-29 07:25:38 +00:00
int CMenus::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
{
2010-05-29 07:25:38 +00:00
RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
2009-10-27 14:38:53 +00:00
UI()->DoLabel(pRect, pText, 14.0f, 0);
return UI()->DoButtonLogic(pID, pText, Checked, pRect);
}
2010-08-16 02:12:03 +00:00
int CMenus::DoButton_DemoPlayer_Sprite(const void *pID, int SpriteId, int Checked, const CUIRect *pRect)
{
RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_DEMOBUTTONS].m_Id);
Graphics()->QuadsBegin();
2010-08-16 02:12:03 +00:00
RenderTools()->SelectSprite(SpriteId);
IGraphics::CQuadItem QuadItem(pRect->x, pRect->y, pRect->w, pRect->h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
return UI()->DoButtonLogic(pID, "", Checked, pRect);
}
2010-05-29 07:25:38 +00:00
void CMenus::RenderDemoPlayer(CUIRect MainView)
{
2010-05-29 07:25:38 +00:00
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
2010-05-29 07:25:38 +00:00
const float SeekBarHeight = 15.0f;
const float ButtonbarHeight = 20.0f;
const float Margins = 5.0f;
float TotalHeight;
2010-05-29 07:25:38 +00:00
if(m_MenuActive)
TotalHeight = SeekBarHeight+ButtonbarHeight+Margins*3;
else
2010-05-29 07:25:38 +00:00
TotalHeight = SeekBarHeight+Margins*2;
2010-05-29 07:25:38 +00:00
MainView.HSplitBottom(TotalHeight, 0, &MainView);
MainView.VSplitLeft(250.0f, 0, &MainView);
MainView.VSplitRight(250.0f, &MainView, 0);
2010-05-29 07:25:38 +00:00
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_T, 10.0f);
2010-05-29 07:25:38 +00:00
MainView.Margin(5.0f, &MainView);
2010-05-29 07:25:38 +00:00
CUIRect SeekBar, ButtonBar;
int CurrentTick = pInfo->m_CurrentTick - pInfo->m_FirstTick;
int TotalTicks = pInfo->m_LastTick - pInfo->m_FirstTick;
2010-05-29 07:25:38 +00:00
if(m_MenuActive)
{
2010-05-29 07:25:38 +00:00
MainView.HSplitTop(SeekBarHeight, &SeekBar, &ButtonBar);
ButtonBar.HSplitTop(Margins, 0, &ButtonBar);
}
else
2010-05-29 07:25:38 +00:00
SeekBar = MainView;
// do seekbar
{
2010-05-29 07:25:38 +00:00
static int s_SeekBarId = 0;
void *id = &s_SeekBarId;
char aBuffer[128];
2010-05-29 07:25:38 +00:00
RenderTools()->DrawUIRect(&SeekBar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f);
2010-05-29 07:25:38 +00:00
float Amount = CurrentTick/(float)TotalTicks;
2010-05-29 07:25:38 +00:00
CUIRect FilledBar = SeekBar;
FilledBar.w = 10.0f + (FilledBar.w-10.0f)*Amount;
2010-05-29 07:25:38 +00:00
RenderTools()->DrawUIRect(&FilledBar, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
2010-05-29 07:25:38 +00:00
str_format(aBuffer, sizeof(aBuffer), "%d:%02d / %d:%02d",
CurrentTick/SERVER_TICK_SPEED/60, (CurrentTick/SERVER_TICK_SPEED)%60,
TotalTicks/SERVER_TICK_SPEED/60, (TotalTicks/SERVER_TICK_SPEED)%60);
UI()->DoLabel(&SeekBar, aBuffer, SeekBar.h*0.70f, 0);
// do the logic
2010-05-29 07:25:38 +00:00
int Inside = UI()->MouseInside(&SeekBar);
2009-10-27 14:38:53 +00:00
if(UI()->ActiveItem() == id)
{
2009-10-27 14:38:53 +00:00
if(!UI()->MouseButton(0))
UI()->SetActiveItem(0);
else
{
2010-05-29 07:25:38 +00:00
static float PrevAmount = 0.0f;
float Amount = (UI()->MouseX()-SeekBar.x)/(float)SeekBar.w;
if(Amount > 0 && Amount < 1.0f && PrevAmount != Amount)
{
2010-05-29 07:25:38 +00:00
PrevAmount = Amount;
m_pClient->OnReset();
m_pClient->m_SuppressEvents = true;
DemoPlayer()->SetPos(Amount);
m_pClient->m_SuppressEvents = false;
}
}
}
2009-10-27 14:38:53 +00:00
else if(UI()->HotItem() == id)
{
2009-10-27 14:38:53 +00:00
if(UI()->MouseButton(0))
UI()->SetActiveItem(id);
}
2010-05-29 07:25:38 +00:00
if(Inside)
2009-10-27 14:38:53 +00:00
UI()->SetHotItem(id);
}
if(CurrentTick == TotalTicks)
{
DemoPlayer()->Pause();
DemoPlayer()->SetPos(0);
}
2010-05-29 07:25:38 +00:00
if(m_MenuActive)
{
// do buttons
2010-05-29 07:25:38 +00:00
CUIRect Button;
// combined play and pause button
2010-05-29 07:25:38 +00:00
ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
static int s_PlayPauseButton = 0;
if(!pInfo->m_Paused)
2010-05-29 07:25:38 +00:00
{
if(DoButton_DemoPlayer_Sprite(&s_PlayPauseButton, SPRITE_DEMOBUTTON_PAUSE, pInfo->m_Paused, &Button))
2010-05-29 07:25:38 +00:00
DemoPlayer()->Pause();
}
else
{
if(DoButton_DemoPlayer_Sprite(&s_PlayPauseButton, SPRITE_DEMOBUTTON_PLAY, !pInfo->m_Paused, &Button))
2010-08-16 02:12:03 +00:00
DemoPlayer()->Unpause();
}
// stop button
2010-05-29 07:25:38 +00:00
ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
static int s_ResetButton = 0;
if(DoButton_DemoPlayer_Sprite(&s_ResetButton, SPRITE_DEMOBUTTON_STOP, false, &Button))
{
DemoPlayer()->Pause();
DemoPlayer()->SetPos(0);
}
// slowdown
2010-05-29 07:25:38 +00:00
ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
static int s_SlowDownButton = 0;
if(DoButton_DemoPlayer_Sprite(&s_SlowDownButton, SPRITE_DEMOBUTTON_SLOWER, 0, &Button))
{
2010-05-29 07:25:38 +00:00
if(pInfo->m_Speed > 4.0f) DemoPlayer()->SetSpeed(4.0f);
else if(pInfo->m_Speed > 2.0f) DemoPlayer()->SetSpeed(2.0f);
else if(pInfo->m_Speed > 1.0f) DemoPlayer()->SetSpeed(1.0f);
else if(pInfo->m_Speed > 0.5f) DemoPlayer()->SetSpeed(0.5f);
else DemoPlayer()->SetSpeed(0.05f);
}
// fastforward
2010-05-29 07:25:38 +00:00
ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
static int s_FastForwardButton = 0;
if(DoButton_DemoPlayer_Sprite(&s_FastForwardButton, SPRITE_DEMOBUTTON_FASTER, 0, &Button))
{
2010-05-29 07:25:38 +00:00
if(pInfo->m_Speed < 0.5f) DemoPlayer()->SetSpeed(0.5f);
else if(pInfo->m_Speed < 1.0f) DemoPlayer()->SetSpeed(1.0f);
else if(pInfo->m_Speed < 2.0f) DemoPlayer()->SetSpeed(2.0f);
else if(pInfo->m_Speed < 4.0f) DemoPlayer()->SetSpeed(4.0f);
else DemoPlayer()->SetSpeed(8.0f);
}
// speed meter
2010-05-29 07:25:38 +00:00
ButtonBar.VSplitLeft(Margins*3, 0, &ButtonBar);
char aBuffer[64];
if(pInfo->m_Speed >= 1.0f)
str_format(aBuffer, sizeof(aBuffer), "x%.0f", pInfo->m_Speed);
else
2010-05-29 07:25:38 +00:00
str_format(aBuffer, sizeof(aBuffer), "x%.1f", pInfo->m_Speed);
UI()->DoLabel(&ButtonBar, aBuffer, Button.h*0.7f, -1);
2009-06-15 07:34:25 +00:00
// close button
2010-05-29 07:25:38 +00:00
ButtonBar.VSplitRight(ButtonbarHeight*3, &ButtonBar, &Button);
static int s_ExitButton = 0;
if(DoButton_DemoPlayer(&s_ExitButton, Localize("Close"), 0, &Button))
Client()->Disconnect();
}
}
2010-05-29 07:25:38 +00:00
static CUIRect gs_ListBoxOriginalView;
static CUIRect gs_ListBoxView;
static float gs_ListBoxRowHeight;
static int gs_ListBoxItemIndex;
static int gs_ListBoxSelectedIndex;
static int gs_ListBoxNewSelected;
static int gs_ListBoxDoneEvents;
static int gs_ListBoxNumItems;
static int gs_ListBoxItemsPerRow;
static float gs_ListBoxScrollValue;
static bool gs_ListBoxItemActivated;
void CMenus::UiDoListboxStart(void *pId, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems,
int ItemsPerRow, int SelectedIndex, float ScrollValue)
{
2010-05-29 07:25:38 +00:00
CUIRect Scroll, Row;
CUIRect View = *pRect;
CUIRect Header, Footer;
// draw header
2010-05-29 07:25:38 +00:00
View.HSplitTop(ms_ListheaderHeight, &Header, &View);
RenderTools()->DrawUIRect(&Header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f);
UI()->DoLabel(&Header, pTitle, Header.h*ms_FontmodHeight, 0);
// draw footers
2010-05-29 07:25:38 +00:00
View.HSplitBottom(ms_ListheaderHeight, &View, &Footer);
RenderTools()->DrawUIRect(&Footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f);
Footer.VSplitLeft(10.0f, 0, &Footer);
UI()->DoLabel(&Footer, pBottomText, Header.h*ms_FontmodHeight, 0);
// background
2010-05-29 07:25:38 +00:00
RenderTools()->DrawUIRect(&View, vec4(0,0,0,0.15f), 0, 0);
// prepare the scroll
2010-05-29 07:25:38 +00:00
View.VSplitRight(15, &View, &Scroll);
// setup the variables
2010-05-29 07:25:38 +00:00
gs_ListBoxOriginalView = View;
gs_ListBoxSelectedIndex = SelectedIndex;
gs_ListBoxNewSelected = SelectedIndex;
gs_ListBoxItemIndex = 0;
gs_ListBoxRowHeight = RowHeight;
gs_ListBoxNumItems = NumItems;
gs_ListBoxItemsPerRow = ItemsPerRow;
gs_ListBoxDoneEvents = 0;
gs_ListBoxScrollValue = ScrollValue;
gs_ListBoxItemActivated = false;
// do the scrollbar
2010-05-29 07:25:38 +00:00
View.HSplitTop(gs_ListBoxRowHeight, &Row, 0);
2010-05-29 07:25:38 +00:00
int NumViewable = (int)(gs_ListBoxOriginalView.h/Row.h) + 1;
int Num = (NumItems+gs_ListBoxItemsPerRow-1)/gs_ListBoxItemsPerRow-NumViewable+1;
if(Num < 0)
Num = 0;
if(Num > 0)
{
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP))
gs_ListBoxScrollValue -= 1.0f/Num;
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
gs_ListBoxScrollValue += 1.0f/Num;
2010-05-29 07:25:38 +00:00
if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f;
if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f;
}
Scroll.HMargin(5.0f, &Scroll);
gs_ListBoxScrollValue = DoScrollbarV(pId, &Scroll, gs_ListBoxScrollValue);
// the list
2010-05-29 07:25:38 +00:00
gs_ListBoxView = gs_ListBoxOriginalView;
gs_ListBoxView.VMargin(5.0f, &gs_ListBoxView);
UI()->ClipEnable(&gs_ListBoxView);
gs_ListBoxView.y -= gs_ListBoxScrollValue*Num*Row.h;
}
2010-05-29 07:25:38 +00:00
CMenus::CListboxItem CMenus::UiDoListboxNextRow()
{
2010-05-29 07:25:38 +00:00
static CUIRect s_RowView;
CListboxItem Item = {0};
if(gs_ListBoxItemIndex%gs_ListBoxItemsPerRow == 0)
gs_ListBoxView.HSplitTop(gs_ListBoxRowHeight /*-2.0f*/, &s_RowView, &gs_ListBoxView);
s_RowView.VSplitLeft(s_RowView.w/(gs_ListBoxItemsPerRow-gs_ListBoxItemIndex%gs_ListBoxItemsPerRow), &Item.m_Rect, &s_RowView);
Item.m_Visible = 1;
2009-10-27 14:38:53 +00:00
//item.rect = row;
2010-05-29 07:25:38 +00:00
Item.m_HitRect = Item.m_Rect;
2009-10-27 14:38:53 +00:00
//CUIRect select_hit_box = item.rect;
2010-05-29 07:25:38 +00:00
if(gs_ListBoxSelectedIndex == gs_ListBoxItemIndex)
Item.m_Selected = 1;
2009-10-27 14:38:53 +00:00
// make sure that only those in view can be selected
2010-05-29 07:25:38 +00:00
if(Item.m_Rect.y+Item.m_Rect.h > gs_ListBoxOriginalView.y)
2009-10-27 14:38:53 +00:00
{
2010-05-29 07:25:38 +00:00
if(Item.m_HitRect.y < Item.m_HitRect.y) // clip the selection
2009-10-27 14:38:53 +00:00
{
2010-05-29 07:25:38 +00:00
Item.m_HitRect.h -= gs_ListBoxOriginalView.y-Item.m_HitRect.y;
Item.m_HitRect.y = gs_ListBoxOriginalView.y;
2009-10-27 14:38:53 +00:00
}
}
else
2010-05-29 07:25:38 +00:00
Item.m_Visible = 0;
2009-10-27 14:38:53 +00:00
// check if we need to do more
2010-05-29 07:25:38 +00:00
if(Item.m_Rect.y > gs_ListBoxOriginalView.y+gs_ListBoxOriginalView.h)
Item.m_Visible = 0;
2009-10-27 14:38:53 +00:00
2010-05-29 07:25:38 +00:00
gs_ListBoxItemIndex++;
return Item;
2009-10-27 14:38:53 +00:00
}
2010-05-29 07:25:38 +00:00
CMenus::CListboxItem CMenus::UiDoListboxNextItem(void *pId, bool Selected)
2009-10-27 14:38:53 +00:00
{
2010-05-29 07:25:38 +00:00
int ThisItemIndex = gs_ListBoxItemIndex;
if(Selected)
{
2010-05-29 07:25:38 +00:00
if(gs_ListBoxSelectedIndex == gs_ListBoxNewSelected)
gs_ListBoxNewSelected = ThisItemIndex;
gs_ListBoxSelectedIndex = ThisItemIndex;
}
2010-05-29 07:25:38 +00:00
CListboxItem Item = UiDoListboxNextRow();
2010-05-29 07:25:38 +00:00
if(Item.m_Visible && UI()->DoButtonLogic(pId, "", gs_ListBoxSelectedIndex == gs_ListBoxItemIndex, &Item.m_HitRect))
gs_ListBoxNewSelected = ThisItemIndex;
// process input, regard selected index
if(gs_ListBoxSelectedIndex == ThisItemIndex)
{
2010-05-29 07:25:38 +00:00
if(!gs_ListBoxDoneEvents)
{
2010-05-29 07:25:38 +00:00
gs_ListBoxDoneEvents = 1;
if(m_EnterPressed || (Input()->MouseDoubleClick() && UI()->ActiveItem() == pId))
{
2010-05-29 07:25:38 +00:00
gs_ListBoxItemActivated = true;
UI()->SetActiveItem(0);
2010-05-29 07:25:38 +00:00
}
else
{
for(int i = 0; i < m_NumInputEvents; i++)
{
2010-05-29 07:25:38 +00:00
int NewIndex = -1;
if(m_aInputEvents[i].m_Flags&IInput::FLAG_PRESS)
{
if(m_aInputEvents[i].m_Key == KEY_DOWN) NewIndex = gs_ListBoxNewSelected + 1;
if(m_aInputEvents[i].m_Key == KEY_UP) NewIndex = gs_ListBoxNewSelected - 1;
}
if(NewIndex > -1 && NewIndex < gs_ListBoxNumItems)
{
// scroll
int NumViewable = (int)(gs_ListBoxOriginalView.h/gs_ListBoxRowHeight) + 1;
int ScrollNum = (gs_ListBoxNumItems+gs_ListBoxItemsPerRow-1)/gs_ListBoxItemsPerRow-NumViewable+1;
if(ScrollNum > 0 && NewIndex/gs_ListBoxItemsPerRow-gs_ListBoxSelectedIndex/gs_ListBoxItemsPerRow)
{
// TODO: make the scrolling better
if(NewIndex - gs_ListBoxSelectedIndex > 0)
gs_ListBoxScrollValue += 1.0f/ScrollNum;
else
gs_ListBoxScrollValue -= 1.0f/ScrollNum;
if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f;
if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f;
}
gs_ListBoxNewSelected = NewIndex;
}
}
}
}
//selected_index = i;
2010-05-29 07:25:38 +00:00
CUIRect r = Item.m_Rect;
2009-10-27 14:38:53 +00:00
r.Margin(1.5f, &r);
RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
}
2010-05-29 07:25:38 +00:00
return Item;
}
2010-05-29 07:25:38 +00:00
int CMenus::UiDoListboxEnd(float *pScrollValue, bool *pItemActivated)
{
2009-10-27 14:38:53 +00:00
UI()->ClipDisable();
2010-05-29 07:25:38 +00:00
if(pScrollValue)
*pScrollValue = gs_ListBoxScrollValue;
if(pItemActivated)
*pItemActivated = gs_ListBoxItemActivated;
return gs_ListBoxNewSelected;
}
struct FETCH_CALLBACKINFO
{
2010-05-29 07:25:38 +00:00
CMenus *m_pSelf;
const char *m_pPrefix;
};
2010-05-29 07:25:38 +00:00
void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser)
{
2010-06-07 09:27:16 +00:00
if(pName[0] == '.')
return;
2010-06-07 09:27:16 +00:00
2010-05-29 07:25:38 +00:00
FETCH_CALLBACKINFO *pInfo = (FETCH_CALLBACKINFO *)pUser;
2010-05-29 07:25:38 +00:00
CDemoItem Item;
str_format(Item.m_aFilename, sizeof(Item.m_aFilename), "%s/%s", pInfo->m_pPrefix, pName);
str_copy(Item.m_aName, pName, sizeof(Item.m_aName));
pInfo->m_pSelf->m_lDemos.add(Item);
}
2010-05-29 07:25:38 +00:00
void CMenus::DemolistPopulate()
{
2010-05-29 07:25:38 +00:00
m_lDemos.clear();
2010-06-04 20:14:02 +00:00
2010-09-03 19:41:37 +00:00
if(str_comp(m_aCurrentDemoFolder, "demos") != 0) //add parent folder
2010-06-04 20:14:02 +00:00
{
CDemoItem Item;
str_copy(Item.m_aName, "..", sizeof(Item.m_aName));
str_copy(Item.m_aFilename, "..", sizeof(Item.m_aFilename));
m_lDemos.add(Item);
}
2010-05-29 07:25:38 +00:00
char aBuf[512];
2010-06-04 20:14:02 +00:00
str_format(aBuf, sizeof(aBuf), "%s/%s", Client()->UserDirectory(), m_aCurrentDemoFolder);
2010-09-03 19:41:37 +00:00
FETCH_CALLBACKINFO Info = {this, aBuf};
2010-05-29 07:25:38 +00:00
fs_listdir(aBuf, DemolistFetchCallback, &Info);
2010-06-04 20:14:02 +00:00
Info.m_pPrefix = m_aCurrentDemoFolder;
fs_listdir(m_aCurrentDemoFolder, DemolistFetchCallback, &Info);
}
2010-05-29 07:25:38 +00:00
void CMenus::RenderDemoList(CUIRect MainView)
{
static int s_SelectedItem = -1;
2010-05-29 07:25:38 +00:00
static int s_Inited = 0;
if(!s_Inited)
{
2010-05-29 07:25:38 +00:00
DemolistPopulate();
s_Inited = 1;
if(m_lDemos.size() > 0)
s_SelectedItem = 0;
}
bool IsDir = false;
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
{
if(str_comp(m_lDemos[s_SelectedItem].m_aName, "..") == 0 || fs_is_dir(m_lDemos[s_SelectedItem].m_aFilename))
IsDir = true;
}
// delete demo
if(m_DemolistDelEntry)
{
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size() && !IsDir)
{
Storage()->RemoveFile(m_lDemos[s_SelectedItem].m_aFilename);
DemolistPopulate();
s_SelectedItem = s_SelectedItem-1 < 0 ? m_lDemos.size() > 0 ? 0 : -1 : s_SelectedItem-1;
}
m_DemolistDelEntry = false;
}
// render background
2010-05-29 07:25:38 +00:00
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
MainView.Margin(10.0f, &MainView);
2010-05-29 07:25:38 +00:00
CUIRect ButtonBar;
MainView.HSplitBottom(ms_ButtonHeight+5.0f, &MainView, &ButtonBar);
ButtonBar.HSplitTop(5.0f, 0, &ButtonBar);
2010-05-29 07:25:38 +00:00
static int s_DemoListId = 0;
static float s_ScrollValue = 0;
2010-05-29 07:25:38 +00:00
UiDoListboxStart(&s_DemoListId, &MainView, 17.0f, Localize("Demos"), "", m_lDemos.size(), 1, s_SelectedItem, s_ScrollValue);
//for(int i = 0; i < num_demos; i++)
2010-05-29 07:25:38 +00:00
for(sorted_array<CDemoItem>::range r = m_lDemos.all(); !r.empty(); r.pop_front())
{
2010-05-29 07:25:38 +00:00
CListboxItem Item = UiDoListboxNextItem((void*)(&r.front()));
if(Item.m_Visible)
UI()->DoLabel(&Item.m_Rect, r.front().m_aName, Item.m_Rect.h*ms_FontmodHeight, -1);
}
2010-05-29 07:25:38 +00:00
bool Activated = false;
s_SelectedItem = UiDoListboxEnd(&s_ScrollValue, &Activated);
2008-11-17 16:46:21 +00:00
CUIRect RefreshRect, PlayRect, DeleteRect;
ButtonBar.VSplitRight(130.0f, &ButtonBar, &PlayRect);
ButtonBar.VSplitLeft(130.0f, &RefreshRect, &ButtonBar);
ButtonBar.VSplitLeft(10.0f, &DeleteRect, &ButtonBar);
ButtonBar.VSplitLeft(120.0f, &DeleteRect, &ButtonBar);
2008-11-17 16:46:21 +00:00
2010-05-29 07:25:38 +00:00
static int s_RefreshButton = 0;
if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect))
{
2010-05-29 07:25:38 +00:00
DemolistPopulate();
}
2010-06-04 20:14:02 +00:00
2010-05-29 07:25:38 +00:00
static int s_PlayButton = 0;
char aTitleButton[10];
2010-06-04 20:14:02 +00:00
if(IsDir)
str_copy(aTitleButton, Localize("Open"), sizeof(aTitleButton));
2010-06-04 20:14:02 +00:00
else
str_copy(aTitleButton, Localize("Play"), sizeof(aTitleButton));
if(DoButton_Menu(&s_PlayButton, aTitleButton, 0, &PlayRect) || Activated)
2010-09-03 19:41:37 +00:00
{
2010-05-29 07:25:38 +00:00
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
{
2010-09-03 19:41:37 +00:00
if(str_comp(m_lDemos[s_SelectedItem].m_aName, "..") == 0) //parent folder
2010-06-04 20:14:02 +00:00
{
DemoSetParentDirectory();
DemolistPopulate();
s_SelectedItem = m_lDemos.size() > 0 ? 0 : -1;
2010-06-04 20:14:02 +00:00
}
2010-09-03 19:41:37 +00:00
else if(IsDir) //folder
2010-06-04 20:14:02 +00:00
{
2010-09-03 19:41:37 +00:00
char aTemp[256];
str_copy(aTemp, m_aCurrentDemoFolder, sizeof(aTemp));
str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", aTemp, m_lDemos[s_SelectedItem].m_aName);
2010-06-04 20:14:02 +00:00
DemolistPopulate();
s_SelectedItem = m_lDemos.size() > 0 ? 0 : -1;
2010-06-04 20:14:02 +00:00
}
2010-09-03 19:41:37 +00:00
else //file
2010-06-04 20:14:02 +00:00
{
const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename);
if(pError)
2010-08-08 22:35:37 +00:00
PopupMessage(Localize("Error"), str_comp(pError, "error loading demo") ? pError : Localize("error loading demo"), Localize("Ok"));
2010-06-04 20:14:02 +00:00
}
}
}
2008-11-17 16:46:21 +00:00
if(!IsDir)
{
static int s_DeleteButton = 0;
if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &DeleteRect) || m_DeletePressed)
{
if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
m_Popup = POPUP_DELETE_DEMO;
}
}
}
2010-06-04 20:14:02 +00:00
void CMenus::DemoSetParentDirectory()
{
int Stop = 0;
2010-09-03 19:41:37 +00:00
for(int i = 0; i < 256; i++)
2010-06-04 20:14:02 +00:00
{
if(m_aCurrentDemoFolder[i] == '/')
Stop = i;
}
//keeps chars which are before the last '/' and remove chars which are after
2010-09-03 19:41:37 +00:00
for(int i = 0; i < 256; i++)
2010-06-04 20:14:02 +00:00
{
if(i >= Stop)
2010-09-03 19:41:37 +00:00
m_aCurrentDemoFolder[i] = '\0';
2010-06-04 20:14:02 +00:00
}
}