added CountryStatusDisplay GUI element and using it into InformationDisplay.

This commit is contained in:
rachytski 2012-06-02 21:29:57 +04:00 committed by Alex Zolotarev
parent 21b63475a7
commit 9201356184
9 changed files with 366 additions and 60 deletions

View file

@ -13,14 +13,10 @@ HEADERS += \
controller.hpp\
element.hpp \
button.hpp \
text_view.hpp \
SOURCES += \
controller.cpp \
element.cpp \
button.cpp \
text_view.cpp \

View file

@ -0,0 +1,238 @@
#include "country_status_display.hpp"
#include "../gui/controller.hpp"
#include "../std/bind.hpp"
#include "../std/sstream.hpp"
#include "../storage/storage.hpp"
#include "../yg/overlay_renderer.hpp"
void CountryStatusDisplay::cache()
{
m_downloadButton->setIsVisible(false);
m_statusMsg->setIsVisible(false);
if (m_countryIdx != storage::TIndex())
{
switch (m_countryStatus)
{
case storage::EInQueue:
{
m_statusMsg->setIsVisible(true);
ostringstream out;
out << m_countryName << " is added to the\ndownloading queue";
m_statusMsg->setText(out.str());
}
break;
case storage::EDownloading:
{
m_statusMsg->setIsVisible(true);
ostringstream out;
out << "Downloading " << m_countryName << "(" << m_countryProgress.first * 100 / m_countryProgress.second << "%)";
m_statusMsg->setText(out.str());
}
break;
case storage::ENotDownloaded:
{
m_downloadButton->setIsVisible(true);
m_downloadButton->setText("Download " + m_countryName);
}
break;
case storage::EDownloadFailed:
{
m_downloadButton->setIsVisible(true);
m_downloadButton->setText("Try again");
ostringstream out;
out << "Downloading " << m_countryName << "\nhas failed.";
m_statusMsg->setIsVisible(true);
m_statusMsg->setText(out.str());
setPivot(pivot());
}
break;
default:
return;
}
}
/// element bound rect is possibly changed
setIsDirtyRect(true);
}
void CountryStatusDisplay::CountryStatusChanged(storage::TIndex const & idx)
{
if (idx == m_countryIdx)
{
m_countryStatus = m_storage->CountryStatus(m_countryIdx);
setIsDirtyDrawing(true);
invalidate();
}
}
void CountryStatusDisplay::CountryProgress(storage::TIndex const & idx, pair<int64_t, int64_t> const & progress)
{
if ((m_countryIdx == idx) && m_storage->CountryStatus(idx) == storage::EDownloading)
{
m_countryProgress = progress;
setIsDirtyDrawing(true);
invalidate();
}
}
CountryStatusDisplay::CountryStatusDisplay(Params const & p)
: gui::Element(p), m_storage(p.m_storage)
{
m_slotID = m_storage->Subscribe(bind(&CountryStatusDisplay::CountryStatusChanged, this, _1),
bind(&CountryStatusDisplay::CountryProgress, this, _1, _2));
gui::Button::Params bp;
bp.m_depth = yg::maxDepth;
bp.m_width = 200;
bp.m_height = 40;
bp.m_pivot = m2::PointD(0, 0);
bp.m_position = yg::EPosCenter;
bp.m_text = "Download";
m_downloadButton.reset(new gui::Button(bp));
m_downloadButton->setOnClickListener(bind(&CountryStatusDisplay::DownloadCountry, this));
m_downloadButton->setIsVisible(false);
m_downloadButton->setPosition(yg::EPosCenter);
m_downloadButton->setFont(gui::Element::EActive, yg::FontDesc(16));
m_downloadButton->setFont(gui::Element::EPressed, yg::FontDesc(16));
gui::TextView::Params tp;
tp.m_depth = yg::maxDepth;
tp.m_pivot = m2::PointD(0, 0);
tp.m_text = "Downloading";
m_statusMsg.reset(new gui::TextView(tp));
m_statusMsg->setIsVisible(false);
m_statusMsg->setPosition(yg::EPosCenter);
m_statusMsg->setFont(gui::Element::EActive, yg::FontDesc(18));
m_countryIdx = storage::TIndex();
m_countryStatus = storage::EUnknown;
}
CountryStatusDisplay::~CountryStatusDisplay()
{
m_storage->Unsubscribe(m_slotID);
}
void CountryStatusDisplay::DownloadCountry()
{
m_storage->DownloadCountry(m_countryIdx);
}
void CountryStatusDisplay::setCountryName(string const & name)
{
if (m_countryName != name)
{
m_countryIdx = m_storage->FindIndexByName(name);
m_countryStatus = m_storage->CountryStatus(m_countryIdx);
m_countryProgress = m_storage->CountrySizeInBytes(m_countryIdx);
m_countryName = name;
setIsDirtyDrawing(true);
invalidate();
}
}
void CountryStatusDisplay::draw(yg::gl::OverlayRenderer *r,
math::Matrix<double, 3, 3> const & m) const
{
if (!isVisible())
return;
checkDirtyDrawing();
// r->drawRectangle(roughBoundRect(), yg::Color(0, 0, 255, 64), yg::maxDepth);
if (m_downloadButton->isVisible())
m_downloadButton->draw(r, m);
if (m_statusMsg->isVisible())
m_statusMsg->draw(r, m);
}
vector<m2::AnyRectD> const & CountryStatusDisplay::boundRects() const
{
checkDirtyDrawing();
if (isDirtyRect())
{
m_boundRects.clear();
m2::RectD r = m_downloadButton->roughBoundRect();
r.Add(m_statusMsg->roughBoundRect());
m_boundRects.push_back(m2::AnyRectD(r));
setIsDirtyRect(false);
}
return m_boundRects;
}
void CountryStatusDisplay::setController(gui::Controller *controller)
{
Element::setController(controller);
m_statusMsg->setController(controller);
m_downloadButton->setController(controller);
}
void CountryStatusDisplay::setPivot(m2::PointD const & pv)
{
if (m_countryStatus == storage::EDownloadFailed)
{
size_t buttonHeight = m_downloadButton->roughBoundRect().SizeY();
size_t statusHeight = m_statusMsg->roughBoundRect().SizeY();
size_t commonHeight = buttonHeight + statusHeight + 10 * visualScale();
m_downloadButton->setPivot(m2::PointD(pv.x, pv.y + commonHeight / 2 - buttonHeight / 2));
m_statusMsg->setPivot(m2::PointD(pv.x, pv.y - commonHeight / 2 + statusHeight / 2));
}
else
{
m_downloadButton->setPivot(pv);
m_statusMsg->setPivot(pv);
}
gui::Element::setPivot(pv);
}
bool CountryStatusDisplay::onTapStarted(m2::PointD const & pt)
{
if (m_downloadButton->isVisible())
return m_downloadButton->onTapStarted(pt);
return false;
}
bool CountryStatusDisplay::onTapMoved(m2::PointD const & pt)
{
if (m_downloadButton->isVisible())
return m_downloadButton->onTapMoved(pt);
return false;
}
bool CountryStatusDisplay::onTapEnded(m2::PointD const & pt)
{
if (m_downloadButton->isVisible())
return m_downloadButton->onTapEnded(pt);
return false;
}
bool CountryStatusDisplay::onTapCancelled(m2::PointD const & pt)
{
if (m_downloadButton->isVisible())
return m_downloadButton->onTapCancelled(pt);
return false;
}

View file

@ -0,0 +1,78 @@
#pragma once
#include "../storage/storage.hpp"
#include "../std/shared_ptr.hpp"
#include "../gui/element.hpp"
#include "../gui/button.hpp"
#include "../gui/text_view.hpp"
/// This class is a composite GUI element to display
/// an on-screen GUI for the country, which is not downloaded yet.
class CountryStatusDisplay : public gui::Element
{
private:
/// Storage-related members and methods
/// @{
/// connection to the Storage for notifications
unsigned m_slotID;
storage::Storage * m_storage;
/// notification callback upon country status change
void CountryStatusChanged(storage::TIndex const &);
/// notification callback upon country downloading progress
void CountryProgress(storage::TIndex const &, pair<int64_t, int64_t> const & progress);
/// @}
/// download button
shared_ptr<gui::Button> m_downloadButton;
/// country status message
shared_ptr<gui::TextView> m_statusMsg;
/// current country name
string m_countryName;
/// current country status
storage::TStatus m_countryStatus;
/// index of the country in Storage
storage::TIndex m_countryIdx;
/// downloading progress of the country
pair<int64_t, int64_t> m_countryProgress;
/// bounding rects
mutable vector<m2::AnyRectD> m_boundRects;
/// caching resources for fast rendering.
void cache();
/// callback for button click to download country
void DownloadCountry();
public:
struct Params : public gui::Element::Params
{
storage::Storage * m_storage;
};
CountryStatusDisplay(Params const & p);
~CountryStatusDisplay();
/// set current country name
void setCountryName(string const & name);
/// reposition element
void setPivot(m2::PointD const & pv);
/// attach element to controller.
void setController(gui::Controller *controller);
/// render element
void draw(yg::gl::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
/// get bounding rects
vector<m2::AnyRectD> const & boundRects() const;
/// react on touch events
/// @{
bool onTapStarted(m2::PointD const & pt);
bool onTapMoved(m2::PointD const & pt);
bool onTapEnded(m2::PointD const & pt);
bool onTapCancelled(m2::PointD const & pt);
/// @}
};

View file

@ -111,6 +111,7 @@ Framework::Framework()
m_width(0),
m_height(0),
m_centeringMode(EDoNothing),
m_informationDisplay(&m_storage),
m_lowestMapVersion(-1)
{
m_guiController.reset(new gui::Controller());
@ -126,8 +127,6 @@ Framework::Framework()
"Just click the downloader button \n"\
"at the bottom of the screen.";
m_informationDisplay.setEmptyModelMessage(s);
m_informationDisplay.enableCenter(true);
m_informationDisplay.enableRuler(true);
m_informationDisplay.setRulerParams(m_minRulerWidth, m_metresMinWidth, m_metresMaxWidth);
@ -469,11 +468,14 @@ void Framework::DrawAdditionalInfo(shared_ptr<PaintEvent> const & e)
m2::PointD const center = m_navigator.Screen().GlobalRect().GlobalCenter();
m_informationDisplay.setScreen(m_navigator.Screen());
bool isEmptyModel = m_renderPolicy->IsEmptyModel();
m_informationDisplay.enableEmptyModelMessage(isEmptyModel);
if (isEmptyModel)
m_informationDisplay.setEmptyCountryName(m_renderPolicy->GetCountryName().c_str());
m_informationDisplay.enableCountryStatusDisplay(isEmptyModel);
m_informationDisplay.setScreen(m_navigator.Screen());
m_informationDisplay.setDebugInfo(0/*m_renderQueue.renderState().m_duration*/, GetDrawScale());

View file

@ -72,8 +72,6 @@ protected:
m2::AnyRectD m_invalidRect;
m2::PointD m_placemark;
InformationDisplay m_informationDisplay;
double const m_metresMinWidth;
double const m_metresMaxWidth;
int const m_minRulerWidth;
@ -95,6 +93,7 @@ protected:
storage::Storage m_storage;
scoped_ptr<gui::Controller> m_guiController;
InformationDisplay m_informationDisplay;
//my::Timer m_timer;
inline double ElapsedSeconds() const

View file

@ -1,5 +1,6 @@
#include "information_display.hpp"
#include "drawer_yg.hpp"
#include "country_status_display.hpp"
#include "../indexer/mercator.hpp"
@ -24,21 +25,18 @@
#include "../std/iomanip.hpp"
#include "../std/target_os.hpp"
InformationDisplay::InformationDisplay()
InformationDisplay::InformationDisplay(storage::Storage * storage)
: m_ruler(Ruler::Params()),
m_bottomShift(0)
{
gui::Button::Params p;
CountryStatusDisplay::Params p;
p.m_pivot = m2::PointD(0, 0);
p.m_position = yg::EPosCenter;
p.m_depth = yg::maxDepth;
p.m_text = "Download";
p.m_width = 200;
p.m_height = 40;
p.m_storage = storage;
m_downloadButton.reset(new gui::Button(p));
m_downloadButton->setIsVisible(false);
m_countryStatusDisplay.reset(new CountryStatusDisplay(p));
enableDebugPoints(false);
enableRuler(false);
@ -46,7 +44,7 @@ InformationDisplay::InformationDisplay()
enableDebugInfo(false);
enableMemoryWarning(false);
enableBenchmarkInfo(false);
enableEmptyModelMessage(false);
enableCountryStatusDisplay(false);
for (int i = 0; i < sizeof(m_DebugPts) / sizeof(m2::PointD); ++i)
m_DebugPts[i] = m2::PointD(0, 0);
@ -58,13 +56,20 @@ InformationDisplay::InformationDisplay()
void InformationDisplay::setController(gui::Controller *controller)
{
m_controller = controller;
m_controller->AddElement(m_downloadButton);
m_controller->AddElement(m_countryStatusDisplay);
}
void InformationDisplay::setScreen(ScreenBase const & screen)
{
m_screen = screen;
m_ruler.setScreen(screen);
if (m_countryStatusDisplay->isVisible())
{
m2::RectD pxRect = m_screen.PixelRect();
m2::PointD pt = m2::PointD(pxRect.SizeX() / 2, pxRect.SizeY() / 2) - m2::PointD(0, m_bottomShift * m_visualScale);
m_countryStatusDisplay->setPivot(pt);
}
}
void InformationDisplay::setBottomShift(double bottomShift)
@ -280,6 +285,7 @@ WindowHandle * InformationDisplay::s_windowHandle = 0;
size_t s_msgNum = 0;
void InformationDisplay::logMessage(my::LogLevel level, my::SrcPoint const &, string const & msg)
void InformationDisplay::setEmptyCountryName(const char * country)
{
{
threads::MutexGuard guard(s_logMutex);
@ -298,6 +304,7 @@ void InformationDisplay::logMessage(my::LogLevel level, my::SrcPoint const &, st
/// call redisplay
s_windowHandle->invalidate();
m_countryStatusDisplay->setCountryName(country);
}
void InformationDisplay::enableLog(bool doEnable, WindowHandle * windowHandle)
@ -350,15 +357,14 @@ void InformationDisplay::drawLog(DrawerYG * drawer)
}
*/
void InformationDisplay::enableEmptyModelMessage(bool doEnable)
void InformationDisplay::enableCountryStatusDisplay(bool doEnable)
{
m_isEmptyModelMessageEnabled = doEnable;
// m_downloadButton->setIsVisible(doEnable);
m_countryStatusDisplay->setIsVisible(doEnable);
}
void InformationDisplay::setEmptyModelMessage(char const * msg)
void InformationDisplay::setEmptyCountryName(const char *country)
{
m_emptyModelMessage = msg;
m_countryStatusDisplay->setCountryName(country);
}
void InformationDisplay::setDownloadListener(gui::Button::TOnClickListener l)
@ -366,32 +372,6 @@ void InformationDisplay::setDownloadListener(gui::Button::TOnClickListener l)
m_downloadButton->setOnClickListener(l);
}
void InformationDisplay::drawEmptyModelMessage(DrawerYG * pDrawer)
{
m2::RectD pxRect = m_screen.PixelRect();
m2::PointD pt = m2::PointD(pxRect.SizeX() / 2, pxRect.SizeY() / 2) - m2::PointD(0, m_bottomShift * m_visualScale);
yg::StraightTextElement::Params params;
params.m_depth = yg::maxDepth;
params.m_fontDesc = m_emptyMessageFont;
params.m_log2vis = false;
params.m_pivot = pt;
params.m_position = yg::EPosCenter;
params.m_glyphCache = pDrawer->screen()->glyphCache();
params.m_logText = strings::MakeUniString(m_emptyModelMessage);
params.m_doSplit = true;
params.m_delimiters = "\n";
params.m_useAllParts = true;
yg::StraightTextElement ste(params);
ste.draw(pDrawer->screen().get(), math::Identity<double, 3>());
m2::PointD pv(pt.x, ste.roughBoundRect().maxY() + m_downloadButton->roughBoundRect().SizeY() / 2 + 10 * m_visualScale);
m_downloadButton->setPivot(pv);
}
void InformationDisplay::enableBenchmarkInfo(bool doEnable)
{
m_isBenchmarkInfoEnabled = doEnable;
@ -477,6 +457,4 @@ void InformationDisplay::doDraw(DrawerYG *drawer)
drawBenchmarkInfo(drawer);
//if (s_isLogEnabled)
// drawLog(drawer);
if (m_isEmptyModelMessageEnabled)
drawEmptyModelMessage(drawer);
}

View file

@ -22,6 +22,13 @@ namespace gui
class Controller;
}
namespace storage
{
class Storage;
}
class CountryStatusDisplay;
/// Class, which displays additional information on the primary layer.
/// like rules, coordinates, GPS position and heading
class InformationDisplay
@ -50,7 +57,7 @@ private:
bool m_isDebugInfoEnabled;
double m_frameDuration;
bool m_isEmptyModelMessageEnabled;
string m_emptyCountryName;
string m_emptyModelMessage;
shared_ptr<gui::Button> m_downloadButton;
@ -80,10 +87,11 @@ private:
static size_t s_logSize;
static WindowHandle * s_windowHandle;
*/
shared_ptr<CountryStatusDisplay> m_countryStatusDisplay;
public:
InformationDisplay();
InformationDisplay(storage::Storage * storage);
void setController(gui::Controller * controller);
@ -125,10 +133,9 @@ public:
void setLogSize(size_t logSize);
void drawLog(DrawerYG * pDrawer);
void enableEmptyModelMessage(bool doEnable);
void setEmptyModelMessage(char const * msg);
void enableCountryStatusDisplay(bool doEnable);
void setDownloadListener(gui::Button::TOnClickListener l);
void drawEmptyModelMessage(DrawerYG * pDrawer);
void setEmptyCountryName(char const * country);
static void logMessage(my::LogLevel, my::SrcPoint const &, string const &);
};

View file

@ -50,6 +50,7 @@ HEADERS += \
bookmark.hpp \
tile_set.hpp \
geourl_process.hpp \
country_status_display.hpp \
SOURCES += \
feature_vec_model.cpp \
@ -91,6 +92,7 @@ SOURCES += \
tile_set.cpp \
geourl_process.cpp \
bookmark.cpp \
country_status_display.cpp \
!iphone*:!bada*:!android* {
HEADERS += qgl_render_context.hpp

View file

@ -43,6 +43,12 @@ namespace storage
m_country == other.m_country &&
m_region == other.m_region);
}
bool operator!=(TIndex const & other) const
{
return !(*this == other);
}
bool operator<(TIndex const & other) const
{
if (m_group != other.m_group)