Browse Source

Fixed a couple of messaging problems on the mac; reduced the number of messages used by timers; improved ProgressBar performance; fixed a bug in ThreadWithProgressWindow; added tooltips to TreeView items; slightly tweaked the look of tooltips and improved their behaviour; stopped tab keystrokes being consumed unless they're needed; fixed a small bug in ZipFile.

tags/2021-05-28
jules 16 years ago
parent
commit
ec0557e7b6
16 changed files with 1716 additions and 1635 deletions
  1. +7
    -4
      build/macosx/platform_specific_code/juce_mac_MessageManager.mm
  2. +1435
    -1435
      extras/juce demo/src/demos/WidgetsDemo.cpp
  3. +129
    -96
      juce_amalgamated.cpp
  4. +10
    -3
      juce_amalgamated.h
  5. +1
    -1
      src/juce_appframework/events/juce_MessageManager.cpp
  6. +0
    -1
      src/juce_appframework/events/juce_Timer.cpp
  7. +9
    -3
      src/juce_appframework/gui/components/controls/juce_ProgressBar.cpp
  8. +1
    -0
      src/juce_appframework/gui/components/controls/juce_ProgressBar.h
  9. +21
    -1
      src/juce_appframework/gui/components/controls/juce_TreeView.cpp
  10. +5
    -0
      src/juce_appframework/gui/components/controls/juce_TreeView.h
  11. +6
    -6
      src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp
  12. +4
    -5
      src/juce_appframework/gui/components/windows/juce_ComponentPeer.cpp
  13. +6
    -8
      src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp
  14. +77
    -68
      src/juce_appframework/gui/components/windows/juce_TooltipWindow.cpp
  15. +4
    -3
      src/juce_appframework/gui/components/windows/juce_TooltipWindow.h
  16. +1
    -1
      src/juce_core/misc/juce_ZipFile.cpp

+ 7
- 4
build/macosx/platform_specific_code/juce_mac_MessageManager.mm View File

@@ -254,12 +254,15 @@ static JuceAppDelegate* juceAppDelegate = 0;
void MessageManager::runDispatchLoop() void MessageManager::runDispatchLoop()
{ {
const ScopedAutoReleasePool pool;
if (! quitMessagePosted) // check that the quit message wasn't already posted..
{
const ScopedAutoReleasePool pool;
// must only be called by the message thread!
jassert (isThisTheMessageThread());
// must only be called by the message thread!
jassert (isThisTheMessageThread());
[NSApp run];
[NSApp run];
}
} }
void MessageManager::stopDispatchLoop() void MessageManager::stopDispatchLoop()


+ 1435
- 1435
extras/juce demo/src/demos/WidgetsDemo.cpp
File diff suppressed because it is too large
View File


+ 129
- 96
juce_amalgamated.cpp View File

@@ -8636,7 +8636,7 @@ public:


bool isExhausted() throw() bool isExhausted() throw()
{ {
return pos >= zipEntryInfo.compressedSize;
return headerSize <= 0 || pos >= zipEntryInfo.compressedSize;
} }


int64 getPosition() throw() int64 getPosition() throw()
@@ -37043,7 +37043,7 @@ void MessageManagerLock::init (Thread* const threadToCheck, ThreadPoolJob* const
{ {
if (MessageManager::instance->currentThreadHasLockedMessageManager()) if (MessageManager::instance->currentThreadHasLockedMessageManager())
{ {
locked = true; // either we're on the message thread, or this it's a re-entrant call.
locked = true; // either we're on the message thread, or this is a re-entrant call.
} }
else else
{ {
@@ -37422,7 +37422,6 @@ public:
addTimer (t); addTimer (t);


const ScopedUnlock ul (lock); const ScopedUnlock ul (lock);
callbackNeeded = false;


JUCE_TRY JUCE_TRY
{ {
@@ -44946,7 +44945,8 @@ BEGIN_JUCE_NAMESPACE


ProgressBar::ProgressBar (double& progress_) ProgressBar::ProgressBar (double& progress_)
: progress (progress_), : progress (progress_),
displayPercentage (true)
displayPercentage (true),
lastCallbackTime (0)
{ {
currentValue = jlimit (0.0, 1.0, progress); currentValue = jlimit (0.0, 1.0, progress);
} }
@@ -45014,9 +45014,14 @@ void ProgressBar::timerCallback()
{ {
if (currentValue < newProgress if (currentValue < newProgress
&& newProgress >= 0 && newProgress < 1.0 && newProgress >= 0 && newProgress < 1.0
&& currentValue >= 0 && newProgress < 1.0)
&& currentValue >= 0 && currentValue < 1.0)
{ {
newProgress = jmin (currentValue + 0.02, newProgress);
const uint32 now = Time::getMillisecondCounter();
const int timeSinceLastCallback = (int) (now - lastCallbackTime);
lastCallbackTime = now;

newProgress = jmin (currentValue + 0.00018 * timeSinceLastCallback,
newProgress);
} }


currentValue = newProgress; currentValue = newProgress;
@@ -51606,7 +51611,8 @@ END_JUCE_NAMESPACE


BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE


class TreeViewContentComponent : public Component
class TreeViewContentComponent : public Component,
public TooltipClient
{ {
public: public:
TreeViewContentComponent (TreeView* const owner_) TreeViewContentComponent (TreeView* const owner_)
@@ -51868,6 +51874,20 @@ public:
owner->itemsChanged(); owner->itemsChanged();
} }


const String getTooltip()
{
int x, y;
getMouseXYRelative (x, y);
Rectangle pos;

TreeViewItem* const item = findItemAt (y, pos);

if (item != 0)
return item->getTooltip();

return owner->getTooltip();
}

juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator


private: private:
@@ -52533,6 +52553,11 @@ void TreeViewItem::itemSelectionChanged (bool)
{ {
} }


const String TreeViewItem::getTooltip()
{
return String::empty;
}

const String TreeViewItem::getDragSourceDescription() const String TreeViewItem::getDragSourceDescription()
{ {
return String::empty; return String::empty;
@@ -60487,10 +60512,8 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title,
aw->addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut); aw->addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut);
aw->addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut); aw->addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut);
} }
else
else if (numButtons == 3)
{ {
jassert (numButtons == 3);

aw->addButton (button1, 1, button1ShortCut); aw->addButton (button1, 1, button1ShortCut);
aw->addButton (button2, 2, button2ShortCut); aw->addButton (button2, 2, button2ShortCut);
aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0));
@@ -61571,7 +61594,7 @@ ImageEffectFilter* LookAndFeel::getSliderEffect()


static const TextLayout layoutTooltipText (const String& text) throw() static const TextLayout layoutTooltipText (const String& text) throw()
{ {
const float tooltipFontSize = 15.0f;
const float tooltipFontSize = 12.0f;
const int maxToolTipWidth = 400; const int maxToolTipWidth = 400;


const Font f (tooltipFontSize, Font::bold); const Font f (tooltipFontSize, Font::bold);
@@ -61586,7 +61609,7 @@ void LookAndFeel::getTooltipSize (const String& tipText, int& width, int& height
const TextLayout tl (layoutTooltipText (tipText)); const TextLayout tl (layoutTooltipText (tipText));


width = tl.getWidth() + 14; width = tl.getWidth() + 14;
height = tl.getHeight() + 10;
height = tl.getHeight() + 6;
} }


void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int height) void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int height)
@@ -61595,8 +61618,10 @@ void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int h


const Colour textCol (findColour (TooltipWindow::textColourId)); const Colour textCol (findColour (TooltipWindow::textColourId));


#if ! JUCE_MAC // The mac windows already have a non-optional 1 pix outline, so don't double it here..
g.setColour (findColour (TooltipWindow::outlineColourId)); g.setColour (findColour (TooltipWindow::outlineColourId));
g.drawRect (0, 0, width, height);
g.drawRect (0, 0, width, height, 1);
#endif


const TextLayout tl (layoutTooltipText (text)); const TextLayout tl (layoutTooltipText (text));


@@ -72476,10 +72501,9 @@ bool ComponentPeer::handleKeyPress (const int keyCode,


if (keyInfo.isKeyCode (KeyPress::tabKey) && Component::getCurrentlyFocusedComponent() != 0) if (keyInfo.isKeyCode (KeyPress::tabKey) && Component::getCurrentlyFocusedComponent() != 0)
{ {
Component::getCurrentlyFocusedComponent()
->moveKeyboardFocusToSibling (! keyInfo.getModifiers().isShiftDown());

keyWasUsed = true;
Component* const currentlyFocused = Component::getCurrentlyFocusedComponent();
currentlyFocused->moveKeyboardFocusToSibling (! keyInfo.getModifiers().isShiftDown());
keyWasUsed = (currentlyFocused != Component::getCurrentlyFocusedComponent());
break; break;
} }


@@ -73869,14 +73893,12 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title,
timeOutMsWhenCancelling (timeOutMsWhenCancelling_) timeOutMsWhenCancelling (timeOutMsWhenCancelling_)
{ {
alertWindow = LookAndFeel::getDefaultLookAndFeel() alertWindow = LookAndFeel::getDefaultLookAndFeel()
.createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty,
AlertWindow::NoIcon, 1, 0);
.createAlertWindow (title, String::empty, cancelButtonText,
String::empty, String::empty,
AlertWindow::NoIcon, hasCancelButton ? 1 : 0, 0);


if (hasProgressBar) if (hasProgressBar)
alertWindow->addProgressBarComponent (progress); alertWindow->addProgressBarComponent (progress);

if (hasCancelButton)
alertWindow->addButton (cancelButtonText, 1);
} }


ThreadWithProgressWindow::~ThreadWithProgressWindow() ThreadWithProgressWindow::~ThreadWithProgressWindow()
@@ -73895,13 +73917,13 @@ bool ThreadWithProgressWindow::runThread (const int priority)
alertWindow->setMessage (message); alertWindow->setMessage (message);
} }


const bool wasCancelled = alertWindow->runModalLoop() != 0;
const bool finishedNaturally = alertWindow->runModalLoop() != 0;


stopThread (timeOutMsWhenCancelling); stopThread (timeOutMsWhenCancelling);


alertWindow->setVisible (false); alertWindow->setVisible (false);


return ! wasCancelled;
return finishedNaturally;
} }


void ThreadWithProgressWindow::setProgress (const double newProgress) void ThreadWithProgressWindow::setProgress (const double newProgress)
@@ -73920,7 +73942,7 @@ void ThreadWithProgressWindow::timerCallback()
if (! isThreadRunning()) if (! isThreadRunning())
{ {
// thread has finished normally.. // thread has finished normally..
alertWindow->exitModalState (0);
alertWindow->exitModalState (1);
alertWindow->setVisible (false); alertWindow->setVisible (false);
} }
else else
@@ -73943,7 +73965,6 @@ TooltipWindow::TooltipWindow (Component* const parentComponent,
millisecondsBeforeTipAppears (millisecondsBeforeTipAppears_), millisecondsBeforeTipAppears (millisecondsBeforeTipAppears_),
mouseX (0), mouseX (0),
mouseY (0), mouseY (0),
lastMouseMoveTime (0),
lastHideTime (0), lastHideTime (0),
lastComponentUnderMouse (0), lastComponentUnderMouse (0),
changedCompsSinceShown (true) changedCompsSinceShown (true)
@@ -73964,7 +73985,7 @@ TooltipWindow::~TooltipWindow()


void TooltipWindow::paint (Graphics& g) void TooltipWindow::paint (Graphics& g)
{ {
getLookAndFeel().drawTooltip (g, tip, getWidth(), getHeight());
getLookAndFeel().drawTooltip (g, tipShowing, getWidth(), getHeight());
} }


void TooltipWindow::mouseEnter (const MouseEvent&) void TooltipWindow::mouseEnter (const MouseEvent&)
@@ -73972,104 +73993,113 @@ void TooltipWindow::mouseEnter (const MouseEvent&)
hide(); hide();
} }


void TooltipWindow::showFor (Component* const c)
void TooltipWindow::showFor (Component* const c, const String& tip)
{ {
TooltipClient* const ttc = dynamic_cast <TooltipClient*> (c);
jassert (tip.isNotEmpty());
tipShowing = tip;


if (ttc != 0 && ! c->isCurrentlyBlockedByAnotherModalComponent())
tip = ttc->getTooltip();
else
tip = String::empty;
int mx, my;
Desktop::getMousePosition (mx, my);


if (tip.isEmpty())
{
hide();
}
else
{
int mx, my;
Desktop::getMousePosition (mx, my);
if (getParentComponent() != 0)
getParentComponent()->globalPositionToRelative (mx, my);


if (getParentComponent() != 0)
getParentComponent()->globalPositionToRelative (mx, my);
int x, y, w, h;
getLookAndFeel().getTooltipSize (tip, w, h);


int x, y, w, h;
getLookAndFeel().getTooltipSize (tip, w, h);
if (mx > getParentWidth() / 2)
x = mx - (w + 12);
else
x = mx + 24;


if (mx > getParentWidth() / 2)
x = mx - (w + 12);
else
x = mx + 24;
if (my > getParentHeight() / 2)
y = my - (h + 6);
else
y = my + 6;


if (my > getParentHeight() / 2)
y = my - (h + 6);
else
y = my + 6;
setBounds (x, y, w, h);
setVisible (true);


setBounds (x, y, w, h);
setVisible (true);
if (getParentComponent() == 0)
{
addToDesktop (ComponentPeer::windowHasDropShadow
| ComponentPeer::windowIsTemporary);
}


if (getParentComponent() == 0)
{
addToDesktop (ComponentPeer::windowHasDropShadow
| ComponentPeer::windowIsTemporary);
}
toFront (false);
}


toFront (false);
const String TooltipWindow::getTipFor (Component* const c)
{
if (c->isValidComponent() && Process::isForegroundProcess())
{
TooltipClient* const ttc = dynamic_cast <TooltipClient*> (c);

if (ttc != 0 && ! c->isCurrentlyBlockedByAnotherModalComponent())
return ttc->getTooltip();
} }

return String::empty;
} }


void TooltipWindow::hide() void TooltipWindow::hide()
{ {
tipShowing = String::empty;
removeFromDesktop(); removeFromDesktop();
setVisible (false); setVisible (false);
} }


void TooltipWindow::timerCallback() void TooltipWindow::timerCallback()
{ {
const unsigned int now = Time::getApproximateMillisecondCounter();
Component* const newComp = Component::getComponentUnderMouse();
const String newTip (getTipFor (newComp));

const bool tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse);
lastComponentUnderMouse = newComp;
lastTipUnderMouse = newTip;

const int clickCount = Desktop::getInstance().getMouseButtonClickCounter();
const bool mouseWasClicked = clickCount > mouseClicks;
mouseClicks = clickCount;

int mx, my; int mx, my;
Desktop::getMousePosition (mx, my); Desktop::getMousePosition (mx, my);
const bool mouseMovedQuickly = (abs (mx - mouseX) + abs (my - mouseY) > 12);
mouseX = mx;
mouseY = my;


const unsigned int now = Time::getApproximateMillisecondCounter();
Component* const underMouse = Component::getComponentUnderMouse();
const bool changedComp = (underMouse != lastComponentUnderMouse);
lastComponentUnderMouse = underMouse;
if (tipChanged || mouseWasClicked || mouseMovedQuickly)
lastCompChangeTime = now;


if (changedComp
|| abs (mx - mouseX) > 4
|| abs (my - mouseY) > 4
|| Desktop::getInstance().getMouseButtonClickCounter() > mouseClicks)
if (isVisible() || now < lastHideTime + 500)
{ {
lastMouseMoveTime = now;
if (isVisible())
// if a tip is currently visible (or has just disappeared), update to a new one
// immediately if needed..
if (newComp == 0 || mouseWasClicked || newTip.isEmpty())
{ {
lastHideTime = now;
hide();
if (isVisible())
{
lastHideTime = now;
hide();
}
}
else if (tipChanged)
{
showFor (newComp, newTip);
} }

changedCompsSinceShown = changedCompsSinceShown || changedComp;

tip = String::empty;

mouseX = mx;
mouseY = my;
} }

if (changedCompsSinceShown)
else
{ {
if ((now > lastMouseMoveTime + millisecondsBeforeTipAppears
|| now < lastHideTime + 500)
&& ! isVisible())
// if there isn't currently a tip, but one is needed, only let it
// appear after a timeout..
if (newTip.isNotEmpty()
&& newTip != tipShowing
&& now > lastCompChangeTime + millisecondsBeforeTipAppears)
{ {
if (underMouse->isValidComponent())
showFor (underMouse);

changedCompsSinceShown = false;
showFor (newComp, newTip);
} }
} }

mouseClicks = Desktop::getInstance().getMouseButtonClickCounter();
} }


END_JUCE_NAMESPACE END_JUCE_NAMESPACE
@@ -270323,12 +270353,15 @@ static JuceAppDelegate* juceAppDelegate = 0;


void MessageManager::runDispatchLoop() void MessageManager::runDispatchLoop()
{ {
const ScopedAutoReleasePool pool;
if (! quitMessagePosted) // check that the quit message wasn't already posted..
{
const ScopedAutoReleasePool pool;


// must only be called by the message thread!
jassert (isThisTheMessageThread());
// must only be called by the message thread!
jassert (isThisTheMessageThread());


[NSApp run];
[NSApp run];
}
} }


void MessageManager::stopDispatchLoop() void MessageManager::stopDispatchLoop()


+ 10
- 3
juce_amalgamated.h View File

@@ -29942,16 +29942,17 @@ private:


const int millisecondsBeforeTipAppears; const int millisecondsBeforeTipAppears;
int mouseX, mouseY, mouseClicks; int mouseX, mouseY, mouseClicks;
unsigned int lastMouseMoveTime, lastHideTime;
unsigned int lastCompChangeTime, lastHideTime;
Component* lastComponentUnderMouse; Component* lastComponentUnderMouse;
bool changedCompsSinceShown; bool changedCompsSinceShown;
String tip;
String tipShowing, lastTipUnderMouse;


void paint (Graphics& g); void paint (Graphics& g);
void mouseEnter (const MouseEvent& e); void mouseEnter (const MouseEvent& e);
void timerCallback(); void timerCallback();


void showFor (Component* const c);
static const String getTipFor (Component* const c);
void showFor (Component* const c, const String& tip);
void hide(); void hide();


TooltipWindow (const TooltipWindow&); TooltipWindow (const TooltipWindow&);
@@ -43355,6 +43356,11 @@ public:
*/ */
virtual void itemSelectionChanged (bool isNowSelected); virtual void itemSelectionChanged (bool isNowSelected);


/** The item can return a tool tip string here if it wants to.
@see TooltipClient
*/
virtual const String getTooltip();

/** To allow items from your treeview to be dragged-and-dropped, implement this method. /** To allow items from your treeview to be dragged-and-dropped, implement this method.


If this returns a non-empty name then when the user drags an item, the treeview will If this returns a non-empty name then when the user drags an item, the treeview will
@@ -45947,6 +45953,7 @@ private:
double currentValue; double currentValue;
bool displayPercentage; bool displayPercentage;
String displayedMessage, currentMessage; String displayedMessage, currentMessage;
uint32 lastCallbackTime;


void timerCallback(); void timerCallback();




+ 1
- 1
src/juce_appframework/events/juce_MessageManager.cpp View File

@@ -278,7 +278,7 @@ void MessageManagerLock::init (Thread* const threadToCheck, ThreadPoolJob* const
{ {
if (MessageManager::instance->currentThreadHasLockedMessageManager()) if (MessageManager::instance->currentThreadHasLockedMessageManager())
{ {
locked = true; // either we're on the message thread, or this it's a re-entrant call.
locked = true; // either we're on the message thread, or this is a re-entrant call.
} }
else else
{ {


+ 0
- 1
src/juce_appframework/events/juce_Timer.cpp View File

@@ -247,7 +247,6 @@ public:
addTimer (t); addTimer (t);
const ScopedUnlock ul (lock); const ScopedUnlock ul (lock);
callbackNeeded = false;
JUCE_TRY JUCE_TRY
{ {


+ 9
- 3
src/juce_appframework/gui/components/controls/juce_ProgressBar.cpp View File

@@ -40,7 +40,8 @@ BEGIN_JUCE_NAMESPACE
//============================================================================== //==============================================================================
ProgressBar::ProgressBar (double& progress_) ProgressBar::ProgressBar (double& progress_)
: progress (progress_), : progress (progress_),
displayPercentage (true)
displayPercentage (true),
lastCallbackTime (0)
{ {
currentValue = jlimit (0.0, 1.0, progress); currentValue = jlimit (0.0, 1.0, progress);
} }
@@ -109,9 +110,14 @@ void ProgressBar::timerCallback()
{ {
if (currentValue < newProgress if (currentValue < newProgress
&& newProgress >= 0 && newProgress < 1.0 && newProgress >= 0 && newProgress < 1.0
&& currentValue >= 0 && newProgress < 1.0)
&& currentValue >= 0 && currentValue < 1.0)
{ {
newProgress = jmin (currentValue + 0.02, newProgress);
const uint32 now = Time::getMillisecondCounter();
const int timeSinceLastCallback = (int) (now - lastCallbackTime);
lastCallbackTime = now;
newProgress = jmin (currentValue + 0.00018 * timeSinceLastCallback,
newProgress);
} }
currentValue = newProgress; currentValue = newProgress;


+ 1
- 0
src/juce_appframework/gui/components/controls/juce_ProgressBar.h View File

@@ -119,6 +119,7 @@ private:
double currentValue; double currentValue;
bool displayPercentage; bool displayPercentage;
String displayedMessage, currentMessage; String displayedMessage, currentMessage;
uint32 lastCallbackTime;
void timerCallback(); void timerCallback();


+ 21
- 1
src/juce_appframework/gui/components/controls/juce_TreeView.cpp View File

@@ -41,7 +41,8 @@ BEGIN_JUCE_NAMESPACE
//============================================================================== //==============================================================================
class TreeViewContentComponent : public Component
class TreeViewContentComponent : public Component,
public TooltipClient
{ {
public: public:
TreeViewContentComponent (TreeView* const owner_) TreeViewContentComponent (TreeView* const owner_)
@@ -303,6 +304,20 @@ public:
owner->itemsChanged(); owner->itemsChanged();
} }
const String getTooltip()
{
int x, y;
getMouseXYRelative (x, y);
Rectangle pos;
TreeViewItem* const item = findItemAt (y, pos);
if (item != 0)
return item->getTooltip();
return owner->getTooltip();
}
//============================================================================== //==============================================================================
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
@@ -980,6 +995,11 @@ void TreeViewItem::itemSelectionChanged (bool)
{ {
} }
const String TreeViewItem::getTooltip()
{
return String::empty;
}
const String TreeViewItem::getDragSourceDescription() const String TreeViewItem::getDragSourceDescription()
{ {
return String::empty; return String::empty;


+ 5
- 0
src/juce_appframework/gui/components/controls/juce_TreeView.h View File

@@ -337,6 +337,11 @@ public:
*/ */
virtual void itemSelectionChanged (bool isNowSelected); virtual void itemSelectionChanged (bool isNowSelected);
/** The item can return a tool tip string here if it wants to.
@see TooltipClient
*/
virtual const String getTooltip();
/** To allow items from your treeview to be dragged-and-dropped, implement this method. /** To allow items from your treeview to be dragged-and-dropped, implement this method.
If this returns a non-empty name then when the user drags an item, the treeview will If this returns a non-empty name then when the user drags an item, the treeview will


+ 6
- 6
src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp View File

@@ -495,10 +495,8 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title,
aw->addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut); aw->addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut);
aw->addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut); aw->addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut);
} }
else
else if (numButtons == 3)
{ {
jassert (numButtons == 3);
aw->addButton (button1, 1, button1ShortCut); aw->addButton (button1, 1, button1ShortCut);
aw->addButton (button2, 2, button2ShortCut); aw->addButton (button2, 2, button2ShortCut);
aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0));
@@ -1591,7 +1589,7 @@ ImageEffectFilter* LookAndFeel::getSliderEffect()
//============================================================================== //==============================================================================
static const TextLayout layoutTooltipText (const String& text) throw() static const TextLayout layoutTooltipText (const String& text) throw()
{ {
const float tooltipFontSize = 15.0f;
const float tooltipFontSize = 12.0f;
const int maxToolTipWidth = 400; const int maxToolTipWidth = 400;
const Font f (tooltipFontSize, Font::bold); const Font f (tooltipFontSize, Font::bold);
@@ -1606,7 +1604,7 @@ void LookAndFeel::getTooltipSize (const String& tipText, int& width, int& height
const TextLayout tl (layoutTooltipText (tipText)); const TextLayout tl (layoutTooltipText (tipText));
width = tl.getWidth() + 14; width = tl.getWidth() + 14;
height = tl.getHeight() + 10;
height = tl.getHeight() + 6;
} }
void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int height) void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int height)
@@ -1615,8 +1613,10 @@ void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int h
const Colour textCol (findColour (TooltipWindow::textColourId)); const Colour textCol (findColour (TooltipWindow::textColourId));
#if ! JUCE_MAC // The mac windows already have a non-optional 1 pix outline, so don't double it here..
g.setColour (findColour (TooltipWindow::outlineColourId)); g.setColour (findColour (TooltipWindow::outlineColourId));
g.drawRect (0, 0, width, height);
g.drawRect (0, 0, width, height, 1);
#endif
const TextLayout tl (layoutTooltipText (text)); const TextLayout tl (layoutTooltipText (text));


+ 4
- 5
src/juce_appframework/gui/components/windows/juce_ComponentPeer.cpp View File

@@ -461,13 +461,12 @@ bool ComponentPeer::handleKeyPress (const int keyCode,
if (keyInfo.isKeyCode (KeyPress::tabKey) && Component::getCurrentlyFocusedComponent() != 0) if (keyInfo.isKeyCode (KeyPress::tabKey) && Component::getCurrentlyFocusedComponent() != 0)
{ {
Component::getCurrentlyFocusedComponent()
->moveKeyboardFocusToSibling (! keyInfo.getModifiers().isShiftDown());
keyWasUsed = true;
Component* const currentlyFocused = Component::getCurrentlyFocusedComponent();
currentlyFocused->moveKeyboardFocusToSibling (! keyInfo.getModifiers().isShiftDown());
keyWasUsed = (currentlyFocused != Component::getCurrentlyFocusedComponent());
break; break;
} }
target = target->parentComponent_; target = target->parentComponent_;
} }


+ 6
- 8
src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp View File

@@ -50,14 +50,12 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title,
timeOutMsWhenCancelling (timeOutMsWhenCancelling_) timeOutMsWhenCancelling (timeOutMsWhenCancelling_)
{ {
alertWindow = LookAndFeel::getDefaultLookAndFeel() alertWindow = LookAndFeel::getDefaultLookAndFeel()
.createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty,
AlertWindow::NoIcon, 1, 0);
.createAlertWindow (title, String::empty, cancelButtonText,
String::empty, String::empty,
AlertWindow::NoIcon, hasCancelButton ? 1 : 0, 0);
if (hasProgressBar) if (hasProgressBar)
alertWindow->addProgressBarComponent (progress); alertWindow->addProgressBarComponent (progress);
if (hasCancelButton)
alertWindow->addButton (cancelButtonText, 1);
} }
ThreadWithProgressWindow::~ThreadWithProgressWindow() ThreadWithProgressWindow::~ThreadWithProgressWindow()
@@ -76,13 +74,13 @@ bool ThreadWithProgressWindow::runThread (const int priority)
alertWindow->setMessage (message); alertWindow->setMessage (message);
} }
const bool wasCancelled = alertWindow->runModalLoop() != 0;
const bool finishedNaturally = alertWindow->runModalLoop() != 0;
stopThread (timeOutMsWhenCancelling); stopThread (timeOutMsWhenCancelling);
alertWindow->setVisible (false); alertWindow->setVisible (false);
return ! wasCancelled;
return finishedNaturally;
} }
void ThreadWithProgressWindow::setProgress (const double newProgress) void ThreadWithProgressWindow::setProgress (const double newProgress)
@@ -101,7 +99,7 @@ void ThreadWithProgressWindow::timerCallback()
if (! isThreadRunning()) if (! isThreadRunning())
{ {
// thread has finished normally.. // thread has finished normally..
alertWindow->exitModalState (0);
alertWindow->exitModalState (1);
alertWindow->setVisible (false); alertWindow->setVisible (false);
} }
else else


+ 77
- 68
src/juce_appframework/gui/components/windows/juce_TooltipWindow.cpp View File

@@ -36,6 +36,7 @@ BEGIN_JUCE_NAMESPACE
#include "juce_TooltipWindow.h" #include "juce_TooltipWindow.h"
#include "../../../../juce_core/basics/juce_Time.h" #include "../../../../juce_core/basics/juce_Time.h"
#include "../../../../juce_core/threads/juce_Process.h"
#include "../lookandfeel/juce_LookAndFeel.h" #include "../lookandfeel/juce_LookAndFeel.h"
#include "../juce_Desktop.h" #include "../juce_Desktop.h"
@@ -47,7 +48,6 @@ TooltipWindow::TooltipWindow (Component* const parentComponent,
millisecondsBeforeTipAppears (millisecondsBeforeTipAppears_), millisecondsBeforeTipAppears (millisecondsBeforeTipAppears_),
mouseX (0), mouseX (0),
mouseY (0), mouseY (0),
lastMouseMoveTime (0),
lastHideTime (0), lastHideTime (0),
lastComponentUnderMouse (0), lastComponentUnderMouse (0),
changedCompsSinceShown (true) changedCompsSinceShown (true)
@@ -68,7 +68,7 @@ TooltipWindow::~TooltipWindow()
void TooltipWindow::paint (Graphics& g) void TooltipWindow::paint (Graphics& g)
{ {
getLookAndFeel().drawTooltip (g, tip, getWidth(), getHeight());
getLookAndFeel().drawTooltip (g, tipShowing, getWidth(), getHeight());
} }
void TooltipWindow::mouseEnter (const MouseEvent&) void TooltipWindow::mouseEnter (const MouseEvent&)
@@ -76,104 +76,113 @@ void TooltipWindow::mouseEnter (const MouseEvent&)
hide(); hide();
} }
void TooltipWindow::showFor (Component* const c)
void TooltipWindow::showFor (Component* const c, const String& tip)
{ {
TooltipClient* const ttc = dynamic_cast <TooltipClient*> (c);
jassert (tip.isNotEmpty());
tipShowing = tip;
int mx, my;
Desktop::getMousePosition (mx, my);
if (ttc != 0 && ! c->isCurrentlyBlockedByAnotherModalComponent())
tip = ttc->getTooltip();
else
tip = String::empty;
if (getParentComponent() != 0)
getParentComponent()->globalPositionToRelative (mx, my);
if (tip.isEmpty())
{
hide();
}
else
{
int mx, my;
Desktop::getMousePosition (mx, my);
int x, y, w, h;
getLookAndFeel().getTooltipSize (tip, w, h);
if (getParentComponent() != 0)
getParentComponent()->globalPositionToRelative (mx, my);
if (mx > getParentWidth() / 2)
x = mx - (w + 12);
else
x = mx + 24;
int x, y, w, h;
getLookAndFeel().getTooltipSize (tip, w, h);
if (my > getParentHeight() / 2)
y = my - (h + 6);
else
y = my + 6;
if (mx > getParentWidth() / 2)
x = mx - (w + 12);
else
x = mx + 24;
setBounds (x, y, w, h);
setVisible (true);
if (my > getParentHeight() / 2)
y = my - (h + 6);
else
y = my + 6;
if (getParentComponent() == 0)
{
addToDesktop (ComponentPeer::windowHasDropShadow
| ComponentPeer::windowIsTemporary);
}
setBounds (x, y, w, h);
setVisible (true);
toFront (false);
}
if (getParentComponent() == 0)
{
addToDesktop (ComponentPeer::windowHasDropShadow
| ComponentPeer::windowIsTemporary);
}
const String TooltipWindow::getTipFor (Component* const c)
{
if (c->isValidComponent() && Process::isForegroundProcess())
{
TooltipClient* const ttc = dynamic_cast <TooltipClient*> (c);
toFront (false);
if (ttc != 0 && ! c->isCurrentlyBlockedByAnotherModalComponent())
return ttc->getTooltip();
} }
return String::empty;
} }
void TooltipWindow::hide() void TooltipWindow::hide()
{ {
tipShowing = String::empty;
removeFromDesktop(); removeFromDesktop();
setVisible (false); setVisible (false);
} }
void TooltipWindow::timerCallback() void TooltipWindow::timerCallback()
{ {
const unsigned int now = Time::getApproximateMillisecondCounter();
Component* const newComp = Component::getComponentUnderMouse();
const String newTip (getTipFor (newComp));
const bool tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse);
lastComponentUnderMouse = newComp;
lastTipUnderMouse = newTip;
const int clickCount = Desktop::getInstance().getMouseButtonClickCounter();
const bool mouseWasClicked = clickCount > mouseClicks;
mouseClicks = clickCount;
int mx, my; int mx, my;
Desktop::getMousePosition (mx, my); Desktop::getMousePosition (mx, my);
const bool mouseMovedQuickly = (abs (mx - mouseX) + abs (my - mouseY) > 12);
mouseX = mx;
mouseY = my;
const unsigned int now = Time::getApproximateMillisecondCounter();
Component* const underMouse = Component::getComponentUnderMouse();
const bool changedComp = (underMouse != lastComponentUnderMouse);
lastComponentUnderMouse = underMouse;
if (changedComp
|| abs (mx - mouseX) > 4
|| abs (my - mouseY) > 4
|| Desktop::getInstance().getMouseButtonClickCounter() > mouseClicks)
{
lastMouseMoveTime = now;
if (tipChanged || mouseWasClicked || mouseMovedQuickly)
lastCompChangeTime = now;
if (isVisible())
if (isVisible() || now < lastHideTime + 500)
{
// if a tip is currently visible (or has just disappeared), update to a new one
// immediately if needed..
if (newComp == 0 || mouseWasClicked || newTip.isEmpty())
{ {
lastHideTime = now;
hide();
if (isVisible())
{
lastHideTime = now;
hide();
}
}
else if (tipChanged)
{
showFor (newComp, newTip);
} }
changedCompsSinceShown = changedCompsSinceShown || changedComp;
tip = String::empty;
mouseX = mx;
mouseY = my;
} }
if (changedCompsSinceShown)
else
{ {
if ((now > lastMouseMoveTime + millisecondsBeforeTipAppears
|| now < lastHideTime + 500)
&& ! isVisible())
// if there isn't currently a tip, but one is needed, only let it
// appear after a timeout..
if (newTip.isNotEmpty()
&& newTip != tipShowing
&& now > lastCompChangeTime + millisecondsBeforeTipAppears)
{ {
if (underMouse->isValidComponent())
showFor (underMouse);
changedCompsSinceShown = false;
showFor (newComp, newTip);
} }
} }
mouseClicks = Desktop::getInstance().getMouseButtonClickCounter();
} }
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 4
- 3
src/juce_appframework/gui/components/windows/juce_TooltipWindow.h View File

@@ -101,16 +101,17 @@ private:
//============================================================================== //==============================================================================
const int millisecondsBeforeTipAppears; const int millisecondsBeforeTipAppears;
int mouseX, mouseY, mouseClicks; int mouseX, mouseY, mouseClicks;
unsigned int lastMouseMoveTime, lastHideTime;
unsigned int lastCompChangeTime, lastHideTime;
Component* lastComponentUnderMouse; Component* lastComponentUnderMouse;
bool changedCompsSinceShown; bool changedCompsSinceShown;
String tip;
String tipShowing, lastTipUnderMouse;
void paint (Graphics& g); void paint (Graphics& g);
void mouseEnter (const MouseEvent& e); void mouseEnter (const MouseEvent& e);
void timerCallback(); void timerCallback();
void showFor (Component* const c);
static const String getTipFor (Component* const c);
void showFor (Component* const c, const String& tip);
void hide(); void hide();
TooltipWindow (const TooltipWindow&); TooltipWindow (const TooltipWindow&);


+ 1
- 1
src/juce_core/misc/juce_ZipFile.cpp View File

@@ -137,7 +137,7 @@ public:
bool isExhausted() throw() bool isExhausted() throw()
{ {
return pos >= zipEntryInfo.compressedSize;
return headerSize <= 0 || pos >= zipEntryInfo.compressedSize;
} }
int64 getPosition() throw() int64 getPosition() throw()


Loading…
Cancel
Save