mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Formatted source files
This commit is contained in:
parent
115647a8c0
commit
fe04adee1d
9 changed files with 406 additions and 604 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -22,43 +22,42 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( UIListCtrl, UILANGameClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIListCtrl, UILANGameClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
UILANGameClass::UILANGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILANGameClass::SetupServers( void )
|
||||
void UILANGameClass::Draw(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILANGameClass::Draw( void )
|
||||
void UILANGameClass::UpdateUIElement(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILANGameClass::SelectServer( Event *ev )
|
||||
void UILANGameClass::SetupServers(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILANGameClass::JoinServer( Event *ev )
|
||||
void UILANGameClass::SelectServer(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
qboolean UILANGameClass::KeyEvent( int key, unsigned int time )
|
||||
void UILANGameClass::JoinServer(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILANGameClass::UpdateUIElement( void )
|
||||
qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -20,29 +20,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UILANGAME_H__
|
||||
#define __CL_UILANGAME_H__
|
||||
#pragma once
|
||||
|
||||
class UILANGameClass : public UIListCtrl {
|
||||
class UILANGameClass : public UIListCtrl
|
||||
{
|
||||
protected:
|
||||
int m_iLastUpdateTime;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
int m_iLastUpdateTime;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UILANGameClass );
|
||||
CLASS_PROTOTYPE(UILANGameClass);
|
||||
|
||||
private:
|
||||
void SetupServers( void );
|
||||
void SetupServers(void);
|
||||
|
||||
protected:
|
||||
void Draw( void ) override;
|
||||
void SelectServer( Event *ev );
|
||||
void JoinServer( Event *ev );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void UpdateUIElement( void ) override;
|
||||
void Draw(void) override;
|
||||
void SelectServer(Event *ev);
|
||||
void JoinServer(Event *ev);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void UpdateUIElement(void) override;
|
||||
|
||||
public:
|
||||
UILANGameClass();
|
||||
UILANGameClass();
|
||||
};
|
||||
|
||||
#endif /* __CL_UILANGAME_H__ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -22,62 +22,62 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( UIListCtrl, UIFAKKLoadGameClass, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIListCtrl, UIFAKKLoadGameClass, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
UIFAKKLoadGameClass::UIFAKKLoadGameClass()
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SelectGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::UpdateUIElement(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::LoadGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SaveGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::SelectGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::RemoveGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::RemoveGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::DeleteGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::NoDeleteGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::NoDeleteGame( Event *ev )
|
||||
void UIFAKKLoadGameClass::DeleteGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
qboolean UIFAKKLoadGameClass::KeyEvent( int key, unsigned int time )
|
||||
void UIFAKKLoadGameClass::LoadGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::UpdateUIElement( void )
|
||||
void UIFAKKLoadGameClass::SaveGame(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UIFAKKLoadGameClass::SetupFiles( void )
|
||||
qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void UI_SetupFiles( void ) {
|
||||
// FIXME: stub
|
||||
void UI_SetupFiles(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -22,23 +22,25 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#pragma once
|
||||
|
||||
class UIFAKKLoadGameClass : public UIListCtrl {
|
||||
bool m_bRemovePending;
|
||||
class UIFAKKLoadGameClass : public UIListCtrl
|
||||
{
|
||||
bool m_bRemovePending;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFAKKLoadGameClass );
|
||||
CLASS_PROTOTYPE(UIFAKKLoadGameClass);
|
||||
|
||||
protected:
|
||||
void SelectGame( Event *ev );
|
||||
void LoadGame( Event *ev );
|
||||
void SaveGame( Event *ev );
|
||||
void RemoveGame( Event *ev );
|
||||
void DeleteGame( Event *ev );
|
||||
void NoDeleteGame( Event *ev );
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void UpdateUIElement( void ) override;
|
||||
public:
|
||||
UIFAKKLoadGameClass();
|
||||
void SelectGame(Event *ev);
|
||||
void LoadGame(Event *ev);
|
||||
void SaveGame(Event *ev);
|
||||
void RemoveGame(Event *ev);
|
||||
void DeleteGame(Event *ev);
|
||||
void NoDeleteGame(Event *ev);
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void UpdateUIElement(void) override;
|
||||
|
||||
void SetupFiles( void );
|
||||
public:
|
||||
UIFAKKLoadGameClass();
|
||||
|
||||
void SetupFiles(void);
|
||||
};
|
||||
|
|
|
@ -22,423 +22,321 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "cl_ui.h"
|
||||
|
||||
CLASS_DECLARATION( UIWidget, View3D, NULL )
|
||||
{
|
||||
{ &W_Activated, &View3D::OnActivate },
|
||||
{ &W_Deactivated, &View3D::OnDeactivate },
|
||||
{ &W_LeftMouseDown, &View3D::Pressed },
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, View3D, NULL) {
|
||||
{&W_Activated, &View3D::OnActivate },
|
||||
{&W_Deactivated, &View3D::OnDeactivate},
|
||||
{&W_LeftMouseDown, &View3D::Pressed },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
#define MAX_SUBTITLES 4
|
||||
|
||||
cvar_t* subs[MAX_SUBTITLES];
|
||||
cvar_t* teams[MAX_SUBTITLES];
|
||||
float fadeTime[MAX_SUBTITLES];
|
||||
float subLife[MAX_SUBTITLES];
|
||||
float alpha[MAX_SUBTITLES];
|
||||
char oldStrings[MAX_SUBTITLES][2048];
|
||||
cvar_t *subs[MAX_SUBTITLES];
|
||||
cvar_t *teams[MAX_SUBTITLES];
|
||||
float fadeTime[MAX_SUBTITLES];
|
||||
float subLife[MAX_SUBTITLES];
|
||||
float alpha[MAX_SUBTITLES];
|
||||
char oldStrings[MAX_SUBTITLES][2048];
|
||||
|
||||
View3D::View3D()
|
||||
{
|
||||
// set as transparent
|
||||
setBackgroundColor(UClear, true);
|
||||
// no border
|
||||
setBorderStyle(border_none);
|
||||
AllowActivate(true);
|
||||
// set as transparent
|
||||
setBackgroundColor(UClear, true);
|
||||
// no border
|
||||
setBorderStyle(border_none);
|
||||
AllowActivate(true);
|
||||
|
||||
m_printfadetime = 0.0;
|
||||
m_print_mat = NULL;
|
||||
m_locationprint = qfalse;
|
||||
m_printfadetime = 0.0;
|
||||
m_print_mat = NULL;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::Draw(void)
|
||||
{
|
||||
if (clc.state != CA_DISCONNECTED) {
|
||||
SCR_DrawScreenField();
|
||||
}
|
||||
if (clc.state != CA_DISCONNECTED) {
|
||||
SCR_DrawScreenField();
|
||||
}
|
||||
|
||||
set2D();
|
||||
set2D();
|
||||
|
||||
re.SavePerformanceCounters();
|
||||
re.SavePerformanceCounters();
|
||||
|
||||
Draw2D();
|
||||
Draw2D();
|
||||
}
|
||||
|
||||
void View3D::DrawLetterbox
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawLetterbox(void)
|
||||
{
|
||||
float frac;
|
||||
vec4_t col;
|
||||
float frac;
|
||||
vec4_t col;
|
||||
|
||||
col[0] = col[1] = col[2] = 0;
|
||||
col[3] = 1;
|
||||
col[0] = col[1] = col[2] = 0;
|
||||
col[3] = 1;
|
||||
|
||||
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
|
||||
if (frac > 0.0) {
|
||||
m_letterbox_active = true;
|
||||
re.SetColor(col);
|
||||
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
|
||||
if (frac > 0.0) {
|
||||
m_letterbox_active = true;
|
||||
re.SetColor(col);
|
||||
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
re.DrawBox(0.0, m_screenframe.size.height - m_screenframe.size.height * frac, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
m_letterbox_active = false;
|
||||
}
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_screenframe.size.height - m_screenframe.size.height * frac,
|
||||
m_screenframe.size.width,
|
||||
m_screenframe.size.height
|
||||
);
|
||||
} else {
|
||||
m_letterbox_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawFades
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawFades(void)
|
||||
{
|
||||
if (cl.snap.ps.blend[3] > 0) {
|
||||
re.SetColor(cl.snap.ps.blend);
|
||||
if (cl.snap.ps.stats[STAT_ADDFADE]) {
|
||||
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
if (cl.snap.ps.blend[3] > 0) {
|
||||
re.SetColor(cl.snap.ps.blend);
|
||||
if (cl.snap.ps.stats[STAT_ADDFADE]) {
|
||||
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::Draw2D
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::Draw2D(void)
|
||||
{
|
||||
if (!cls.no_menus) {
|
||||
DrawFades();
|
||||
}
|
||||
if (!cls.no_menus) {
|
||||
DrawFades();
|
||||
}
|
||||
|
||||
DrawLetterbox();
|
||||
DrawLetterbox();
|
||||
|
||||
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus)
|
||||
{
|
||||
SCR_DrawDebugGraph();
|
||||
}
|
||||
else if (!cls.no_menus)
|
||||
{
|
||||
if (cge) {
|
||||
cge->CG_Draw2D();
|
||||
}
|
||||
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus) {
|
||||
SCR_DrawDebugGraph();
|
||||
} else if (!cls.no_menus) {
|
||||
if (cge) {
|
||||
cge->CG_Draw2D();
|
||||
}
|
||||
|
||||
if (m_locationprint) {
|
||||
LocationPrint();
|
||||
} else {
|
||||
CenterPrint();
|
||||
}
|
||||
if (m_locationprint) {
|
||||
LocationPrint();
|
||||
} else {
|
||||
CenterPrint();
|
||||
}
|
||||
|
||||
if (!cls.no_menus)
|
||||
{
|
||||
DrawSoundOverlay();
|
||||
DrawSubtitleOverlay();
|
||||
}
|
||||
}
|
||||
if (!cls.no_menus) {
|
||||
DrawSoundOverlay();
|
||||
DrawSubtitleOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
if (fps->integer && !cls.no_menus)
|
||||
{
|
||||
DrawFPS();
|
||||
DrawProf();
|
||||
}
|
||||
if (fps->integer && !cls.no_menus) {
|
||||
DrawFPS();
|
||||
DrawProf();
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawFPS
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawFPS(void)
|
||||
{
|
||||
char string[128];
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2)
|
||||
{
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2) {
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
}
|
||||
else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
m_font->setColor(UBlack);
|
||||
}
|
||||
|
||||
void View3D::DrawProf
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawProf(void)
|
||||
{
|
||||
// Normal empty function
|
||||
// Normal empty function
|
||||
}
|
||||
|
||||
void View3D::PrintSound
|
||||
(
|
||||
int channel,
|
||||
const char *name,
|
||||
float vol,
|
||||
int rvol,
|
||||
float pitch,
|
||||
float base,
|
||||
int& line
|
||||
)
|
||||
|
||||
void View3D::PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::DrawSoundOverlay
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawSoundOverlay(void)
|
||||
{
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
if (sound_overlay->integer) {
|
||||
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
|
||||
Cvar_Set("sound_overlay", "0");
|
||||
}
|
||||
if (sound_overlay->integer) {
|
||||
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
|
||||
Cvar_Set("sound_overlay", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::CenterPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::CenterPrint(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::LocationPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::LocationPrint(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::OnActivate
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::OnActivate(Event *ev)
|
||||
{
|
||||
UIWidget* wid;
|
||||
UList<UIWidget*> widgets;
|
||||
UIWidget *wid;
|
||||
UList<UIWidget *> widgets;
|
||||
|
||||
UI_CloseInventory();
|
||||
cls.keyCatchers &= ~KEYCATCH_UI;
|
||||
|
||||
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid))
|
||||
{
|
||||
if (wid->getAlwaysOnBottom() && wid != this) {
|
||||
widgets.AddTail(wid);
|
||||
}
|
||||
}
|
||||
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid)) {
|
||||
if (wid->getAlwaysOnBottom() && wid != this) {
|
||||
widgets.AddTail(wid);
|
||||
}
|
||||
}
|
||||
|
||||
widgets.IterateFromHead();
|
||||
while (widgets.IsCurrentValid())
|
||||
{
|
||||
widgets.getCurrent()->BringToFrontPropogated();
|
||||
widgets.IterateNext();
|
||||
}
|
||||
widgets.IterateFromHead();
|
||||
while (widgets.IsCurrentValid()) {
|
||||
widgets.getCurrent()->BringToFrontPropogated();
|
||||
widgets.IterateNext();
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::OnDeactivate
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::OnDeactivate(Event *ev)
|
||||
{
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
cls.keyCatchers |= KEYCATCH_UI;
|
||||
}
|
||||
|
||||
void View3D::DrawSubtitleOverlay
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::DrawSubtitleOverlay(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::ClearCenterPrint
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::ClearCenterPrint(void)
|
||||
{
|
||||
m_printfadetime = 0.0;
|
||||
m_printfadetime = 0.0;
|
||||
}
|
||||
|
||||
void View3D::UpdateCenterPrint
|
||||
(
|
||||
const char *s,
|
||||
float alpha
|
||||
)
|
||||
|
||||
void View3D::UpdateCenterPrint(const char *s, float alpha)
|
||||
{
|
||||
m_printstring = s;
|
||||
m_printstring = s;
|
||||
|
||||
if (s[0] == '@') {
|
||||
m_print_mat = uWinMan.RegisterShader(s + 1);
|
||||
} else {
|
||||
m_print_mat = NULL;
|
||||
}
|
||||
if (s[0] == '@') {
|
||||
m_print_mat = uWinMan.RegisterShader(s + 1);
|
||||
} else {
|
||||
m_print_mat = NULL;
|
||||
}
|
||||
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_locationprint = qfalse;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::UpdateLocationPrint
|
||||
(
|
||||
int x,
|
||||
int y,
|
||||
const char *s,
|
||||
float alpha
|
||||
)
|
||||
|
||||
void View3D::UpdateLocationPrint(int x, int y, const char *s, float alpha)
|
||||
{
|
||||
m_printstring = s;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_x_coord = x;
|
||||
m_y_coord = y;
|
||||
m_locationprint = qtrue;
|
||||
m_printstring = s;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_x_coord = x;
|
||||
m_y_coord = y;
|
||||
m_locationprint = qtrue;
|
||||
}
|
||||
|
||||
qboolean View3D::LetterboxActive
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
qboolean View3D::LetterboxActive(void)
|
||||
{
|
||||
return m_letterbox_active;
|
||||
return m_letterbox_active;
|
||||
}
|
||||
|
||||
float avWidth = 0.0;
|
||||
|
||||
void View3D::InitSubtitle
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::InitSubtitle(void)
|
||||
{
|
||||
float totalWidth;
|
||||
float totalWidth;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
|
||||
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
|
||||
strcpy(oldStrings[i], subs[i]->string);
|
||||
fadeTime[i] = 4000.0;
|
||||
subLife[i] = 4000.0;
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
|
||||
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
|
||||
strcpy(oldStrings[i], subs[i]->string);
|
||||
fadeTime[i] = 4000.0;
|
||||
subLife[i] = 4000.0;
|
||||
}
|
||||
|
||||
totalWidth = 0.0;
|
||||
for (char j = 'A'; j <= 'Z'; j++) {
|
||||
totalWidth += m_font->getCharWidth(j);
|
||||
}
|
||||
totalWidth = 0.0;
|
||||
for (char j = 'A'; j <= 'Z'; j++) {
|
||||
totalWidth += m_font->getCharWidth(j);
|
||||
}
|
||||
|
||||
avWidth = totalWidth / 26.0;
|
||||
avWidth = totalWidth / 26.0;
|
||||
}
|
||||
|
||||
void View3D::FrameInitialized
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void View3D::FrameInitialized(void)
|
||||
{
|
||||
Connect(this, W_Activated, W_Activated);
|
||||
Connect(this, W_Deactivated, W_Deactivated);
|
||||
Connect(this, W_Activated, W_Activated);
|
||||
Connect(this, W_Deactivated, W_Deactivated);
|
||||
}
|
||||
|
||||
void View3D::Pressed
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void View3D::Pressed(Event *ev)
|
||||
{
|
||||
IN_MouseOff();
|
||||
OnActivate(ev);
|
||||
IN_MouseOff();
|
||||
OnActivate(ev);
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( UIWidget, ConsoleView, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, ConsoleView, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void ConsoleView::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void ConsoleView::Draw(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
|
|
|
@ -22,16 +22,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "ui_local.h"
|
||||
|
||||
CLASS_DECLARATION( UILanGameList, UIGlobalGameList, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UILanGameList, UIGlobalGameList, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void UIGlobalGameList::UpdateServers
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UIGlobalGameList::UpdateServers(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
|
|
@ -20,18 +20,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __UIGLOBALGAMELIST_H__
|
||||
#define __UIGLOBALGAMELIST_H__
|
||||
#pragma once
|
||||
|
||||
#include "uilangamelist.h"
|
||||
|
||||
class UIGlobalGameList : public UILanGameList {
|
||||
class UIGlobalGameList : public UILanGameList
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIGlobalGameList );
|
||||
CLASS_PROTOTYPE(UIGlobalGameList);
|
||||
|
||||
public:
|
||||
virtual void UpdateServers() override;
|
||||
virtual void UpdateServers() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -22,228 +22,143 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "ui_local.h"
|
||||
|
||||
CLASS_DECLARATION( UIWidget, UILanGameList, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UIWidget, UILanGameList, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
UILanGameList::UILanGameList()
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::CreateServerWidgets
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::FrameInitialized(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::DestroyServerWidgets
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::AddColumn(str sName, UIReggedMaterial *pMaterial, int iWidth, Container<str> *csEntries)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::RepositionServerWidgets
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::AddNoServer(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::DrawNoServers
|
||||
(
|
||||
UIRect2D frame
|
||||
)
|
||||
|
||||
void UILanGameList::CreateServerWidgets(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::AddColumn
|
||||
(
|
||||
str sName,
|
||||
UIReggedMaterial *pMaterial,
|
||||
int iWidth,
|
||||
Container<str> *csEntries
|
||||
)
|
||||
|
||||
void UILanGameList::DestroyServerWidgets(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::AddNoServer
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::RepositionServerWidgets(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::UpdateServers
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
qboolean UILanGameList::KeyEvent(int key, unsigned int time)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
void UILanGameList::FrameInitialized
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::DrawNoServers(UIRect2D frame)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::EventScanNetwork
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void UILanGameList::Highlight(UIWidget *wid)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::EventScaningNetwork
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void UILanGameList::Connect(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
bool UILanGameList::isDying
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::EventConnect(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
return false;
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::Draw
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
qboolean UILanGameList::SetActiveRow(UIWidget *w)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean UILanGameList::KeyEvent
|
||||
(
|
||||
int key,
|
||||
unsigned int time
|
||||
)
|
||||
|
||||
void UILanGameList::UpdateServers(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::Highlight
|
||||
(
|
||||
UIWidget *wid
|
||||
)
|
||||
|
||||
void UILanGameList::Draw(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::Connect
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::Realign(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::EventConnect
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void UILanGameList::EventScanNetwork(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
void UILanGameList::PlayEnterSound
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::EventScaningNetwork(Event *ev)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
qboolean UILanGameList::SetActiveRow
|
||||
(
|
||||
UIWidget *w
|
||||
)
|
||||
|
||||
bool UILanGameList::isDying(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
return qfalse;
|
||||
// FIXME: stub
|
||||
return false;
|
||||
}
|
||||
|
||||
void UILanGameList::Realign
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
void UILanGameList::PlayEnterSound(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( UILabel, UILanGameListLabel, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
CLASS_DECLARATION(UILabel, UILanGameListLabel, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
UILanGameListLabel::UILanGameListLabel()
|
||||
{
|
||||
|
||||
m_list = NULL;
|
||||
m_iLastPressedTime = 0;
|
||||
}
|
||||
|
||||
UILanGameListLabel::UILanGameListLabel
|
||||
(
|
||||
UILanGameList *list
|
||||
)
|
||||
|
||||
UILanGameListLabel::UILanGameListLabel(UILanGameList *list)
|
||||
{
|
||||
|
||||
m_list = list;
|
||||
m_iLastPressedTime = 0;
|
||||
}
|
||||
|
||||
void UILanGameListLabel::Pressed
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void UILanGameListLabel::Pressed(Event *ev)
|
||||
{
|
||||
if (m_list) {
|
||||
m_list->Highlight(this);
|
||||
|
||||
if (uii.Sys_Milliseconds() - m_iLastPressedTime < 200) {
|
||||
m_list->Connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UILanGameListLabel::Unpressed
|
||||
(
|
||||
Event *ev
|
||||
)
|
||||
|
||||
void UILanGameListLabel::Unpressed(Event *ev)
|
||||
{
|
||||
|
||||
if (m_list) {
|
||||
m_iLastPressedTime = uii.Sys_Milliseconds();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -20,71 +20,69 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __UILANGAMELIST_H__
|
||||
#define __UILANGAMELIST_H__
|
||||
#pragma once
|
||||
|
||||
class UILanGameList : public UIWidget {
|
||||
bool m_created;
|
||||
UIVertScroll *m_Vscroll;
|
||||
class UIHorizScroll *m_Hscroll;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
UILabel *m_noservers_wid;
|
||||
UIReggedMaterial *m_fill_mat;
|
||||
Container<UIWidget *> m_widgetlist;
|
||||
Container<UIWidget *> m_titlewidgets;
|
||||
Container<UIWidget *> m_miscwidgets;
|
||||
int m_activerow;
|
||||
int m_activeitem;
|
||||
Container<serverInfo_t *> m_servers;
|
||||
int m_iNumColumns;
|
||||
int m_iPrevNumServers;
|
||||
int m_iCurrNumServers;
|
||||
float m_fCurColumnWidth;
|
||||
class UILanGameList : public UIWidget
|
||||
{
|
||||
bool m_created;
|
||||
UIVertScroll *m_Vscroll;
|
||||
class UIHorizScroll *m_Hscroll;
|
||||
UIReggedMaterial *m_noservers_mat;
|
||||
UILabel *m_noservers_wid;
|
||||
UIReggedMaterial *m_fill_mat;
|
||||
Container<UIWidget *> m_widgetlist;
|
||||
Container<UIWidget *> m_titlewidgets;
|
||||
Container<UIWidget *> m_miscwidgets;
|
||||
int m_activerow;
|
||||
int m_activeitem;
|
||||
Container<serverInfo_t *> m_servers;
|
||||
int m_iNumColumns;
|
||||
int m_iPrevNumServers;
|
||||
int m_iCurrNumServers;
|
||||
float m_fCurColumnWidth;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UILanGameList );
|
||||
CLASS_PROTOTYPE(UILanGameList);
|
||||
|
||||
private:
|
||||
void CreateServerWidgets( void );
|
||||
void DestroyServerWidgets( void );
|
||||
void RepositionServerWidgets( void );
|
||||
void DrawNoServers( UIRect2D frame );
|
||||
void AddColumn( str sName, UIReggedMaterial *pMaterial, int iWidth, Container<str> *csEntries );
|
||||
void AddNoServer( void );
|
||||
virtual void UpdateServers( void );
|
||||
void CreateServerWidgets(void);
|
||||
void DestroyServerWidgets(void);
|
||||
void RepositionServerWidgets(void);
|
||||
void DrawNoServers(UIRect2D frame);
|
||||
void AddColumn(str sName, UIReggedMaterial *pMaterial, int iWidth, Container<str> *csEntries);
|
||||
void AddNoServer(void);
|
||||
virtual void UpdateServers(void);
|
||||
|
||||
protected:
|
||||
void FrameInitialized( void ) override;
|
||||
void EventScanNetwork( Event *ev );
|
||||
void EventScaningNetwork( Event *ev );
|
||||
void FrameInitialized(void) override;
|
||||
void EventScanNetwork(Event *ev);
|
||||
void EventScaningNetwork(Event *ev);
|
||||
|
||||
public:
|
||||
UILanGameList();
|
||||
UILanGameList();
|
||||
|
||||
bool isDying( void );
|
||||
void Draw() override;
|
||||
qboolean KeyEvent( int key, unsigned int time ) override;
|
||||
void Highlight( UIWidget *wid );
|
||||
void Connect( void );
|
||||
void EventConnect( Event *ev );
|
||||
void PlayEnterSound( void );
|
||||
qboolean SetActiveRow( UIWidget *w );
|
||||
void Realign( void ) override;
|
||||
bool isDying(void);
|
||||
void Draw() override;
|
||||
qboolean KeyEvent(int key, unsigned int time) override;
|
||||
void Highlight(UIWidget *wid);
|
||||
void Connect(void);
|
||||
void EventConnect(Event *ev);
|
||||
void PlayEnterSound(void);
|
||||
qboolean SetActiveRow(UIWidget *w);
|
||||
void Realign(void) override;
|
||||
};
|
||||
|
||||
class UILanGameListLabel : public UILabel {
|
||||
int m_iLastPressedTime;
|
||||
UILanGameList *m_list;
|
||||
class UILanGameListLabel : public UILabel
|
||||
{
|
||||
int m_iLastPressedTime;
|
||||
UILanGameList *m_list;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UILanGameListLabel );
|
||||
CLASS_PROTOTYPE(UILanGameListLabel);
|
||||
|
||||
UILanGameListLabel();
|
||||
UILanGameListLabel( UILanGameList *list );
|
||||
UILanGameListLabel();
|
||||
UILanGameListLabel(UILanGameList *list);
|
||||
|
||||
void Pressed( Event *ev );
|
||||
void Unpressed( Event *ev );
|
||||
void Pressed(Event *ev);
|
||||
void Unpressed(Event *ev);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue