[guilib] fix labelcontrols with auto width always being marked as dirty if they speci...
[vuplus_xbmc] / xbmc / guilib / GUIRenderingControl.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "GUIRenderingControl.h"
22 #include "GUIUserMessages.h"
23 #include "threads/SingleLock.h"
24 #include "guilib/IRenderingCallback.h"
25 #include "windowing/WindowingFactory.h"
26
27 using namespace std;
28
29 #define LABEL_ROW1 10
30 #define LABEL_ROW2 11
31 #define LABEL_ROW3 12
32
33 CGUIRenderingControl::CGUIRenderingControl(int parentID, int controlID, float posX, float posY, float width, float height)
34     : CGUIControl(parentID, controlID, posX, posY, width, height)
35 {
36   ControlType = GUICONTROL_RENDERADDON;
37   m_callback = NULL;
38 }
39
40 CGUIRenderingControl::CGUIRenderingControl(const CGUIRenderingControl &from)
41 : CGUIControl(from)
42 {
43   ControlType = GUICONTROL_RENDERADDON;
44   m_callback = NULL;
45 }
46
47 bool CGUIRenderingControl::InitCallback(IRenderingCallback *callback)
48 {
49   if (!callback)
50     return false;
51
52   CSingleLock lock(m_rendering);
53   g_graphicsContext.CaptureStateBlock();
54   float x = g_graphicsContext.ScaleFinalXCoord(GetXPosition(), GetYPosition());
55   float y = g_graphicsContext.ScaleFinalYCoord(GetXPosition(), GetYPosition());
56   float w = g_graphicsContext.ScaleFinalXCoord(GetXPosition() + GetWidth(), GetYPosition() + GetHeight()) - x;
57   float h = g_graphicsContext.ScaleFinalYCoord(GetXPosition() + GetWidth(), GetYPosition() + GetHeight()) - y;
58   if (x < 0) x = 0;
59   if (y < 0) y = 0;
60   if (x + w > g_graphicsContext.GetWidth()) w = g_graphicsContext.GetWidth() - x;
61   if (y + h > g_graphicsContext.GetHeight()) h = g_graphicsContext.GetHeight() - y;
62
63   void *device = NULL;
64 #if HAS_DX
65   device = g_Windowing.Get3DDevice();
66 #endif
67   if (callback->Create((int)(x+0.5f), (int)(y+0.5f), (int)(w+0.5f), (int)(h+0.5f), device))
68     m_callback = callback;
69   else
70     return false;
71
72   g_graphicsContext.ApplyStateBlock();
73   return true;
74 }
75
76 void CGUIRenderingControl::UpdateVisibility(const CGUIListItem *item)
77 {
78   // if made invisible, start timer, only free addonptr after
79   // some period, configurable by window class
80   CGUIControl::UpdateVisibility(item);
81   if (!IsVisible() && m_callback)
82     FreeResources();
83 }
84
85 void CGUIRenderingControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
86 {
87   // TODO Add processing to the addon so it could mark when actually changing
88   CSingleLock lock(m_rendering);
89   if (m_callback && m_callback->IsDirty())
90     MarkDirtyRegion();
91
92   CGUIControl::Process(currentTime, dirtyregions);
93 }
94
95 void CGUIRenderingControl::Render()
96 {
97   CSingleLock lock(m_rendering);
98   if (m_callback)
99   {
100     // set the viewport - note: We currently don't have any control over how
101     // the addon renders, so the best we can do is attempt to define
102     // a viewport??
103     g_graphicsContext.SetViewPort(m_posX, m_posY, m_width, m_height);
104     g_graphicsContext.CaptureStateBlock();
105     m_callback->Render();
106     g_graphicsContext.ApplyStateBlock();
107     g_graphicsContext.RestoreViewPort();
108   }
109
110   CGUIControl::Render();
111 }
112
113 void CGUIRenderingControl::FreeResources(bool immediately)
114 {
115   CSingleLock lock(m_rendering);
116
117   if (!m_callback) return;
118
119   g_graphicsContext.CaptureStateBlock(); //TODO locking
120   m_callback->Stop();
121   g_graphicsContext.ApplyStateBlock();
122   m_callback = NULL;
123 }
124
125 bool CGUIRenderingControl::CanFocusFromPoint(const CPoint &point) const
126 { // mouse is allowed to focus this control, but it doesn't actually receive focus
127   return IsVisible() && HitTest(point);
128 }