| @@ -49,7 +49,7 @@ public: | |||
| This will take care of creating any groups needed to get to the given | |||
| registry value. | |||
| */ | |||
| static void setValue (const String& regValuePath, | |||
| static bool setValue (const String& regValuePath, | |||
| const String& value); | |||
| /** Returns true if the given value exists in the registry. */ | |||
| @@ -72,12 +72,17 @@ public: | |||
| @param iconResourceNumber the icon that gets displayed for the file type will be | |||
| found by looking up this resource number in the | |||
| executable. Pass 0 here to not use an icon | |||
| @param registerForCurrentUserOnly if false, this will try to register the association | |||
| for all users (you might not have permission to do this | |||
| unless running in an installer). If true, it will register the | |||
| association in HKEY_CURRENT_USER. | |||
| */ | |||
| static void registerFileAssociation (const String& fileExtension, | |||
| static bool registerFileAssociation (const String& fileExtension, | |||
| const String& symbolicDescription, | |||
| const String& fullDescription, | |||
| const File& targetExecutable, | |||
| int iconResourceNumber); | |||
| int iconResourceNumber, | |||
| bool registerForCurrentUserOnly); | |||
| private: | |||
| WindowsRegistry(); | |||
| @@ -89,14 +89,14 @@ String WindowsRegistry::getValue (const String& regValuePath, const String& defa | |||
| return defaultValue; | |||
| } | |||
| void WindowsRegistry::setValue (const String& regValuePath, const String& value) | |||
| bool WindowsRegistry::setValue (const String& regValuePath, const String& value) | |||
| { | |||
| const RegistryKeyWrapper key (regValuePath, true); | |||
| if (key.key != 0) | |||
| RegSetValueEx (key.key, key.wideCharValueName, 0, REG_SZ, | |||
| (const BYTE*) value.toWideCharPointer(), | |||
| (DWORD) CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer())); | |||
| return key.key != 0 | |||
| && RegSetValueEx (key.key, key.wideCharValueName, 0, REG_SZ, | |||
| (const BYTE*) value.toWideCharPointer(), | |||
| (DWORD) CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer())) == ERROR_SUCCESS; | |||
| } | |||
| bool WindowsRegistry::valueExists (const String& regValuePath) | |||
| @@ -130,20 +130,21 @@ void WindowsRegistry::deleteKey (const String& regKeyPath) | |||
| RegDeleteKey (key.key, key.wideCharValueName); | |||
| } | |||
| void WindowsRegistry::registerFileAssociation (const String& fileExtension, | |||
| bool WindowsRegistry::registerFileAssociation (const String& fileExtension, | |||
| const String& symbolicDescription, | |||
| const String& fullDescription, | |||
| const File& targetExecutable, | |||
| int iconResourceNumber) | |||
| const int iconResourceNumber, | |||
| const bool registerForCurrentUserOnly) | |||
| { | |||
| setValue ("HKEY_CLASSES_ROOT\\" + fileExtension + "\\", symbolicDescription); | |||
| const String key ("HKEY_CLASSES_ROOT\\" + symbolicDescription); | |||
| if (iconResourceNumber != 0) | |||
| setValue (key + "\\DefaultIcon\\", | |||
| targetExecutable.getFullPathName() + "," + String (-iconResourceNumber)); | |||
| setValue (key + "\\", fullDescription); | |||
| setValue (key + "\\shell\\open\\command\\", targetExecutable.getFullPathName() + " %1"); | |||
| const char* const root = registerForCurrentUserOnly ? "HKEY_CURRENT_USER\\Software\\Classes\\" | |||
| : "HKEY_CLASSES_ROOT\\"; | |||
| const String key (root + symbolicDescription); | |||
| return setValue (root + fileExtension + "\\", symbolicDescription) | |||
| && setValue (key + "\\", fullDescription) | |||
| && setValue (key + "\\shell\\open\\command\\", targetExecutable.getFullPathName() + " \"%1\"") | |||
| && (iconResourceNumber == 0 | |||
| || setValue (key + "\\DefaultIcon\\", | |||
| targetExecutable.getFullPathName() + "," + String (-iconResourceNumber))); | |||
| } | |||
| @@ -140,19 +140,13 @@ public: | |||
| //============================================================================== | |||
| /** Returns the rectangle's top-left position as a Point. */ | |||
| const Point<ValueType>& getPosition() const noexcept { return pos; } | |||
| inline const Point<ValueType>& getPosition() const noexcept { return pos; } | |||
| /** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */ | |||
| void setPosition (const Point<ValueType>& newPos) noexcept { pos = newPos; } | |||
| inline void setPosition (const Point<ValueType>& newPos) noexcept { pos = newPos; } | |||
| /** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */ | |||
| void setPosition (const ValueType newX, const ValueType newY) noexcept { pos.setXY (newX, newY); } | |||
| /** Returns a rectangle with the same size as this one, but a new position. */ | |||
| Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); } | |||
| /** Returns a rectangle with the same size as this one, but a new position. */ | |||
| Rectangle withPosition (const Point<ValueType>& newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); } | |||
| inline void setPosition (const ValueType newX, const ValueType newY) noexcept { pos.setXY (newX, newY); } | |||
| /** Returns the rectangle's top-left position as a Point. */ | |||
| const Point<ValueType>& getTopLeft() const noexcept { return pos; } | |||
| @@ -169,49 +163,51 @@ public: | |||
| /** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */ | |||
| void setSize (const ValueType newWidth, const ValueType newHeight) noexcept { w = newWidth; h = newHeight; } | |||
| /** Returns a rectangle with the same position as this one, but a new size. */ | |||
| Rectangle withSize (const ValueType newWidth, const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); } | |||
| /** Changes all the rectangle's co-ordinates. */ | |||
| void setBounds (const ValueType newX, const ValueType newY, | |||
| const ValueType newWidth, const ValueType newHeight) noexcept | |||
| { | |||
| pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; | |||
| } | |||
| const ValueType newWidth, const ValueType newHeight) noexcept { pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; } | |||
| /** Changes the rectangle's X coordinate */ | |||
| void setX (const ValueType newX) noexcept { pos.x = newX; } | |||
| inline void setX (const ValueType newX) noexcept { pos.x = newX; } | |||
| /** Changes the rectangle's Y coordinate */ | |||
| void setY (const ValueType newY) noexcept { pos.y = newY; } | |||
| inline void setY (const ValueType newY) noexcept { pos.y = newY; } | |||
| /** Changes the rectangle's width */ | |||
| void setWidth (const ValueType newWidth) noexcept { w = newWidth; } | |||
| inline void setWidth (const ValueType newWidth) noexcept { w = newWidth; } | |||
| /** Changes the rectangle's height */ | |||
| void setHeight (const ValueType newHeight) noexcept { h = newHeight; } | |||
| inline void setHeight (const ValueType newHeight) noexcept { h = newHeight; } | |||
| /** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */ | |||
| Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); } | |||
| Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); } | |||
| /** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */ | |||
| Rectangle withY (const ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); } | |||
| Rectangle withY (const ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); } | |||
| /** Returns a rectangle with the same size as this one, but a new position. */ | |||
| Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); } | |||
| /** Returns a rectangle with the same size as this one, but a new position. */ | |||
| Rectangle withPosition (const Point<ValueType>& newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); } | |||
| /** Returns a rectangle whose size is the same as this one, but whose top-left position is (0, 0). */ | |||
| Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); } | |||
| /** Returns a rectangle which has the same position and height as this one, but with a different width. */ | |||
| Rectangle withWidth (const ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); } | |||
| Rectangle withWidth (const ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); } | |||
| /** Returns a rectangle which has the same position and width as this one, but with a different height. */ | |||
| Rectangle withHeight (const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); } | |||
| Rectangle withHeight (const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); } | |||
| /** Returns a rectangle with the same position as this one, but a new size. */ | |||
| Rectangle withSize (const ValueType newWidth, const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); } | |||
| /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. | |||
| If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. | |||
| @see withLeft | |||
| */ | |||
| void setLeft (const ValueType newLeft) noexcept | |||
| { | |||
| w = jmax (ValueType(), pos.x + w - newLeft); | |||
| pos.x = newLeft; | |||
| } | |||
| void setLeft (const ValueType newLeft) noexcept { w = jmax (ValueType(), pos.x + w - newLeft); pos.x = newLeft; } | |||
| /** Returns a new rectangle with a different x position, but the same right-hand edge as this one. | |||
| If the new x is beyond the right of the current right-hand edge, the width will be set to zero. | |||
| @@ -223,11 +219,7 @@ public: | |||
| If the y is moved to be below the current bottom edge, the height will be set to zero. | |||
| @see withTop | |||
| */ | |||
| void setTop (const ValueType newTop) noexcept | |||
| { | |||
| h = jmax (ValueType(), pos.y + h - newTop); | |||
| pos.y = newTop; | |||
| } | |||
| void setTop (const ValueType newTop) noexcept { h = jmax (ValueType(), pos.y + h - newTop); pos.y = newTop; } | |||
| /** Returns a new rectangle with a different y position, but the same bottom edge as this one. | |||
| If the new y is beyond the bottom of the current rectangle, the height will be set to zero. | |||
| @@ -239,11 +231,7 @@ public: | |||
| If the new right is below the current X value, the X will be pushed down to match it. | |||
| @see getRight, withRight | |||
| */ | |||
| void setRight (const ValueType newRight) noexcept | |||
| { | |||
| pos.x = jmin (pos.x, newRight); | |||
| w = newRight - pos.x; | |||
| } | |||
| void setRight (const ValueType newRight) noexcept { pos.x = jmin (pos.x, newRight); w = newRight - pos.x; } | |||
| /** Returns a new rectangle with a different right-hand edge position, but the same left-hand edge as this one. | |||
| If the new right edge is below the current left-hand edge, the width will be set to zero. | |||
| @@ -255,11 +243,7 @@ public: | |||
| If the new bottom is lower than the current Y value, the Y will be pushed down to match it. | |||
| @see getBottom, withBottom | |||
| */ | |||
| void setBottom (const ValueType newBottom) noexcept | |||
| { | |||
| pos.y = jmin (pos.y, newBottom); | |||
| h = newBottom - pos.y; | |||
| } | |||
| void setBottom (const ValueType newBottom) noexcept { pos.y = jmin (pos.y, newBottom); h = newBottom - pos.y; } | |||
| /** Returns a new rectangle with a different bottom edge position, but the same top edge as this one. | |||
| If the new y is beyond the bottom of the current rectangle, the height will be set to zero. | |||
| @@ -425,16 +409,10 @@ public: | |||
| //============================================================================== | |||
| /** Returns true if the two rectangles are identical. */ | |||
| bool operator== (const Rectangle& other) const noexcept | |||
| { | |||
| return pos == other.pos && w == other.w && h == other.h; | |||
| } | |||
| bool operator== (const Rectangle& other) const noexcept { return pos == other.pos && w == other.w && h == other.h; } | |||
| /** Returns true if the two rectangles are not identical. */ | |||
| bool operator!= (const Rectangle& other) const noexcept | |||
| { | |||
| return pos != other.pos || w != other.w || h != other.h; | |||
| } | |||
| bool operator!= (const Rectangle& other) const noexcept { return pos != other.pos || w != other.w || h != other.h; } | |||
| /** Returns true if this co-ordinate is inside the rectangle. */ | |||
| bool contains (const ValueType xCoord, const ValueType yCoord) const noexcept | |||
| @@ -473,7 +451,6 @@ public: | |||
| } | |||
| /** Returns the region that is the overlap between this and another rectangle. | |||
| If the two rectangles don't overlap, the rectangle returned will be empty. | |||
| */ | |||
| Rectangle getIntersection (const Rectangle& other) const noexcept | |||
| @@ -716,16 +693,19 @@ public: | |||
| StringArray toks; | |||
| toks.addTokens (stringVersion.trim(), ",; \t\r\n", String::empty); | |||
| return Rectangle (toks[0].trim().getIntValue(), | |||
| toks[1].trim().getIntValue(), | |||
| toks[2].trim().getIntValue(), | |||
| toks[3].trim().getIntValue()); | |||
| return Rectangle (parseIntAfterSpace (toks[0]), | |||
| parseIntAfterSpace (toks[1]), | |||
| parseIntAfterSpace (toks[2]), | |||
| parseIntAfterSpace (toks[3])); | |||
| } | |||
| private: | |||
| friend class RectangleList; | |||
| Point<ValueType> pos; | |||
| ValueType w, h; | |||
| static int parseIntAfterSpace (const String& s) noexcept | |||
| { return s.getCharPointer().findEndOfWhitespace().getIntValue32(); } | |||
| }; | |||
| @@ -58,16 +58,20 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||
| ChildProcess child; | |||
| if (child.start (command)) | |||
| { | |||
| const String result (child.readAllProcessOutput()); | |||
| StringArray tokens; | |||
| const String result (child.readAllProcessOutput().trim()); | |||
| if (selectMultipleFiles) | |||
| tokens.addTokens (result, separator, "\""); | |||
| else | |||
| tokens.add (result); | |||
| if (result.isNotEmpty()) | |||
| { | |||
| StringArray tokens; | |||
| for (int i = 0; i < tokens.size(); i++) | |||
| results.add (File (tokens[i])); | |||
| if (selectMultipleFiles) | |||
| tokens.addTokens (result, separator, "\""); | |||
| else | |||
| tokens.add (result); | |||
| for (int i = 0; i < tokens.size(); i++) | |||
| results.add (File (tokens[i])); | |||
| } | |||
| child.waitForProcessToFinish (60 * 1000); | |||
| } | |||
| @@ -744,7 +744,6 @@ public: | |||
| LinuxComponentPeer (Component* const component, const int windowStyleFlags, Window parentToAddTo) | |||
| : ComponentPeer (component, windowStyleFlags), | |||
| windowH (0), parentWindow (0), | |||
| wx (0), wy (0), ww (0), wh (0), | |||
| fullScreen (false), mapped (false), | |||
| visual (0), depth (0) | |||
| { | |||
| @@ -814,26 +813,49 @@ public: | |||
| void setBounds (int x, int y, int w, int h, bool isNowFullScreen) | |||
| { | |||
| if (fullScreen && ! isNowFullScreen) | |||
| { | |||
| // When transitioning back from fullscreen, we might need to remove | |||
| // the FULLSCREEN window property | |||
| Atom fs = Atoms::getIfExists ("_NET_WM_STATE_FULLSCREEN"); | |||
| if (fs != None) | |||
| { | |||
| Window root = RootWindow (display, DefaultScreen (display)); | |||
| XClientMessageEvent clientMsg; | |||
| clientMsg.display = display; | |||
| clientMsg.window = windowH; | |||
| clientMsg.type = ClientMessage; | |||
| clientMsg.format = 32; | |||
| clientMsg.message_type = Atoms::WindowState; | |||
| clientMsg.data.l[0] = 0; // Remove | |||
| clientMsg.data.l[1] = fs; | |||
| clientMsg.data.l[2] = 0; | |||
| clientMsg.data.l[3] = 1; // Normal Source | |||
| ScopedXLock xlock; | |||
| XSendEvent (display, root, false, | |||
| SubstructureRedirectMask | SubstructureNotifyMask, | |||
| (XEvent*) &clientMsg); | |||
| } | |||
| } | |||
| fullScreen = isNowFullScreen; | |||
| if (windowH != 0) | |||
| { | |||
| WeakReference<Component> deletionChecker (component); | |||
| wx = x; | |||
| wy = y; | |||
| ww = jmax (1, w); | |||
| wh = jmax (1, h); | |||
| bounds.setBounds (x, y, jmax (1, w), jmax (1, h)); | |||
| WeakReference<Component> deletionChecker (component); | |||
| ScopedXLock xlock; | |||
| // Make sure the Window manager does what we want | |||
| XSizeHints* hints = XAllocSizeHints(); | |||
| hints->flags = USSize | USPosition; | |||
| hints->width = ww; | |||
| hints->height = wh; | |||
| hints->x = wx; | |||
| hints->y = wy; | |||
| XSizeHints* const hints = XAllocSizeHints(); | |||
| hints->flags = USSize | USPosition; | |||
| hints->x = bounds.getX(); | |||
| hints->y = bounds.getY(); | |||
| hints->width = bounds.getWidth(); | |||
| hints->height = bounds.getHeight(); | |||
| if ((getStyleFlags() & (windowHasTitleBar | windowIsResizable)) == windowHasTitleBar) | |||
| { | |||
| @@ -846,10 +868,12 @@ public: | |||
| XFree (hints); | |||
| XMoveResizeWindow (display, windowH, | |||
| wx - windowBorder.getLeft(), | |||
| wy - windowBorder.getTop(), ww, wh); | |||
| bounds.getX() - windowBorder.getLeft(), | |||
| bounds.getY() - windowBorder.getTop(), | |||
| bounds.getWidth(), | |||
| bounds.getHeight()); | |||
| if (deletionChecker != 0) | |||
| if (deletionChecker != nullptr) | |||
| { | |||
| updateBorderSize(); | |||
| handleMovedOrResized(); | |||
| @@ -857,10 +881,10 @@ public: | |||
| } | |||
| } | |||
| void setPosition (int x, int y) { setBounds (x, y, ww, wh, false); } | |||
| void setSize (int w, int h) { setBounds (wx, wy, w, h, false); } | |||
| Rectangle<int> getBounds() const { return Rectangle<int> (wx, wy, ww, wh); } | |||
| Point<int> getScreenPosition() const { return Point<int> (wx, wy); } | |||
| void setPosition (int x, int y) { setBounds (x, y, bounds.getWidth(), bounds.getHeight(), false); } | |||
| void setSize (int w, int h) { setBounds (bounds.getX(), bounds.getY(), w, h, false); } | |||
| Rectangle<int> getBounds() const { return bounds; } | |||
| Point<int> getScreenPosition() const { return bounds.getPosition(); } | |||
| Point<int> localToGlobal (const Point<int>& relativePosition) | |||
| { | |||
| @@ -998,7 +1022,7 @@ public: | |||
| bool contains (const Point<int>& position, bool trueIfInAChildWindow) const | |||
| { | |||
| if (! (isPositiveAndBelow (position.getX(), ww) && isPositiveAndBelow (position.getY(), wh))) | |||
| if (! bounds.withZeroOrigin().contains (position)) | |||
| return false; | |||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | |||
| @@ -1008,7 +1032,7 @@ public: | |||
| if (c == getComponent()) | |||
| break; | |||
| if (c->contains (position + Point<int> (wx, wy) - c->getScreenPosition())) | |||
| if (c->contains (position + bounds.getPosition() - c->getScreenPosition())) | |||
| return false; | |||
| } | |||
| @@ -1016,21 +1040,14 @@ public: | |||
| return true; | |||
| ::Window root, child; | |||
| unsigned int bw, depth; | |||
| int wx, wy, w, h; | |||
| int wx, wy; | |||
| unsigned int ww, wh, bw, depth; | |||
| ScopedXLock xlock; | |||
| if (! XGetGeometry (display, (::Drawable) windowH, &root, | |||
| &wx, &wy, (unsigned int*) &w, (unsigned int*) &h, | |||
| &bw, &depth)) | |||
| { | |||
| return false; | |||
| } | |||
| if (! XTranslateCoordinates (display, windowH, windowH, position.getX(), position.getY(), &wx, &wy, &child)) | |||
| return false; | |||
| return child == None; | |||
| return XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &depth) | |||
| && XTranslateCoordinates (display, windowH, windowH, position.getX(), position.getY(), &wx, &wy, &child) | |||
| && child == None; | |||
| } | |||
| BorderSize<int> getFrameSize() const | |||
| @@ -1821,7 +1838,7 @@ private: | |||
| friend class LinuxRepaintManager; | |||
| Window windowH, parentWindow; | |||
| int wx, wy, ww, wh; | |||
| Rectangle<int> bounds; | |||
| Image taskbarImage; | |||
| bool fullScreen, mapped; | |||
| Visual* visual; | |||
| @@ -2230,19 +2247,16 @@ private: | |||
| if (windowH != 0) | |||
| { | |||
| Window root, child; | |||
| unsigned int bw, depth; | |||
| int wx = 0, wy = 0; | |||
| unsigned int ww = 0, wh = 0, bw, depth; | |||
| ScopedXLock xlock; | |||
| if (! XGetGeometry (display, (::Drawable) windowH, &root, | |||
| &wx, &wy, (unsigned int*) &ww, (unsigned int*) &wh, | |||
| &bw, &depth)) | |||
| { | |||
| wx = wy = ww = wh = 0; | |||
| } | |||
| else if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child)) | |||
| { | |||
| wx = wy = 0; | |||
| } | |||
| if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &depth)) | |||
| if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child)) | |||
| wx = wy = 0; | |||
| bounds.setBounds (wx, wy, ww, wh); | |||
| } | |||
| } | |||
| @@ -74,11 +74,11 @@ public: | |||
| /** @internal */ | |||
| void paint (Graphics& g); | |||
| /** @internal */ | |||
| static ReferenceCountedObject* attachViewToComponent (Component&, void*); | |||
| private: | |||
| class Pimpl; | |||
| friend class Pimpl; | |||
| ScopedPointer<Pimpl> pimpl; | |||
| ReferenceCountedObjectPtr<ReferenceCountedObject> attachment; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponent); | |||
| }; | |||
| @@ -23,10 +23,11 @@ | |||
| ============================================================================== | |||
| */ | |||
| class NSViewComponent::Pimpl : public ComponentMovementWatcher | |||
| class NSViewAttachment : public ReferenceCountedObject, | |||
| public ComponentMovementWatcher | |||
| { | |||
| public: | |||
| Pimpl (NSView* const view_, Component& owner_) | |||
| NSViewAttachment (NSView* const view_, Component& owner_) | |||
| : ComponentMovementWatcher (&owner_), | |||
| view (view_), | |||
| owner (owner_), | |||
| @@ -38,7 +39,7 @@ public: | |||
| componentPeerChanged(); | |||
| } | |||
| ~Pimpl() | |||
| ~NSViewAttachment() | |||
| { | |||
| removeFromParent(); | |||
| [view release]; | |||
| @@ -96,12 +97,6 @@ public: | |||
| componentPeerChanged(); | |||
| } | |||
| Rectangle<int> getViewBounds() const | |||
| { | |||
| NSRect r = [view frame]; | |||
| return Rectangle<int> ((int) r.size.width, (int) r.size.height); | |||
| } | |||
| NSView* const view; | |||
| private: | |||
| @@ -115,7 +110,7 @@ private: | |||
| // override the call and use it as a sign that they're being deleted, which breaks everything.. | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl); | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewAttachment); | |||
| }; | |||
| //============================================================================== | |||
| @@ -126,22 +121,31 @@ void NSViewComponent::setView (void* const view) | |||
| { | |||
| if (view != getView()) | |||
| { | |||
| pimpl = nullptr; | |||
| attachment = nullptr; | |||
| if (view != nullptr) | |||
| pimpl = new Pimpl ((NSView*) view, *this); | |||
| attachment = attachViewToComponent (*this, view); | |||
| } | |||
| } | |||
| void* NSViewComponent::getView() const | |||
| { | |||
| return pimpl == nullptr ? nullptr : pimpl->view; | |||
| return attachment != nullptr ? static_cast <NSViewAttachment*> (attachment.getObject())->view | |||
| : nullptr; | |||
| } | |||
| void NSViewComponent::resizeToFitView() | |||
| { | |||
| if (pimpl != nullptr) | |||
| setBounds (pimpl->getViewBounds()); | |||
| if (attachment != nullptr) | |||
| { | |||
| NSRect r = [static_cast <NSViewAttachment*> (attachment.getObject())->view frame]; | |||
| setBounds (Rectangle<int> ((int) r.size.width, (int) r.size.height)); | |||
| } | |||
| } | |||
| void NSViewComponent::paint (Graphics&) {} | |||
| ReferenceCountedObject* NSViewComponent::attachViewToComponent (Component& comp, void* const view) | |||
| { | |||
| return new NSViewAttachment ((NSView*) view, comp); | |||
| } | |||