mirror of https://github.com/AxioDL/metaforce.git
Finish COptionsScreen
This commit is contained in:
parent
4304cb1d29
commit
e13583ff80
|
@ -0,0 +1,35 @@
|
|||
#ifndef __URDE_CARTIFACTDOLL_HPP__
|
||||
#define __URDE_CARTIFACTDOLL_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "Character/CActorLights.hpp"
|
||||
#include "CToken.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CModel;
|
||||
namespace MP1
|
||||
{
|
||||
|
||||
class CArtifactDoll
|
||||
{
|
||||
std::vector<TLockedToken<CModel>> x0_models;
|
||||
std::vector<CLight> x10_lights;
|
||||
std::unique_ptr<CActorLights> x20_actorLights;
|
||||
float x24_fader = 0.f;
|
||||
bool x28_24_loaded : 1;
|
||||
void UpdateActorLights();
|
||||
public:
|
||||
CGameCubeDoll();
|
||||
void Update(float dt);
|
||||
void Draw(float alpha);
|
||||
void Touch();
|
||||
bool CheckLoadComplete();
|
||||
bool IsLoaded() const { return x20_24_loaded; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __URDE_CARTIFACTDOLL_HPP__
|
|
@ -0,0 +1,69 @@
|
|||
#include "CGameCubeDoll.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "Graphics/CBooRenderer.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
namespace MP1
|
||||
{
|
||||
|
||||
CGameCubeDoll::CGameCubeDoll()
|
||||
{
|
||||
x0_model = g_SimplePool->GetObj("CMDL_GameCube");
|
||||
x8_lights.push_back(CLight::BuildDirectional(zeus::CVector3f::skForward, zeus::CColor::skWhite));
|
||||
x18_actorLights = std::make_unique<CActorLights>(8, zeus::CVector3f::skZero, 4, 4, false, false, false, 0.1f);
|
||||
x20_24_loaded = false;
|
||||
}
|
||||
|
||||
void CGameCubeDoll::UpdateActorLights()
|
||||
{
|
||||
x8_lights[0] = CLight::BuildDirectional(
|
||||
(zeus::CVector3f::skForward + zeus::CVector3f::skRight * 0.25f + zeus::CVector3f::skDown * 0.1f).normalized(),
|
||||
zeus::CColor::skWhite);
|
||||
x18_actorLights->BuildFakeLightList(x8_lights, zeus::CColor(0.25f, 1.f));
|
||||
}
|
||||
|
||||
void CGameCubeDoll::Update(float dt)
|
||||
{
|
||||
if (!CheckLoadComplete())
|
||||
return;
|
||||
x1c_fader = std::min(2.f * dt + x1c_fader, 1.f);
|
||||
UpdateActorLights();
|
||||
}
|
||||
|
||||
void CGameCubeDoll::Draw(float alpha)
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
|
||||
g_Renderer->SetPerspective(55.f, g_Viewport.x8_width, g_Viewport.xc_height, 0.2f, 4096.f);
|
||||
CGraphics::SetViewPointMatrix(zeus::CTransform::Translate(0.f, -2.f, 0.f));
|
||||
x18_actorLights->ActivateLights(x0_model->GetInstance());
|
||||
CGraphics::SetModelMatrix(zeus::CTransform::RotateZ(zeus::degToRad(360.f * CGraphics::GetSecondsMod900() * -0.25f)) *
|
||||
zeus::CTransform::Scale(0.2f));
|
||||
CModelFlags flags(5, 0, 3, zeus::CColor(1.f, alpha * x1c_fader));
|
||||
x0_model->Draw(flags);
|
||||
}
|
||||
|
||||
void CGameCubeDoll::Touch()
|
||||
{
|
||||
if (!CheckLoadComplete())
|
||||
return;
|
||||
x0_model->Touch(0);
|
||||
}
|
||||
|
||||
bool CGameCubeDoll::CheckLoadComplete()
|
||||
{
|
||||
if (IsLoaded())
|
||||
return true;
|
||||
if (x0_model.IsLoaded())
|
||||
{
|
||||
x20_24_loaded = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef __URDE_CGAMECUBEDOLL_HPP__
|
||||
#define __URDE_CGAMECUBEDOLL_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "Character/CActorLights.hpp"
|
||||
#include "CToken.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CModel;
|
||||
namespace MP1
|
||||
{
|
||||
|
||||
class CGameCubeDoll
|
||||
{
|
||||
TLockedToken<CModel> x0_model;
|
||||
std::vector<CLight> x8_lights;
|
||||
std::unique_ptr<CActorLights> x18_actorLights;
|
||||
float x1c_fader = 0.f;
|
||||
bool x20_24_loaded : 1;
|
||||
void UpdateActorLights();
|
||||
public:
|
||||
CGameCubeDoll();
|
||||
void Update(float dt);
|
||||
void Draw(float alpha);
|
||||
void Touch();
|
||||
bool CheckLoadComplete();
|
||||
bool IsLoaded() const { return x20_24_loaded; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __URDE_CGAMECUBEDOLL_HPP__
|
|
@ -251,7 +251,7 @@ bool CInventoryScreen::HasLeftInventoryItem(int idx) const
|
|||
}
|
||||
}
|
||||
|
||||
void CInventoryScreen::VActivate() const
|
||||
void CInventoryScreen::VActivate()
|
||||
{
|
||||
for (int i=0 ; i<5 ; ++i)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
void Draw(float transInterp, float totalAlpha, float yOff);
|
||||
float GetCameraYBias() const;
|
||||
bool VReady() const;
|
||||
void VActivate() const;
|
||||
void VActivate();
|
||||
void RightTableSelectionChanged(int selBegin, int selEnd);
|
||||
void ChangedMode();
|
||||
void UpdateRightTable();
|
||||
|
|
|
@ -17,7 +17,7 @@ bool CLogBookScreen::VReady() const
|
|||
return true;
|
||||
}
|
||||
|
||||
void CLogBookScreen::VActivate() const
|
||||
void CLogBookScreen::VActivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
CLogBookScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg);
|
||||
|
||||
bool VReady() const;
|
||||
void VActivate() const;
|
||||
void VActivate();
|
||||
u32 GetRightTableCount() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ set(MP1_SOURCES
|
|||
CLogBookScreen.hpp CLogBookScreen.cpp
|
||||
COptionsScreen.hpp COptionsScreen.cpp
|
||||
CSamusDoll.hpp CSamusDoll.cpp
|
||||
CGameCubeDoll.hpp CGameCubeDoll.cpp
|
||||
CArtifactDoll.hpp CArtifactDoll.cpp
|
||||
MP1.hpp MP1.cpp
|
||||
${MP1_PLAT_SOURCES}
|
||||
${MP1_WORLD_SOURCES})
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#include "COptionsScreen.hpp"
|
||||
#include "GuiSys/CGuiTableGroup.hpp"
|
||||
#include "GuiSys/CGuiTextPane.hpp"
|
||||
#include "GuiSys/CGuiSliderGroup.hpp"
|
||||
#include "Input/RumbleFxTable.hpp"
|
||||
#include "CArchitectureQueue.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -9,7 +14,179 @@ COptionsScreen::COptionsScreen(const CStateManager& mgr, CGuiFrame& frame,
|
|||
const CStringTable& pauseStrg)
|
||||
: CPauseScreenBase(mgr, frame, pauseStrg)
|
||||
{
|
||||
x1a0_gameCube = std::unique_ptr<CGameCubeDoll>();
|
||||
x2a0_24_inOptionBody = false;
|
||||
}
|
||||
|
||||
COptionsScreen::~COptionsScreen()
|
||||
{
|
||||
CSfxManager::SfxStop(x1a4_sliderSfx);
|
||||
}
|
||||
|
||||
void COptionsScreen::UpdateOptionView()
|
||||
{
|
||||
ResetOptionWidgetVisibility();
|
||||
|
||||
const std::pair<int, const SGameOption*>& category =
|
||||
GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()];
|
||||
if (category.first == 0)
|
||||
return;
|
||||
|
||||
float zOff = x38_hightlightPitch * x1c_rightSel;
|
||||
const SGameOption& opt = category.second[x1c_rightSel];
|
||||
switch (opt.type)
|
||||
{
|
||||
case EOptionType::Float:
|
||||
x18c_slidergroup_slider->SetIsActive(true);
|
||||
x18c_slidergroup_slider->SetVisibility(true, ETraversalMode::Children);
|
||||
x18c_slidergroup_slider->SetMinVal(opt.minVal);
|
||||
x18c_slidergroup_slider->SetMaxVal(opt.maxVal);
|
||||
x18c_slidergroup_slider->SetIncrement(opt.increment);
|
||||
x18c_slidergroup_slider->SetCurVal(CGameOptions::GetOption(opt.option));
|
||||
x18c_slidergroup_slider->SetLocalPosition(x3c_sliderStart + zeus::CVector3f(0.f, 0.f, zOff));
|
||||
break;
|
||||
case EOptionType::DoubleEnum:
|
||||
x190_tablegroup_double->SetUserSelection(CGameOptions::GetOption(opt.option));
|
||||
x190_tablegroup_double->SetIsVisible(true);
|
||||
x190_tablegroup_double->SetIsActive(true);
|
||||
UpdateSideTable(x190_tablegroup_double);
|
||||
x190_tablegroup_double->SetLocalPosition(x48_tableDoubleStart + zeus::CVector3f(0.f, 0.f, zOff));
|
||||
break;
|
||||
case EOptionType::TripleEnum:
|
||||
x194_tablegroup_triple->SetUserSelection(CGameOptions::GetOption(opt.option));
|
||||
x194_tablegroup_triple->SetIsVisible(true);
|
||||
x194_tablegroup_triple->SetIsActive(true);
|
||||
UpdateSideTable(x194_tablegroup_triple);
|
||||
x194_tablegroup_triple->SetLocalPosition(x54_tableTripleStart + zeus::CVector3f(0.f, 0.f, zOff));
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void COptionsScreen::ResetOptionWidgetVisibility()
|
||||
{
|
||||
x18c_slidergroup_slider->SetIsActive(false);
|
||||
x18c_slidergroup_slider->SetVisibility(false, ETraversalMode::Children);
|
||||
x190_tablegroup_double->SetIsVisible(false);
|
||||
x190_tablegroup_double->SetIsActive(false);
|
||||
x194_tablegroup_triple->SetIsActive(false);
|
||||
x194_tablegroup_triple->SetIsVisible(false);
|
||||
}
|
||||
|
||||
void COptionsScreen::OnSliderChanged(CGuiSliderGroup* caller, float val)
|
||||
{
|
||||
if (x10_mode != EMode::RightTable)
|
||||
return;
|
||||
|
||||
EGameOption opt = GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()].second[x1c_rightSel].option;
|
||||
CGameOptions::SetOption(opt, caller->GetGurVal());
|
||||
}
|
||||
|
||||
void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int sel)
|
||||
{
|
||||
if (x10_mode != EMode::RightTable)
|
||||
return;
|
||||
|
||||
EGameOption opt = GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()].second[x1c_rightSel].option;
|
||||
CGameOptions::SetOption(opt, caller->GetUserSelection());
|
||||
|
||||
if (opt == EGameOption::Rumble && caller->GetUserSelection() > 0)
|
||||
{
|
||||
x1a8_rumble.HardStopAll();
|
||||
x1a8_rumble.Rumble(RumbleFxTable[11], 1.f, ERumblePriority::One, EIOPort::Zero);
|
||||
}
|
||||
|
||||
CPauseScreenBase::UpdateSideTable(caller);
|
||||
CSfxManager::SfxStart(1437, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
}
|
||||
|
||||
bool COptionsScreen::InputDisabled() const
|
||||
{
|
||||
return x19c_quitGame.operator bool();
|
||||
}
|
||||
|
||||
void COptionsScreen::Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue)
|
||||
{
|
||||
x1a8_rumble.Update(dt);
|
||||
CPauseScreenBase::Update(dt, rand, archQueue);
|
||||
|
||||
if (x1a4_sliderSfx.operator bool() !=
|
||||
(x18c_slidergroup_slider->GetState() != CGuiSliderGroup::EState::None))
|
||||
{
|
||||
if (x18c_slidergroup_slider->GetState() != CGuiSliderGroup::EState::None)
|
||||
x1a4_sliderSfx = CSfxManager::SfxStart(1451, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
else
|
||||
CSfxManager::SfxStop(x1a4_sliderSfx);
|
||||
}
|
||||
|
||||
if (x2a0_24_inOptionBody)
|
||||
x29c_optionAlpha = std::min(x29c_optionAlpha + 4.f * dt, 1.f);
|
||||
else
|
||||
x29c_optionAlpha = std::max(x29c_optionAlpha - 4.f * dt, 0.f);
|
||||
|
||||
if (std::fabs(x29c_optionAlpha) < 0.00001f)
|
||||
{
|
||||
ResetOptionWidgetVisibility();
|
||||
x174_textpane_body->SetIsVisible(false);
|
||||
}
|
||||
|
||||
zeus::CColor color = g_tweakGuiColors->GetPauseItemAmberColor();
|
||||
color.a = x29c_optionAlpha;
|
||||
x18c_slidergroup_slider->SetColor(color);
|
||||
x190_tablegroup_double->SetColor(color);
|
||||
x194_tablegroup_triple->SetColor(color);
|
||||
|
||||
if (x19c_quitGame)
|
||||
{
|
||||
EQuitAction action = x19c_quitGame->Update(dt);
|
||||
if (action == EQuitAction::Yes)
|
||||
{
|
||||
archQueue.Push(MakeMsg::CreateQuitGameplay(EArchMsgTarget::Game));
|
||||
CSfxManager::SetChannel(CSfxManager::ESfxChannels::Default);
|
||||
CSfxManager::SfxStart(1422, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
}
|
||||
else if (action == EQuitAction::No)
|
||||
{
|
||||
CSfxManager::SfxStart(1423, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
x19c_quitGame.reset();
|
||||
}
|
||||
}
|
||||
|
||||
x1a0_gameCube->Update(dt);
|
||||
}
|
||||
|
||||
void COptionsScreen::Touch()
|
||||
{
|
||||
CPauseScreenBase::Touch();
|
||||
x1a0_gameCube->Touch();
|
||||
}
|
||||
|
||||
void COptionsScreen::ProcessControllerInput(const CFinalInput& input)
|
||||
{
|
||||
if (!x19c_quitGame)
|
||||
{
|
||||
CPauseScreenBase::ProcessControllerInput(input);
|
||||
CGameOptions::TryRestoreDefaults(input, x70_tablegroup_leftlog->GetUserSelection(),
|
||||
x1c_rightSel, false, false);
|
||||
if (x70_tablegroup_leftlog->GetUserSelection() == 4 && input.PA())
|
||||
x19c_quitGame = std::make_unique<CQuitGameScreen>(EQuitType::QuitGame);
|
||||
}
|
||||
else
|
||||
{
|
||||
x19c_quitGame->ProcessUserInput(input);
|
||||
}
|
||||
}
|
||||
|
||||
void COptionsScreen::Draw(float transInterp, float totalAlpha, float yOff)
|
||||
{
|
||||
CPauseScreenBase::Draw(transInterp, totalAlpha, yOff);
|
||||
x1a0_gameCube->Draw(transInterp * (1.f - x29c_optionAlpha));
|
||||
if (x19c_quitGame)
|
||||
{
|
||||
CGraphics::SetDepthRange(0.f, 0.001f);
|
||||
x19c_quitGame->Draw();
|
||||
CGraphics::SetDepthRange(0.f, 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
bool COptionsScreen::VReady() const
|
||||
|
@ -17,14 +194,85 @@ bool COptionsScreen::VReady() const
|
|||
return true;
|
||||
}
|
||||
|
||||
void COptionsScreen::VActivate() const
|
||||
void COptionsScreen::VActivate()
|
||||
{
|
||||
for (int i=0 ; i<5 ; ++i)
|
||||
xa8_textpane_categories[i]->TextSupport()->SetText(xc_pauseStrg.GetString(i + 16));
|
||||
|
||||
x178_textpane_title->TextSupport()->SetText(xc_pauseStrg.GetString(15));
|
||||
|
||||
for (int i=0 ; i<5 ; ++i)
|
||||
x70_tablegroup_leftlog->GetWorkerWidget(i)->SetIsSelectable(false);
|
||||
|
||||
x174_textpane_body->TextSupport()->SetJustification(EJustification::Center);
|
||||
x174_textpane_body->TextSupport()->SetVerticalJustification(EVerticalJustification::Bottom);
|
||||
|
||||
static_cast<CGuiTextPane*>(x190_tablegroup_double->GetWorkerWidget(0))->
|
||||
TextSupport()->SetText(xc_pauseStrg.GetString(95));
|
||||
static_cast<CGuiTextPane*>(x190_tablegroup_double->GetWorkerWidget(1))->
|
||||
TextSupport()->SetText(xc_pauseStrg.GetString(94));
|
||||
|
||||
static_cast<CGuiTextPane*>(x194_tablegroup_triple->GetWorkerWidget(0))->
|
||||
TextSupport()->SetText(xc_pauseStrg.GetString(96));
|
||||
static_cast<CGuiTextPane*>(x194_tablegroup_triple->GetWorkerWidget(1))->
|
||||
TextSupport()->SetText(xc_pauseStrg.GetString(97));
|
||||
static_cast<CGuiTextPane*>(x194_tablegroup_triple->GetWorkerWidget(2))->
|
||||
TextSupport()->SetText(xc_pauseStrg.GetString(98));
|
||||
|
||||
x18c_slidergroup_slider->SetSelectionChangedCallback(
|
||||
std::bind(&COptionsScreen::OnSliderChanged, this, std::placeholders::_1, std::placeholders::_2));
|
||||
x190_tablegroup_double->SetMenuSelectionChangeCallback(
|
||||
std::bind(&COptionsScreen::OnEnumChanged, this, std::placeholders::_1, std::placeholders::_2));
|
||||
x194_tablegroup_triple->SetMenuSelectionChangeCallback(
|
||||
std::bind(&COptionsScreen::OnEnumChanged, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
void COptionsScreen::RightTableSelectionChanged(int selBegin, int selEnd)
|
||||
{
|
||||
UpdateOptionView();
|
||||
}
|
||||
|
||||
void COptionsScreen::ChangedMode()
|
||||
{
|
||||
if (x10_mode == EMode::RightTable)
|
||||
{
|
||||
x174_textpane_body->SetIsVisible(true);
|
||||
UpdateOptionView();
|
||||
x2a0_24_inOptionBody = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
x2a0_24_inOptionBody = false;
|
||||
}
|
||||
}
|
||||
|
||||
void COptionsScreen::UpdateRightTable()
|
||||
{
|
||||
CPauseScreenBase::UpdateRightTable();
|
||||
const std::pair<int, const SGameOption*>& category =
|
||||
GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()];
|
||||
for (int i=0 ; i<5 ; ++i)
|
||||
{
|
||||
if (i < category.first)
|
||||
xd8_textpane_titles[i]->TextSupport()->SetText(xc_pauseStrg.GetString(category.second[i].stringId));
|
||||
else
|
||||
xd8_textpane_titles[i]->TextSupport()->SetText(u"");
|
||||
}
|
||||
}
|
||||
|
||||
bool COptionsScreen::ShouldLeftTableAdvance() const
|
||||
{
|
||||
return x70_tablegroup_leftlog->GetUserSelection() != 4;
|
||||
}
|
||||
|
||||
bool COptionsScreen::ShouldRightTableAdvance() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 COptionsScreen::GetRightTableCount() const
|
||||
{
|
||||
return 0;
|
||||
return GameOptionsRegistry[x70_tablegroup_leftlog->GetUserSelection()].first;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "CInGameGuiManager.hpp"
|
||||
#include "CPauseScreenBase.hpp"
|
||||
#include "CGameCubeDoll.hpp"
|
||||
#include "CQuitGameScreen.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -11,11 +13,34 @@ namespace MP1
|
|||
|
||||
class COptionsScreen : public CPauseScreenBase
|
||||
{
|
||||
std::unique_ptr<CQuitGameScreen> x19c_quitGame;
|
||||
std::unique_ptr<CGameCubeDoll> x1a0_gameCube;
|
||||
CSfxHandle x1a4_sliderSfx;
|
||||
CRumbleGenerator x1a8_rumble;
|
||||
float x29c_optionAlpha = 0.f;
|
||||
bool x2a0_24_inOptionBody : 1;
|
||||
|
||||
void UpdateOptionView();
|
||||
void ResetOptionWidgetVisibility();
|
||||
void OnSliderChanged(CGuiSliderGroup* caller, float val);
|
||||
void OnEnumChanged(CGuiTableGroup* caller, int sel);
|
||||
|
||||
public:
|
||||
COptionsScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg);
|
||||
~COptionsScreen();
|
||||
|
||||
bool InputDisabled() const;
|
||||
void Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue);
|
||||
void Touch();
|
||||
void ProcessControllerInput(const CFinalInput& input);
|
||||
void Draw(float transInterp, float totalAlpha, float yOff);
|
||||
bool VReady() const;
|
||||
void VActivate() const;
|
||||
void VActivate();
|
||||
void RightTableSelectionChanged(int selBegin, int selEnd);
|
||||
void ChangedMode();
|
||||
void UpdateRightTable();
|
||||
bool ShouldLeftTableAdvance() const;
|
||||
bool ShouldRightTableAdvance() const;
|
||||
u32 GetRightTableCount() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
virtual void Draw(float transInterp, float totalAlpha, float yOff);
|
||||
virtual float GetCameraYBias() const { return 0.f; }
|
||||
virtual bool VReady() const=0;
|
||||
virtual void VActivate() const=0;
|
||||
virtual void VActivate()=0;
|
||||
virtual void RightTableSelectionChanged(int selBegin, int selEnd) {}
|
||||
virtual void ChangedMode() {}
|
||||
virtual void UpdateRightTable();
|
||||
|
|
Loading…
Reference in New Issue