[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
[XaraXtreme-commits] Commit Complete
Commit by : alex
Repository : xara
Revision : 1090
Date : Tue May 16 21:02:23 BST 2006
Changed paths:
M /Trunk/XaraLX/Kernel/app.cpp
M /Trunk/XaraLX/Kernel/statline.cpp
M /Trunk/XaraLX/Kernel/statline.h
Fixed some statusline problems
Diff:
Index: Trunk/XaraLX/Kernel/app.cpp
===================================================================
--- Trunk/XaraLX/Kernel/app.cpp (revision 1089)
+++ Trunk/XaraLX/Kernel/app.cpp (revision 1090)
@@ -1486,12 +1486,6 @@
// ControlList::Idle();
- StatusLine* pStatusLine=GetpStatusLine();
- if (pStatusLine!=NULL)
- pStatusLine->OnIdle();
-// else
-// ERROR3("Application::OnIdle() - pStatusLine==NULL");
-
// Idles=TRUE;
return Idles;
Index: Trunk/XaraLX/Kernel/statline.h
===================================================================
--- Trunk/XaraLX/Kernel/statline.h (revision 1089)
+++ Trunk/XaraLX/Kernel/statline.h (revision 1090)
@@ -107,6 +107,7 @@
#include "monotime.h"
#include "stdbars.h"
//#include "ed.h"
+#include "ktimer.h"
class Spread;
class StringBase;
@@ -138,8 +139,8 @@
public:
StatusLine();
~StatusLine();
+
MsgResult Message(Msg* Msg);
- BOOL OnIdle();
BOOL UpdateText(String_256* ptext, BOOL PrefixSelDesc=TRUE);
BOOL UpdateTextForColourPicker(String_256* ptext, BOOL PrefixSelDesc=TRUE);
BOOL UpdateMousePosAndSnap(DocCoord* pDocCoord, Spread* pSpread, DocView* pDocView, BOOL Snapped);
@@ -166,7 +167,10 @@
BOOL UnlockControlHelp () { DoControlHelp = TRUE; return (TRUE); }
BOOL AllowControlHelp () { return (DoControlHelp); }
+ void SetNeedsUpdate(BOOL Immediate=FALSE);
+
protected:
+ BOOL OnIdleEvent();
BOOL SetMousePosPaneWidth(Spread* pSpread);
BOOL RefreshHelpText();
@@ -213,8 +217,24 @@
BOOL ProgressShown;
String_256 StatusText;
BOOL SetStatusText(const String_256 &text);
+ String_256 m_MousePosText;
- CC_DECLARE_DYNCREATE(StatusLine);
+ void OnTimer()
+ {
+ ::wxWakeUpIdle(); // a bodge to ensure the idle handler is awake
+ }
+
+ class StatusTimer : public KernelTimer
+ {
+ public:
+ StatusTimer(StatusLine * pOwner) : m_pOwner(pOwner) {}
+ virtual void Notify() {m_pOwner->OnTimer();}
+ StatusLine * m_pOwner;
+ };
+
+ StatusTimer m_Timer;
+
+ CC_DECLARE_DYNCREATE(StatusLine);
};
#endif // INC_STATUSLINE
Index: Trunk/XaraLX/Kernel/statline.cpp
===================================================================
--- Trunk/XaraLX/Kernel/statline.cpp (revision 1089)
+++ Trunk/XaraLX/Kernel/statline.cpp (revision 1090)
@@ -151,6 +151,50 @@
// render pane animation (could be in statline.cpp but kept here next to pane defn)
static UINT32 RenderAnimation[] = { _R(IDB_SL_REND1), _R(IDB_SL_REND2), _R(IDB_SL_REND3) };
+/*
+
+Timer mechanism and the status line
+===================================
+
+Working out the status line text is actually reasonably expensive, especially
+given some of the arcane lengths we go to to get it. Painting it is
+even more expensive. And doing an Update() on it to ensure it paints
+immediately yet more so. The thing this interferes with the most is
+typing in the text tool.
+
+So we use the following algortithm:
+
+We set a timer to go off every 250ms. This is the idle timer. A little
+confusingly it is a one-shot timer, but bear with me.
+
+If something happens that requires a status line update (or is likely
+to) it calls StatusLine::NeedsUpdate(). By default what this does is
+reset the timer (so it won't go off for another 250ms). However
+it is possible to force an 'immediate' update (actually on the
+next idle event) by calling NeedsUpdate(TRUE) which simulates
+an immediate timer expiry.
+
+When the timer expires (whether or not NeedsUpdate() has been called),
+it signals to the idle event handler for the DialogOp at the lowest
+possible priority. This ensures all rendering etc. will have finished.
+
+When the idle event is received, it checks to see if NeedsUpdate()
+has been called in the interim (i.e. if the timer is running). If
+the timer is running, the idle event handler returns saying it wants
+no more idles. If not, it attempts to process the status line text.
+
+If the status line text has changed, it sets the new text (immediately)
+but only invalidates it (i.e. does not do an update).
+
+Whether or not the text changed, it then sets the timer off again
+by calling NeedsUpdate().
+
+
+*/
+
+
+
+
/*****************************************************************************
> StatusLine::StatusLine()
@@ -159,7 +203,7 @@
Purpose: Constructor for StatusLine
*****************************************************************************/
-StatusLine::StatusLine()
+StatusLine::StatusLine() : m_Timer(this)
{
// ensure initial updates
OldMemory=0;
@@ -178,6 +222,8 @@
JobDescription=NULL;
CurrentPercent=-1;
ProgressShown=FALSE;
+
+ GetApplication()->RegisterIdleProcessor(IDLEPRIORITY_LOW, this);
}
@@ -202,11 +248,13 @@
// are temporarily created when invoking bar closure
s_pStatusLine = NULL;
}
+
+ GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_LOW, this);
}
/*****************************************************************************
-> BOOL StatusLine::OnIdle()
+> BOOL StatusLine::OnIdleEvent()
Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xxxxxxxx>
Created: 15/11/94
@@ -214,80 +262,102 @@
Updates the text on the status bar if 'TextDelay'
has elapsed since it was last changed.
Also updates the mouse position pane
- Returns: FALSE if anything fails (see Errors)
- HOWEVER, the function will try to proceed
- to keep the status line as tidy as possible
- Errors: pCCStatusBar==NULL,
- RefreshHelpText() fails,
- UpdateMousePos() fails,
- pCCStatusBar->UpdatePaneText() fails,
+ Returns: FALSE (to indicate we want no more idle events)
+ The wakeup from the timer will create one for us
+ Errors: -
+
+
*****************************************************************************/
-BOOL StatusLine::OnIdle()
+BOOL StatusLine::OnIdleEvent()
{
- // If the current doc doesn't have a doc view (e.g. it's a clipboard doc), then there's no point
- // carrying on, because it's not a proper document, hence doen't require up-to-date status bar info.
- if (DocView::GetSelected() == NULL)
- return TRUE;
+ // Don't do any status line updates if the timer is running
+ if (!m_Timer.IsRunning())
+ {
- BOOL ReturnValue=TRUE; // set to FALSE if any section of code fails
-
+ // If the current doc doesn't have a doc view (e.g. it's a clipboard doc), then there's no point
+ // carrying on, because it's not a proper document, hence doen't require up-to-date status bar info.
+ if (DocView::GetSelected() == NULL)
+ return FALSE;
+
+
#ifndef STANDALONE
- // if mouse position pane needs resizing, do it (ensuring it's enabled)
- if (MousePosPaneNeedsResizing)
- {
- MousePosPaneNeedsResizing=FALSE;
- Spread* pSpread=Document::GetSelectedSpread();
- if (pSpread)
+ // if mouse position pane needs resizing, do it (ensuring it's enabled)
+ if (MousePosPaneNeedsResizing)
{
- if (!SetMousePosPaneWidth(pSpread))
- ReturnValue=FALSE;
+ MousePosPaneNeedsResizing=FALSE;
+ Spread* pSpread=Document::GetSelectedSpread();
+ if (pSpread)
+ {
+ SetMousePosPaneWidth(pSpread);
PORTNOTE("StatusLine", "Removed use of CCStatusBar")
#ifndef EXCLUDE_FROM_XARALX
- if (pCCStatusBar->PaneState(_R(IDS_SL_MOUSEPOS),Enable)==Fail)
- ReturnValue=FALSE;
+ if (pCCStatusBar->PaneState(_R(IDS_SL_MOUSEPOS),Enable)==Fail)
+ ReturnValue=FALSE;
#endif
+ }
}
- }
#endif
- // if sufficient time elapsed since status line last changed, refresh it
- if (TextTimer.Elapsed(TextDelay,TRUE))
- if (RefreshHelpText()==FALSE)
- ReturnValue=FALSE;
+ RefreshHelpText();
#ifdef _STATUSLINE_MEMORYPANE
- // establish if amount of memory changed BODGE
- MEMORYSTATUS MemState;
- MemState.dwLength=sizeof(MEMORYSTATUS);
- GlobalMemoryStatus(&MemState);
- INT32 Memory=MemState.dwAvailPhys;
- BOOL MemoryChanged=(OldMemory!=Memory);
- OldMemory=Memory;
+ // establish if amount of memory changed BODGE
+ MEMORYSTATUS MemState;
+ MemState.dwLength=sizeof(MEMORYSTATUS);
+ GlobalMemoryStatus(&MemState);
+ INT32 Memory=MemState.dwAvailPhys;
+ BOOL MemoryChanged=(OldMemory!=Memory);
+ OldMemory=Memory;
+
+ if (MemoryChanged)
+ {
+ // If this ever appears in retail builds it will have to be rewritten properly (it
+ // isn't internationally portable at the moment).
+ String_256 StrBuf(TEXT(""));
+ camSnprintf(StrBuf, 256, TEXT("%dK"), Memory / 1024);
+ if (StrBuf.Length()>4)
+ StrBuf.Insert(&String_8(TEXT(",")),StrBuf.Length()-4);
+ BOOL ok = SetStringGadgetValue(_R(IDS_SL_MEMORY),StrBuf);
+ if (ok)
+ PaintGadgetNow(_R(IDS_SL_MEMORY))
+ else
+ ReturnValue=FALSE;
+ }
+#endif // _STATUSLINE_MEMORYPANE
- if (MemoryChanged)
+ // The timer had expired, so we need to indicate we need another update
+ SetNeedsUpdate();
+ }
+
+ // Always say we don't need more idle events
+ return FALSE;
+}
+
+/*****************************************************************************
+> void StatusLine::SetNeedsUpdate(BOOL Immediate = FALSE);
+
+ Author: Alex Bligh <alex@xxxxxxxxxxx>
+ Created: 16/5/2005
+ Purpose: Indicate the status line needs an update
+ Returns: -
+ Errors: -
+
+*****************************************************************************/
+
+void StatusLine::SetNeedsUpdate(BOOL Immediate /*=FALSE*/)
+{
+ if (Immediate)
{
- // If this ever appears in retail builds it will have to be rewritten properly (it
- // isn't internationally portable at the moment).
- String_256 StrBuf(TEXT(""));
- camSnprintf(StrBuf, 256, TEXT("%dK"), Memory / 1024);
- if (StrBuf.Length()>4)
- StrBuf.Insert(&String_8(TEXT(",")),StrBuf.Length()-4);
- BOOL ok = SetStringGadgetValue(_R(IDS_SL_MEMORY),StrBuf);
- if (ok)
- PaintGadgetNow(_R(IDS_SL_MEMORY))
- else
- ReturnValue=FALSE;
+ // Simulate a timer event
+ m_Timer.Stop();
+ OnTimer();
+ return;
}
-#endif // _STATUSLINE_MEMORYPANE
-// We don't need to know that the status line failed to update normally.
-// ENSURE(ReturnValue==TRUE, "StatusLine::OnIdle() failed!");
-
- return TRUE;
+ m_Timer.Start(1000, TRUE);
}
-
/*****************************************************************************
> BOOL StatusLine::RefreshHelpText()
@@ -320,9 +390,11 @@
}
if (!TextValid)
+ {
TextValid=BaseBar::GetStatusLineText(&text); // try bar drag
- if (TextValid)
- PrefixSelDesc=STATUSLINE_SELDESC_BARDRAG;
+ if (TextValid)
+ PrefixSelDesc=STATUSLINE_SELDESC_BARDRAG;
+ }
WinCoord WndPos(0,0);
CWindowID WinID=DialogManager::GetWindowUnderPointer(&WndPos);
@@ -357,7 +429,7 @@
// drag op in progress so we must have valid text (stops tool being interogated)
if (!TextValid)
{
- text="";
+ text=_T("");
TextValid=TRUE;
}
}
@@ -372,11 +444,14 @@
if (pDocView==DocView::GetSelected())
{
OverSelectedDoc=TRUE;
- PrefixSelDesc=STATUSLINE_SELDESC_SELDOC;
Tool* pTool=Tool::GetCurrent();
ERROR3IF(pTool==NULL,"StatusLine::RefreshHelpText() - no selected tool");
if (pTool)
+ {
TextValid=pTool->GetStatusLineText(&text,pSpread,DocPos,ClickModifiers::GetClickModifiers());
+ if (TextValid)
+ PrefixSelDesc=STATUSLINE_SELDESC_SELDOC;
+ }
else
ReturnValue=FALSE;
}
@@ -385,100 +460,115 @@
TextValid=text.Load(_R(IDS_CLICKHERETOSELECTDOC)); // over unselected doc
if (!TextValid)
ReturnValue=FALSE;
- PrefixSelDesc=STATUSLINE_SELDESC_OTHERDOC;
+ else
+ PrefixSelDesc=STATUSLINE_SELDESC_OTHERDOC;
}
}
- else
- {
+
PORTNOTE("statline", "Removed use of ControlHelper")
#if !defined(EXCLUDE_FROM_XARALX)
+ if (!TextValid)
+ {
TextValid=ControlHelper::GetStatusLineText(&text,WinID); // try buttons/bars
if (TextValid)
PrefixSelDesc=STATUSLINE_SELDESC_BUTTONS;
+ }
#endif
+
+ if (!TextValid)
+ {
TextValid=DialogManager::GetStatusLineText(&text,NULL);
if (TextValid)
PrefixSelDesc=STATUSLINE_SELDESC_BUTTONS;
+ }
#ifndef STANDALONE
- if (!TextValid)
- TextValid=CColourBar::GetStatusLineText(&text); // try ColourBar
+ if (!TextValid)
+ {
+ TextValid=CColourBar::GetStatusLineText(&text); // try ColourBar
if (TextValid)
PrefixSelDesc=STATUSLINE_SELDESC_COLBAR;
+ }
PORTNOTE("StatusLine", "Removed use of ColourPicker")
#ifndef EXCLUDE_FROM_XARALX
- if (!TextValid)
- TextValid=ColourPicker::GetStatusLineText(&text); // try Colour Editor
-#endif
+ if (!TextValid)
+ {
+ TextValid=ColourPicker::GetStatusLineText(&text); // try Colour Editor
if (TextValid)
PrefixSelDesc=STATUSLINE_SELDESC_COLBAR;
+ }
#endif
+#endif //STANDALONE
+
PORTNOTE("StatusLine", "Removed use of PreviewDlg")
#ifndef EXCLUDE_FROM_XARALX
- if (!TextValid)
- TextValid=PreviewDialog::GetStatusLineText(&text); // try Preview Dialog
-#endif
+ if (!TextValid)
+ {
+ TextValid=PreviewDialog::GetStatusLineText(&text); // try Preview Dialog
if (TextValid)
PrefixSelDesc=STATUSLINE_SELDESC_PREVIEWDLG;
+ }
+#endif
// WEBSTER - markn 15/1/97
// No rulers in webster
PORTNOTE("StatusLine", "Removed use of Rulers")
#ifndef EXCLUDE_FROM_XARALX
#ifndef WEBSTER
- if (!TextValid)
- {
- DocView* pDocView = DocView::GetSelected();
- RulerPair* pRulerPair = NULL;
- if (pDocView!=NULL)
- pRulerPair = pDocView->GetpRulerPair();
- if (pRulerPair!=NULL)
- TextValid = pRulerPair->GetStatusLineText(&text,WndPos,WinID); // try Rulers
- }
+ if (!TextValid)
+ {
+ DocView* pDocView = DocView::GetSelected();
+ RulerPair* pRulerPair = NULL;
+ if (pDocView!=NULL)
+ pRulerPair = pDocView->GetpRulerPair();
+ if (pRulerPair!=NULL)
+ TextValid = pRulerPair->GetStatusLineText(&text,WndPos,WinID); // try Rulers
+ if (TextValid)
+ PrefixSelDesc=STATUSLINE_SELDESC_STATBAR;
+ }
#endif // WEBSTER
#endif
- if (TextValid)
- PrefixSelDesc=STATUSLINE_SELDESC_STATBAR;
PORTNOTE("StatusLine", "Removed use of Galleries")
#ifndef EXCLUDE_FROM_XARALX
#ifndef EXCLUDE_GALS
- if (!TextValid && WinID!=NULL)
+ if (!TextValid && WinID!=NULL)
+ {
+ // Lets try the Galleries ....
+ // ** This uses Naughty Oily stuff. (Bodge for the Viewer).
+ CWindowID ParentWnd = ::GetParent(WinID);
+ if (ParentWnd != NULL)
{
- // Lets try the Galleries ....
- // ** This uses Naughty Oily stuff. (Bodge for the Viewer).
- CWindowID ParentWnd = ::GetParent(WinID);
- if (ParentWnd != NULL)
+ DialogBarOp* pBar = DialogBarOp::FindDialogBarOp((UINT32)ParentWnd);
+ if (pBar != NULL && pBar->IS_KIND_OF(SuperGallery))
{
- DialogBarOp* pBar = DialogBarOp::FindDialogBarOp((UINT32)ParentWnd);
- if (pBar != NULL && pBar->IS_KIND_OF(SuperGallery))
- {
- CRect TargetRect;
- ::GetWindowRect(WinID, &TargetRect);
+ CRect TargetRect;
+ ::GetWindowRect(WinID, &TargetRect);
- // Get the screen DPI
- INT32 DPI = 96;
- HDC ScreenDC = CreateCompatibleDC(NULL);
- if (ScreenDC == NULL)
- ERROR2(FALSE, "Unable to create screen DC");
- DPI = GetDeviceCaps(ScreenDC, LOGPIXELSY);
- DeleteDC(ScreenDC);
+ // Get the screen DPI
+ INT32 DPI = 96;
+ HDC ScreenDC = CreateCompatibleDC(NULL);
+ if (ScreenDC == NULL)
+ ERROR2(FALSE, "Unable to create screen DC");
+ DPI = GetDeviceCaps(ScreenDC, LOGPIXELSY);
+ DeleteDC(ScreenDC);
- INT32 WindowHeight = TargetRect.Height();
+ INT32 WindowHeight = TargetRect.Height();
- DocCoord KernelMousePos;
- KernelMousePos.x = ((WndPos.x) * 72000) / DPI;
- KernelMousePos.y = ((WindowHeight - WndPos.y) * 72000) / DPI;
+ DocCoord KernelMousePos;
+ KernelMousePos.x = ((WndPos.x) * 72000) / DPI;
+ KernelMousePos.y = ((WindowHeight - WndPos.y) * 72000) / DPI;
- TextValid = ((SuperGallery*)pBar)->GetStatusLineHelp(&KernelMousePos, &text);
- }
+ TextValid = ((SuperGallery*)pBar)->GetStatusLineHelp(&KernelMousePos, &text);
+ if (TextValid)
+ PrefixSelDesc=STATUSLINE_SELDESC_STATBAR;
}
}
+ }
#endif
#endif
- }
#ifndef STANDALONE
// blank mouse pos if not over selected doc
@@ -1102,9 +1192,15 @@
String_256 MousePosText("");
if (!Blank && GetMousePosText(&MousePosText,*pDocCoord,pSpread)==FALSE)
ReturnValue=FALSE;
- ReturnValue &=SetStringGadgetValue(_R(IDC_SL_MOUSEPOS), MousePosText);
-// PaintGadgetNow(_R(IDC_SL_MOUSEPOS)); - is there any need to paint this now? Flushes gtk buffer etc. Not a great idea.
+ if (MousePosText != m_MousePosText)
+ {
+ m_MousePosText= MousePosText;
+
+ ReturnValue &=SetStringGadgetValue(_R(IDC_SL_MOUSEPOS), MousePosText);
+ // PaintGadgetNow(_R(IDC_SL_MOUSEPOS)); - is there any need to paint this now? Flushes gtk buffer etc. Not a great idea.
+ }
+
// WEBSTER - markn 15/1/97
// No rulers in Webster
PORTNOTE("StatusLine", "Removed use of Rulers")
@@ -1266,7 +1362,7 @@
if (BitmapID == GetGadgetBitmap(_R(IDB_SL_RENDN)))
return TRUE;
SetGadgetBitmap(_R(IDB_SL_RENDN), BitmapID);
- PaintGadgetNow(_R(IDB_SL_RENDN));
+ //PaintGadgetNow(_R(IDB_SL_RENDN));
return TRUE;
}
@@ -1413,12 +1509,17 @@
BOOL StatusLine::SetStatusText(const String_256 &text)
{
+ SetNeedsUpdate(); // Don't allow another update on idles for 250ms
+
+ if (StatusText == text)
+ return TRUE;
+
StatusText = text;
if (!ProgressShown)
{
- StatusText = text;
+ TRACEUSER("amb", _T("updating status text"));
BOOL ok=SetStringGadgetValue(_R(IDC_SL_STATUSTEXT), text);
- PaintGadgetNow(_R(IDC_SL_STATUSTEXT));
+// PaintGadgetNow(_R(IDC_SL_STATUSTEXT));
return ok;
}
return TRUE;
Xara