initial import of radio message - UNTESTED, DO NOT EVEN TRY LOL
added supported mods for radio messages into core gameconf various internal fixes/improvements for menus --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40786
This commit is contained in:
parent
11bd835e55
commit
94c0783d5c
@ -10,5 +10,40 @@
|
||||
"linux" "14"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"cstrike"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"HudRadioMenuMsg" "ShowMenu"
|
||||
}
|
||||
}
|
||||
|
||||
"dod"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"HudRadioMenuMsg" "ShowMenu"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
"sourceforts"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"HudRadioMenuMsg" "ShowMenu"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
"insurgency"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"HudRadioMenuMsg" "ShowMenu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,28 +142,12 @@ void VoteHandler::OnBroadcastEnd(IBaseMenu *menu)
|
||||
|
||||
MenuManager::MenuManager()
|
||||
{
|
||||
m_ShowMenu = -1;
|
||||
m_pDefaultStyle = NULL;
|
||||
m_Styles.push_back(&g_ValveMenuStyle);
|
||||
SetDefaultStyle(&g_ValveMenuStyle);
|
||||
}
|
||||
|
||||
void MenuManager::OnSourceModAllInitialized()
|
||||
{
|
||||
int num = g_SMAPI->GetUserMessageCount();
|
||||
if (num >= 1)
|
||||
{
|
||||
for (int i=0; i<num; i++)
|
||||
{
|
||||
if (strcmp(g_SMAPI->GetUserMessage(i, NULL), "ShowMenu") == 0)
|
||||
{
|
||||
m_ShowMenu = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* :TODO: styles */
|
||||
m_Styles.push_back(&g_ValveMenuStyle);
|
||||
SetDefaultStyle(&g_ValveMenuStyle);
|
||||
}
|
||||
|
||||
void MenuManager::OnSourceModAllShutdown()
|
||||
@ -203,6 +187,11 @@ IMenuStyle *MenuManager::GetStyle(unsigned int index)
|
||||
return m_Styles[index];
|
||||
}
|
||||
|
||||
void MenuManager::AddStyle(IMenuStyle *style)
|
||||
{
|
||||
m_Styles.push_back(style);
|
||||
}
|
||||
|
||||
unsigned int MenuManager::GetStyleCount()
|
||||
{
|
||||
return (unsigned int)m_Styles.size();
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
unsigned int numClients,
|
||||
unsigned int time);
|
||||
IMenuStyle *GetDefaultStyle();
|
||||
void AddStyle(IMenuStyle *style);
|
||||
bool SetDefaultStyle(IMenuStyle *style);
|
||||
IMenuDisplay *RenderMenu(int client, menu_states_t &states, ItemOrder order);
|
||||
protected:
|
||||
|
@ -121,13 +121,10 @@ MenuSource BaseMenuStyle::GetClientMenu(int client, void **object)
|
||||
}
|
||||
|
||||
return MenuSource_Display;
|
||||
} else {
|
||||
return GetClientExternMenu(client, object);
|
||||
} else if (player->bInExternMenu) {
|
||||
return MenuSource_External;
|
||||
}
|
||||
}
|
||||
|
||||
MenuSource BaseMenuStyle::GetClientExternMenu(int client, void **object)
|
||||
{
|
||||
return MenuSource_None;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
class CBaseMenuPlayer
|
||||
{
|
||||
public:
|
||||
CBaseMenuPlayer() : bInMenu(false), bAutoIgnore(false)
|
||||
CBaseMenuPlayer() : bInMenu(false), bAutoIgnore(false), bInExternMenu(false)
|
||||
{
|
||||
}
|
||||
menu_states_t states;
|
||||
@ -51,6 +51,7 @@ public:
|
||||
bool bAutoIgnore;
|
||||
float menuStartTime;
|
||||
unsigned int menuHoldTime;
|
||||
bool bInExternMenu;
|
||||
};
|
||||
|
||||
class CBaseMenu;
|
||||
@ -75,7 +76,6 @@ public: //what derived may implement
|
||||
virtual void AddClientToWatch(int client);
|
||||
virtual void RemoveClientFromWatch(int client);
|
||||
virtual void ProcessWatchList();
|
||||
virtual MenuSource GetClientExternMenu(int client, void **object);
|
||||
public: //helpers
|
||||
void CancelMenu(CBaseMenu *menu);
|
||||
void ClientPressedKey(int client, unsigned int key_press);
|
||||
|
305
core/MenuStyle_Radio.cpp
Normal file
305
core/MenuStyle_Radio.cpp
Normal file
@ -0,0 +1,305 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* ===============================================================
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* ===============================================================
|
||||
*
|
||||
* This file is not open source and may not be copied without explicit
|
||||
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||
* in whole or significant part.
|
||||
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "MenuStyle_Radio.h"
|
||||
#include "sm_stringutil.h"
|
||||
#include "UserMessages.h"
|
||||
#include "GameConfigs.h"
|
||||
|
||||
extern const char *g_RadioNumTable[];
|
||||
CRadioStyle g_RadioMenuStyle;
|
||||
int g_ShowMenuId = -1;
|
||||
|
||||
CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1])
|
||||
{
|
||||
}
|
||||
|
||||
void CRadioStyle::OnSourceModAllInitialized()
|
||||
{
|
||||
const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
|
||||
if (!msg || msg[0] == '\0')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
|
||||
|
||||
if (!IsSupported())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_Menus.AddStyle(this);
|
||||
g_Menus.SetDefaultStyle(this);
|
||||
|
||||
g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
|
||||
}
|
||||
|
||||
void CRadioStyle::OnSourceModShutdown()
|
||||
{
|
||||
g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
|
||||
}
|
||||
|
||||
bool CRadioStyle::IsSupported()
|
||||
{
|
||||
return (g_ShowMenuId != -1);
|
||||
}
|
||||
|
||||
bool CRadioStyle::OnClientCommand(int client)
|
||||
{
|
||||
const char *cmd = engine->Cmd_Argv(0);
|
||||
|
||||
if (strcmp(cmd, "menuselect") == 0)
|
||||
{
|
||||
if (!m_players[client].bInMenu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int arg = atoi(engine->Cmd_Argv(1));
|
||||
ClientPressedKey(client, arg);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned int g_last_holdtime = 0;
|
||||
static unsigned int g_last_client_count = 0;
|
||||
static int g_last_clients[256];
|
||||
|
||||
void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
|
||||
{
|
||||
int count = pFilter->GetRecipientCount();
|
||||
bf_read br(bf->GetBasePointer(), 2);
|
||||
|
||||
br.ReadWord();
|
||||
int c = br.ReadChar();
|
||||
|
||||
g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
|
||||
|
||||
for (int i=0; i<count; i++)
|
||||
{
|
||||
g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
void CRadioStyle::OnUserMessageSent(int msg_id)
|
||||
{
|
||||
for (unsigned int i=0; i<g_last_client_count; i++)
|
||||
{
|
||||
int client = g_last_clients[i];
|
||||
if (m_players[client].bInMenu)
|
||||
{
|
||||
_CancelClientMenu(client, true);
|
||||
}
|
||||
m_players[client].bInExternMenu = true;
|
||||
m_players[client].menuHoldTime = g_last_holdtime;
|
||||
}
|
||||
g_last_client_count = 0;
|
||||
}
|
||||
|
||||
void CRadioStyle::SendDisplay(int client, IMenuDisplay *display)
|
||||
{
|
||||
CRadioDisplay *rDisplay = (CRadioDisplay *)display;
|
||||
rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
|
||||
}
|
||||
|
||||
IMenuDisplay *CRadioStyle::CreateDisplay()
|
||||
{
|
||||
return new CRadioDisplay();
|
||||
}
|
||||
|
||||
IBaseMenu *CRadioStyle::CreateMenu()
|
||||
{
|
||||
return new CRadioMenu();
|
||||
}
|
||||
|
||||
unsigned int CRadioStyle::GetMaxPageItems()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
const char *CRadioStyle::GetStyleName()
|
||||
{
|
||||
return "radio";
|
||||
}
|
||||
|
||||
CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
|
||||
{
|
||||
return &m_players[client];
|
||||
}
|
||||
|
||||
CRadioDisplay::CRadioDisplay()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool CRadioDisplay::DrawRawLine(const char *rawline)
|
||||
{
|
||||
m_BufferText.append(rawline);
|
||||
m_BufferText.append("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRadioDisplay::Reset()
|
||||
{
|
||||
m_BufferText.assign("");
|
||||
m_Title.assign("");
|
||||
m_NextPos = 1;
|
||||
}
|
||||
|
||||
bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
|
||||
{
|
||||
return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
|
||||
}
|
||||
|
||||
bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IMenuStyle *CRadioDisplay::GetParentStyle()
|
||||
{
|
||||
return &g_RadioMenuStyle;
|
||||
}
|
||||
|
||||
void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
|
||||
{
|
||||
if (m_Title.size() != 0 && onlyIfEmpty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Title.assign(text);
|
||||
}
|
||||
|
||||
unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
|
||||
{
|
||||
if (m_NextPos > 10 || !CanDrawItem(item.style))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item.style & ITEMDRAW_RAWLINE)
|
||||
{
|
||||
if (item.style & ITEMDRAW_SPACER)
|
||||
{
|
||||
m_BufferText.append("\n");
|
||||
} else {
|
||||
m_BufferText.append(item.display);
|
||||
m_BufferText.append("\n");
|
||||
}
|
||||
return 0;
|
||||
} else if (item.style & ITEMDRAW_SPACER) {
|
||||
m_BufferText.append("\n");
|
||||
return m_NextPos++;
|
||||
}
|
||||
|
||||
if (item.style & ITEMDRAW_DISABLED)
|
||||
{
|
||||
m_BufferText.append(g_RadioNumTable[m_NextPos]);
|
||||
m_BufferText.append(". ");
|
||||
m_BufferText.append(item.display);
|
||||
m_BufferText.append("\n");
|
||||
} else {
|
||||
m_BufferText.append("->. ");
|
||||
m_BufferText.append(item.display);
|
||||
m_BufferText.append("\n");
|
||||
keys |= (1<<(m_NextPos-1));
|
||||
}
|
||||
|
||||
return m_NextPos++;
|
||||
}
|
||||
|
||||
bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
|
||||
{
|
||||
if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
|
||||
{
|
||||
char buffer[4096];
|
||||
size_t len;
|
||||
|
||||
len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str());
|
||||
|
||||
cell_t players[1] = {client};
|
||||
|
||||
char *ptr = buffer;
|
||||
char save = 0;
|
||||
while (true)
|
||||
{
|
||||
if (len > 240)
|
||||
{
|
||||
save = ptr[240];
|
||||
ptr[240] = '\0';
|
||||
}
|
||||
bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0);
|
||||
buffer->WriteWord(keys);
|
||||
buffer->WriteChar(time ? time : -1);
|
||||
buffer->WriteByte( (len > 240) ? 1 : 0 );
|
||||
buffer->WriteString(ptr);
|
||||
g_UserMsgs.EndMessage();
|
||||
if (len > 240)
|
||||
{
|
||||
ptr[240] = save;
|
||||
ptr = &ptr[240];
|
||||
len -= 240;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRadioDisplay::DeleteThis()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
CRadioMenu::CRadioMenu() : CBaseMenu(&g_RadioMenuStyle)
|
||||
{
|
||||
}
|
||||
|
||||
bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IMenuDisplay *CRadioMenu::CreateDisplay()
|
||||
{
|
||||
return new CRadioDisplay(this);
|
||||
}
|
||||
|
||||
bool CRadioMenu::Display(int client, IMenuHandler *handler, unsigned int time)
|
||||
{
|
||||
return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
|
||||
}
|
||||
|
||||
void CRadioMenu::Cancel_Finally()
|
||||
{
|
||||
g_RadioMenuStyle.CancelMenu(this);
|
||||
}
|
||||
|
||||
const char *g_RadioNumTable[11] =
|
||||
{
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
|
||||
};
|
94
core/MenuStyle_Radio.h
Normal file
94
core/MenuStyle_Radio.h
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* ===============================================================
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* ===============================================================
|
||||
*
|
||||
* This file is not open source and may not be copied without explicit
|
||||
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||
* in whole or significant part.
|
||||
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_MENUSTYLE_RADIO_H
|
||||
#define _INCLUDE_MENUSTYLE_RADIO_H
|
||||
|
||||
#include "sm_globals.h"
|
||||
#include "MenuManager.h"
|
||||
#include "MenuStyle_Base.h"
|
||||
#include "sourcemm_api.h"
|
||||
#include <IPlayerHelpers.h>
|
||||
#include <IUserMessages.h>
|
||||
#include "sm_fastlink.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
class CRadioStyle :
|
||||
public BaseMenuStyle,
|
||||
public SMGlobalClass,
|
||||
public IUserMessageListener
|
||||
{
|
||||
public:
|
||||
CRadioStyle();
|
||||
public: //SMGlobalClass
|
||||
void OnSourceModAllInitialized();
|
||||
void OnSourceModShutdown();
|
||||
public: //BaseMenuStyle
|
||||
CBaseMenuPlayer *GetMenuPlayer(int client);
|
||||
void SendDisplay(int client, IMenuDisplay *display);
|
||||
public: //IMenuStyle
|
||||
const char *GetStyleName();
|
||||
IMenuDisplay *CreateDisplay();
|
||||
IBaseMenu *CreateMenu();
|
||||
unsigned int GetMaxPageItems();
|
||||
public: //IUserMessageListener
|
||||
void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
||||
void OnUserMessageSent(int msg_id);
|
||||
public:
|
||||
bool IsSupported();
|
||||
bool OnClientCommand(int client);
|
||||
private:
|
||||
CBaseMenuPlayer *m_players;
|
||||
};
|
||||
|
||||
class CRadioMenu;
|
||||
|
||||
class CRadioDisplay : public IMenuDisplay
|
||||
{
|
||||
public:
|
||||
CRadioDisplay();
|
||||
CRadioDisplay(CRadioMenu *menu);
|
||||
public: //IMenuDisplay
|
||||
IMenuStyle *GetParentStyle();
|
||||
void Reset();
|
||||
void DrawTitle(const char *text, bool onlyIfEmpty=false);
|
||||
unsigned int DrawItem(const ItemDrawInfo &item);
|
||||
bool DrawRawLine(const char *rawline);
|
||||
bool SetExtOption(MenuOption option, const void *valuePtr);
|
||||
bool CanDrawItem(unsigned int drawFlags);
|
||||
bool SendDisplay(int client, IMenuHandler *handler, unsigned int time);
|
||||
void DeleteThis();
|
||||
void SendRawDisplay(int client, unsigned int time);
|
||||
private:
|
||||
String m_BufferText;
|
||||
String m_Title;
|
||||
unsigned int m_NextPos;
|
||||
int keys;
|
||||
};
|
||||
|
||||
class CRadioMenu : public CBaseMenu
|
||||
{
|
||||
public:
|
||||
CRadioMenu();
|
||||
public:
|
||||
bool SetExtOption(MenuOption option, const void *valuePtr);
|
||||
IMenuDisplay *CreateDisplay();
|
||||
bool Display(int client, IMenuHandler *handler, unsigned int time);
|
||||
void Cancel_Finally();
|
||||
};
|
||||
|
||||
extern CRadioStyle g_RadioMenuStyle;
|
||||
|
||||
#endif //_INCLUDE_MENUSTYLE_RADIO_H
|
@ -18,6 +18,7 @@
|
||||
#include "AdminCache.h"
|
||||
#include "ConCmdManager.h"
|
||||
#include "MenuStyle_Valve.h"
|
||||
#include "MenuStyle_Radio.h"
|
||||
|
||||
PlayerManager g_Players;
|
||||
|
||||
@ -385,24 +386,36 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
|
||||
|
||||
void PlayerManager::OnClientCommand(edict_t *pEntity)
|
||||
{
|
||||
cell_t res = Pl_Continue;
|
||||
int client = engine->IndexOfEdict(pEntity);
|
||||
|
||||
int args = engine->Cmd_Argc() - 1;
|
||||
|
||||
m_clcommand->PushCell(client);
|
||||
m_clcommand->PushCell(args);
|
||||
m_clcommand->Execute(&res, NULL);
|
||||
|
||||
if (res >= Pl_Stop)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
cell_t res = Pl_Continue;
|
||||
|
||||
bool result = g_ValveMenuStyle.OnClientCommand(client);
|
||||
if (result)
|
||||
{
|
||||
res = Pl_Handled;
|
||||
} else {
|
||||
result = g_RadioMenuStyle.OnClientCommand(client);
|
||||
if (result)
|
||||
{
|
||||
res = Pl_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
int args = engine->Cmd_Argc() - 1;
|
||||
|
||||
cell_t res2 = Pl_Continue;
|
||||
m_clcommand->PushCell(client);
|
||||
m_clcommand->PushCell(args);
|
||||
m_clcommand->Execute(&res2, NULL);
|
||||
|
||||
if (res2 > res)
|
||||
{
|
||||
res = res2;
|
||||
}
|
||||
|
||||
if (res >= Pl_Stop)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
res = g_ConCmds.DispatchClientCommand(client, (ResultType)res);
|
||||
|
@ -235,6 +235,10 @@
|
||||
RelativePath="..\MenuStyle_Base.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\MenuStyle_Radio.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\MenuStyle_Valve.cpp"
|
||||
>
|
||||
@ -353,6 +357,10 @@
|
||||
RelativePath="..\MenuStyle_Base.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\MenuStyle_Radio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\MenuStyle_Valve.h"
|
||||
>
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "ForwardSys.h"
|
||||
#include "TimerSys.h"
|
||||
#include "MenuStyle_Valve.h"
|
||||
#include "MenuStyle_Radio.h"
|
||||
|
||||
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
|
||||
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
|
||||
@ -390,6 +391,7 @@ void SourceModBase::GameFrame(bool simulating)
|
||||
if (g_SimTicks.tickcount && (curtime - g_LastMenuTime >= 1.0f))
|
||||
{
|
||||
g_ValveMenuStyle.ProcessWatchList();
|
||||
g_RadioMenuStyle.ProcessWatchList();
|
||||
g_LastMenuTime = curtime;
|
||||
}
|
||||
|
||||
|
@ -617,14 +617,6 @@ namespace SourceMod
|
||||
*/
|
||||
virtual IMenuStyle *GetDefaultStyle() =0;
|
||||
|
||||
/**
|
||||
* @brief Sets the default draw style Core uses.
|
||||
*
|
||||
* @param style Menu style.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
virtual bool SetDefaultStyle(IMenuStyle *style) =0;
|
||||
|
||||
/**
|
||||
* @brief Given a set of menu states, converts it to an IDisplay object.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user