Browse Source

New class NativeMessageBox, with static methods for showing several types of native alert boxes.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
927cebcdbb
31 changed files with 4609 additions and 3393 deletions
  1. +2
    -0
      Builds/MacOSX/Juce.xcodeproj/project.pbxproj
  2. +1
    -0
      Builds/VisualStudio2005/Juce.vcproj
  3. +1
    -0
      Builds/VisualStudio2008/Juce.vcproj
  4. +1
    -0
      Builds/VisualStudio2008_DLL/Juce.vcproj
  5. +1
    -0
      Builds/VisualStudio2010/Juce.vcxproj
  6. +3
    -0
      Builds/VisualStudio2010/Juce.vcxproj.filters
  7. +2
    -0
      Builds/iOS/Juce.xcodeproj/project.pbxproj
  8. +2
    -0
      Juce.jucer
  9. +38
    -3
      extras/Introjucer/Source/Project/jucer_ProjectTreeViewBase.cpp
  10. +4
    -0
      extras/Introjucer/Source/Project/jucer_ProjectTreeViewBase.h
  11. +472
    -89
      juce_amalgamated.cpp
  12. +150
    -4
      juce_amalgamated.h
  13. +1
    -1
      src/core/juce_StandardHeader.h
  14. +1
    -1
      src/core/juce_TargetPlatform.h
  15. +15
    -1
      src/gui/components/lookandfeel/juce_LookAndFeel.cpp
  16. +4
    -0
      src/gui/components/lookandfeel/juce_LookAndFeel.h
  17. +61
    -15
      src/gui/components/windows/juce_AlertWindow.cpp
  18. +2
    -0
      src/gui/components/windows/juce_AlertWindow.h
  19. +157
    -0
      src/gui/components/windows/juce_NativeMessageBox.h
  20. +3
    -0
      src/juce_app_includes.h
  21. +83
    -0
      src/native/android/java/JuceAppActivity.java
  22. +4
    -0
      src/native/android/juce_android_NativeCode.cpp
  23. +36
    -4
      src/native/android/juce_android_Windowing.cpp
  24. +1
    -0
      src/native/linux/juce_linux_NativeCode.cpp
  25. +30
    -9
      src/native/linux/juce_linux_Windowing.cpp
  26. +104
    -29
      src/native/mac/juce_ios_MiscUtilities.mm
  27. +107
    -9
      src/native/mac/juce_mac_MiscUtilities.mm
  28. +1
    -0
      src/native/mac/juce_mac_NativeCode.mm
  29. +1
    -0
      src/native/windows/juce_win32_NativeCode.cpp
  30. +3320
    -3227
      src/native/windows/juce_win32_Windowing.cpp
  31. +1
    -1
      src/text/juce_String.h

+ 2
- 0
Builds/MacOSX/Juce.xcodeproj/project.pbxproj View File

@@ -798,6 +798,7 @@
C286C779DD52C29F86E3DBE9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DialogWindow.h; path = ../../src/gui/components/windows/juce_DialogWindow.h; sourceTree = SOURCE_ROOT; };
090907E4FE95EE2B11C1A0E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DocumentWindow.cpp; path = ../../src/gui/components/windows/juce_DocumentWindow.cpp; sourceTree = SOURCE_ROOT; };
6E522DF13EC47755234A5D57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DocumentWindow.h; path = ../../src/gui/components/windows/juce_DocumentWindow.h; sourceTree = SOURCE_ROOT; };
3FC6FC331B4E104D1DC223D6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NativeMessageBox.h; path = ../../src/gui/components/windows/juce_NativeMessageBox.h; sourceTree = SOURCE_ROOT; };
2E4A5F7128313C23AD0356F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ResizableWindow.cpp; path = ../../src/gui/components/windows/juce_ResizableWindow.cpp; sourceTree = SOURCE_ROOT; };
207CDD87107EAC8ED17DD601 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ResizableWindow.h; path = ../../src/gui/components/windows/juce_ResizableWindow.h; sourceTree = SOURCE_ROOT; };
87E57C8F3448D615271CD9F6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SplashScreen.cpp; path = ../../src/gui/components/windows/juce_SplashScreen.cpp; sourceTree = SOURCE_ROOT; };
@@ -1568,6 +1569,7 @@
C286C779DD52C29F86E3DBE9,
090907E4FE95EE2B11C1A0E1,
6E522DF13EC47755234A5D57,
3FC6FC331B4E104D1DC223D6,
2E4A5F7128313C23AD0356F7,
207CDD87107EAC8ED17DD601,
87E57C8F3448D615271CD9F6,


+ 1
- 0
Builds/VisualStudio2005/Juce.vcproj View File

@@ -674,6 +674,7 @@
<File RelativePath="..\..\src\gui\components\windows\juce_DialogWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_DocumentWindow.cpp"/>
<File RelativePath="..\..\src\gui\components\windows\juce_DocumentWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_NativeMessageBox.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_ResizableWindow.cpp"/>
<File RelativePath="..\..\src\gui\components\windows\juce_ResizableWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_SplashScreen.cpp"/>


+ 1
- 0
Builds/VisualStudio2008/Juce.vcproj View File

@@ -674,6 +674,7 @@
<File RelativePath="..\..\src\gui\components\windows\juce_DialogWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_DocumentWindow.cpp"/>
<File RelativePath="..\..\src\gui\components\windows\juce_DocumentWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_NativeMessageBox.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_ResizableWindow.cpp"/>
<File RelativePath="..\..\src\gui\components\windows\juce_ResizableWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_SplashScreen.cpp"/>


+ 1
- 0
Builds/VisualStudio2008_DLL/Juce.vcproj View File

@@ -676,6 +676,7 @@
<File RelativePath="..\..\src\gui\components\windows\juce_DialogWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_DocumentWindow.cpp"/>
<File RelativePath="..\..\src\gui\components\windows\juce_DocumentWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_NativeMessageBox.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_ResizableWindow.cpp"/>
<File RelativePath="..\..\src\gui\components\windows\juce_ResizableWindow.h"/>
<File RelativePath="..\..\src\gui\components\windows\juce_SplashScreen.cpp"/>


+ 1
- 0
Builds/VisualStudio2010/Juce.vcxproj View File

@@ -688,6 +688,7 @@
<ClInclude Include="..\..\src\gui\components\windows\juce_ComponentPeer.h"/>
<ClInclude Include="..\..\src\gui\components\windows\juce_DialogWindow.h"/>
<ClInclude Include="..\..\src\gui\components\windows\juce_DocumentWindow.h"/>
<ClInclude Include="..\..\src\gui\components\windows\juce_NativeMessageBox.h"/>
<ClInclude Include="..\..\src\gui\components\windows\juce_ResizableWindow.h"/>
<ClInclude Include="..\..\src\gui\components\windows\juce_SplashScreen.h"/>
<ClInclude Include="..\..\src\gui\components\windows\juce_ThreadWithProgressWindow.h"/>


+ 3
- 0
Builds/VisualStudio2010/Juce.vcxproj.filters View File

@@ -1998,6 +1998,9 @@
<ClInclude Include="..\..\src\gui\components\windows\juce_DocumentWindow.h">
<Filter>Juce\Source\gui\components\windows</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gui\components\windows\juce_NativeMessageBox.h">
<Filter>Juce\Source\gui\components\windows</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gui\components\windows\juce_ResizableWindow.h">
<Filter>Juce\Source\gui\components\windows</Filter>
</ClInclude>


+ 2
- 0
Builds/iOS/Juce.xcodeproj/project.pbxproj View File

@@ -798,6 +798,7 @@
C286C779DD52C29F86E3DBE9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DialogWindow.h; path = ../../src/gui/components/windows/juce_DialogWindow.h; sourceTree = SOURCE_ROOT; };
090907E4FE95EE2B11C1A0E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DocumentWindow.cpp; path = ../../src/gui/components/windows/juce_DocumentWindow.cpp; sourceTree = SOURCE_ROOT; };
6E522DF13EC47755234A5D57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DocumentWindow.h; path = ../../src/gui/components/windows/juce_DocumentWindow.h; sourceTree = SOURCE_ROOT; };
3FC6FC331B4E104D1DC223D6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NativeMessageBox.h; path = ../../src/gui/components/windows/juce_NativeMessageBox.h; sourceTree = SOURCE_ROOT; };
2E4A5F7128313C23AD0356F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ResizableWindow.cpp; path = ../../src/gui/components/windows/juce_ResizableWindow.cpp; sourceTree = SOURCE_ROOT; };
207CDD87107EAC8ED17DD601 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ResizableWindow.h; path = ../../src/gui/components/windows/juce_ResizableWindow.h; sourceTree = SOURCE_ROOT; };
87E57C8F3448D615271CD9F6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SplashScreen.cpp; path = ../../src/gui/components/windows/juce_SplashScreen.cpp; sourceTree = SOURCE_ROOT; };
@@ -1568,6 +1569,7 @@
C286C779DD52C29F86E3DBE9,
090907E4FE95EE2B11C1A0E1,
6E522DF13EC47755234A5D57,
3FC6FC331B4E104D1DC223D6,
2E4A5F7128313C23AD0356F7,
207CDD87107EAC8ED17DD601,
87E57C8F3448D615271CD9F6,


+ 2
- 0
Juce.jucer View File

@@ -965,6 +965,8 @@
file="src/gui/components/windows/juce_DocumentWindow.cpp"/>
<FILE id="hKM9A0HPm" name="juce_DocumentWindow.h" compile="0" resource="0"
file="src/gui/components/windows/juce_DocumentWindow.h"/>
<FILE id="p01Trf" name="juce_NativeMessageBox.h" compile="0" resource="0"
file="src/gui/components/windows/juce_NativeMessageBox.h"/>
<FILE id="jpK2YGSu7" name="juce_ResizableWindow.cpp" compile="1" resource="0"
file="src/gui/components/windows/juce_ResizableWindow.cpp"/>
<FILE id="M6UTdqVNd" name="juce_ResizableWindow.h" compile="0" resource="0"


+ 38
- 3
extras/Introjucer/Source/Project/jucer_ProjectTreeViewBase.cpp View File

@@ -315,7 +315,7 @@ void ProjectTreeViewBase::filesDropped (const StringArray& files, int insertInde
addFiles (files, insertIndex);
}
static void getAllSelectedNodesInTree (Component* componentInTree, OwnedArray <Project::Item>& selectedNodes)
void ProjectTreeViewBase::getAllSelectedNodesInTree (Component* componentInTree, OwnedArray <Project::Item>& selectedNodes)
{
TreeView* tree = dynamic_cast <TreeView*> (componentInTree);
@@ -450,13 +450,41 @@ void ProjectTreeViewBase::showMultiSelectionPopupMenu()
void ProjectTreeViewBase::itemDoubleClicked (const MouseEvent& e)
{
showDocument();
invokeShowDocument();
}
class TreeviewItemSelectionTimer : public Timer
{
public:
TreeviewItemSelectionTimer (ProjectTreeViewBase& owner_)
: owner (owner_)
{}
void timerCallback()
{
owner.invokeShowDocument();
}
private:
ProjectTreeViewBase& owner;
JUCE_DECLARE_NON_COPYABLE (TreeviewItemSelectionTimer);
};
void ProjectTreeViewBase::itemSelectionChanged (bool isNowSelected)
{
if (isNowSelected)
showDocument();
{
delayedSelectionTimer = new TreeviewItemSelectionTimer (*this);
// for images, give the user longer to start dragging before assuming they're
// clicking to select it for previewing..
delayedSelectionTimer->startTimer (item.isImageFile() ? 250 : 120);
}
else
{
delayedSelectionTimer = 0;
}
}
const String ProjectTreeViewBase::getTooltip()
@@ -466,9 +494,16 @@ const String ProjectTreeViewBase::getTooltip()
const String ProjectTreeViewBase::getDragSourceDescription()
{
delayedSelectionTimer = 0;
return projectItemDragType;
}
void ProjectTreeViewBase::invokeShowDocument()
{
delayedSelectionTimer = 0;
showDocument();
}
//==============================================================================
ProjectTreeViewBase* ProjectTreeViewBase::getParentProjectItem() const
{


+ 4
- 0
extras/Introjucer/Source/Project/jucer_ProjectTreeViewBase.h View File

@@ -65,6 +65,7 @@ public:
virtual void addFiles (const StringArray& files, int insertIndex);
virtual void moveSelectedItemsTo (OwnedArray <Project::Item>& selectedNodes, int insertIndex);
virtual void showMultiSelectionPopupMenu();
void invokeShowDocument();
virtual ProjectTreeViewBase* findTreeViewItem (const Project::Item& itemToFind);
@@ -94,11 +95,14 @@ public:
bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent);
void itemDropped (const String& sourceDescription, Component* sourceComponent, int insertIndex);
static void getAllSelectedNodesInTree (Component* componentInTree, OwnedArray <Project::Item>& selectedNodes);
//==============================================================================
Project::Item item;
protected:
bool isFileMissing;
ScopedPointer<Timer> delayedSelectionTimer;
//==============================================================================
void treeChildrenChanged (const ValueTree& parentTree);


+ 472
- 89
juce_amalgamated.cpp View File

@@ -185,7 +185,7 @@
#endif
#endif

#if ! JUCE_VC7_OR_EARLIER && ! defined (__INTEL_COMPILER)
#if ! JUCE_VC7_OR_EARLIER
#define JUCE_USE_INTRINSICS 1
#endif
#else
@@ -40418,6 +40418,10 @@ void Component::setBounds (const int x, const int y, int w, int h)
else if (! flags.hasHeavyweightPeerFlag)
repaintParent();
}
else
{
bufferedImage = Image::null;
}

if (flags.hasHeavyweightPeerFlag)
{
@@ -41040,10 +41044,8 @@ bool Component::isCurrentlyBlockedByAnotherModalComponent() const
{
Component* const mc = getCurrentlyModalComponent();

return mc != 0
&& mc != this
&& (! mc->isParentOf (this))
&& ! mc->canModalEventBeSentToComponent (this);
return ! (mc == 0 || mc == this || mc->isParentOf (this)
|| mc->canModalEventBeSentToComponent (this));
}

int JUCE_CALLTYPE Component::getNumCurrentlyModalComponents() throw()
@@ -42007,7 +42009,9 @@ void Component::internalBroughtToFront()
Component* const cm = getCurrentlyModalComponent();

if (cm != 0 && cm->getTopLevelComponent() != getTopLevelComponent())
ModalComponentManager::getInstance()->bringModalComponentsToFront();
ModalComponentManager::getInstance()->bringModalComponentsToFront (false); // very important that this is false, otherwise in win32,
// non-front components can't get focus when another modal comp is
// active, and therefore can't receive mouse-clicks
}

void Component::focusGained (FocusChangeType)
@@ -42981,7 +42985,7 @@ void ModalComponentManager::handleAsyncUpdate()
}
}

void ModalComponentManager::bringModalComponentsToFront()
void ModalComponentManager::bringModalComponentsToFront (bool topOneShouldGrabFocus)
{
ComponentPeer* lastOne = 0;

@@ -42998,8 +43002,10 @@ void ModalComponentManager::bringModalComponentsToFront()
{
if (lastOne == 0)
{
peer->toFront (true);
peer->grabFocus();
peer->toFront (topOneShouldGrabFocus);

if (topOneShouldGrabFocus)
peer->grabFocus();
}
else
peer->toBehind (lastOne);
@@ -65205,6 +65211,7 @@ namespace LookAndFeelHelpers
}

LookAndFeel::LookAndFeel()
: useNativeAlertWindows (false)
{
/* if this fails it means you're trying to create a LookAndFeel object before
the static Colours have been initialised. That ain't gonna work. It probably
@@ -65731,6 +65738,20 @@ const Font LookAndFeel::getAlertWindowFont()
return Font (12.0f);
}

void LookAndFeel::setUsingNativeAlertWindows (bool shouldUseNativeAlerts)
{
useNativeAlertWindows = shouldUseNativeAlerts;
}

bool LookAndFeel::isUsingNativeAlertWindows()
{
#if JUCE_LINUX
return false; // not available currently..
#else
return useNativeAlertWindows;
#endif
}

void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar,
int width, int height,
double progress, const String& textToShow)
@@ -66712,7 +66733,6 @@ class SliderLabelComp : public Label
{
public:
SliderLabelComp() : Label (String::empty, String::empty) {}
~SliderLabelComp() {}

void mouseWheelMove (const MouseEvent&, float, float) {}
};
@@ -76947,10 +76967,17 @@ void AlertWindow::showMessageBox (AlertIconType iconType,
const String& buttonText,
Component* associatedComponent)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, true);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
NativeMessageBox::showMessageBox (iconType, title, message, associatedComponent);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, true);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;

info.invoke();
info.invoke();
}
}
#endif

@@ -76960,10 +76987,17 @@ void AlertWindow::showMessageBoxAsync (AlertIconType iconType,
const String& buttonText,
Component* associatedComponent)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, false);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
return NativeMessageBox::showMessageBoxAsync (iconType, title, message, associatedComponent);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, false);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;

info.invoke();
info.invoke();
}
}

bool AlertWindow::showOkCancelBox (AlertIconType iconType,
@@ -76974,11 +77008,18 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 2, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("ok") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
return NativeMessageBox::showOkCancelBox (iconType, title, message, associatedComponent, callback);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 2, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("ok") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text;

return info.invoke() != 0;
return info.invoke() != 0;
}
}

int AlertWindow::showYesNoCancelBox (AlertIconType iconType,
@@ -76990,14 +77031,38 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 3, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("yes") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("no") : button2Text;
info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
return NativeMessageBox::showYesNoCancelBox (iconType, title, message, associatedComponent, callback);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 3, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("yes") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("no") : button2Text;
info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text;

return info.invoke();
return info.invoke();
}
}

#if JUCE_MODAL_LOOPS_PERMITTED
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
{
if (isOkCancel)
{
return NativeMessageBox::showOkCancelBox (AlertWindow::NoIcon, title, bodyText);
}
else
{
NativeMessageBox::showMessageBox (AlertWindow::NoIcon, title, bodyText);
return true;
}
}
#endif

END_JUCE_NAMESPACE
/*** End of inlined file: juce_AlertWindow.cpp ***/

@@ -247614,19 +247679,21 @@ private:
return;
}

if (LOWORD (wParam) == WA_CLICKACTIVE && component->isCurrentlyBlockedByAnotherModalComponent())
{
Component* const underMouse = component->getComponentAt (component->getMouseXYRelative());
Component* underMouse = component->getComponentAt (component->getMouseXYRelative());

if (underMouse == 0)
underMouse = component;

if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent())
if (underMouse->isCurrentlyBlockedByAnotherModalComponent())
{
if (LOWORD (wParam) == WA_CLICKACTIVE)
Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
else
ModalComponentManager::getInstance()->bringModalComponentsToFront();
}
else
{
handleBroughtToFront();

if (component->isCurrentlyBlockedByAnotherModalComponent())
Component::getCurrentlyModalComponent()->toFront (true);
}
}

@@ -248480,13 +248547,107 @@ bool Process::isForegroundProcess()
return false;
}

bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
class Win32MessageBox : public AsyncUpdater
{
return MessageBox (0, bodyText.toWideCharPointer(), title.toWideCharPointer(),
MB_SETFOREGROUND | (isOkCancel ? MB_OKCANCEL
: MB_OK)) == IDOK;
public:
Win32MessageBox (AlertWindow::AlertIconType iconType,
const String& title_, const String& message_,
Component* associatedComponent,
UINT extraFlags,
ModalComponentManager::Callback* callback_,
const bool runAsync)
: flags (extraFlags | getMessageBoxFlags (iconType)),
owner (getWindowForMessageBox (associatedComponent)),
title (title_), message (message_), callback (callback_)
{
if (runAsync)
triggerAsyncUpdate();
}

int getResult() const
{
const int r = MessageBox (owner, message.toWideCharPointer(), title.toWideCharPointer(), flags);
return (r == IDYES || r == IDOK) ? 1 : (r == IDNO ? 2 : 0);
}

void handleAsyncUpdate()
{
const int result = getResult();

if (callback != 0)
callback->modalStateFinished (result);

delete this;
}

private:
UINT flags;
HWND owner;
String title, message;
ModalComponentManager::Callback* callback;

static UINT getMessageBoxFlags (AlertWindow::AlertIconType iconType) throw()
{
UINT flags = MB_TASKMODAL | MB_SETFOREGROUND;

switch (iconType)
{
case AlertWindow::QuestionIcon: flags |= MB_ICONQUESTION; break;
case AlertWindow::WarningIcon: flags |= MB_ICONWARNING; break;
case AlertWindow::InfoIcon: flags |= MB_ICONINFORMATION; break;
default: break;
}

return flags;
}

static HWND getWindowForMessageBox (Component* associatedComponent)
{
return associatedComponent != 0 ? (HWND) associatedComponent->getWindowHandle() : 0;
}
};

void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
Win32MessageBox box (iconType, title, message, associatedComponent, MB_OK, 0, false);
(void) box.getResult();
}

void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
new Win32MessageBox (iconType, title, message, associatedComponent, MB_OK, 0, true);
}

bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<Win32MessageBox> mb (new Win32MessageBox (iconType, title, message, associatedComponent,
MB_OKCANCEL, callback, callback != 0));
if (callback == 0)
return mb->getResult() != 0;

mb.release();
return 0;
}

int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<Win32MessageBox> mb (new Win32MessageBox (iconType, title, message, associatedComponent,
MB_YESNOCANCEL, callback, callback != 0));
if (callback == 0)
return mb->getResult();

mb.release();
return 0;
}

void Desktop::createMouseInputSources()
@@ -264775,17 +264936,37 @@ void PlatformUtilities::beep()
std::cout << "\a" << std::flush;
}

bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
// use a non-native one for the time being..
if (isOkCancel)
return AlertWindow::showOkCancelBox (AlertWindow::NoIcon, title, bodyText);
else
AlertWindow::showMessageBox (AlertWindow::NoIcon, title, bodyText);
AlertWindow::showMessageBox (AlertWindow::NoIcon, title, message);
}

return true;
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
AlertWindow::showMessageBoxAsync (AlertWindow::NoIcon, title, message);
}

bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
return AlertWindow::showOkCancelBox (iconType, title, message, String::empty, String::empty,
associatedComponent, callback);
}

int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
return AlertWindow::showYesNoCancelBox (iconType, title, message,
String::empty, String::empty, String::empty,
associatedComponent, callback);
}

const int KeyPress::spaceKey = XK_space & 0xff;
@@ -269504,65 +269685,137 @@ void PlatformUtilities::addItemToDock (const File& file)

#if ! JUCE_ONLY_BUILD_CORE_LIBRARY

class iOSMessageBox;

END_JUCE_NAMESPACE

@interface JuceAlertBoxDelegate : NSObject
{
@public
bool clickedOk;
iOSMessageBox* owner;
}

- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex;

@end

BEGIN_JUCE_NAMESPACE

class iOSMessageBox
{
public:
iOSMessageBox (const String& title, const String& message,
NSString* button1, NSString* button2, NSString* button3,
ModalComponentManager::Callback* callback_, const bool isAsync_)
: result (0), delegate (nil), alert (nil),
callback (callback_), isYesNo (button3 != nil), isAsync (isAsync_)
{
delegate = [[JuceAlertBoxDelegate alloc] init];
delegate->owner = this;

alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title)
message: juceStringToNS (message)
delegate: delegate
cancelButtonTitle: button1
otherButtonTitles: button2, button3, nil];
[alert retain];
[alert show];
}

~iOSMessageBox()
{
[alert release];
[delegate release];
}

int getResult()
{
jassert (callback == 0);
const ScopedAutoReleasePool pool;

while (! alert.hidden && alert.superview != nil)
[[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];

return result;
}

void buttonClicked (const int buttonIndex) throw()
{
result = buttonIndex;

if (callback != 0)
callback->modalStateFinished (result);

if (isAsync)
delete this;
}

private:
int result;
JuceAlertBoxDelegate* delegate;
UIAlertView* alert;
ModalComponentManager::Callback* callback;
const bool isYesNo, isAsync;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox);
};

END_JUCE_NAMESPACE

@implementation JuceAlertBoxDelegate

- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex
{
clickedOk = (buttonIndex == 0);
owner->buttonClicked (buttonIndex);
alertView.hidden = true;
}

@end

BEGIN_JUCE_NAMESPACE

// (This function is used directly by other bits of code)
bool juce_iPhoneShowModalAlert (const String& title,
const String& bodyText,
NSString* okButtonText,
NSString* cancelButtonText)
void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
const ScopedAutoReleasePool pool;
iOSMessageBox mb (title, message, @"OK", nil, nil, 0, false);
(void) mb.getResult();
}

JuceAlertBoxDelegate* callback = [[JuceAlertBoxDelegate alloc] init];

UIAlertView* alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title)
message: juceStringToNS (bodyText)
delegate: callback
cancelButtonTitle: okButtonText
otherButtonTitles: cancelButtonText, nil];
[alert retain];
[alert show];
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
const ScopedAutoReleasePool pool;
new iOSMessageBox (title, message, @"OK", nil, nil, 0, true);
}

while (! alert.hidden && alert.superview != nil)
[[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"OK", nil, callback, callback != 0));

const bool result = callback->clickedOk;
[alert release];
[callback release];
if (callback == 0)
return mb->getResult() == 1;

return result;
mb.release();
return 0;
}

bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
return juce_iPhoneShowModalAlert (title, bodyText,
@"OK",
isOkCancel ? @"Cancel" : nil);
ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != 0));

if (callback == 0)
return mb->getResult();

mb.release();
return 0;
}

bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
@@ -269630,16 +269883,111 @@ void PlatformUtilities::addItemToDock (const File& file)

#if ! JUCE_ONLY_BUILD_CORE_LIBRARY

bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
class OSXMessageBox : public AsyncUpdater
{
const ScopedAutoReleasePool pool;
return NSRunAlertPanel (juceStringToNS (title),
juceStringToNS (bodyText),
@"Ok",
isOkCancel ? @"Cancel" : nil,
nil) == NSAlertDefaultReturn;
public:
OSXMessageBox (AlertWindow::AlertIconType iconType_,
const String& title_, const String& message_,
NSString* button1_, NSString* button2_, NSString* button3_,
ModalComponentManager::Callback* callback_,
const bool runAsync)
: iconType (iconType_), title (title_),
message (message_), callback (callback_),
button1 ([button1_ retain]),
button2 ([button2_ retain]),
button3 ([button3_ retain])
{
if (runAsync)
triggerAsyncUpdate();
}

~OSXMessageBox()
{
[button1 release];
[button2 release];
[button3 release];
}

int getResult() const
{
const ScopedAutoReleasePool pool;
NSInteger r = getRawResult();
return r == NSAlertDefaultReturn ? 1 : (r == NSAlertOtherReturn ? 2 : 0);
}

void handleAsyncUpdate()
{
const int result = getResult();

if (callback != 0)
callback->modalStateFinished (result);

delete this;
}

private:
AlertWindow::AlertIconType iconType;
String title, message;
ModalComponentManager::Callback* callback;
NSString* button1;
NSString* button2;
NSString* button3;

NSInteger getRawResult() const
{
NSString* messageString = juceStringToNS (message);
NSString* titleString = juceStringToNS (title);

switch (iconType)
{
case AlertWindow::InfoIcon: return NSRunInformationalAlertPanel (titleString, messageString, button1, button2, button3);
case AlertWindow::WarningIcon: return NSRunCriticalAlertPanel (titleString, messageString, button1, button2, button3);
default: return NSRunAlertPanel (titleString, messageString, button1, button2, button3);
}
}
};

void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
OSXMessageBox box (iconType, title, message, @"OK", nil, nil, 0, false);
(void) box.getResult();
}

void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
new OSXMessageBox (iconType, title, message, @"OK", nil, nil, 0, true);
}

bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<OSXMessageBox> mb (new OSXMessageBox (iconType, title, message,
@"OK", @"Cancel", nil, callback, callback != 0));
if (callback == 0)
return mb->getResult() == 1;

mb.release();
return 0;
}

int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<OSXMessageBox> mb (new OSXMessageBox (iconType, title, message,
@"Yes", @"Cancel", @"No", callback, callback != 0));
if (callback == 0)
return mb->getResult();

mb.release();
return 0;
}

bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /*canMoveFiles*/)
@@ -283771,6 +284119,9 @@ BEGIN_JUCE_NAMESPACE
METHOD (activityClass, excludeClipRegion, "excludeClipRegion", "(Landroid/graphics/Canvas;FFFF)V") \
METHOD (activityClass, renderGlyph, "renderGlyph", "(CLandroid/graphics/Paint;Landroid/graphics/Matrix;Landroid/graphics/Rect;)[I") \
STATICMETHOD (activityClass, createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;ILjava/lang/StringBuffer;)Lcom/juce/JuceAppActivity$HTTPStream;") \
METHOD (activityClass, showMessageBox, "showMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
METHOD (activityClass, showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
METHOD (activityClass, showYesNoCancelBox, "showYesNoCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
\
METHOD (stringBufferClass, stringBufferConstructor, "<init>", "()V") \
METHOD (stringBufferClass, stringBufferToString, "toString", "()Ljava/lang/String;") \
@@ -287405,12 +287756,44 @@ bool Process::isForegroundProcess()
return true; // TODO
}

bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
// TODO
android.activity.callVoidMethod (android.showMessageBox, javaString (title).get(), javaString (message).get(), (jlong) 0);
}

bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
jassert (callback != 0); // on android, all alerts must be non-modal!!

android.activity.callVoidMethod (android.showOkCancelBox, javaString (title).get(), javaString (message).get(),
(jlong) (pointer_sized_int) callback);
return 0;
}

int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
jassert (callback != 0); // on android, all alerts must be non-modal!!

android.activity.callVoidMethod (android.showYesNoCancelBox, javaString (title).get(), javaString (message).get(),
(jlong) (pointer_sized_int) callback);
return 0;
}

JUCE_JNI_CALLBACK (JuceAppActivity, alertDismissed, void, (JNIEnv* env, jobject activity,
jlong callbackAsLong, jint result))
{
ModalComponentManager::Callback* callback = (ModalComponentManager::Callback*) callbackAsLong;

if (callback != 0)
callback->modalStateFinished (result);
}

void Desktop::setScreenSaverEnabled (const bool isEnabled)


+ 150
- 4
juce_amalgamated.h View File

@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 60
#define JUCE_BUILDNUMBER 61

/** Current Juce version number.

@@ -232,7 +232,7 @@ namespace JuceDummyNamespace {}
#endif
#endif

#if ! JUCE_VC7_OR_EARLIER && ! defined (__INTEL_COMPILER)
#if ! JUCE_VC7_OR_EARLIER
#define JUCE_USE_INTRINSICS 1
#endif
#else
@@ -5478,7 +5478,7 @@ std::basic_ostream <wchar_t, traits>& JUCE_CALLTYPE operator<< (std::basic_ostre
}

/** Writes a string to an OutputStream as UTF8. */
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text);
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& stringToWrite);

#endif // __JUCE_STRING_JUCEHEADER__
/*** End of inlined file: juce_String.h ***/
@@ -29980,7 +29980,7 @@ public:
void attachCallback (Component* component, Callback* callback);

/** Brings any modal components to the front. */
void bringModalComponentsToFront();
void bringModalComponentsToFront (bool topOneShouldGrabFocus = true);

#if JUCE_MODAL_LOOPS_PERMITTED
/** Runs the event loop until the currently topmost modal component is dismissed, and
@@ -57042,9 +57042,11 @@ public:
it'll show a box with just an ok button
@returns true if the ok button was pressed, false if they pressed cancel.
*/
#if JUCE_MODAL_LOOPS_PERMITTED
static bool JUCE_CALLTYPE showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel);
#endif

/** A set of colour IDs to use to change the colour of various aspects of the alert box.

@@ -60086,6 +60088,9 @@ public:
virtual const Font getAlertWindowMessageFont();
virtual const Font getAlertWindowFont();

void setUsingNativeAlertWindows (bool shouldUseNativeAlerts);
bool isUsingNativeAlertWindows();

/** Draws a progress bar.

If the progress value is less than 0 or greater than 1.0, this should draw a spinning
@@ -60511,6 +60516,8 @@ private:

ScopedPointer<Drawable> folderImage, documentImage;

bool useNativeAlertWindows;

void drawShinyButtonShape (Graphics& g,
float x, float y, float w, float h, float maxCornerSize,
const Colour& baseColour,
@@ -64605,6 +64612,145 @@ private:
#endif
#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__

#endif
#ifndef __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__

/*** Start of inlined file: juce_NativeMessageBox.h ***/
#ifndef __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__
#define __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__

class NativeMessageBox
{
public:
/** Shows a dialog box that just has a message and a single 'ok' button to close it.

If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.

@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
*/
#if JUCE_MODAL_LOOPS_PERMITTED
static void JUCE_CALLTYPE showMessageBox (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
Component* associatedComponent = 0);
#endif

/** Shows a dialog box that just has a message and a single 'ok' button to close it.

If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.

@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
*/
static void JUCE_CALLTYPE showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
Component* associatedComponent = 0);

/** Shows a dialog box with two buttons.

Ideal for ok/cancel or yes/no choices. The return key can also be used
to trigger the first button, and the escape key for the second button.

If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.

@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
@param callback if this is non-null, the menu will be launched asynchronously,
returning immediately, and the callback will receive a call to its
modalStateFinished() when the box is dismissed, with its parameter
being 1 if the ok button was pressed, or 0 for cancel, The callback object
will be owned and deleted by the system, so make sure that it works
safely and doesn't keep any references to objects that might be deleted
before it gets called.
@returns true if button 1 was clicked, false if it was button 2. If the callback parameter
is not null, the method always returns false, and the user's choice is delivered
later by the callback.
*/
static bool JUCE_CALLTYPE showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
#if JUCE_MODAL_LOOPS_PERMITTED
Component* associatedComponent = 0,
ModalComponentManager::Callback* callback = 0);
#else
Component* associatedComponent,
ModalComponentManager::Callback* callback);
#endif

/** Shows a dialog box with three buttons.

Ideal for yes/no/cancel boxes.

The escape key can be used to trigger the third button.

If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.

@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
@param callback if this is non-null, the menu will be launched asynchronously,
returning immediately, and the callback will receive a call to its
modalStateFinished() when the box is dismissed, with its parameter
being 1 if the "yes" button was pressed, 2 for the "no" button, or 0
if it was cancelled, The callback object will be owned and deleted by the
system, so make sure that it works safely and doesn't keep any references
to objects that might be deleted before it gets called.

@returns If the callback parameter has been set, this returns 0. Otherwise, it returns one
of the following values:
- 0 if 'cancel' was pressed
- 1 if 'yes' was pressed
- 2 if 'no' was pressed
*/
static int JUCE_CALLTYPE showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
#if JUCE_MODAL_LOOPS_PERMITTED
Component* associatedComponent = 0,
ModalComponentManager::Callback* callback = 0);
#else
Component* associatedComponent,
ModalComponentManager::Callback* callback);
#endif
};

#endif // __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__
/*** End of inlined file: juce_NativeMessageBox.h ***/


#endif
#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__



+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 60
#define JUCE_BUILDNUMBER 61
/** Current Juce version number.


+ 1
- 1
src/core/juce_TargetPlatform.h View File

@@ -174,7 +174,7 @@
#endif
#endif
#if ! JUCE_VC7_OR_EARLIER && ! defined (__INTEL_COMPILER)
#if ! JUCE_VC7_OR_EARLIER
#define JUCE_USE_INTRINSICS 1
#endif
#else


+ 15
- 1
src/gui/components/lookandfeel/juce_LookAndFeel.cpp View File

@@ -163,6 +163,7 @@ namespace LookAndFeelHelpers
//==============================================================================
LookAndFeel::LookAndFeel()
: useNativeAlertWindows (false)
{
/* if this fails it means you're trying to create a LookAndFeel object before
the static Colours have been initialised. That ain't gonna work. It probably
@@ -696,6 +697,20 @@ const Font LookAndFeel::getAlertWindowFont()
return Font (12.0f);
}
void LookAndFeel::setUsingNativeAlertWindows (bool shouldUseNativeAlerts)
{
useNativeAlertWindows = shouldUseNativeAlerts;
}
bool LookAndFeel::isUsingNativeAlertWindows()
{
#if JUCE_LINUX
return false; // not available currently..
#else
return useNativeAlertWindows;
#endif
}
//==============================================================================
void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar,
int width, int height,
@@ -1688,7 +1703,6 @@ class SliderLabelComp : public Label
{
public:
SliderLabelComp() : Label (String::empty, String::empty) {}
~SliderLabelComp() {}
void mouseWheelMove (const MouseEvent&, float, float) {}
};


+ 4
- 0
src/gui/components/lookandfeel/juce_LookAndFeel.h View File

@@ -203,6 +203,9 @@ public:
virtual const Font getAlertWindowMessageFont();
virtual const Font getAlertWindowFont();
void setUsingNativeAlertWindows (bool shouldUseNativeAlerts);
bool isUsingNativeAlertWindows();
/** Draws a progress bar.
If the progress value is less than 0 or greater than 1.0, this should draw a spinning
@@ -657,6 +660,7 @@ private:
ScopedPointer<Drawable> folderImage, documentImage;
bool useNativeAlertWindows;
void drawShinyButtonShape (Graphics& g,
float x, float y, float w, float h, float maxCornerSize,


+ 61
- 15
src/gui/components/windows/juce_AlertWindow.cpp View File

@@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE
#include "../../../events/juce_MessageManager.h"
#include "../../../application/juce_Application.h"
#include "../../../memory/juce_ScopedPointer.h"
#include "juce_NativeMessageBox.h"
//==============================================================================
@@ -668,10 +669,17 @@ void AlertWindow::showMessageBox (AlertIconType iconType,
const String& buttonText,
Component* associatedComponent)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, true);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
NativeMessageBox::showMessageBox (iconType, title, message, associatedComponent);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, true);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
info.invoke();
info.invoke();
}
}
#endif
@@ -681,10 +689,17 @@ void AlertWindow::showMessageBoxAsync (AlertIconType iconType,
const String& buttonText,
Component* associatedComponent)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, false);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
return NativeMessageBox::showMessageBoxAsync (iconType, title, message, associatedComponent);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 1, 0, false);
info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText;
info.invoke();
info.invoke();
}
}
bool AlertWindow::showOkCancelBox (AlertIconType iconType,
@@ -695,11 +710,18 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 2, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("ok") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
return NativeMessageBox::showOkCancelBox (iconType, title, message, associatedComponent, callback);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 2, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("ok") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text;
return info.invoke() != 0;
return info.invoke() != 0;
}
}
int AlertWindow::showYesNoCancelBox (AlertIconType iconType,
@@ -711,12 +733,36 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 3, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("yes") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("no") : button2Text;
info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text;
if (LookAndFeel::getDefaultLookAndFeel().isUsingNativeAlertWindows())
{
return NativeMessageBox::showYesNoCancelBox (iconType, title, message, associatedComponent, callback);
}
else
{
AlertWindowInfo info (title, message, associatedComponent, iconType, 3, callback, callback == 0);
info.button1 = button1Text.isEmpty() ? TRANS("yes") : button1Text;
info.button2 = button2Text.isEmpty() ? TRANS("no") : button2Text;
info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text;
return info.invoke();
return info.invoke();
}
}
#if JUCE_MODAL_LOOPS_PERMITTED
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
{
if (isOkCancel)
{
return NativeMessageBox::showOkCancelBox (AlertWindow::NoIcon, title, bodyText);
}
else
{
NativeMessageBox::showMessageBox (AlertWindow::NoIcon, title, bodyText);
return true;
}
}
#endif
END_JUCE_NAMESPACE

+ 2
- 0
src/gui/components/windows/juce_AlertWindow.h View File

@@ -395,9 +395,11 @@ public:
it'll show a box with just an ok button
@returns true if the ok button was pressed, false if they pressed cancel.
*/
#if JUCE_MODAL_LOOPS_PERMITTED
static bool JUCE_CALLTYPE showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel);
#endif
//==============================================================================


+ 157
- 0
src/gui/components/windows/juce_NativeMessageBox.h View File

@@ -0,0 +1,157 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__
#define __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__
class NativeMessageBox
{
public:
/** Shows a dialog box that just has a message and a single 'ok' button to close it.
If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.
@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
*/
#if JUCE_MODAL_LOOPS_PERMITTED
static void JUCE_CALLTYPE showMessageBox (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
Component* associatedComponent = 0);
#endif
/** Shows a dialog box that just has a message and a single 'ok' button to close it.
If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.
@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
*/
static void JUCE_CALLTYPE showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
Component* associatedComponent = 0);
/** Shows a dialog box with two buttons.
Ideal for ok/cancel or yes/no choices. The return key can also be used
to trigger the first button, and the escape key for the second button.
If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.
@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
@param callback if this is non-null, the menu will be launched asynchronously,
returning immediately, and the callback will receive a call to its
modalStateFinished() when the box is dismissed, with its parameter
being 1 if the ok button was pressed, or 0 for cancel, The callback object
will be owned and deleted by the system, so make sure that it works
safely and doesn't keep any references to objects that might be deleted
before it gets called.
@returns true if button 1 was clicked, false if it was button 2. If the callback parameter
is not null, the method always returns false, and the user's choice is delivered
later by the callback.
*/
static bool JUCE_CALLTYPE showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
#if JUCE_MODAL_LOOPS_PERMITTED
Component* associatedComponent = 0,
ModalComponentManager::Callback* callback = 0);
#else
Component* associatedComponent,
ModalComponentManager::Callback* callback);
#endif
/** Shows a dialog box with three buttons.
Ideal for yes/no/cancel boxes.
The escape key can be used to trigger the third button.
If the callback parameter is null, the box is shown modally, and the method will
block until the user has clicked the button (or pressed the escape or return keys).
If the callback parameter is non-null, the box will be displayed and placed into a
modal state, but this method will return immediately, and the callback will be invoked
later when the user dismisses the box.
@param iconType the type of icon to show
@param title the headline to show at the top of the box
@param message a longer, more descriptive message to show underneath the title
@param associatedComponent if this is non-null, it specifies the component that the
alert window should be associated with. Depending on the look
and feel, this might be used for positioning of the alert window.
@param callback if this is non-null, the menu will be launched asynchronously,
returning immediately, and the callback will receive a call to its
modalStateFinished() when the box is dismissed, with its parameter
being 1 if the "yes" button was pressed, 2 for the "no" button, or 0
if it was cancelled, The callback object will be owned and deleted by the
system, so make sure that it works safely and doesn't keep any references
to objects that might be deleted before it gets called.
@returns If the callback parameter has been set, this returns 0. Otherwise, it returns one
of the following values:
- 0 if 'cancel' was pressed
- 1 if 'yes' was pressed
- 2 if 'no' was pressed
*/
static int JUCE_CALLTYPE showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title,
const String& message,
#if JUCE_MODAL_LOOPS_PERMITTED
Component* associatedComponent = 0,
ModalComponentManager::Callback* callback = 0);
#else
Component* associatedComponent,
ModalComponentManager::Callback* callback);
#endif
};
#endif // __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__

+ 3
- 0
src/juce_app_includes.h View File

@@ -614,6 +614,9 @@
#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__
#include "gui/components/windows/juce_DocumentWindow.h"
#endif
#ifndef __JUCE_NATIVEMESSAGEBOX_JUCEHEADER__
#include "gui/components/windows/juce_NativeMessageBox.h"
#endif
#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__
#include "gui/components/windows/juce_ResizableWindow.h"
#endif


+ 83
- 0
src/native/android/java/JuceAppActivity.java View File

@@ -26,6 +26,8 @@
package com.juce;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.content.Context;
import android.view.ViewGroup;
@@ -167,6 +169,87 @@ public final class JuceAppActivity extends Activity
clipboard.setText (newText);
}
//==============================================================================
public final void showMessageBox (String title, String message, final long callback)
{
AlertDialog.Builder builder = new AlertDialog.Builder (this);
builder.setTitle (title)
.setMessage (message)
.setCancelable (true)
.setPositiveButton ("OK", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
JuceAppActivity.this.alertDismissed (callback, 0);
}
});
builder.create().show();
}
public final void showOkCancelBox (String title, String message, final long callback)
{
AlertDialog.Builder builder = new AlertDialog.Builder (this);
builder.setTitle (title)
.setMessage (message)
.setCancelable (true)
.setPositiveButton ("OK", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
JuceAppActivity.this.alertDismissed (callback, 1);
}
})
.setNegativeButton ("Cancel", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
JuceAppActivity.this.alertDismissed (callback, 0);
}
});
builder.create().show();
}
public final void showYesNoCancelBox (String title, String message, final long callback)
{
AlertDialog.Builder builder = new AlertDialog.Builder (this);
builder.setTitle (title)
.setMessage (message)
.setCancelable (true)
.setPositiveButton ("Yes", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
JuceAppActivity.this.alertDismissed (callback, 1);
}
})
.setNegativeButton ("No", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
JuceAppActivity.this.alertDismissed (callback, 2);
}
})
.setNeutralButton ("Cancel", new DialogInterface.OnClickListener()
{
public void onClick (DialogInterface dialog, int id)
{
dialog.cancel();
JuceAppActivity.this.alertDismissed (callback, 0);
}
});
builder.create().show();
}
public native void alertDismissed (long callback, int id);
//==============================================================================
public final int[] renderGlyph (char glyph, Paint paint, Matrix matrix, Rect bounds)
{


+ 4
- 0
src/native/android/juce_android_NativeCode.cpp View File

@@ -66,6 +66,7 @@ BEGIN_JUCE_NAMESPACE
#include "../../gui/graphics/imaging/juce_CameraDevice.h"
#include "../../gui/components/windows/juce_ComponentPeer.h"
#include "../../gui/components/windows/juce_AlertWindow.h"
#include "../../gui/components/windows/juce_NativeMessageBox.h"
#include "../../gui/components/juce_Desktop.h"
#include "../../gui/components/menus/juce_MenuBarModel.h"
#include "../../gui/components/special/juce_OpenGLComponent.h"
@@ -147,6 +148,9 @@ BEGIN_JUCE_NAMESPACE
METHOD (activityClass, excludeClipRegion, "excludeClipRegion", "(Landroid/graphics/Canvas;FFFF)V") \
METHOD (activityClass, renderGlyph, "renderGlyph", "(CLandroid/graphics/Paint;Landroid/graphics/Matrix;Landroid/graphics/Rect;)[I") \
STATICMETHOD (activityClass, createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;ILjava/lang/StringBuffer;)Lcom/juce/JuceAppActivity$HTTPStream;") \
METHOD (activityClass, showMessageBox, "showMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
METHOD (activityClass, showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
METHOD (activityClass, showYesNoCancelBox, "showYesNoCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \
\
METHOD (stringBufferClass, stringBufferConstructor, "<init>", "()V") \
METHOD (stringBufferClass, stringBufferToString, "toString", "()Ljava/lang/String;") \


+ 36
- 4
src/native/android/juce_android_Windowing.cpp View File

@@ -592,12 +592,44 @@ bool Process::isForegroundProcess()
}
//==============================================================================
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
// TODO
android.activity.callVoidMethod (android.showMessageBox, javaString (title).get(), javaString (message).get(), (jlong) 0);
}
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
jassert (callback != 0); // on android, all alerts must be non-modal!!
android.activity.callVoidMethod (android.showOkCancelBox, javaString (title).get(), javaString (message).get(),
(jlong) (pointer_sized_int) callback);
return 0;
}
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
jassert (callback != 0); // on android, all alerts must be non-modal!!
android.activity.callVoidMethod (android.showYesNoCancelBox, javaString (title).get(), javaString (message).get(),
(jlong) (pointer_sized_int) callback);
return 0;
}
JUCE_JNI_CALLBACK (JuceAppActivity, alertDismissed, void, (JNIEnv* env, jobject activity,
jlong callbackAsLong, jint result))
{
ModalComponentManager::Callback* callback = (ModalComponentManager::Callback*) callbackAsLong;
if (callback != 0)
callback->modalStateFinished (result);
}
//==============================================================================


+ 1
- 0
src/native/linux/juce_linux_NativeCode.cpp View File

@@ -88,6 +88,7 @@ BEGIN_JUCE_NAMESPACE
#include "../../gui/components/keyboard/juce_KeyPress.h"
#include "../../gui/components/windows/juce_ComponentPeer.h"
#include "../../gui/components/windows/juce_AlertWindow.h"
#include "../../gui/components/windows/juce_NativeMessageBox.h"
#include "../../gui/components/filebrowser/juce_FileChooser.h"
#include "../../gui/components/special/juce_WebBrowserComponent.h"
#include "../../gui/components/special/juce_OpenGLComponent.h"


+ 30
- 9
src/native/linux/juce_linux_Windowing.cpp View File

@@ -3342,19 +3342,40 @@ void PlatformUtilities::beep()
//==============================================================================
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
// use a non-native one for the time being..
if (isOkCancel)
return AlertWindow::showOkCancelBox (AlertWindow::NoIcon, title, bodyText);
else
AlertWindow::showMessageBox (AlertWindow::NoIcon, title, bodyText);
AlertWindow::showMessageBox (AlertWindow::NoIcon, title, message);
}
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
AlertWindow::showMessageBoxAsync (AlertWindow::NoIcon, title, message);
}
return true;
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
return AlertWindow::showOkCancelBox (iconType, title, message, String::empty, String::empty,
associatedComponent, callback);
}
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
return AlertWindow::showYesNoCancelBox (iconType, title, message,
String::empty, String::empty, String::empty,
associatedComponent, callback);
}
//==============================================================================
const int KeyPress::spaceKey = XK_space & 0xff;
const int KeyPress::returnKey = XK_Return & 0xff;


+ 104
- 29
src/native/mac/juce_ios_MiscUtilities.mm View File

@@ -91,65 +91,140 @@ void PlatformUtilities::addItemToDock (const File& file)
//==============================================================================
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
//==============================================================================
class iOSMessageBox;
END_JUCE_NAMESPACE
@interface JuceAlertBoxDelegate : NSObject
{
@public
bool clickedOk;
iOSMessageBox* owner;
}
- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex;
@end
BEGIN_JUCE_NAMESPACE
class iOSMessageBox
{
public:
iOSMessageBox (const String& title, const String& message,
NSString* button1, NSString* button2, NSString* button3,
ModalComponentManager::Callback* callback_, const bool isAsync_)
: result (0), delegate (nil), alert (nil),
callback (callback_), isYesNo (button3 != nil), isAsync (isAsync_)
{
delegate = [[JuceAlertBoxDelegate alloc] init];
delegate->owner = this;
alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title)
message: juceStringToNS (message)
delegate: delegate
cancelButtonTitle: button1
otherButtonTitles: button2, button3, nil];
[alert retain];
[alert show];
}
~iOSMessageBox()
{
[alert release];
[delegate release];
}
int getResult()
{
jassert (callback == 0);
const ScopedAutoReleasePool pool;
while (! alert.hidden && alert.superview != nil)
[[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
return result;
}
void buttonClicked (const int buttonIndex) throw()
{
result = buttonIndex;
if (callback != 0)
callback->modalStateFinished (result);
if (isAsync)
delete this;
}
private:
int result;
JuceAlertBoxDelegate* delegate;
UIAlertView* alert;
ModalComponentManager::Callback* callback;
const bool isYesNo, isAsync;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox);
};
END_JUCE_NAMESPACE
@implementation JuceAlertBoxDelegate
- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex
{
clickedOk = (buttonIndex == 0);
owner->buttonClicked (buttonIndex);
alertView.hidden = true;
}
@end
BEGIN_JUCE_NAMESPACE
// (This function is used directly by other bits of code)
bool juce_iPhoneShowModalAlert (const String& title,
const String& bodyText,
NSString* okButtonText,
NSString* cancelButtonText)
//==============================================================================
void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
const ScopedAutoReleasePool pool;
iOSMessageBox mb (title, message, @"OK", nil, nil, 0, false);
(void) mb.getResult();
}
JuceAlertBoxDelegate* callback = [[JuceAlertBoxDelegate alloc] init];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title)
message: juceStringToNS (bodyText)
delegate: callback
cancelButtonTitle: okButtonText
otherButtonTitles: cancelButtonText, nil];
[alert retain];
[alert show];
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
const ScopedAutoReleasePool pool;
new iOSMessageBox (title, message, @"OK", nil, nil, 0, true);
}
while (! alert.hidden && alert.superview != nil)
[[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"OK", nil, callback, callback != 0));
const bool result = callback->clickedOk;
[alert release];
[callback release];
if (callback == 0)
return mb->getResult() == 1;
return result;
mb.release();
return 0;
}
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
return juce_iPhoneShowModalAlert (title, bodyText,
@"OK",
isOkCancel ? @"Cancel" : nil);
ScopedPointer<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != 0));
if (callback == 0)
return mb->getResult();
mb.release();
return 0;
}
//==============================================================================


+ 107
- 9
src/native/mac/juce_mac_MiscUtilities.mm View File

@@ -63,18 +63,116 @@ void PlatformUtilities::addItemToDock (const File& file)
//==============================================================================
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
//==============================================================================
class OSXMessageBox : public AsyncUpdater
{
const ScopedAutoReleasePool pool;
return NSRunAlertPanel (juceStringToNS (title),
juceStringToNS (bodyText),
@"Ok",
isOkCancel ? @"Cancel" : nil,
nil) == NSAlertDefaultReturn;
public:
OSXMessageBox (AlertWindow::AlertIconType iconType_,
const String& title_, const String& message_,
NSString* button1_, NSString* button2_, NSString* button3_,
ModalComponentManager::Callback* callback_,
const bool runAsync)
: iconType (iconType_), title (title_),
message (message_), callback (callback_),
button1 ([button1_ retain]),
button2 ([button2_ retain]),
button3 ([button3_ retain])
{
if (runAsync)
triggerAsyncUpdate();
}
~OSXMessageBox()
{
[button1 release];
[button2 release];
[button3 release];
}
int getResult() const
{
const ScopedAutoReleasePool pool;
NSInteger r = getRawResult();
return r == NSAlertDefaultReturn ? 1 : (r == NSAlertOtherReturn ? 2 : 0);
}
void handleAsyncUpdate()
{
const int result = getResult();
if (callback != 0)
callback->modalStateFinished (result);
delete this;
}
private:
AlertWindow::AlertIconType iconType;
String title, message;
ModalComponentManager::Callback* callback;
NSString* button1;
NSString* button2;
NSString* button3;
NSInteger getRawResult() const
{
NSString* messageString = juceStringToNS (message);
NSString* titleString = juceStringToNS (title);
switch (iconType)
{
case AlertWindow::InfoIcon: return NSRunInformationalAlertPanel (titleString, messageString, button1, button2, button3);
case AlertWindow::WarningIcon: return NSRunCriticalAlertPanel (titleString, messageString, button1, button2, button3);
default: return NSRunAlertPanel (titleString, messageString, button1, button2, button3);
}
}
};
void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
OSXMessageBox box (iconType, title, message, @"OK", nil, nil, 0, false);
(void) box.getResult();
}
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent)
{
new OSXMessageBox (iconType, title, message, @"OK", nil, nil, 0, true);
}
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<OSXMessageBox> mb (new OSXMessageBox (iconType, title, message,
@"OK", @"Cancel", nil, callback, callback != 0));
if (callback == 0)
return mb->getResult() == 1;
mb.release();
return 0;
}
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
const String& title, const String& message,
Component* associatedComponent,
ModalComponentManager::Callback* callback)
{
ScopedPointer<OSXMessageBox> mb (new OSXMessageBox (iconType, title, message,
@"Yes", @"Cancel", @"No", callback, callback != 0));
if (callback == 0)
return mb->getResult();
mb.release();
return 0;
}
//==============================================================================
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /*canMoveFiles*/)
{


+ 1
- 0
src/native/mac/juce_mac_NativeCode.mm View File

@@ -71,6 +71,7 @@ BEGIN_JUCE_NAMESPACE
#include "../../gui/graphics/imaging/juce_ImageFileFormat.h"
#include "../../gui/graphics/imaging/juce_CameraDevice.h"
#include "../../gui/components/windows/juce_AlertWindow.h"
#include "../../gui/components/windows/juce_NativeMessageBox.h"
#include "../../gui/components/windows/juce_ComponentPeer.h"
#include "../../gui/components/juce_Desktop.h"
#include "../../gui/components/menus/juce_MenuBarModel.h"


+ 1
- 0
src/native/windows/juce_win32_NativeCode.cpp View File

@@ -66,6 +66,7 @@ BEGIN_JUCE_NAMESPACE
#include "../../gui/graphics/imaging/juce_CameraDevice.h"
#include "../../gui/components/windows/juce_ComponentPeer.h"
#include "../../gui/components/windows/juce_AlertWindow.h"
#include "../../gui/components/windows/juce_NativeMessageBox.h"
#include "../../gui/components/juce_Desktop.h"
#include "../../gui/components/menus/juce_MenuBarModel.h"
#include "../../gui/components/special/juce_OpenGLComponent.h"


+ 3320
- 3227
src/native/windows/juce_win32_Windowing.cpp
File diff suppressed because it is too large
View File


+ 1
- 1
src/text/juce_String.h View File

@@ -1323,7 +1323,7 @@ std::basic_ostream <wchar_t, traits>& JUCE_CALLTYPE operator<< (std::basic_ostre
}
/** Writes a string to an OutputStream as UTF8. */
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text);
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& stringToWrite);
#endif // __JUCE_STRING_JUCEHEADER__

Loading…
Cancel
Save