Maintenance: [forced, user-approved] Family D5: remove UITextViewerContext and TextViewerActions entirely. UITextViewer ctor 0x86F0A0

Batch #10206 by ragnarok-clanker: forced by an admin (4 lower score(s), 20 changed function(s)); checked with 36 compiled unit(s), including every includer of Source/UI/Acceptance/UIJoinPartyAcceptWnd.h, Source/UI/Dialogs/UIBookWnd.h, Source/UI/Dialogs/UIDisconnectedServerMsgWnd.h, Source/UI/Dialogs/UINoticeConfirmWnd.h, Source/UI/Dialogs/UIWaitWnd.h, Source/UI/EntryQueue/UIEntryQueueWnd.h, Source/UI/Party/UIRequestJoinPartyWnd.h, Source/UI/Text/UITextViewer.h, Source/UI/Window/UIAccountLimitedToolWnd.h, Source/UI/Window/UIMessageBox.h, Source/UI/Window/UINavigationHelpWnd.h, Source/UI/Window/UINormalMB.h, Source/UI/Window/UIPartyBookingHelpWnd.h.
This commit is contained in:
ragnarok-clanker 2026-11-02 22:23:07 +00:00
commit cc8a43db9f
23 changed files with 56 additions and 90 deletions

View file

@ -284,8 +284,7 @@ void UIChooseSellBuyWnd::AddChoice(const char* name, int id, int x, int y) {
// INLINED
void UIChooseSellBuyWnd::CreateViewer(int width, int height) {
auto& text = this->m_acceptance->text;
this->viewer = new UITextViewer(*this->m_context, text);
this->viewer = new UITextViewer(*this->m_context);
this->viewer->Configure(10, 22, width - 20, height - 55, 0);
const std::string chip = std::string(prefix) + "colorchip.bmp";
const auto* bitmap = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(chip.c_str()));
@ -401,7 +400,6 @@ void UIChooseWnd::Slot15(int width, int height) {
// OFFSET: 0x008DE520
// FUNCTION: fn_12169
void UIDisconnectedServerMsgWnd::Slot15(int width, int height) {
auto& text = *this->m_textContext;
auto* button = new UIBitmapButton(*this->m_context);
button->SetBitmap("유저인터페이스\\btn_ok.bmp", 0, 0);
button->SetBitmap("유저인터페이스\\btn_ok_a.bmp", 1, 0);
@ -412,7 +410,7 @@ void UIDisconnectedServerMsgWnd::Slot15(int width, int height) {
this->AddChild(button);
this->m_message0 = 184;
this->m_viewer = new UITextViewer(*this->m_context, text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(10, 22, width - 20, height - 55, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
@ -3677,7 +3675,7 @@ bool UInCashWnd::Slot03() {
// OFFSET: 0x008DB750
// FUNCTION: fn_12159
void UIBookWnd::Slot15(int width, int height) {
this->m_viewer = new UITextViewer(*this->m_context, this->m_book->text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(30, 45, width - 60, height - 60, 0);
this->AddChild(this->m_viewer);
@ -3706,7 +3704,7 @@ void UIBookWnd::Slot15(int width, int height) {
// FUNCTION: fn_12175
void UIItemCollectionWnd::Slot15(int width, int height) {
this->m_kind = 12;
this->m_viewer = new UITextViewer(*this->m_context, *reinterpret_cast<UITextViewerContext*>(nullptr));
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(91, 31, width - 98, height - 40, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
@ -6175,8 +6173,8 @@ UIComboBoxWnd::UIComboBoxWnd(UIWindowContext& windows)
// OFFSET: 0x008C77A0
// FUNCTION: fn_11938
UIDisconnectedServerMsgWnd::UIDisconnectedServerMsgWnd(UIWindowContext& windows, UITextViewerContext& text)
: UIFrameWnd(windows, 0), m_viewer(nullptr), m_textContext(&text) {
UIDisconnectedServerMsgWnd::UIDisconnectedServerMsgWnd(UIWindowContext& windows)
: UIFrameWnd(windows, 0), m_viewer(nullptr) {
}
// OFFSET: 0x008C82D0
@ -6540,7 +6538,7 @@ void UINoticeConfirmWnd::Slot15(int width, int height) {
}
this->m_message0 = 184;
this->m_viewer = new UITextViewer(*this->m_context, *this->m_textContext);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(10, 22, width - 20, height - 55, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
@ -6704,7 +6702,7 @@ void UIWaitWnd::Slot15(int width, int height) {
this->m_button->SetTooltip("");
this->AddChild(this->m_button);
this->m_textViewer = new UITextViewer(*this->m_context, *this->m_textContext);
this->m_textViewer = new UITextViewer(*this->m_context);
this->m_textViewer->Configure(10, 22, width - 20, height - 55, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);

View file

@ -5,12 +5,11 @@
#include "UI/Window/UIFrameWnd.h"
class UITextViewer;
struct UITextViewerContext;
struct WindowResponseRecorder;
struct NormalItemSlotWindow;
struct UIAcceptanceContext {
UITextViewerContext& text;
void* unknown_text;
WindowResponseRecorder& recorder;
const int& screenWidth;
const int& screenHeight;

View file

@ -9,11 +9,10 @@
class UISpriteButton;
class UITextViewer;
struct UITextViewerContext;
struct WindowOrdering;
struct UIBookContext {
UITextViewerContext& text;
void* unknown_text;
WindowOrdering& ordering;
};

View file

@ -3,12 +3,11 @@
#include "UI/Window/UIFrameWnd.h"
struct UITextViewerContext;
class UITextViewer;
class UIDisconnectedServerMsgWnd : public UIFrameWnd {
public:
UIDisconnectedServerMsgWnd(UIWindowContext& windows, UITextViewerContext& text);
UIDisconnectedServerMsgWnd(UIWindowContext& windows);
void Slot15(int width, int height) override;
void Paint() override;
int SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) override;
@ -16,7 +15,7 @@ public:
/* 00B4 */ UITextViewer* m_viewer;
protected:
UITextViewerContext* m_textContext;
void* unknown_textContext;
};
#endif

View file

@ -4,7 +4,6 @@
#include "UI/Window/UIFrameWnd.h"
class UITextViewer;
struct UITextViewerContext;
class UINoticeConfirmWnd : public UIFrameWnd {
public:
@ -17,7 +16,7 @@ public:
void Slot15(int width, int height) override;
protected:
UITextViewerContext* m_textContext;
void* unknown_textContext;
};
#endif

View file

@ -5,7 +5,6 @@
class UIBitmapButton;
class UITextViewer;
struct UITextViewerContext;
class UIWaitWnd : public UIFrameWnd {
public:
@ -20,7 +19,7 @@ public:
void Slot15(int width, int height) override;
protected:
UITextViewerContext* m_textContext;
void* unknown_textContext;
};
#endif

View file

@ -108,8 +108,6 @@ UIEntryQueueRequestWnd::UIEntryQueueRequestWnd(UIWindowContext& windows, UIEntry
// OFFSET: 0x00BA48E0
// FUNCTION: fn_19691
bool UIEntryQueueRequestWnd::Create() {
auto& text = this->m_entryQueue->text;
this->Resize(300, 250);
this->AddBaseButton();
this->AddCloseButton("", 0);
@ -118,7 +116,7 @@ bool UIEntryQueueRequestWnd::Create() {
this->Slot22(300, 250);
this->Move((g_renderer->viewport.width - 640) / 2 + 185, (g_renderer->viewport.height - 480) / 2 + 180);
this->m_viewer = new UITextViewer(*this->m_context, text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(10, 22, 280, 305, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
@ -238,8 +236,6 @@ UIEntryQueueStandByWnd::UIEntryQueueStandByWnd(UIWindowContext& windows, UIEntry
// OFFSET: 0x00BA5700
// FUNCTION: fn_19698
bool UIEntryQueueStandByWnd::Create() {
auto& text = this->m_entryQueue->text;
this->Resize(280, 120);
this->AddBaseButton();
this->SetSize(280, 120);
@ -247,7 +243,7 @@ bool UIEntryQueueStandByWnd::Create() {
this->Slot22(280, 120);
this->Move((g_renderer->viewport.width - 640) / 2 + 185, (g_renderer->viewport.height - 480) / 2 + 180);
this->m_viewer = new UITextViewer(*this->m_context, text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(10, 22, 260, 65, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);
@ -636,11 +632,9 @@ void UIEntryQueueWnd::Slot11() {
// OFFSET: 0x00BA3A50
// FUNCTION: fn_19679
void UIEntryQueueHelpWnd::Slot15(int width, int height) {
auto& text = this->m_entryQueue->text;
this->Resize(280, 280);
this->m_viewer = new UITextViewer(*this->m_context, text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(10, 22, 270, 225, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);

View file

@ -14,11 +14,10 @@ class UIBitmapButton;
class UIStaticText;
struct EntryQueueInfo;
class UITextViewer;
struct UITextViewerContext;
struct WindowResponseRecorder;
struct UIEntryQueueContext {
UITextViewerContext& text;
void* unknown_text;
WindowResponseRecorder& recorder;
};

View file

@ -32,8 +32,6 @@ UIRequestJoinPartyWnd::~UIRequestJoinPartyWnd() = default;
// OFFSET: 0x007BEFD0
// FUNCTION: fn_09301
void UIRequestJoinPartyWnd::Slot15(int, int) {
auto& text = this->m_request->text;
this->icon = new UIBitmapButton(*this->m_context);
this->icon->SetSize(25, 25);
const std::string initial = std::string(prefix) + "renewalparty\\icon_jobs_4046.bmp";
@ -67,7 +65,7 @@ void UIRequestJoinPartyWnd::Slot15(int, int) {
}
this->m_message0 = 541;
this->details = new UITextViewer(*this->m_context, text);
this->details = new UITextViewer(*this->m_context);
this->details->Configure(43, 20, 167, 60, 0);
this->details->textColor = 0xFFFFFFFFu;
this->details->Invalidate();
@ -85,7 +83,7 @@ void UIRequestJoinPartyWnd::Slot15(int, int) {
std::vector<std::string> unused;
WrapPlainText(LookupMessage(3518), unused, 30);
this->blockText = new UITextViewer(*this->m_context, text);
this->blockText = new UITextViewer(*this->m_context);
this->blockText->Configure(31, 81, 182, 47, 0);
this->blockText->textColor = 0xFFD7C53Cu;
this->blockText->Invalidate();

View file

@ -9,12 +9,11 @@ class UITextViewer;
class UICheckBox;
class UIStaticText;
class UIBitmapButton;
struct UITextViewerContext;
struct PartyJoinRequest;
class UIRequestJoinPartyMgr;
struct UIRequestJoinPartyContext {
UITextViewerContext& text;
void* unknown_text;
UIRequestJoinPartyMgr& requests;
};

View file

@ -63,8 +63,7 @@ namespace {
// OFFSET: 0x0086F0A0
// FUNCTION: fn_11086
UITextViewer::UITextViewer(UIWindowContext& windows, UITextViewerContext& text)
: UIListBox(windows), splitTipLinks(0), outline(0), bold(0), m_text(&text) {
UITextViewer::UITextViewer(UIWindowContext& windows) : UIListBox(windows), splitTipLinks(0), outline(0), bold(0) {
this->lineHeight = 18;
constexpr char path[] = "유저인터페이스\\colorchip.bmp";
const auto* chip = static_cast<CBitmapRes*>(ResourceMgr::Instance().Load(path));

View file

@ -7,23 +7,6 @@
class UITextButton;
class TextViewerActions {
public:
virtual void Navigate(std::string map, int type, unsigned char flags, bool option, int x, int y, int target) = 0;
virtual void NavigateNamed(std::string map, int type, int option) = 0;
virtual void OpenTip(UIWindow& window, int id) = 0;
virtual void OpenQuest(int id) = 0;
protected:
~TextViewerActions() = default;
};
struct UITextViewerContext {
TextViewerActions& actions;
HWND& applicationWindow;
};
class UITextViewer : public UIListBox {
friend class UIWindow;
friend class UIQuestDisplay;
@ -31,7 +14,7 @@ class UITextViewer : public UIListBox {
public:
UITextViewer();
UITextViewer(UIWindowContext& windows, UITextViewerContext& text);
UITextViewer(UIWindowContext& windows);
~UITextViewer() override;
void Slot15(int width, int height) override;
void Paint() override;
@ -51,8 +34,9 @@ public:
/* 00E9 */ unsigned char outline;
/* 00EA */ unsigned char bold;
/* 00EC */ void* unknown_00EC;
private:
UITextViewerContext* m_text;
std::pair<int, int> LinkPosition(unsigned position, unsigned addedLines);
void AddLinks(const char* text, unsigned addedLines, int kind);
bool AddItemLinks(std::string text, unsigned addedLines);

View file

@ -1,4 +1,9 @@
#include "UI/Chat/UINewChatWnd.h"
#include "Client/Application/ApplicationWindow.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/ModeMgr.h"
#include "Contents/NavigationManager.h"
#include "UI/Dialogs/UITipboxWnd.h"
#include "UI/Window/UIWindowMgr.h"
#include "Contents/Items/ItemInfo.h"
#include "UI/Lists/UIScrollBar.h"
@ -30,7 +35,7 @@ void UITextViewer::Activate(UITextButton* button, int id) {
switch (id) {
case 437:
if (!arguments.at(0).empty()) {
ShellExecuteA(this->m_text->applicationWindow, "open", arguments[0].c_str(), nullptr, nullptr, SW_SHOWNORMAL);
ShellExecuteA(hWnd, "open", arguments[0].c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
break;
@ -44,7 +49,7 @@ void UITextViewer::Activate(UITextButton* button, int id) {
const int y = number(2);
if (arguments.size() <= 3) {
this->m_text->actions.Navigate(map, 2, 5, false, x, y, 1002);
g_navigationManager.sub_B99030(map, 2, 5, false, x, y, 1002);
break;
}
@ -52,7 +57,7 @@ void UITextViewer::Activate(UITextButton* button, int id) {
int policy = number(4);
if (policy == -222) {
this->m_text->actions.NavigateNamed((type == 3 ? "$$DB " : "") + map, type, 0);
g_navigationManager.sub_B995D0((type == 3 ? "$$DB " : "") + map, type, 0);
break;
}
@ -74,7 +79,7 @@ void UITextViewer::Activate(UITextButton* button, int id) {
flag += 4;
}
this->m_text->actions.Navigate(map, type, flag, option == 0, x, y, target);
g_navigationManager.sub_B99030(map, type, flag, option == 0, x, y, target);
break;
}
case 464: {
@ -98,13 +103,13 @@ void UITextViewer::Activate(UITextButton* button, int id) {
case 517:
if (!arguments.empty()) {
if (UIWindow* window = g_windowMgr.EnsureWindow(315)) {
this->m_text->actions.OpenTip(*window, number(0));
static_cast<UITipboxWnd*>(window)->ShowTip(number(0));
}
}
break;
case 539:
this->m_text->actions.OpenQuest(number(0));
static_cast<CGameMode*>(g_modeMgr.GetGameMode())->ReceiveServiceRequest(6, number(0));
break;
default:
break;

View file

@ -131,7 +131,7 @@ void UIAccountLimitedToolWnd::Slot15(int, int) {
this->m_buttons[i]->Invalidate();
}
this->m_viewer = new UITextViewer(*this->m_context, *this->m_textContext);
this->m_viewer = new UITextViewer(*this->m_context);
const int buttonHeight = this->m_buttons[1]->geometry.height;
this->m_viewer->Configure(10, buttonHeight + 189, this->geometry.width - 20, this->geometry.height - buttonHeight - 199, 0);
this->m_viewer->backgroundColor = 0xFF969696;
@ -366,8 +366,8 @@ int UIAccountLimitedToolWnd::SendMsg(UIWindow* sender, int message, std::intptr_
// OFFSET: 0x00946800
// FUNCTION: fn_12846
UIAccountLimitedToolWnd::UIAccountLimitedToolWnd(UIWindowContext& windows, UITextViewerContext& texts)
: UIFrameWnd(windows, 0), m_accountIdText(nullptr), m_viewer(nullptr), m_textContext(&texts) {
UIAccountLimitedToolWnd::UIAccountLimitedToolWnd(UIWindowContext& windows)
: UIFrameWnd(windows, 0), m_accountIdText(nullptr), m_viewer(nullptr) {
SecureZeroMemory(this->m_edits, sizeof(this->m_edits));
SecureZeroMemory(this->m_buttons, sizeof(this->m_buttons));
}

View file

@ -5,7 +5,6 @@
#include <string>
struct UITextViewerContext;
class UIBitmapButton;
class UIEditCtrl;
class UIStaticText;
@ -13,7 +12,7 @@ class UITextViewer;
class UIAccountLimitedToolWnd : public UIFrameWnd {
public:
UIAccountLimitedToolWnd(UIWindowContext& windows, UITextViewerContext& texts);
UIAccountLimitedToolWnd(UIWindowContext& windows);
void Slot15(int width, int height) override;
void Paint() override;
int SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) override;
@ -26,7 +25,7 @@ public:
protected:
void* unknown_controls;
UITextViewerContext* m_textContext;
void* unknown_textContext;
};
#endif

View file

@ -684,7 +684,7 @@ void UIMessageBox::Configure(
inset = image->geometry.width + image->geometry.x;
}
this->viewer = new UITextViewer(*this->m_context, this->m_dialog->text);
this->viewer = new UITextViewer(*this->m_context);
this->viewer->Configure(inset + 10, 22, width - inset - 20, height - 55, 0);
this->viewer->backgroundColor = Palette(ResourceMgr::Instance(), 2, 2) | 0xFF000000u;
this->viewer->Invalidate();
@ -773,7 +773,7 @@ int UIMessageBox::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i
return 0;
case 98:
if (a == 426) {
ShellExecuteA(this->m_dialog->text.applicationWindow, "open", LookupMessage(3445), nullptr, nullptr, SW_SHOWNORMAL);
ShellExecuteA(hWnd, "open", LookupMessage(3445), nullptr, nullptr, SW_SHOWNORMAL);
}
return 0;

View file

@ -6,13 +6,12 @@
#include <string>
class UITextViewer;
struct UITextViewerContext;
class UIWindowMgr;
struct WindowResponseRecorder;
struct UIMessageBoxContext {
UITextViewerContext& text;
void* unknown_text;
UIWindowMgr& retirement;
WindowResponseRecorder& recorder;
int& response;

View file

@ -9,7 +9,7 @@
// OFFSET: 0x00921530
// FUNCTION: fn_12642
void UINavigationHelpWnd::Slot15(int width, int height) {
this->m_viewer = new UITextViewer(*this->m_context, *this->m_text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(5, 22, width - 10, height - 27, 0);
this->m_viewer->backgroundRed = 0xd2;
this->m_viewer->backgroundGreen = 0xd2;
@ -68,6 +68,6 @@ int UINavigationHelpWnd::SendMsg(UIWindow*, int message, std::intptr_t a, std::i
// OFFSET: 0x009115B0
// FUNCTION: fn_12517
UINavigationHelpWnd::UINavigationHelpWnd(UIWindowContext& windows, UITextViewerContext& text)
: UIFrameWnd(windows, 0), m_text(&text), m_viewer(nullptr), unknown_00B8(0) {
UINavigationHelpWnd::UINavigationHelpWnd(UIWindowContext& windows)
: UIFrameWnd(windows, 0), m_viewer(nullptr), unknown_00B8(0) {
}

View file

@ -4,18 +4,17 @@
#include "UI/Window/UIFrameWnd.h"
class UITextViewer;
struct UITextViewerContext;
class UINavigationHelpWnd : public UIFrameWnd {
public:
UINavigationHelpWnd(UIWindowContext& windows, UITextViewerContext& text);
UINavigationHelpWnd(UIWindowContext& windows);
void Slot15(int width, int height) override;
void Paint() override;
int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override;
protected:
void* unknown_controls;
UITextViewerContext* m_text;
void* unknown_text;
/* 00B4 */ UITextViewer* m_viewer;
/* 00B8 */ int unknown_00B8;
};

View file

@ -93,7 +93,7 @@ void UINormalMB::Create(UIWindow* owner, const char* text, int type, bool defaul
inset = image->geometry.width + image->geometry.x;
}
this->m_viewer = new UITextViewer(*this->m_context, *this->m_textContext);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(inset + 10, 22, width - inset - 20, height - 55, 0);
unsigned red, green, blue;
SkinPaletteChannels(ResourceMgr::Instance(), 2, 2, red, green, blue);

View file

@ -7,7 +7,6 @@
#include <string>
class UITextViewer;
struct UITextViewerContext;
class UINormalMB : public UIFrameWnd {
friend class UICashEmotionListWnd;
@ -28,7 +27,7 @@ protected:
/* 00F0 */ std::map<int, void (*)()> m_actions;
private:
UITextViewerContext* m_textContext;
void* unknown_textContext;
void AddButton(const char* normal, const char* hover, const char* pressed, int x, int y, int id);
};

View file

@ -16,7 +16,7 @@ void UIPartyBookingHelpWnd::Slot15(int width, int height) {
this->AddBaseButton();
this->AddCloseButton("", 0);
this->m_viewer = new UITextViewer(*this->m_context, *this->m_text);
this->m_viewer = new UITextViewer(*this->m_context);
this->m_viewer->Configure(10, 25, width - 20, height - 35, 1);
this->AddChild(this->m_viewer);
@ -53,6 +53,6 @@ int UIPartyBookingHelpWnd::SendMsg(UIWindow* sender, int message, std::intptr_t
// OFFSET: 0x00911860
// FUNCTION: fn_12519
UIPartyBookingHelpWnd::UIPartyBookingHelpWnd(UIWindowContext& windows, UITextViewerContext& text)
: UIFrameWnd(windows, 0), m_text(&text) {
UIPartyBookingHelpWnd::UIPartyBookingHelpWnd(UIWindowContext& windows)
: UIFrameWnd(windows, 0) {
}

View file

@ -4,18 +4,17 @@
#include "UI/Window/UIFrameWnd.h"
class UITextViewer;
struct UITextViewerContext;
class UIPartyBookingHelpWnd : public UIFrameWnd {
public:
UIPartyBookingHelpWnd(UIWindowContext& windows, UITextViewerContext& text);
UIPartyBookingHelpWnd(UIWindowContext& windows);
void Slot15(int width, int height) override;
void Paint() override;
int SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) override;
protected:
void* unknown_controls;
UITextViewerContext* m_text;
void* unknown_text;
/* 00B4 */ UITextViewer* m_viewer;
};