From 1dc8488ca613db47e5abed40b21a1893538f571c Mon Sep 17 00:00:00 2001 From: Crypto City <cryptocity@example.com> Date: Fri, 17 Jan 2020 01:44:59 +0000 Subject: [PATCH] game: wip - switch to turbo badger for ui --- GameData/TB/cc/research-row.tb.txt | 13 + GameData/TB/cc/research.tb.txt | 34 ++ src/game/ui-research.cc | 515 ++++++++++------------------- src/game/ui-research.h | 69 ++-- 4 files changed, 265 insertions(+), 366 deletions(-) create mode 100644 GameData/TB/cc/research-row.tb.txt create mode 100644 GameData/TB/cc/research.tb.txt diff --git a/GameData/TB/cc/research-row.tb.txt b/GameData/TB/cc/research-row.tb.txt new file mode 100644 index 000000000..46a09e65f --- /dev/null +++ b/GameData/TB/cc/research-row.tb.txt @@ -0,0 +1,13 @@ +WindowInfo + +TBLayout: axis: x, size: "available", distribution: "gravity" + TBLayout: axis: y, distribution: "preferred", position: "left top" + TBTextField: id: "name" + TBTextField: id: "status" + TBTextField: id: "desc" + TBLayout: axis: y, distribution: "preferred", position: "left top", gravity: "all" + TBTextField: text: "", gravity: "left right" + TBLayout: axis: y, id: "researching", size: "preferred" + TBEditField: id: "amount", text: "0", value: 1 + TBTextField: id: "chance", text: "0% chance", value: 1 + TBButton: id: "research", text: "Research", value: 1 diff --git a/GameData/TB/cc/research.tb.txt b/GameData/TB/cc/research.tb.txt new file mode 100644 index 000000000..ae0dc10b0 --- /dev/null +++ b/GameData/TB/cc/research.tb.txt @@ -0,0 +1,34 @@ +WindowInfo + title Research + modal: 1 + +TBLayout: axis: y, distribution-position: "left top", distribution: "available" + + TBLayout: axis x, distribution-position: "left top", distribution: "available" + + TBLayout: axis: y + TBLayout: axis: x, distribution-position: "left" + TBTextField: text: "Balance:" + TBTextField: id: "balance", text: "" + TBLayout: axis: x, distribution-position: "left" + TBTextField: text: "Research bonus:" + TBTextField: id: "research-bonus", text: "" + TBLayout: axis: x, distribution-position: "left" + TBTextField: text: "Discovered by you:" + TBTextField: id: "num-discoveries", text: "" + + TBLayout: axis: y + TBLayout: axis: x, distribution-position: "left" + TBCheckBox: id: "show-discovered" + TBTextField: text: "Discovered" + TBLayout: axis: x, distribution-position: "left" + TBCheckBox: id: "show-researching" + TBTextField: text: "Researching" + TBLayout: axis: x, distribution-position: "left" + TBCheckBox: id: "show-locked" + TBTextField: text: "Locked" + + TBEditField: id: "search", placeholder: "search", type: "search", gravity: "left right" + + TBLayout: axis: y, distribution: "available" + TBSelectList: id: "discoveries", gravity: "all" diff --git a/src/game/ui-research.cc b/src/game/ui-research.cc index d5b12ba6a..bcaaaf60d 100644 --- a/src/game/ui-research.cc +++ b/src/game/ui-research.cc @@ -9,13 +9,10 @@ #include "Urho3D/Graphics/Graphics.h" #include "Urho3D/UI/UI.h" #include "Urho3D/UI/UIEvents.h" -#include "Urho3D/UI/Window.h" -#include "Urho3D/UI/DropDownList.h" -#include "Urho3D/UI/LineEdit.h" -#include "Urho3D/UI/Text.h" -#include "Urho3D/UI/Button.h" -#include "Urho3D/UI/ListView.h" -#include "Urho3D/UI/CheckBox.h" +#include <tb/tb_widgets_common.h> +#include <tb/tb_widgets_reader.h> +#include <tb/tb_editfield.h> +#include <tb/tb_select.h> #include "ui-tb-message-box.h" #include "game/game-state.h" #include "game/game-wallet.h" @@ -23,19 +20,7 @@ #include "ui-research.h" using namespace Urho3D; - -#define HEADER_WIDTH 160 - -static SharedPtr<Text> AddText(SharedPtr<UIElement> e, const char *s, float scale = 1.0f) -{ - SharedPtr<Text> text(new Text(e->GetContext())); - text->SetStyleAuto(); - text->SetText(s); - text->SetName("text"); - e->AddChild(text); - text->SetFontSize(text->GetFontSize() * scale); - return text; -} +using namespace tb; static String get_place_string(size_t n) { @@ -47,215 +32,19 @@ static String get_place_string(size_t n) return String(n) + postfix; } -UIResearchDialog::UIResearchDialog(Context *ctx, const GameState *game): - Object(ctx), - game(game), - research_bonus(0) +UIResearchDialog::DiscoveryWidget::DiscoveryWidget(UIResearchDialog::DiscoveryItem *item, DiscoverySource *source, tb::TBSelectItemViewer *source_viewer, int index): + m_source(source), + m_source_viewer(source_viewer), + m_index(index) { - auto* graphics = GetSubsystem<Graphics>(); - auto root = ctx->GetSubsystem<UI>()->GetRoot(); - auto* cache = ctx->GetSubsystem<ResourceCache>(); - auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml"); - root->SetDefaultStyle(style); + SetSkinBg(TBIDC("TBSelectItem")); + SetLayoutDistribution(LAYOUT_DISTRIBUTION_GRAVITY); + SetLayoutDistributionPosition(LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP); + SetPaintOverflowFadeout(false); - window = root->CreateChild<Window>(); - window->SetName("UIResearchDialog"); - window->SetMinWidth(graphics->GetWidth() * 0.85f); - window->SetLayout(LM_VERTICAL, 6, IntRect(6, 6, 6, 6)); - window->SetAlignment(HA_CENTER, VA_CENTER); - window->SetStyleAuto(style); + g_widgets_reader->LoadFile(GetContentRoot(), "cc/research-row.tb.txt"); - // Create Window 'titlebar' container - auto* titleBar = new UIElement(context_); - titleBar->SetMinSize(0, 24); - titleBar->SetVerticalAlignment(VA_TOP); - titleBar->SetLayoutMode(LM_HORIZONTAL); - - // Create the Window title Text - auto *windowTitle_ = new Text(context_); - windowTitle_->SetName("WindowTitle"); - windowTitle_->SetText("Research"); - windowTitle_->SetStyleAuto(style); - - // Create the Window's close button - auto* buttonClose = new Button(context_); - buttonClose->SetName("CloseButton"); - buttonClose->SetStyle("CloseButton"); - - // Add the controls to the title bar - titleBar->AddChild(windowTitle_); - titleBar->AddChild(buttonClose); - - // Add the title bar to the Window - window->AddChild(titleBar); - - // header - SharedPtr<UIElement> headerLayout(new UIElement(context_)); - headerLayout->SetStyleAuto(style); - headerLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 12, 0, 2)); - window->AddChild(headerLayout); - - // Player data - SharedPtr<UIElement> playerDataLayout(new UIElement(context_)); - playerDataLayout->SetStyleAuto(style); - playerDataLayout->SetLayout(LM_VERTICAL, 6, IntRect(0, 12, 0, 2)); - headerLayout->AddChild(playerDataLayout); - - // Balance - SharedPtr<UIElement> balanceLayout(new UIElement(context_)); - balanceLayout->SetStyleAuto(style); - balanceLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - playerDataLayout->AddChild(balanceLayout); - AddText(balanceLayout, "Balance:")->SetMaxWidth(HEADER_WIDTH); - balanceWidget = AddText(balanceLayout, "0"); - - // Research bonus - SharedPtr<UIElement> researchBonusLayout(new UIElement(context_)); - researchBonusLayout->SetStyleAuto(style); - researchBonusLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - playerDataLayout->AddChild(researchBonusLayout); - AddText(researchBonusLayout, "Research bonus:")->SetMaxWidth(HEADER_WIDTH); - researchBonusWidget = AddText(researchBonusLayout, "0"); - - // Number of discoveries - SharedPtr<UIElement> numDiscoveriesLayout(new UIElement(context_)); - numDiscoveriesLayout->SetStyleAuto(style); - numDiscoveriesLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - playerDataLayout->AddChild(numDiscoveriesLayout); - AddText(numDiscoveriesLayout, "Discovered by you:")->SetMaxWidth(HEADER_WIDTH); - numDiscoveriesWidget = AddText(numDiscoveriesLayout, "0"); - - // Filters - SharedPtr<UIElement> filtersLayout(new UIElement(context_)); - filtersLayout->SetStyleAuto(style); - filtersLayout->SetLayout(LM_VERTICAL, 6, IntRect(0, 12, 0, 2)); - filtersLayout->SetMaxWidth(window->GetWidth() / 4); - headerLayout->AddChild(filtersLayout); - - // Discovered - SharedPtr<UIElement> showDiscoveredLayout(new UIElement(context_)); - showDiscoveredLayout->SetStyleAuto(style); - showDiscoveredLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - filtersLayout->AddChild(showDiscoveredLayout); - showDiscoveredWidget = new CheckBox(context_); - showDiscoveredWidget->SetStyleAuto(style); - showDiscoveredWidget->SetChecked(false); - showDiscoveredLayout->AddChild(showDiscoveredWidget); - AddText(showDiscoveredLayout, "Show discovered"); - - // Researching - SharedPtr<UIElement> showResearchingLayout(new UIElement(context_)); - showResearchingLayout->SetStyleAuto(style); - showResearchingLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - filtersLayout->AddChild(showResearchingLayout); - showResearchingWidget = new CheckBox(context_); - showResearchingWidget->SetStyleAuto(style); - showResearchingWidget->SetChecked(true); - showResearchingLayout->AddChild(showResearchingWidget); - AddText(showResearchingLayout, "Show researching"); - - // Locked - SharedPtr<UIElement> showLockedLayout(new UIElement(context_)); - showLockedLayout->SetStyleAuto(style); - showLockedLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - filtersLayout->AddChild(showLockedLayout); - showLockedWidget = new CheckBox(context_); - showLockedWidget->SetStyleAuto(style); - showLockedWidget->SetChecked(false); - showLockedLayout->AddChild(showLockedWidget); - AddText(showLockedLayout, "Show locked"); - - // Search - SharedPtr<UIElement> searchLayout(new UIElement(context_)); - searchLayout->SetStyleAuto(style); - searchLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 2, 0, 2)); - window->AddChild(searchLayout); - AddText(searchLayout, "Search:")->SetMaxWidth(HEADER_WIDTH); - searchWidget = new LineEdit(context_); - searchWidget->SetName("searchBox"); - searchWidget->SetMinHeight(24); - searchWidget->SetStyleAuto(style); - searchLayout->AddChild(searchWidget); - - // Discoveries - discoveriesListWidget = new ListView(context_); - discoveriesListWidget->SetStyleAuto(style); - discoveriesListWidget->SetMinHeight(480); - window->AddChild(discoveriesListWidget); - - UpdateDiscoveriesList(); - - // OK/cancel buttons - auto* horiz = new UIElement(context_); - horiz->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 6, 0, 0)); - window->AddChild(horiz); - - // OK - auto* buttonOK = new Button(context_); - buttonOK->SetName("OK"); - buttonOK->SetMinHeight(24); - buttonOK->SetStyleAuto(style); - horiz->AddChild(buttonOK); - Text *textOK = new Text(context_); - textOK->SetText("OK"); - textOK->SetAlignment(HA_CENTER, VA_CENTER); - textOK->SetStyleAuto(style); - buttonOK->AddChild(textOK); - - // Cancel - auto* buttonCancel = new Button(context_); - buttonCancel->SetName("Cancel"); - buttonCancel->SetMinHeight(24); - buttonCancel->SetStyleAuto(style); - horiz->AddChild(buttonCancel); - Text *textCancel = new Text(context_); - textCancel->SetText("Cancel"); - textCancel->SetAlignment(HA_CENTER, VA_CENTER); - textCancel->SetStyleAuto(style); - buttonCancel->AddChild(textCancel); - - //const IntVector2 size = window->GetSize(); - window->SetPosition(0, 0); - window->SetModal(true); - - buttonClose->SetStyle("CloseButton"); - - SubscribeToEvent(window, E_MODALCHANGED, URHO3D_HANDLER(UIResearchDialog, HandleCancel)); - SubscribeToEvent(buttonOK, E_RELEASED, URHO3D_HANDLER(UIResearchDialog, HandleOK)); - SubscribeToEvent(buttonCancel, E_RELEASED, URHO3D_HANDLER(UIResearchDialog, HandleCancel)); - SubscribeToEvent(buttonClose, E_RELEASED, URHO3D_HANDLER(UIResearchDialog, HandleCancel)); - SubscribeToEvent(searchWidget, E_TEXTCHANGED, URHO3D_HANDLER(UIResearchDialog, HandleSearchChanged)); - SubscribeToEvent(showDiscoveredWidget, E_TOGGLED, [this](StringHash eventType, VariantMap& eventData) { FilterDiscoveries(); }); - SubscribeToEvent(showResearchingWidget, E_TOGGLED, [this](StringHash eventType, VariantMap& eventData) { FilterDiscoveries(); }); - SubscribeToEvent(showLockedWidget, E_TOGGLED, [this](StringHash eventType, VariantMap& eventData) { FilterDiscoveries(); }); - - AddRef(); -} - -UIResearchDialog::~UIResearchDialog() -{ - if (window) - window->Remove(); -} - -void UIResearchDialog::RegisterObject(Context* context) -{ - context->RegisterFactory<UIResearchDialog>(); -} - -SharedPtr<UIElement> UIResearchDialog::CreateDiscoveryWidget(const cryptonote::discovery_t &d) -{ - auto* cache = context_->GetSubsystem<ResourceCache>(); - auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml"); - - SharedPtr<UIElement> mainLayout(new UIElement(context_)); - mainLayout->SetStyleAuto(style); - mainLayout->SetLayout(LM_HORIZONTAL, 6, IntRect(8, 8, 8, 8)); - - SharedPtr<UIElement> leftColumnLayout(new UIElement(context_)); - leftColumnLayout->SetStyleAuto(style); - leftColumnLayout->SetLayout(LM_VERTICAL, 6, IntRect(0, 2, 0, 2)); - mainLayout->AddChild(leftColumnLayout); + const cryptonote::discovery_t &d = item->discovery; std::string status; enum { state_discovered, state_researching, state_locked } state; @@ -269,118 +58,145 @@ SharedPtr<UIElement> UIResearchDialog::CreateDiscoveryWidget(const cryptonote::d else state = state_locked; - Color color; + TBColor color; switch (state) { case state_discovered: - status = "Discovered by " + game->get_player_name(d.discoverer); - color = Color(.5f, .9f, .8f); + status = "Discovered by " + item->dialog->game->get_player_name(d.discoverer); + color = TBColor(128, 230, 204, 255); break; case state_researching: - status = "Researching, current difficulty " + cryptonote::print_money(cc::get_research_age_adjusted_difficulty(d.difficulty, game->top_height - d.research_start_height, d.budget)); - color = Color(.85f, .85f, .85f); + status = "Researching, current difficulty " + cryptonote::print_money(cc::get_research_age_adjusted_difficulty(d.difficulty, item->dialog->game->top_height - d.research_start_height, d.budget)); + color = TBColor(255, 255, 255, 255); break; case state_locked: - status = "Locked (requires " + boost::join(d.prerequisites | boost::adaptors::transformed([this](uint32_t discovery){return discoveries[discovery].name;}), " ") + ")"; - color = Color(.5f, .5f, .5f); + status = "Locked (requires " + boost::join(d.prerequisites | boost::adaptors::transformed([this, item](uint32_t discovery){return item->dialog->discoveries[discovery].name;}), " ") + ")"; + color = TBColor(128, 128, 128, 255); break; } - SharedPtr<Text> text; - text = AddText(leftColumnLayout, d.name.c_str(), 1.5f); - text->SetColor(color); - text = AddText(leftColumnLayout, status.c_str()); - text->SetTextEffect(TE_ITALIC); - text->SetColor(color); - text = AddText(leftColumnLayout, d.desc.c_str()); - text->SetColor(color); + TBTextField *nameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("name")); + nameWidget->SetText(d.name.c_str()); + nameWidget->SetTextColor(color); + TBTextField *statusWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("status")); + statusWidget->SetText(status.c_str()); + statusWidget->SetTextColor(color); + statusWidget->SetItalic(true); + TBTextField *descWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("desc")); + descWidget->SetText(d.desc.c_str()); + descWidget->SetTextColor(color); + TBLayout *researching = GetWidgetByIDAndType<TBLayout>(TBIDC("researching")); if (state == state_researching) { - SharedPtr<UIElement> rightColumnLayout(new UIElement(context_)); - rightColumnLayout->SetStyleAuto(style); - rightColumnLayout->SetLayout(LM_VERTICAL, 6, IntRect(0, 2, 0, 2)); - mainLayout->AddChild(rightColumnLayout); - - SharedPtr<LineEdit> amountWidget(new LineEdit(context_)); - amountWidget->SetStyleAuto(style); - rightColumnLayout->SetMaxWidth(96); - rightColumnLayout->AddChild(amountWidget); - - SharedPtr<Text> researchChanceWidget = AddText(rightColumnLayout, "0% chance"); - researchChanceWidget->SetTextAlignment(HA_CENTER); - - SharedPtr<Button> researchButton(new Button(context_)); - researchButton->SetStyleAuto(style); - rightColumnLayout->AddChild(researchButton); - AddText(researchButton, "Research")->SetAlignment(HA_CENTER, VA_CENTER); - - SubscribeToEvent(researchButton, E_RELEASED, [this, d, amountWidget](StringHash eventType, VariantMap& eventData) { - uint64_t amount; - if (!cryptonote::parse_amount(amount, amountWidget->GetText().CString())) - { - new MessageBox(context_, "Invalid amount"); - return; - } - if (amount < MIN_RESEARCH_AMOUNT) - { - new MessageBox(context_, ("Amount too low, minimum is " + cryptonote::print_money(MIN_RESEARCH_AMOUNT)).c_str()); - return; - } - VariantMap newEventData; - newEventData[ResearchFund::P_DISCOVERY] = d.discovery; - newEventData[ResearchFund::P_AMOUNT] = (unsigned long long)amount; - SendEvent(E_RESEARCH_FUND, newEventData); - new MessageBox(context_, (cryptonote::print_money(amount) + " paid for research\nResults will be known after next block is mined").c_str(), "Info"); - }); - - SubscribeToEvent(amountWidget, E_TEXTCHANGED, [this, d, amountWidget, researchChanceWidget](StringHash eventType, VariantMap& eventData) { - uint64_t amount; - if (!cryptonote::parse_amount(amount, amountWidget->GetText().CString())) - { - researchChanceWidget->SetText("0% chance"); - return; - } - if (amount < MIN_RESEARCH_AMOUNT) - { - researchChanceWidget->SetText("0% chance"); - return; - } - const uint32_t chance = cc::get_discovery_chance_scaled(amount, d.budget, d.difficulty, research_bonus, d.research_start_height, game->top_height + 1); - if (chance == 0) - { - researchChanceWidget->SetText("0% chance"); - return; - } - char s[32]; - snprintf(s, sizeof(s), "%.3f%%", 100.0f * chance / RESEARCH_CHANCE_BASE_SCALE); - researchChanceWidget->SetText(s); - }); + researching->SetVisibility(WIDGET_VISIBILITY_VISIBLE); } - - mainLayout->SetMaxHeight(mainLayout->GetHeight()); - return mainLayout; + else + researching->SetVisibility(WIDGET_VISIBILITY_INVISIBLE); } -void UIResearchDialog::UpdateDiscoveriesList() +bool UIResearchDialog::DiscoveryWidget::OnEvent(const tb::TBWidgetEvent &ev) { - auto* cache = context_->GetSubsystem<ResourceCache>(); - auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml"); - - discoveriesListWidget->RemoveAllItems(); - - for (const auto &d: discoveries) + const UIResearchDialog::DiscoveryItem *item = m_source->GetItem(m_index); + const cryptonote::discovery_t &d = item->discovery; + if (ev.type == EVENT_TYPE_CHANGED && ev.target->GetID() == TBIDC("amount")) { - discoveriesListWidget->AddItem(CreateDiscoveryWidget(d)); + TBEditField *ef = TBSafeCast<TBEditField>(ev.target); + TBTextField *researchChanceWidget = GetWidgetByIDAndType<TBTextField>("chance"); + uint64_t amount; + if (!cryptonote::parse_amount(amount, ef->GetText().CStr())) + { + researchChanceWidget->SetText("0% chance"); + return true; + } + if (amount < MIN_RESEARCH_AMOUNT) + { + researchChanceWidget->SetText("0% chance"); + return true; + } + const uint32_t chance = cc::get_discovery_chance_scaled(amount, d.budget, d.difficulty, item->dialog->research_bonus, d.research_start_height, item->dialog->game->top_height + 1); + if (chance == 0) + { + researchChanceWidget->SetText("0% chance"); + return true; + } + char s[32]; + snprintf(s, sizeof(s), "%.3f%%", 100.0f * chance / RESEARCH_CHANCE_BASE_SCALE); + researchChanceWidget->SetText(s); + return true; } + else if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("research")) + { + TBEditField *ef = TBSafeCast<TBEditField>(ev.target); + uint64_t amount; + if (!cryptonote::parse_amount(amount, ef->GetText().CStr())) + { + new MessageBox(item->dialog->context_, "Invalid amount"); + return true; + } + if (amount < MIN_RESEARCH_AMOUNT) + { + new MessageBox(item->dialog->context_, ("Amount too low, minimum is " + cryptonote::print_money(MIN_RESEARCH_AMOUNT)).c_str()); + return true; + } + VariantMap newEventData; + newEventData[ResearchFund::P_DISCOVERY] = d.discovery; + newEventData[ResearchFund::P_AMOUNT] = (unsigned long long)amount; + item->dialog->SendEvent(E_RESEARCH_FUND, newEventData); + new MessageBox(item->dialog->context_, (cryptonote::print_money(amount) + " paid for research\nResults will be known after next block is mined").c_str(), "Info"); + return true; + } + return TBLayout::OnEvent(ev); +} + +TBWidget *UIResearchDialog::DiscoverySource::CreateItemWidget(int index, TBSelectItemViewer *viewer) +{ + DiscoveryItem *item = GetItem(index); + return new UIResearchDialog::DiscoveryWidget(item, this, viewer, index); +} + +UIResearchDialog::UIResearchDialog(Context *ctx, const GameState *game): + UITBWindow(ctx, "cc/research.tb.txt"), + game(game), + research_bonus(0) +{ + auto* graphics = GetSubsystem<Graphics>(); + TBRect rect; + rect.w = graphics->GetWidth() * .9f; + rect.h = graphics->GetHeight() * .9f; + rect.x = graphics->GetWidth() * .05f; + rect.y = graphics->GetHeight() * .05f; + SetRect(rect); + + balanceWidget = GetWidgetByIDAndType<TBTextField>("balance"); + researchBonusWidget = GetWidgetByIDAndType<TBTextField>("research-bonus"); + numDiscoveriesWidget = GetWidgetByIDAndType<TBTextField>("num-discoveries"); + searchWidget = GetWidgetByIDAndType<TBEditField>("search"); + discoveriesListWidget = GetWidgetByIDAndType<TBSelectList>("discoveries"); + showDiscoveredWidget = GetWidgetByIDAndType<TBCheckBox>("show-discovered"); + showResearchingWidget = GetWidgetByIDAndType<TBCheckBox>("show-researching"); + showLockedWidget = GetWidgetByIDAndType<TBCheckBox>("show-locked"); + + discoveriesListWidget->SetSource(&discoverySource); + + SubscribeToEvent(this, E_TB_WIDGET_EVENT, URHO3D_HANDLER(UIResearchDialog, HandleTBMessage)); + SubscribeToEvent(this, E_TB_WINDOW_CLOSED, URHO3D_HANDLER(UIResearchDialog, HandleClose)); + FilterDiscoveries(); } +UIResearchDialog::~UIResearchDialog() +{ + discoveriesListWidget->SetSource(NULL); +} + +void UIResearchDialog::RegisterObject(Context* context) +{ + context->RegisterFactory<UIResearchDialog>(); +} + void UIResearchDialog::Refresh(const std::shared_ptr<GameWallet> &w) { - auto* cache = context_->GetSubsystem<ResourceCache>(); - auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml"); - discoveries.clear(); if (!w->get_cc_discoveries(discoveries)) return; @@ -394,7 +210,7 @@ void UIResearchDialog::Refresh(const std::shared_ptr<GameWallet> &w) active_research_buildings.push_back(std::make_tuple(flag->x1 - flag->x0 + 1, flag->y1 - flag->y0 + 1, flag->economic_power)); } research_bonus = cc::get_research_bonus(active_research_buildings); - researchBonusWidget->SetText(String(research_bonus) + "%"); + researchBonusWidget->SetText((String(research_bonus) + "%").CString()); std::map<uint32_t, uint32_t> numDiscovered; uint32_t totalDiscovered = 0; @@ -409,9 +225,9 @@ void UIResearchDialog::Refresh(const std::shared_ptr<GameWallet> &w) String s = String(numDiscovered[game->playerState.id]) + "/" + String(totalDiscovered); if (numDiscovered[game->playerState.id] > 0) s += " (" + get_place_string(std::distance(numDiscovered.begin(), numDiscovered.find(game->playerState.id))) + " place)"; - numDiscoveriesWidget->SetText(s); + numDiscoveriesWidget->SetText(s.CString()); - UpdateDiscoveriesList(); + FilterDiscoveries(); } @@ -430,63 +246,68 @@ void UIResearchDialog::CancelUI() SendEvent(E_RESEARCH_CANCELLED, newEventData); // Self destruct - ReleaseRef(); + Close(); } void UIResearchDialog::FilterDiscoveries() { - const char *search = searchWidget->GetText().CString(); - const String search_string(search ? search : ""); - - const unsigned int n_elements = discoveriesListWidget->GetNumItems(); + discoverySource.DeleteAllItems(); + const size_t n_elements = discoveries.size(); for (unsigned int n = 0; n < n_elements; ++n) { - bool visible = true; const cryptonote::discovery_t &d = discoveries[n]; + bool visible = false; if (d.research_start_height > 0 || d.prerequisites.empty()) { if (d.discoverer) - visible = showDiscoveredWidget->IsChecked(); + visible = showDiscoveredWidget->GetValue(); else - visible = showResearchingWidget->IsChecked(); + visible = showResearchingWidget->GetValue(); } else - visible = showLockedWidget->IsChecked(); + visible = showLockedWidget->GetValue(); - UIElement *e = discoveriesListWidget->GetItem(n); - if (visible && search && *search) - { - visible = false; - PODVector<UIElement*> dest; - e->GetChildren(dest, true); - for (const auto &w: dest) - { - const Text *text = dynamic_cast<const Text*>(w); - if (text && text->GetText().Contains(search_string, false)) - { - visible = true; - break; - } - } - } - e->SetVisible(visible); + if (visible) + discoverySource.AddItem(new DiscoveryItem(this, d)); } } -void UIResearchDialog::HandleSearchChanged(StringHash eventType, VariantMap& eventData) +void UIResearchDialog::HandleFilterChanged(StringHash eventType, VariantMap& eventData) { FilterDiscoveries(); } -void UIResearchDialog::HandleOK(StringHash eventType, VariantMap& eventData) +void UIResearchDialog::HandleSearchChanged(StringHash eventType, VariantMap& eventData) { + discoveriesListWidget->SetFilter(searchWidget->GetText()); } -void UIResearchDialog::HandleCancel(StringHash eventType, VariantMap& eventData) +void UIResearchDialog::HandleTBMessage(StringHash eventType, VariantMap& eventData) +{ +#define CONNECT(name, function) do { if (ev->target->GetID() == TBIDC(name)) function(eventType, eventData); } while(0) + using namespace TBWidgetEventNamespace; + + TBWidgetEvent *ev = (TBWidgetEvent*)eventData[P_WIDGET_EVENT].GetVoidPtr(); + if (ev->type == EVENT_TYPE_CLICK) + { + } + else if (ev->type == EVENT_TYPE_CHANGED) + { + CONNECT("show-discovered", HandleFilterChanged); + CONNECT("show-researching", HandleFilterChanged); + CONNECT("show-locked", HandleFilterChanged); + + CONNECT("search", HandleSearchChanged); + } + +#undef CONNECT +} + +void UIResearchDialog::HandleClose(StringHash eventType, VariantMap& eventData) { VariantMap& newEventData = GetEventDataMap(); SendEvent(E_RESEARCH_CANCELLED, newEventData); // Self destruct - ReleaseRef(); + Close(); } diff --git a/src/game/ui-research.h b/src/game/ui-research.h index 81d6141b6..4e6d5468f 100644 --- a/src/game/ui-research.h +++ b/src/game/ui-research.h @@ -6,18 +6,22 @@ #include <Urho3D/Container/Str.h> #include <Urho3D/Container/Ptr.h> #include <Urho3D/Math/StringHash.h> +#include <tb/tb_select_item.h> #include "cryptonote_basic/cc_command_defs.h" #include "rpc/core_rpc_server_commands_defs.h" +#include "ui-tb-window.h" namespace Urho3D { - class UIElement; class Context; - class Window; - class LineEdit; - class ListView; - class CheckBox; - class Text; +} + +namespace tb +{ + class TBEditField; + class TBTextField; + class TBSelectList; + class TBCheckBox; } class GameState; @@ -26,7 +30,7 @@ class GameWallet; URHO3D_EVENT(E_RESEARCH_FUND, ResearchFund) { URHO3D_PARAM(P_DISCOVERY, Discovery); URHO3D_PARAM(P_AMOUNT, Amount); } URHO3D_EVENT(E_RESEARCH_CANCELLED, ResearchCancelled) {} -class UIResearchDialog: public Urho3D::Object +class UIResearchDialog: public UITBWindow { URHO3D_OBJECT(UIResearchDialog, Object); @@ -40,31 +44,58 @@ public: void CancelUI(); private: - void UpdateDiscoveriesList(); void Refresh(const std::shared_ptr<GameWallet> &w); Urho3D::SharedPtr<Urho3D::UIElement> CreateDiscoveryWidget(const cryptonote::discovery_t &d); void FilterDiscoveries(); private: - void HandleOK(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData); - void HandleCancel(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData); void HandleSearchChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData); + void HandleFilterChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData); + void HandleTBMessage(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData); + void HandleClose(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData); private: const GameState *game; - Urho3D::SharedPtr<Urho3D::Window> window; - Urho3D::SharedPtr<Urho3D::Text> balanceWidget; - Urho3D::SharedPtr<Urho3D::Text> researchBonusWidget; - Urho3D::SharedPtr<Urho3D::Text> numDiscoveriesWidget; - Urho3D::SharedPtr<Urho3D::LineEdit> searchWidget; - Urho3D::SharedPtr<Urho3D::ListView> discoveriesListWidget; - Urho3D::SharedPtr<Urho3D::CheckBox> showDiscoveredWidget; - Urho3D::SharedPtr<Urho3D::CheckBox> showResearchingWidget; - Urho3D::SharedPtr<Urho3D::CheckBox> showLockedWidget; + tb::TBTextField *balanceWidget; + tb::TBTextField *researchBonusWidget; + tb::TBTextField *numDiscoveriesWidget; + tb::TBEditField *searchWidget; + tb::TBSelectList *discoveriesListWidget; + tb::TBCheckBox *showDiscoveredWidget; + tb::TBCheckBox *showResearchingWidget; + tb::TBCheckBox *showLockedWidget; std::vector<cryptonote::discovery_t> discoveries; uint32_t research_bonus; std::string last_refresh_stop_hash; + + class DiscoveryItem: public tb::TBGenericStringItem + { + public: + DiscoveryItem(UIResearchDialog *dialog, const cryptonote::discovery_t &discovery): TBGenericStringItem(discovery.name.c_str()), dialog(dialog), discovery(discovery) {} + UIResearchDialog *dialog; + cryptonote::discovery_t discovery; + }; + + class DiscoverySource: public tb::TBSelectItemSourceList<DiscoveryItem> + { + public: + virtual bool Filter(int index, const char *filter) { return true; } + virtual tb::TBWidget *CreateItemWidget(int index, tb::TBSelectItemViewer *viewer); + }; + + class DiscoveryWidget: public tb::TBLayout + { + public: + DiscoveryWidget(DiscoveryItem *item, DiscoverySource *source, tb::TBSelectItemViewer *source_viewer, int index); + virtual bool OnEvent(const tb::TBWidgetEvent &ev); + private: + DiscoverySource *m_source; + tb::TBSelectItemViewer *m_source_viewer; + int m_index; + }; + + DiscoverySource discoverySource; }; #endif