bug fixes for release.

This commit is contained in:
rachytski 2012-10-05 17:44:42 +03:00 committed by Alex Zolotarev
parent 63b732f8f9
commit 13b42462f9
15 changed files with 379 additions and 97 deletions

View file

@ -11,6 +11,8 @@
#include "../platform/Platform.hpp"
#include "../../../../../platform/settings.hpp"
#include "../../../../../map/information_display.hpp"
#include "../../../../../map/location_state.hpp"
extern "C"
{
@ -77,4 +79,52 @@ extern "C"
(void)Settings::Set(jni::ToNativeString(env, name), flag);
}
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_MWMApplication_nativeIsFollowingCompass(JNIEnv * env,
jobject thiz)
{
location::ECompassProcessMode compassMode = g_framework->NativeFramework()->GetInformationDisplay().locationState()->CompassProcessMode();
return compassMode == location::ECompassFollow;
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_MWMApplication_nativeStartCompassFollowing(JNIEnv * env,
jobject thiz)
{
shared_ptr<location::State> ls = g_framework->NativeFramework()->GetInformationDisplay().locationState();
if (!ls->IsCentered())
ls->AnimateToPositionAndEnqueueFollowing();
else
ls->StartCompassFollowing();
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_MWMApplication_nativeStopCompassFollowing(JNIEnv * env,
jobject thiz)
{
g_framework->NativeFramework()->GetInformationDisplay().locationState()->StopCompassFollowing();
}
void CompassStatusChanged(int mode, shared_ptr<jobject> const & obj)
{
JNIEnv * env = jni::GetEnv();
jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "OnCompassStatusChanged", "(I)V");
jint val = static_cast<jint>(mode);
env->CallVoidMethod(*obj.get(), methodID, val);
}
JNIEXPORT jint JNICALL
Java_com_mapswithme_maps_MWMApplication_nativeAddCompassStatusListener(JNIEnv * env, jobject thiz, jobject obj)
{
location::State::TCompassStatusListener fn = bind(&CompassStatusChanged, _1, jni::make_global_ref(obj));
shared_ptr<location::State> ls = g_framework->NativeFramework()->GetInformationDisplay().locationState();
return ls->AddCompassStatusListener(fn);
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_MWMApplication_nativeRemoveCompassStatusListener(JNIEnv * env, jobject thiz, jint slotID)
{
shared_ptr<location::State> ls = g_framework->NativeFramework()->GetInformationDisplay().locationState();
ls->RemoveCompassStatusListener(slotID);
}
}

View file

@ -22,7 +22,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.mapswithme.maps.location.LocationService;
import com.mapswithme.util.ConnectionState;
@ -40,12 +39,15 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
private AlertDialog m_storageDisconnectedDialog = null;
private boolean m_shouldStartLocationService = false;
private boolean m_hasLocation = false;
private boolean m_hasCompass = false;
private boolean m_isLocationActive = false;
private boolean m_suggestAutoFollowMode = false;
private LocationService getLocationService()
{
return mApplication.getLocationService();
}
private MapStorage getMapStorage()
{
return mApplication.getMapStorage();
@ -53,6 +55,7 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
private void startLocation()
{
m_isLocationActive = true;
getLocationService().startUpdate(this);
// Do not turn off the screen while displaying position
Utils.automaticIdleScreen(false, getWindow());
@ -61,6 +64,8 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
private void stopLocation()
{
m_hasLocation = false;
m_hasCompass = false;
m_isLocationActive = false;
getLocationService().stopUpdate(this);
// Enable automatic turning screen off while app is idle
Utils.automaticIdleScreen(true, getWindow());
@ -206,18 +211,41 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
public void onMyPositionClicked(View v)
{
v.setBackgroundResource(R.drawable.myposition_button_normal);
final boolean isLocationActive = v.isSelected();
if (isLocationActive)
stopLocation();
else
if (!m_isLocationActive)
{
startLocation();
v.setSelected(!isLocationActive);
v.setBackgroundResource(R.drawable.myposition_button_normal);
v.setSelected(true);
}
else
{
if (!m_hasCompass)
{
stopLocation();
v.setBackgroundResource(R.drawable.myposition_button_normal);
v.setSelected(false);
}
else
{
if(!mApplication.nativeIsFollowingCompass())
{
mApplication.nativeStartCompassFollowing();
v.setBackgroundResource(R.drawable.myposition_button_follow);
v.setSelected(true);
}
else
{
mApplication.nativeStopCompassFollowing();
v.setBackgroundResource(R.drawable.myposition_button_normal);
v.setSelected(false);
stopLocation();
}
}
}
// Store active state of My Position
SharedPreferences.Editor prefsEdit = getSharedPreferences(mApplication.getPackageName(), MODE_PRIVATE).edit();
prefsEdit.putBoolean(PREFERENCES_MYPOSITION, !isLocationActive);
prefsEdit.putBoolean(PREFERENCES_MYPOSITION, !m_isLocationActive);
prefsEdit.commit();
}
@ -562,6 +590,37 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
}
}
public void onCompassStatusChanged(int newStatus)
{
View v = findViewById(R.id.map_button_myposition);
if (newStatus == 1)
{
v.setSelected(true);
v.setBackgroundResource(R.drawable.myposition_button_follow);
}
else
{
if (m_hasLocation)
v.setBackgroundResource(R.drawable.myposition_button_found);
else
v.setBackgroundResource(R.drawable.myposition_button_normal);
}
}
public void OnCompassStatusChanged(int newStatus)
{
final int val = newStatus;
runOnUiThread(new Runnable()
{
@Override
public void run()
{
onCompassStatusChanged(val);
}
});
}
@Override
public void onLocationUpdated(long time, double lat, double lon, float accuracy)
{
@ -578,15 +637,9 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
magneticNorth = LocationService.correctAngle(magneticNorth, correction);
trueNorth = LocationService.correctAngle(trueNorth, correction);
nativeCompassUpdated(time, magneticNorth, trueNorth, accuracy);
m_hasCompass = true;
if (m_hasLocation
&& mApplication.isProVersion()
&& m_suggestAutoFollowMode)
{
Toast.makeText(this, R.string.suggest_auto_follow_mode, Toast.LENGTH_LONG).show();
m_suggestAutoFollowMode = false;
}
nativeCompassUpdated(time, magneticNorth, trueNorth, accuracy);
}
//@}
@ -601,6 +654,18 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
findViewById(R.id.map_button_myposition).setSelected(isMyPositionEnabled);
}
private int m_compassStatusListenerID = -1;
private void startWatchingCompassStatusUpdate()
{
m_compassStatusListenerID = mApplication.nativeAddCompassStatusListener(this);
}
private void stopWatchingCompassStatusUpdate()
{
mApplication.nativeRemoveCompassStatusListener(m_compassStatusListenerID);
}
@Override
protected void onPause()
{
@ -608,6 +673,8 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
stopWatchingExternalStorage();
stopWatchingCompassStatusUpdate();
super.onPause();
}
@ -627,6 +694,8 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService
m_shouldStartLocationService = true;
}
startWatchingCompassStatusUpdate();
startWatchingExternalStorage();
super.onResume();

View file

@ -183,4 +183,11 @@ public class MWMApplication extends android.app.Application implements MapStorag
/// Dealing with Settings
public native boolean nativeGetBoolean(String name, boolean defaultVal);
public native void nativeSetBoolean(String name, boolean val);
public native boolean nativeIsFollowingCompass();
public native void nativeStartCompassFollowing();
public native void nativeStopCompassFollowing();
public native int nativeAddCompassStatusListener(Object l);
public native void nativeRemoveCompassStatusListener(int slotID);
}

View file

@ -1,6 +1,8 @@
#include "angle_interpolation.hpp"
#include "controller.hpp"
#include "../geometry/angles.hpp"
#include "../base/logging.hpp"
namespace anim
{
@ -22,20 +24,21 @@ namespace anim
void AngleInterpolation::OnStart(double ts)
{
m_startTime = ts;
m_outAngle = m_startAngle;
Task::OnStart(ts);
}
void AngleInterpolation::OnStep(double ts)
{
if (!IsRunning())
return;
if (ts - m_startTime >= m_interval)
{
End();
return;
}
if (!IsRunning())
return;
double elapsedSec = ts - m_startTime;
m_curAngle = m_outAngle = m_startAngle + m_dist * elapsedSec / m_interval;
@ -56,6 +59,7 @@ namespace anim
void AngleInterpolation::SetEndAngle(double val)
{
m_startTime = GetController()->GetCurrentTime();
m_startAngle = m_curAngle;
m_dist = ang::GetShortestDistance(m_startAngle, val);
m_endAngle = m_startAngle + m_dist;

View file

@ -1,13 +1,15 @@
#include "anyrect_interpolation.hpp"
#include "../base/logging.hpp"
namespace anim
{
AnyRectInterpolation::AnyRectInterpolation(m2::AnyRectD const & startRect,
m2::AnyRectD const & endRect,
double rotationSpeed,
m2::AnyRectD & outRect)
: m_interval(rotationSpeed * fabs(ang::GetShortestDistance(startRect.Angle().val(),
endRect.Angle().val())) / (2 * math::pi)),
: m_interval(max(0.5, rotationSpeed * fabs(ang::GetShortestDistance(startRect.Angle().val(),
endRect.Angle().val())) / (2 * math::pi))),
m_angleInt(startRect.Angle().val(),
endRect.Angle().val(),
rotationSpeed,
@ -35,9 +37,16 @@ namespace anim
m_startTime = ts;
m_angleInt.OnStart(ts);
m_angleInt.Start();
m_segmentInt.OnStart(ts);
m_segmentInt.Start();
m_sizeXInt.OnStart(ts);
m_sizeXInt.Start();
m_sizeYInt.OnStart(ts);
m_sizeYInt.Start();
m_outRect = m_startRect;
@ -46,34 +55,68 @@ namespace anim
void AnyRectInterpolation::OnStep(double ts)
{
if (!IsRunning())
return;
if (ts - m_startTime >= m_interval)
{
End();
return;
}
if (!IsRunning())
return;
if (m_angleInt.IsRunning())
m_angleInt.OnStep(ts);
m_angleInt.OnStep(ts);
m_segmentInt.OnStep(ts);
m_sizeXInt.OnStep(ts);
m_sizeYInt.OnStep(ts);
if (m_segmentInt.IsRunning())
m_segmentInt.OnStep(ts);
m_outRect = m2::AnyRectD(m_curCenter, m_curAngle, m2::RectD(-m_curSizeX / 2, -m_curSizeY / 2, m_curSizeX / 2, m_curSizeY / 2));
if (m_sizeXInt.IsRunning())
m_sizeXInt.OnStep(ts);
if (m_sizeYInt.IsRunning())
m_sizeYInt.OnStep(ts);
m_outRect = m2::AnyRectD(m_curCenter,
m_curAngle,
m2::RectD(-m_curSizeX / 2, -m_curSizeY / 2,
m_curSizeX / 2, m_curSizeY / 2));
anim::Task::OnStep(ts);
}
void AnyRectInterpolation::OnEnd(double ts)
{
m_angleInt.OnEnd(ts);
m_segmentInt.OnEnd(ts);
m_sizeXInt.OnEnd(ts);
m_sizeYInt.OnEnd(ts);
if (m_angleInt.IsRunning())
m_angleInt.OnEnd(ts);
if (m_segmentInt.IsRunning())
m_segmentInt.OnEnd(ts);
if (m_sizeXInt.IsRunning())
m_sizeXInt.OnEnd(ts);
if (m_sizeYInt.IsRunning())
m_sizeYInt.OnEnd(ts);
m_outRect = m_endRect;
anim::Task::OnEnd(ts);
}
void AnyRectInterpolation::OnCancel(double ts)
{
if (m_angleInt.IsRunning())
m_angleInt.Cancel();
if (m_segmentInt.IsRunning())
m_segmentInt.Cancel();
if (m_sizeXInt.IsRunning())
m_sizeXInt.Cancel();
if (m_sizeYInt.IsRunning())
m_sizeYInt.Cancel();
anim::Task::OnCancel(ts);
}
}

View file

@ -41,5 +41,6 @@ namespace anim
void OnStart(double ts);
void OnStep(double ts);
void OnEnd(double ts);
void OnCancel(double ts);
};
}

View file

@ -20,6 +20,7 @@ namespace anim
void Controller::AddTask(shared_ptr<Task> const & task)
{
task->SetController(this);
m_tasks.PushBack(task);
m_IdleFrames = m_IdleThreshold;
}
@ -30,6 +31,11 @@ namespace anim
swap(from, to);
}
void Controller::MergeTasks(TTasks & from, TTasks & to)
{
copy(from.begin(), from.end(), back_inserter(to));
}
bool Controller::HasTasks()
{
return !m_tasks.Empty();
@ -55,7 +61,7 @@ namespace anim
{
m_tasks.ProcessList(bind(&Controller::CopyAndClearTasks, _1, ref(m_tasksList)));
double ts = my::Timer::LocalTime();
double ts = GetCurrentTime();
TTasks l;
@ -66,30 +72,43 @@ namespace anim
m_IdleFrames = m_IdleThreshold;
shared_ptr<Task> const & task = *it;
if (task->State() == Task::EStarted)
task->Lock();
if (task->IsReady())
{
task->Start();
task->OnStart(ts);
if (task->State() == Task::EInProgress)
}
if (task->IsRunning())
task->OnStep(ts);
if (task->State() == Task::EInProgress)
if (task->IsRunning())
l.push_back(task);
else
{
if (task->State() == Task::ECancelled)
if (task->IsCancelled())
task->OnCancel(ts);
if (task->State() == Task::EEnded)
if (task->IsEnded())
task->OnEnd(ts);
}
task->Unlock();
}
if (!hasTasks && m_IdleFrames > 0)
m_IdleFrames -= 1;
m_tasks.ProcessList(bind(&Controller::CopyAndClearTasks, ref(l), _1));
m_tasks.ProcessList(bind(&Controller::MergeTasks, ref(l), _1));
}
bool Controller::IsPreWarmed() const
{
return m_IdleFrames > 0;
}
double Controller::GetCurrentTime() const
{
return my::Timer::LocalTime();
}
}

View file

@ -26,6 +26,7 @@ namespace anim
int m_IdleFrames;
static void CopyAndClearTasks(list<shared_ptr<Task> > & from, list<shared_ptr<Task> > & to);
static void MergeTasks(list<shared_ptr<Task> > & from, list<shared_ptr<Task> > & to);
public:
// Constructor
@ -53,5 +54,7 @@ namespace anim
// interrupting rendering process, which might had happened in these
// "frames-in-the-middle".
bool IsPreWarmed() const;
// Getting current simulation time
double GetCurrentTime() const;
};
}

View file

@ -1,9 +1,13 @@
#include "task.hpp"
#include "../std/bind.hpp"
#include "../base/assert.hpp"
namespace anim
{
Task::Task()
: m_State(EStarted)
: m_State(EReady)
{}
Task::~Task()
@ -26,46 +30,50 @@ namespace anim
void Task::SetState(EState State)
{
Lock();
m_State = State;
Unlock();
}
void Task::PerformCallback(EState state)
void Task::PerformCallbacks(EState state)
{
TCallback const & cb = m_Callbacks[state];
if (cb)
cb();
list<TCallback> const & cb = m_Callbacks[state];
for_each(cb.begin(), cb.end(), bind(&TCallback::operator(), _1));
}
void Task::OnStart(double ts)
{
PerformCallback(EStarted);
SetState(EInProgress);
PerformCallbacks(EReady);
}
void Task::OnStep(double ts)
{
PerformCallback(EInProgress);
PerformCallbacks(EInProgress);
}
void Task::OnCancel(double ts)
{
PerformCallback(ECancelled);
PerformCallbacks(ECancelled);
}
void Task::OnEnd(double ts)
{
PerformCallback(EEnded);
PerformCallbacks(EEnded);
}
void Task::Start()
{
ASSERT(IsReady(), ());
SetState(EInProgress);
}
void Task::Cancel()
{
ASSERT(IsRunning() || IsReady(), ());
SetState(ECancelled);
}
void Task::End()
{
ASSERT(IsRunning() || IsReady(), ());
SetState(EEnded);
}
@ -84,8 +92,23 @@ namespace anim
return State() == EInProgress;
}
void Task::SetCallback(EState state, TCallback const & cb)
bool Task::IsReady() const
{
m_Callbacks[state] = cb;
return State() == EReady;
}
void Task::AddCallback(EState state, TCallback const & cb)
{
m_Callbacks[state].push_back(cb);
}
void Task::SetController(Controller * controller)
{
m_controller = controller;
}
Controller * Task::GetController() const
{
return m_controller;
}
}

View file

@ -1,12 +1,15 @@
#pragma once
#include "../std/map.hpp"
#include "../std/list.hpp"
#include "../std/function.hpp"
#include "../base/mutex.hpp"
namespace anim
{
class Controller;
// Interface for single animation task
class Task
{
@ -16,7 +19,7 @@ namespace anim
enum EState
{
EStarted,
EReady,
EInProgress,
ECancelled,
EEnded
@ -26,21 +29,27 @@ namespace anim
EState m_State;
map<EState, TCallback> m_Callbacks;
map<EState, list<TCallback> > m_Callbacks;
void PerformCallback(EState state);
void PerformCallbacks(EState state);
threads::Mutex m_mutex;
Controller * m_controller;
protected:
void SetState(EState state);
friend class Controller;
void SetController(Controller * controller);
public:
Task();
virtual ~Task();
Controller * GetController() const;
EState State() const;
virtual void OnStart(double ts);
@ -48,16 +57,18 @@ namespace anim
virtual void OnEnd(double ts);
virtual void OnCancel(double ts);
void Start();
void Cancel();
void End();
bool IsCancelled() const;
bool IsEnded() const;
bool IsRunning() const;
bool IsReady() const;
void Lock();
void Unlock();
void SetCallback(EState state, TCallback const & cb);
void AddCallback(EState state, TCallback const & cb);
};
}

View file

@ -26,8 +26,9 @@ void Animator::RotateScreen(double startAngle, double endAngle, double duration)
{
if (m_rotateScreenTask)
{
if (!m_rotateScreenTask->IsCancelled())
m_rotateScreenTask->Cancel();
m_rotateScreenTask->Unlock();
m_rotateScreenTask->Cancel();
m_rotateScreenTask.reset();
}
@ -54,8 +55,8 @@ void Animator::StopRotation()
&& !m_rotateScreenTask->IsEnded()
&& !m_rotateScreenTask->IsCancelled())
{
m_rotateScreenTask->Unlock();
m_rotateScreenTask->Cancel();
m_rotateScreenTask->Unlock();
m_rotateScreenTask.reset();
return;
}

View file

@ -36,7 +36,7 @@ size_t BasicTilingRenderPolicy::CalculateTileSize(size_t screenWidth, size_t scr
BasicTilingRenderPolicy::BasicTilingRenderPolicy(Params const & p,
bool doUseQueuedRenderer)
: RenderPolicy(p, GetPlatform().IsPro(), GetPlatform().CpuCores()),
: RenderPolicy(p, true, GetPlatform().CpuCores()),
m_DrawScale(0),
m_IsEmptyModel(false),
m_DoRecreateCoverage(false),

View file

@ -840,7 +840,8 @@ void Framework::StartDrag(DragEvent const & e)
if (m_renderPolicy)
m_renderPolicy->StartDrag();
m_dragCompassProcessMode = m_informationDisplay.locationState()->CompassProcessMode();
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
m_dragCompassProcessMode = locationState->CompassProcessMode();
}
void Framework::DoDrag(DragEvent const & e)
@ -879,7 +880,12 @@ void Framework::StopDrag(DragEvent const & e)
if (GetPixelCenter().Length(s.GtoP(locationState->Position())) >= s.GetMinPixelRectSize() / 2.0)
locationState->SetLocationProcessMode(location::ELocationDoNothing);
else
locationState->SetCompassProcessMode(m_dragCompassProcessMode);
{
if (m_dragCompassProcessMode == location::ECompassFollow)
locationState->AnimateToPositionAndEnqueueFollowing();
else
locationState->AnimateToPosition();
}
}
if (m_renderPolicy)

View file

@ -22,6 +22,8 @@
#include "../indexer/mercator.hpp"
#include "../base/logging.hpp"
namespace location
{
State::Params::Params()
@ -34,7 +36,8 @@ namespace location
m_hasCompass(false),
m_isCentered(false),
m_locationProcessMode(ELocationDoNothing),
m_compassProcessMode(ECompassDoNothing)
m_compassProcessMode(ECompassDoNothing),
m_currentSlotID(0)
{
m_drawHeading = m_compassFilter.GetHeadingRad();
m_locationAreaColor = p.m_locationAreaColor;
@ -103,7 +106,12 @@ namespace location
void State::SetCompassProcessMode(ECompassProcessMode mode)
{
bool stateChanged = (m_compassProcessMode != mode);
m_compassProcessMode = mode;
if (stateChanged)
CallCompassStatusListeners(mode);
}
void State::OnLocationStatusChanged(location::TLocationStatus newStatus)
@ -122,7 +130,7 @@ namespace location
{
// set centering mode for the first location
m_locationProcessMode = ELocationCenterAndScale;
m_compassProcessMode = ECompassDoNothing;
SetCompassProcessMode(ECompassDoNothing);
}
break;
@ -175,7 +183,7 @@ namespace location
SetIsCentered(true);
CheckCompassRotation();
CheckFollowCompass();
CheckCompassFollowing();
m_locationProcessMode = ELocationCenterOnly;
break;
@ -186,7 +194,8 @@ namespace location
SetIsCentered(true);
CheckCompassRotation();
CheckFollowCompass();
CheckCompassFollowing();
break;
case ELocationSkipCentering:
@ -208,7 +217,7 @@ namespace location
m_compassFilter.OnCompassUpdate(info);
CheckCompassRotation();
CheckFollowCompass();
CheckCompassFollowing();
m_framework->Invalidate();
}
@ -430,7 +439,6 @@ namespace location
bool State::hitTest(m2::PointD const & pt) const
{
double radius = m_arrowHeight * m_controller->GetVisualScale();
return m_hasCompass && (pt.SquareLength(pivot()) <= my::sq(radius));
}
@ -486,7 +494,7 @@ namespace location
#endif
}
void State::CheckFollowCompass()
void State::CheckCompassFollowing()
{
if (m_hasCompass
&& (CompassProcessMode() == ECompassFollow)
@ -511,15 +519,23 @@ namespace location
controller->Unlock();
}
void State::MarkCenteredAndFollowCompass()
void State::AnimateToPosition()
{
m_isCentered = true;
SetCompassProcessMode(ECompassFollow);
FollowCompass();
(void)Settings::Set("SuggestAutoFollowMode", false);
anim::Controller * controller = m_framework->GetAnimController();
controller->Lock();
m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect();
m2::AnyRectD endRect = m2::AnyRectD(Position(),
startRect.Angle().val(),
m2::RectD(startRect.GetLocalRect()));
m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2);
controller->Unlock();
}
void State::CenterScreenAndEnqueueFollowing()
void State::AnimateToPositionAndEnqueueFollowing()
{
anim::Controller * controller = m_framework->GetAnimController();
@ -533,12 +549,21 @@ namespace location
shared_ptr<ChangeViewportTask> const & t = m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2);
t->Lock();
t->SetCallback(anim::Task::EEnded, bind(&State::MarkCenteredAndFollowCompass, this));
t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true));
t->AddCallback(anim::Task::EEnded, bind(&State::StartCompassFollowing, this));
t->Unlock();
controller->Unlock();
}
void State::StartCompassFollowing()
{
SetCompassProcessMode(ECompassFollow);
CheckCompassRotation();
CheckCompassFollowing();
setState(EPressed);
}
void State::StopCompassFollowing()
{
SetCompassProcessMode(ECompassDoNothing);
@ -557,6 +582,26 @@ namespace location
m_isCentered = flag;
}
void State::CallCompassStatusListeners(ECompassProcessMode mode)
{
for (TCompassStatusListeners::const_iterator it = m_compassStatusListeners.begin();
it != m_compassStatusListeners.end();
++it)
it->second(mode);
}
int State::AddCompassStatusListener(TCompassStatusListener const & l)
{
int slotID = m_currentSlotID++;
m_compassStatusListeners[slotID] = l;
return slotID;
}
void State::RemoveCompassStatusListener(int slotID)
{
m_compassStatusListeners.erase(slotID);
}
bool State::onTapEnded(m2::PointD const & pt)
{
if (!m_framework->GetNavigator().DoSupportRotation())
@ -570,32 +615,16 @@ namespace location
{
case EActive:
if (m_hasCompass)
{
if (!IsCentered())
CenterScreenAndEnqueueFollowing();
else
{
SetCompassProcessMode(ECompassFollow);
FollowCompass();
(void)Settings::Set("SuggestAutoFollowMode", false);
}
setState(EPressed);
}
StartCompassFollowing();
break;
case EPressed:
setState(EActive);
StopCompassFollowing();
break;
default:
LOG(LWARNING, ("not-used EState values encountered"));
};
controller->Unlock();
m_framework->Invalidate();
return true;
}
}

View file

@ -51,6 +51,10 @@ namespace location
// and draws location and compass marks.
class State : public gui::Element
{
public:
typedef function<void(int)> TCompassStatusListener;
private:
double m_errorRadius; //< error radius in mercator
@ -67,8 +71,6 @@ namespace location
ECompassProcessMode m_compassProcessMode;
void FollowCompass();
void MarkCenteredAndFollowCompass();
void CenterScreenAndEnqueueFollowing();
/// GUI element related fields.
@ -117,6 +119,12 @@ namespace location
shared_ptr<anim::AngleInterpolation> m_headingInterpolation;
typedef map<int, TCompassStatusListener> TCompassStatusListeners;
TCompassStatusListeners m_compassStatusListeners;
int m_currentSlotID;
void CallCompassStatusListeners(ECompassProcessMode mode);
public:
struct Params : base_t::Params
@ -146,12 +154,20 @@ namespace location
void TurnOff();
void StartCompassFollowing();
void StopCompassFollowing();
int AddCompassStatusListener(TCompassStatusListener const & l);
void RemoveCompassStatusListener(int slotID);
void SetIsCentered(bool flag);
bool IsCentered() const;
void AnimateToPosition();
void AnimateToPositionAndEnqueueFollowing();
void CheckCompassRotation();
void CheckFollowCompass();
void CheckCompassFollowing();
/// @name GPS location updates routine.
//@{