|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2017 - ROLI Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found 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.juce.com for more information.
-
- ==============================================================================
- */
-
- #pragma once
-
- //==============================================================================
- class LicenseWebview : public DialogWindow
- {
- public:
- LicenseWebview (ModalComponentManager::Callback* callbackToUse, const String& request)
- : DialogWindow ("Log-in to Projucer", Colour (0xfff1f1f1), true, true)
- {
- LicenseWebviewContent* content;
-
- setUsingNativeTitleBar (true);
- setContentOwned (content = new LicenseWebviewContent (*this, callbackToUse), true);
-
- centreWithSize (getWidth(), getHeight());
-
- content->goToURL (request);
- }
-
- void goToURL (const String& request) { reinterpret_cast<LicenseWebviewContent*> (getContentComponent())->goToURL (request); }
-
- void setPageCallback (const std::function<void (const String&, const HashMap<String, String>&)>& cb)
- {
- reinterpret_cast<LicenseWebviewContent*> (getContentComponent())->pageCallback = cb;
- }
-
- void setNewWindowCallback (const std::function<void (const String&)>& cb)
- {
- reinterpret_cast<LicenseWebviewContent*> (getContentComponent())->newWindowCallback = cb;
- }
-
- void closeButtonPressed() override { exitModalState (-1); }
-
- private:
- class LicenseWebviewContent : public Component
- {
- //==============================================================================
- struct RedirectWebBrowserComponent : public WebBrowserComponent
- {
- RedirectWebBrowserComponent (LicenseWebviewContent& controller) : WebBrowserComponent (false), owner (controller) {}
- virtual ~RedirectWebBrowserComponent() {}
-
- bool pageAboutToLoad (const String& url) override { return owner.pageAboutToLoad (url); }
- void pageFinishedLoading (const String& url) override { owner.pageFinishedLoading (url); }
- void newWindowAttemptingToLoad (const String& url) override { owner.newWindowAttemptingToLoad (url); }
- bool pageLoadHadNetworkError (const String& err) override { return owner.pageLoadHadNetworkError (err); }
-
- LicenseWebviewContent& owner;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RedirectWebBrowserComponent)
- };
-
- //==============================================================================
- struct Header : public Component, private LicenseController::StateChangedCallback,
- private Button::Listener
- {
- Header ()
- : avatarButton ("User Settings", &getIcons().user)
- {
- setOpaque (true);
- addChildComponent (avatarButton);
-
- avatarButton.addListener (this);
-
- if (LicenseController* licenseController = ProjucerApplication::getApp().licenseController)
- {
- licenseController->addLicenseStatusChangedCallback (this);
- licenseStateChanged (licenseController->getState());
- }
- }
-
- virtual ~Header()
- {
- avatarButton.removeListener (this);
-
- if (LicenseController* licenseController = ProjucerApplication::getApp().licenseController)
- licenseController->removeLicenseStatusChangedCallback (this);
- }
-
- void resized() override
- {
- auto r = getLocalBounds().reduced (30, 20);
- avatarButton.setBounds (r.removeFromRight (r.getHeight()));
- }
-
- void paint (Graphics& g) override
- {
- auto r = getLocalBounds().reduced (30, 20);
- g.fillAll (Colour (backgroundColour));
-
- if (juceLogo != nullptr)
- juceLogo->drawWithin (g, r.toFloat(), RectanglePlacement::xLeft + RectanglePlacement::yMid, 1.0);
- }
-
- void licenseStateChanged (const LicenseState& state) override
- {
- avatarButton.iconImage = state.avatar;
- avatarButton.setVisible (state.type != LicenseState::Type::notLoggedIn && state.type != LicenseState::Type::GPL);
- avatarButton.repaint();
- }
-
- void buttonClicked (Button*) override
- {
- if (LicenseController* licenseController = ProjucerApplication::getApp().licenseController)
- {
- const LicenseState::Type type = licenseController->getState().type;
-
- auto* content = new UserSettingsPopup (true);
- content->setSize (200, (type == LicenseState::Type::noLicenseChosenYet ? 100 : 150));
-
- CallOutBox::launchAsynchronously (content, avatarButton.getScreenBounds(), nullptr);
- }
- }
-
- static constexpr uint32 backgroundColour = 0xff414141;
- ScopedPointer<Drawable> juceLogo
- = Drawable::createFromImageData (BinaryData::jucelogowithtext_svg,
- BinaryData::jucelogowithtext_svgSize);
- IconButton avatarButton;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Header)
- };
-
- //==============================================================================
- //==============================================================================
- public:
- LicenseWebviewContent (LicenseWebview& parentWindowToUse, ModalComponentManager::Callback* callbackToUse)
- : parentWindow (parentWindowToUse), modalCallback (callbackToUse), webview (*this)
- {
- addAndMakeVisible (header);
- addAndMakeVisible (webview);
-
- setOpaque (true);
- setSize (978, 718);
-
- #if JUCE_WINDOWS // windows needs the webcomponent be visible
- parentWindow.enterModalState (true, modalCallback.release(), true);
- #endif
- }
-
- void goToURL (const String& request)
- {
- lastURL = request;
- webview.goToURL (lastURL);
- }
-
- void paint (Graphics& g) override { g.fillAll (Colours::lightblue); }
-
- void resized() override
- {
- auto r = getLocalBounds();
- header.setBounds (r.removeFromTop (78));
- webview.setBounds (r);
- }
-
- bool pageAboutToLoad (const String& page)
- {
- URL url (page);
-
- if (page == "about:blank" || page.startsWith ("file://") || page.startsWith ("data:text/html"))
- {
- if (page != lastErrorPageURI)
- lastURL = page;
-
- return true;
- }
- else if (url.getScheme() == "projucer")
- {
- HashMap<String, String> params;
-
- auto n = url.getParameterNames().size();
- for (int i = 0; i < n; ++i)
- params.set (url.getParameterNames()[i], url.getParameterValues()[i]);
-
- String cmd (url.getDomain());
-
- if (n == 0 && cmd.containsChar (L'='))
- {
- // old-style callback
- StringArray domainTokens (StringArray::fromTokens (cmd, "=", ""));
- cmd = domainTokens[0];
-
- params.set (cmd, domainTokens[1]);
- }
-
- if (pageCallback)
- pageCallback (cmd, params);
-
- return false;
- }
-
- bool isValid = (url.getDomain().endsWith ("roli.com") || url.getDomain().endsWith ("juce.com"));
-
- if (isValid)
- lastURL = page;
-
- return true;
- }
-
- void pageFinishedLoading (const String& page)
- {
- URL url (page);
-
- if ((isValidURL (url)
- || page.startsWith ("file://") || page.startsWith ("data:text/html"))
- && ! parentWindow.isCurrentlyModal())
- parentWindow.enterModalState (true, modalCallback.release(), true);
- }
-
- void newWindowAttemptingToLoad (const String& page)
- {
- URL url (page);
- bool isGitHub = url.getDomain().endsWith ("github.com");
-
- if (url.getDomain().endsWith ("roli.com")
- || url.getDomain().endsWith ("juce.com")
- || isGitHub)
- {
- url.launchInDefaultBrowser();
-
- if (newWindowCallback && ! isGitHub)
- newWindowCallback (page);
- }
- }
-
- bool pageLoadHadNetworkError (const String&)
- {
- String errorPageSource = String (BinaryData::offlinepage_html, BinaryData::offlinepage_htmlSize)
- .replace ("__URL_PLACEHOLDER__", lastURL);
-
- #if JUCE_WINDOWS
- auto tmpFile = File::createTempFile (".html");
- tmpFile.replaceWithText (errorPageSource, true);
-
- lastErrorPageURI = "file://" + tmpFile.getFullPathName();
- #else
- lastErrorPageURI = "data:text/html;base64," + Base64::toBase64 (errorPageSource);
- #endif
-
- goToURL (lastErrorPageURI);
-
- return false;
- }
-
- static bool isValidURL (const URL& url) { return (url.getDomain().endsWith ("roli.com") || url.getDomain().endsWith ("juce.com")); }
-
- //==============================================================================
- LicenseWebview& parentWindow;
- ScopedPointer<ModalComponentManager::Callback> modalCallback;
- Header header;
- RedirectWebBrowserComponent webview;
- std::function<void (const String&, const HashMap<String, String>&)> pageCallback;
- std::function<void (const String&)> newWindowCallback;
- String lastURL, lastErrorPageURI;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseWebviewContent)
- };
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseWebview)
- };
|