void GUI::create() { if(window) { window->setFocus(); return; } Config::setConfig("Dialog", true); /* auto setBoolCfg = [&] (string setting, CheckBoxPtr enable) { if(enable) { Config::setConfig(setting, enable); } setBoolCfg("", eUserFilter); setCfg("", eHubFilter); setCfg("", eSearchFilter); setCfg("", eProtoFilter); setCfg("", eFileLogging); */ Application::init(); { Window::Seed seed(_T(PLUGIN_NAME)); seed.location.size.x = 1200; seed.location.size.y = 800; window = new Window(); window->create(seed); auto iconPath = Util::toT(Config::getInstallPath() + "DevPlugin.ico"); try { window->setSmallIcon(new dwt::Icon(iconPath, dwt::Point(16, 16))); window->setLargeIcon(new dwt::Icon(iconPath, dwt::Point(32, 32))); } catch(const dwt::DWTException&) { } window->onClosing([]() -> bool { window = nullptr; Application::uninit(); if(!unloading) { Config::setConfig("Dialog", false); } return true; }); window->onDestroy([this] { clear(); }); } auto grid = window->addChild(Grid::Seed(3, 1)); grid->column(0).mode = GridInfo::FILL; grid->row(0).mode = GridInfo::FILL; grid->row(0).align = GridInfo::STRETCH; grid->setSpacing(8); { Table::Seed seed; seed.style |= WS_BORDER | LVS_SHOWSELALWAYS; seed.lvStyle = LVS_EX_DOUBLEBUFFER | LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP; table = grid->addChild(seed); std::vector<Column> columns; columns.emplace_back(_T("#"), 50); columns.emplace_back(_T("Dir"), 50); columns.emplace_back(_T("Protocol"), 60); columns.emplace_back(_T("IP"), 100); columns.emplace_back(_T("Port"), 50); columns.emplace_back(_T("Peer info"), 200); columns.emplace_back(_T("Message")); table->setColumns(columns); table->onSized([this](const SizedEvent& e) { table->setColumnWidth(6, e.size.x - 50 - 50 - 60 - 100 - 50 - 200 - 20); }); table->onContextMenu([this](const ScreenCoordinate& pt) -> bool { auto menu = window->addChild(Menu::Seed()); auto hasSel = table->hasSelected(); menu->appendItem(_T("Copy selected messages"), [=] { copy(); }, nullptr, hasSel); menu->appendItem(_T("Remove selected messages"), [=] { remove(); }, nullptr, hasSel); menu->appendSeparator(); menu->appendItem(_T("Select all"), [] { table->selectAll(); }, nullptr, !table->empty()); menu->appendSeparator(); menu->appendItem(_T("Open protocol documentation"), [=] { openDoc(); }, nullptr, hasSel); menu->open(pt.x() == -1 || pt.y() == -1 ? table->getContextMenuPos() : pt); return true; }); table->onCustomDraw([this](NMLVCUSTOMDRAW& data) { return GUI::handleCustomDraw(data); }); } { auto cur = grid->addChild(Grid::Seed(1, 5)); cur->setSpacing(30); auto hubMessagesW = cur->addChild(CheckBox::Seed(_T("Add hub messages"))); hubMessagesW->setChecked(true); hubMessagesW->onClicked([this, hubMessagesW] { hubMessages = hubMessagesW->getChecked(); }); auto userMessagesW = cur->addChild(CheckBox::Seed(_T("Add user messages"))); userMessagesW->setChecked(true); userMessagesW->onClicked([this, userMessagesW] { userMessages = userMessagesW->getChecked(); }); { ComboBox::Seed seed; seed.style |= CBS_DROPDOWNLIST | CBS_SORT; filterW = cur->addChild(seed); initFilter(); filterW->onSelectionChanged([this] { auto str = filterW->getText(); if(str == noFilter) { filterSel.clear(); } else { filterSel = move(str); } }); } { auto cur2 = cur->addChild(GroupBox::Seed(_T("Regex filter")))->addChild(Grid::Seed(1, 2)); cur2->column(0).size = 250; TextBox::Seed seed; seed.style |= ES_AUTOHSCROLL; auto box = cur2->addChild(seed); Button::Seed bs(_T("Apply")); bs.padding.x += 8; cur2->addChild(bs)->onClicked([this, box] { regex = ""; try { regex.assign(Util::fromT(box->getText())); } catch(const std::runtime_error&) { dwt::MessageBox(window).show(_T("Invalid regular expression"), window->getText(), dwt::MessageBox::BOX_OK, dwt::MessageBox::BOX_ICONEXCLAMATION); } }); } { auto cur2 = cur->addChild(GroupBox::Seed(_T("Log to a file")))->addChild(Grid::Seed(1, 2)); cur2->column(0).size = 250; log = Config::getConfig("Log"); TextBox::Seed seed(Util::toT(log)); seed.style |= ES_AUTOHSCROLL; auto box = cur2->addChild(seed); box->onUpdated([this, box] { log = Util::fromT(box->getText()); Config::setConfig("Log", log); }); Button::Seed bs(_T("Browse")); bs.padding.x += 8; cur2->addChild(bs)->onClicked([this, box] { auto file = Util::toT(log); if(SaveDialog(window).open(file)) { log = Util::fromT(file); Config::setConfig("Log", log); box->setText(file); } }); } } { auto cur = grid->addChild(Grid::Seed(1, 5)); cur->column(4).mode = GridInfo::FILL; cur->column(4).align = GridInfo::BOTTOM_RIGHT; cur->setSpacing(30); Button::Seed bs; bs.padding.x += 20; bs.caption = _T("Copy selected messages"); cur->addChild(bs)->onClicked([this] { copy(); }); auto scrollW = cur->addChild(CheckBox::Seed(_T("Auto-scroll"))); scrollW->setChecked(true); scrollW->onClicked([this, scrollW] { scroll = scrollW->getChecked(); }); bs.caption = _T("Clear the list"); cur->addChild(bs)->onClicked([this] { clear(); }); auto onTop = cur->addChild(CheckBox::Seed(_T("Keep this window on top"))); onTop->onClicked([onTop] { window->setZOrder(onTop->getChecked() ? HWND_TOPMOST : HWND_NOTOPMOST); }); bs.caption = _T("Close"); bs.style |= BS_DEFPUSHBUTTON; bs.padding.x += 20; cur->addChild(bs)->onClicked([] { window->close(true); }); } grid->resize(window->getClientSize()); window->onSized([grid](const SizedEvent& e) { grid->resize(e.size); }); table->setFocus(); window->setTimer([this]() -> bool { timer(); return true; }, 500); }