1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE examples.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    The code included in this file is provided under the terms of the ISC license
8    http://www.isc.org/downloads/software-support-policy/isc-license. Permission
9    To use, copy, modify, and/or distribute this software for any purpose with or
10    without fee is hereby granted provided that the above copyright notice and
11    this permission notice appear in all copies.
12 
13    THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,
14    WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR
15    PURPOSE, ARE DISCLAIMED.
16 
17   ==============================================================================
18 */
19 
20 /*******************************************************************************
21  The block below describes the properties of this PIP. A PIP is a short snippet
22  of code that can be read by the Projucer and used to generate a JUCE project.
23 
24  BEGIN_JUCE_PIP_METADATA
25 
26  name:             NetworkingDemo
27  version:          1.0.0
28  vendor:           JUCE
29  website:          http://juce.com
30  description:      Showcases networking features.
31 
32  dependencies:     juce_core, juce_data_structures, juce_events, juce_graphics,
33                    juce_gui_basics, juce_gui_extra
34  exporters:        xcode_mac, vs2019, linux_make, androidstudio, xcode_iphone
35 
36  moduleFlags:      JUCE_STRICT_REFCOUNTEDPOINTER=1
37 
38  type:             Component
39  mainClass:        NetworkingDemo
40 
41  useLocalCopy:     1
42 
43  END_JUCE_PIP_METADATA
44 
45 *******************************************************************************/
46 
47 #pragma once
48 
49 #include "../Assets/DemoUtilities.h"
50 
51 //==============================================================================
52 class NetworkingDemo   : public Component,
53                          private Thread
54 {
55 public:
NetworkingDemo()56     NetworkingDemo()
57         : Thread ("Network Demo")
58     {
59         setOpaque (true);
60 
61         addAndMakeVisible (urlBox);
62         urlBox.setText ("https://www.google.com");
63         urlBox.onReturnKey = [this] { fetchButton.triggerClick(); };
64 
65         addAndMakeVisible (fetchButton);
66         fetchButton.onClick = [this] { startThread(); };
67 
68         addAndMakeVisible (resultsBox);
69 
70         setSize (500, 500);
71     }
72 
paint(Graphics & g)73     void paint (Graphics& g) override
74     {
75         g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground));
76     }
77 
resized()78     void resized() override
79     {
80         auto area = getLocalBounds();
81 
82         {
83             auto topArea = area.removeFromTop (40);
84             fetchButton.setBounds (topArea.removeFromRight (180).reduced (8));
85             urlBox     .setBounds (topArea.reduced (8));
86         }
87 
88         resultsBox.setBounds (area.reduced (8));
89     }
90 
run()91     void run() override
92     {
93         auto result = getResultText (urlBox.getText());
94 
95         MessageManagerLock mml (this);
96 
97         if (mml.lockWasGained())
98             resultsBox.loadContent (result);
99     }
100 
getResultText(const URL & url)101     String getResultText (const URL& url)
102     {
103         StringPairArray responseHeaders;
104         int statusCode = 0;
105 
106         if (auto stream = std::unique_ptr<InputStream> (url.createInputStream (false, nullptr, nullptr, {},
107                                                                                10000, // timeout in millisecs
108                                                                                &responseHeaders, &statusCode)))
109         {
110             return (statusCode != 0 ? "Status code: " + String (statusCode) + newLine : String())
111                     + "Response headers: " + newLine
112                     + responseHeaders.getDescription() + newLine
113                     + "----------------------------------------------------" + newLine
114                     + stream->readEntireStreamAsString();
115         }
116 
117         if (statusCode != 0)
118             return "Failed to connect, status code = " + String (statusCode);
119 
120         return "Failed to connect!";
121     }
122 
123 private:
124     TextEditor urlBox;
125     TextButton fetchButton { "Download URL Contents" };
126 
127     CodeDocument resultsDocument;
128     CodeEditorComponent resultsBox  { resultsDocument, nullptr };
129 
lookAndFeelChanged()130     void lookAndFeelChanged() override
131     {
132         urlBox.applyFontToAllText (urlBox.getFont());
133     }
134 
135     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NetworkingDemo)
136 };
137