forked from organicmaps/organicmaps
bug fixes for release.
This commit is contained in:
parent
63b732f8f9
commit
13b42462f9
15 changed files with 379 additions and 97 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,5 +41,6 @@ namespace anim
|
|||
void OnStart(double ts);
|
||||
void OnStep(double ts);
|
||||
void OnEnd(double ts);
|
||||
void OnCancel(double ts);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
//@{
|
||||
|
|
Loading…
Add table
Reference in a new issue