Skip to content

Commit

Permalink
refactor picture rotating
Browse files Browse the repository at this point in the history
The new implementation supports both rotating by fixed angles of +90 degree
(used for remote controls) and rotating by an arbitrary angle which makes
rotating with touch gestures much more intuitive. Nothing changes for zooming
by fixed angles. For rotating by an arbitrary factor every rotation must start
by sending the ACTION_GESTURE_BEGIN action and end by sending the
ACTION_GESTURE_END action. In between the ACTION_GESTURE_ROTATE can be sent
containing an arbitrary floating-point angle (in degrees) to perform rotation
actions.
  • Loading branch information
Montellese committed Aug 10, 2012
1 parent 76f8c0c commit b6f611d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 26 deletions.
25 changes: 21 additions & 4 deletions xbmc/pictures/GUIWindowSlideShow.cpp
Expand Up @@ -170,7 +170,8 @@ void CGUIWindowSlideShow::Reset()
m_Image[1].UnLoad(); m_Image[1].UnLoad();
m_Image[1].Close(); m_Image[1].Close();


m_iRotate = 0; m_fRotate = 0.0f;
m_fInitialRotate = 0.0f;
m_iZoomFactor = 1; m_iZoomFactor = 1;
m_fZoom = 1.0f; m_fZoom = 1.0f;
m_fInitialZoom = 0.0f; m_fInitialZoom = 0.0f;
Expand Down Expand Up @@ -478,7 +479,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
m_iNextSlide = GetNextSlide(); m_iNextSlide = GetNextSlide();


// m_iZoomFactor = 1; // m_iZoomFactor = 1;
m_iRotate = 0; m_fRotate = 0.0f;
} }


if (m_Image[m_iCurrentPic].IsLoaded()) if (m_Image[m_iCurrentPic].IsLoaded())
Expand Down Expand Up @@ -523,6 +524,7 @@ EVENT_RESULT CGUIWindowSlideShow::OnMouseEvent(const CPoint &point, const CMouse
{ {
m_firstGesturePoint = point; m_firstGesturePoint = point;
m_fInitialZoom = m_fZoom; m_fInitialZoom = m_fZoom;
m_fInitialRotate = m_fRotate;
return EVENT_RESULT_HANDLED; return EVENT_RESULT_HANDLED;
} }
else if (event.m_id == ACTION_GESTURE_PAN) else if (event.m_id == ACTION_GESTURE_PAN)
Expand All @@ -549,13 +551,19 @@ EVENT_RESULT CGUIWindowSlideShow::OnMouseEvent(const CPoint &point, const CMouse
else if (event.m_id == ACTION_GESTURE_END) else if (event.m_id == ACTION_GESTURE_END)
{ {
m_fInitialZoom = 0.0f; m_fInitialZoom = 0.0f;
m_fInitialRotate = 0.0f;
return EVENT_RESULT_HANDLED; return EVENT_RESULT_HANDLED;
} }
else if (event.m_id == ACTION_GESTURE_ZOOM) else if (event.m_id == ACTION_GESTURE_ZOOM)
{ {
ZoomRelative(m_fInitialZoom * event.m_offsetX, true); ZoomRelative(m_fInitialZoom * event.m_offsetX, true);
return EVENT_RESULT_HANDLED; return EVENT_RESULT_HANDLED;
} }
else if (event.m_id == ACTION_GESTURE_ROTATE)
{
RotateRelative(m_fInitialRotate + event.m_offsetX - m_fRotate, true);
return EVENT_RESULT_HANDLED;
}
return EVENT_RESULT_UNHANDLED; return EVENT_RESULT_UNHANDLED;
} }


Expand Down Expand Up @@ -800,8 +808,17 @@ void CGUIWindowSlideShow::RenderPause()


void CGUIWindowSlideShow::Rotate() void CGUIWindowSlideShow::Rotate()
{ {
if (!m_Image[m_iCurrentPic].DrawNextImage() && m_iZoomFactor == 1) RotateRelative(90.0f);
m_Image[m_iCurrentPic].Rotate(++m_iRotate); }

void CGUIWindowSlideShow::RotateRelative(float fAngle, bool immediate /* = false */)
{
if (m_Image[m_iCurrentPic].DrawNextImage() || m_fZoom > 1.0f)
return;

m_fRotate += fAngle;

m_Image[m_iCurrentPic].Rotate(fAngle, immediate);
} }


void CGUIWindowSlideShow::Zoom(int iZoom) void CGUIWindowSlideShow::Zoom(int iZoom)
Expand Down
4 changes: 3 additions & 1 deletion xbmc/pictures/GUIWindowSlideShow.h
Expand Up @@ -103,6 +103,7 @@ class CGUIWindowSlideShow : public CGUIWindow
void RenderPause(); void RenderPause();
void RenderErrorMessage(); void RenderErrorMessage();
void Rotate(); void Rotate();
void RotateRelative(float fAngle, bool immediate = false);
void Zoom(int iZoom); void Zoom(int iZoom);
void ZoomRelative(float fZoom, bool immediate = false); void ZoomRelative(float fZoom, bool immediate = false);
void Move(float fX, float fY); void Move(float fX, float fY);
Expand All @@ -112,7 +113,8 @@ class CGUIWindowSlideShow : public CGUIWindow
int m_iCurrentSlide; int m_iCurrentSlide;
int m_iNextSlide; int m_iNextSlide;
int m_iDirection; int m_iDirection;
int m_iRotate; float m_fRotate;
float m_fInitialRotate;
int m_iZoomFactor; int m_iZoomFactor;
float m_fZoom; float m_fZoom;
float m_fInitialZoom; float m_fInitialZoom;
Expand Down
46 changes: 26 additions & 20 deletions xbmc/pictures/SlideShowPicture.cpp
Expand Up @@ -103,18 +103,18 @@ void CSlideShowPic::SetTexture(int iSlideNumber, CBaseTexture* pTexture, DISPLAY
m_transistionTemp.type = TRANSISTION_NONE; m_transistionTemp.type = TRANSISTION_NONE;
m_fTransistionAngle = 0; m_fTransistionAngle = 0;
m_fTransistionZoom = 0; m_fTransistionZoom = 0;
m_fAngle = 0; m_fAngle = 0.0f;
if (pTexture->GetOrientation() == 7) if (pTexture->GetOrientation() == 7)
{ // rotate to 270 degrees { // rotate to 270 degrees
m_fAngle = 3.0f; m_fAngle = 270.0f;
} }
if (pTexture->GetOrientation() == 2) if (pTexture->GetOrientation() == 2)
{ // rotate to 180 degrees { // rotate to 180 degrees
m_fAngle = 2.0f; m_fAngle = 180.0f;
} }
if (pTexture->GetOrientation() == 5) if (pTexture->GetOrientation() == 5)
{ // rotate to 90 degrees { // rotate to 90 degrees
m_fAngle = 1.0f; m_fAngle = 90.0f;
} }
m_fZoomAmount = 1; m_fZoomAmount = 1;
m_fZoomLeft = 0; m_fZoomLeft = 0;
Expand Down Expand Up @@ -159,7 +159,7 @@ void CSlideShowPic::SetOriginalSize(int iOriginalWidth, int iOriginalHeight, boo


int CSlideShowPic::GetOriginalWidth() int CSlideShowPic::GetOriginalWidth()
{ {
int iAngle = (int)(m_fAngle + 0.4f); int iAngle = (int)(m_fAngle / 90.0f + 0.4f);
if (iAngle % 2) if (iAngle % 2)
return m_iOriginalHeight; return m_iOriginalHeight;
else else
Expand All @@ -168,7 +168,7 @@ int CSlideShowPic::GetOriginalWidth()


int CSlideShowPic::GetOriginalHeight() int CSlideShowPic::GetOriginalHeight()
{ {
int iAngle = (int)(m_fAngle + 0.4f); int iAngle = (int)(m_fAngle / 90.0f + 0.4f);
if (iAngle % 2) if (iAngle % 2)
return m_iOriginalWidth; return m_iOriginalWidth;
else else
Expand Down Expand Up @@ -253,22 +253,23 @@ void CSlideShowPic::Process(unsigned int currentTime, CDirtyRegionList &dirtyreg
m_fZoomAmount = zoomamount[i]; m_fZoomAmount = zoomamount[i];
m_bNoEffect = (m_fZoomAmount != 1.0f); // turn effect rendering back on. m_bNoEffect = (m_fZoomAmount != 1.0f); // turn effect rendering back on.
} }
if (m_transistionTemp.type == TRANSISTION_ROTATE) /* not really needed anymore as we support arbitrary rotations
{ // round to nearest integer for accuracy purposes else if (m_transistionTemp.type == TRANSISTION_ROTATE)
m_fAngle = floor(m_fAngle + 0.4f); { // round to nearest of 0, 90, 180 and 270
} float reminder = fmodf(m_fAngle, 90.0f);
if (reminder < 45.0f)
m_fAngle -= reminder;
else
m_fAngle += 90.0f - reminder;
}*/
m_transistionTemp.type = TRANSISTION_NONE; m_transistionTemp.type = TRANSISTION_NONE;
} }
else else
{ {
if (m_transistionTemp.type == TRANSISTION_ROTATE) if (m_transistionTemp.type == TRANSISTION_ROTATE)
{
m_fAngle += m_fTransistionAngle; m_fAngle += m_fTransistionAngle;
}
if (m_transistionTemp.type == TRANSISTION_ZOOM) if (m_transistionTemp.type == TRANSISTION_ZOOM)
{
m_fZoomAmount += m_fTransistionZoom; m_fZoomAmount += m_fTransistionZoom;
}
} }
} }
} }
Expand Down Expand Up @@ -367,8 +368,8 @@ void CSlideShowPic::Process(unsigned int currentTime, CDirtyRegionList &dirtyreg
// Rotate the image as needed // Rotate the image as needed
float x[4]; float x[4];
float y[4]; float y[4];
float si = (float)sin(m_fAngle * M_PI * 0.5); float si = (float)sin(m_fAngle / 180.0f * M_PI);
float co = (float)cos(m_fAngle * M_PI * 0.5); float co = (float)cos(m_fAngle / 180.0f * M_PI);
x[0] = -m_fWidth * co + m_fHeight * si; x[0] = -m_fWidth * co + m_fHeight * si;
y[0] = -m_fWidth * si - m_fHeight * co; y[0] = -m_fWidth * si - m_fHeight * co;
x[1] = m_fWidth * co + m_fHeight * si; x[1] = m_fWidth * co + m_fHeight * si;
Expand Down Expand Up @@ -602,14 +603,19 @@ void CSlideShowPic::SetTransistionTime(int iType, int iTime)
m_transistionEnd.length = iTime; m_transistionEnd.length = iTime;
} }


void CSlideShowPic::Rotate(int iRotate) void CSlideShowPic::Rotate(float fRotateAngle, bool immediate /* = false */)
{ {
if (m_bDrawNextImage) return ; if (m_bDrawNextImage) return;
if (m_transistionTemp.type == TRANSISTION_ZOOM) return ; if (m_transistionTemp.type == TRANSISTION_ZOOM) return;
if (immediate)
{
m_fAngle += fRotateAngle;
return;
}
m_transistionTemp.type = TRANSISTION_ROTATE; m_transistionTemp.type = TRANSISTION_ROTATE;
m_transistionTemp.start = m_iCounter; m_transistionTemp.start = m_iCounter;
m_transistionTemp.length = IMMEDIATE_TRANSISTION_TIME; m_transistionTemp.length = IMMEDIATE_TRANSISTION_TIME;
m_fTransistionAngle = (float)(iRotate - m_fAngle) / (float)m_transistionTemp.length; m_fTransistionAngle = (float)fRotateAngle / (float)m_transistionTemp.length;
// reset the timer // reset the timer
m_transistionEnd.start = m_iCounter + m_transistionStart.length + (int)(g_graphicsContext.GetFPS() * g_guiSettings.GetInt("slideshow.staytime")); m_transistionEnd.start = m_iCounter + m_transistionStart.length + (int)(g_graphicsContext.GetFPS() * g_guiSettings.GetInt("slideshow.staytime"));
} }
Expand Down
2 changes: 1 addition & 1 deletion xbmc/pictures/SlideShowPicture.h
Expand Up @@ -67,7 +67,7 @@ class CSlideShowPic
int SlideNumber() const { return m_iSlideNumber;}; int SlideNumber() const { return m_iSlideNumber;};


void Zoom(float fZoomAmount, bool immediate = false); void Zoom(float fZoomAmount, bool immediate = false);
void Rotate(int iRotateAmount); void Rotate(float fRotateAngle, bool immediate = false);
void Pause(bool bPause); void Pause(bool bPause);
void SetInSlideshow(bool slideshow); void SetInSlideshow(bool slideshow);
void SetOriginalSize(int iOriginalWidth, int iOriginalHeight, bool bFullSize); void SetOriginalSize(int iOriginalWidth, int iOriginalHeight, bool bFullSize);
Expand Down

0 comments on commit b6f611d

Please sign in to comment.