diff --git a/drape_frontend/gui/button.cpp b/drape_frontend/gui/button.cpp index 26c8c194e0..640c15ca04 100644 --- a/drape_frontend/gui/button.cpp +++ b/drape_frontend/gui/button.cpp @@ -99,17 +99,20 @@ bool ButtonHandle::Update(ScreenBase const & screen) return TBase::Update(screen); } -void Button::Draw(Params const & params, ShapeControl & control, ref_ptr texMgr) +StaticLabel::LabelResult Button::PreprocessLabel(Params const & params, ref_ptr texMgr) { StaticLabel::LabelResult result; StaticLabel::CacheStaticText(params.m_label, StaticLabel::DefaultDelim, params.m_anchor, params.m_labelFont, texMgr, result); + return result; +} - float textWidth = result.m_boundRect.SizeX(); - float halfWidth = my::clamp(textWidth, params.m_minWidth, params.m_maxWidth) * 0.5f; - float halfHeight = result.m_boundRect.SizeY() * 0.5f; - float halfWM = halfWidth + params.m_margin; - float halfHM = halfHeight + params.m_margin; +void Button::Draw(Params const & params, ShapeControl & control, gui::StaticLabel::LabelResult & label) +{ + float const halfWidth = params.m_width * 0.5f; + float const halfHeight = label.m_boundRect.SizeY() * 0.5f; + float const halfWM = halfWidth + params.m_margin; + float const halfHM = halfHeight + params.m_margin; // Cache button { @@ -161,21 +164,21 @@ void Button::Draw(Params const & params, ShapeControl & control, ref_ptr texMgr); + static gui::StaticLabel::LabelResult PreprocessLabel(Params const & params, ref_ptr texMgr); + static void Draw(Params const & params, ShapeControl & control, gui::StaticLabel::LabelResult & label); }; } diff --git a/drape_frontend/gui/country_status.cpp b/drape_frontend/gui/country_status.cpp index 2636d43b69..d12eecc836 100644 --- a/drape_frontend/gui/country_status.cpp +++ b/drape_frontend/gui/country_status.cpp @@ -150,6 +150,17 @@ void DrawProgressControl(dp::Anchor anchor, dp::Batcher::TFlushFn const & flushF MutableLabelDrawer::Draw(params, mng, flushFn); } +void ForEachComponent(CountryStatusHelper & helper, CountryStatusHelper::EControlType type, + function const & callback) +{ + for (size_t i = 0; i < helper.GetComponentCount(); ++i) + { + CountryStatusHelper::Control const & control = helper.GetControl(i); + if (callback != nullptr && control.m_type == type) + callback(control); + } +} + } drape_ptr CountryStatus::Draw(ref_ptr tex, @@ -165,54 +176,68 @@ drape_ptr CountryStatus::Draw(ref_ptr tex, drape_ptr renderer = make_unique_dp(); dp::Batcher::TFlushFn flushFn = bind(&ShapeRenderer::AddShape, renderer.get(), _1, _2); - for (size_t i = 0; i < helper.GetComponentCount(); ++i) + // Create labels. + ForEachComponent(helper, CountryStatusHelper::CONTROL_TYPE_LABEL, + [this, &tex, &flushFn, &state](CountryStatusHelper::Control const & control) { - CountryStatusHelper::Control const & control = helper.GetControl(i); - switch (control.m_type) + DrawLabelControl(control.m_label, m_position.m_anchor, flushFn, tex, state); + }); + + // Preprocess buttons. + vector> buttons; + float const kMinButtonWidth = 400; + float maxButtonWidth = kMinButtonWidth; + buttons.reserve(2); + ForEachComponent(helper, CountryStatusHelper::CONTROL_TYPE_BUTTON, + [this, &buttons, &state, &tex, &buttonHandlers, + &maxButtonWidth](CountryStatusHelper::Control const & control) + { + float const visualScale = df::VisualParams::Instance().GetVisualScale(); + + Button::Params params; + params.m_anchor = m_position.m_anchor; + params.m_label = control.m_label; + params.m_labelFont = dp::FontDecl(dp::Color::White(), 18); + params.m_margin = 5.0f * visualScale; + params.m_facet = 8.0f * visualScale; + + auto color = dp::Color(0, 0, 0, 0.44 * 255); + auto pressedColor = dp::Color(0, 0, 0, 0.72 * 255); + if (control.m_buttonType == CountryStatusHelper::BUTTON_TYPE_MAP_ROUTING) { - case CountryStatusHelper::CONTROL_TYPE_BUTTON: - { - float const visualScale = df::VisualParams::Instance().GetVisualScale(); - - ShapeControl shapeControl; - Button::Params params; - params.m_anchor = m_position.m_anchor; - params.m_label = control.m_label; - params.m_labelFont = dp::FontDecl(dp::Color::White(), 18); - params.m_minWidth = 400; - params.m_maxWidth = 600; - params.m_margin = 5.0f * visualScale; - params.m_facet = 8.0f * visualScale; - - auto color = dp::Color(0, 0, 0, 0.44 * 255); - auto pressedColor = dp::Color(0, 0, 0, 0.72 * 255); - if (control.m_buttonType == CountryStatusHelper::BUTTON_TYPE_MAP_ROUTING) - { - color = dp::Color(32, 152, 82, 255); - pressedColor = dp::Color(24, 128, 68, 255); - } - - auto const buttonHandlerIt = buttonHandlers.find(control.m_buttonType); - Shape::TTapHandler buttonHandler = (buttonHandlerIt != buttonHandlers.end() ? buttonHandlerIt->second : nullptr); - params.m_bodyHandleCreator = bind(&CreateButtonHandle, state, buttonHandler, color, pressedColor, _1, _2); - params.m_labelHandleCreator = bind(&CreateLabelHandle, state, tex, _1, _2, _3); - - Button::Draw(params, shapeControl, tex); - renderer->AddShapeControl(move(shapeControl)); - } - break; - case CountryStatusHelper::CONTROL_TYPE_LABEL: - DrawLabelControl(control.m_label, m_position.m_anchor, flushFn, tex, state); - break; - case CountryStatusHelper::CONTROL_TYPE_PROGRESS: - DrawProgressControl(m_position.m_anchor, flushFn, tex, state); - break; - default: - ASSERT(false, ()); - break; + color = dp::Color(32, 152, 82, 255); + pressedColor = dp::Color(24, 128, 68, 255); } + + auto const buttonHandlerIt = buttonHandlers.find(control.m_buttonType); + Shape::TTapHandler buttonHandler = (buttonHandlerIt != buttonHandlers.end() ? buttonHandlerIt->second : nullptr); + params.m_bodyHandleCreator = bind(&CreateButtonHandle, state, buttonHandler, color, pressedColor, _1, _2); + params.m_labelHandleCreator = bind(&CreateLabelHandle, state, tex, _1, _2, _3); + + auto label = Button::PreprocessLabel(params, tex); + float const buttonWidth = label.m_boundRect.SizeX(); + if (buttonWidth > maxButtonWidth) + maxButtonWidth = buttonWidth; + + buttons.emplace_back(make_pair(move(params), move(label))); + }); + + // Create buttons. + for (size_t i = 0; i < buttons.size(); i++) + { + buttons[i].first.m_width = maxButtonWidth; + ShapeControl shapeControl; + Button::Draw(buttons[i].first, shapeControl, buttons[i].second); + renderer->AddShapeControl(move(shapeControl)); } + // Create progress bars. + ForEachComponent(helper, CountryStatusHelper::CONTROL_TYPE_PROGRESS, + [this, &tex, &flushFn, &state](CountryStatusHelper::Control const &) + { + DrawProgressControl(m_position.m_anchor, flushFn, tex, state); + }); + buffer_vector heights; float totalHeight = 0.0f;