diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-26 10:24:09 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-26 10:24:09 +0200 |
commit | 91a6225d8508db01574d7da2c013cb30d6a87ec8 (patch) | |
tree | e3bd2c2f24a22c694c1c23aefd5fc531ae108723 /src/ui/mediaui.c | |
parent | 4708a6580e9af65cd15769e87487fdf4456f1e00 (diff) |
DocumentWidget: Inline downloads
Diffstat (limited to 'src/ui/mediaui.c')
-rw-r--r-- | src/ui/mediaui.c | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/src/ui/mediaui.c b/src/ui/mediaui.c index 3e22a1d2..2fad0cec 100644 --- a/src/ui/mediaui.c +++ b/src/ui/mediaui.c | |||
@@ -20,11 +20,16 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
22 | 22 | ||
23 | #include "playerui.h" | 23 | #include "mediaui.h" |
24 | #include "media.h" | ||
25 | #include "documentwidget.h" | ||
26 | #include "gmdocument.h" | ||
24 | #include "audio/player.h" | 27 | #include "audio/player.h" |
25 | #include "paint.h" | 28 | #include "paint.h" |
26 | #include "util.h" | 29 | #include "util.h" |
27 | 30 | ||
31 | #include <the_Foundation/path.h> | ||
32 | |||
28 | static const char *volumeChar_(float volume) { | 33 | static const char *volumeChar_(float volume) { |
29 | if (volume <= 0) { | 34 | if (volume <= 0) { |
30 | return "\U0001f507"; | 35 | return "\U0001f507"; |
@@ -72,8 +77,11 @@ static void drawPlayerButton_(iPaint *p, iRect rect, const char *label, int font | |||
72 | drawCentered_Text(font, frameRect, iTrue, fg, "%s", label); | 77 | drawCentered_Text(font, frameRect, iTrue, fg, "%s", label); |
73 | } | 78 | } |
74 | 79 | ||
80 | static const uint32_t sevenSegmentDigit_ = 0x1fbf0; | ||
81 | |||
82 | static const char *sevenSegmentStr_ = "\U0001fbf0"; | ||
83 | |||
75 | static int drawSevenSegmentTime_(iInt2 pos, int color, int align, int seconds) { /* returns width */ | 84 | static int drawSevenSegmentTime_(iInt2 pos, int color, int align, int seconds) { /* returns width */ |
76 | const uint32_t sevenSegmentDigit = 0x1fbf0; | ||
77 | const int hours = seconds / 3600; | 85 | const int hours = seconds / 3600; |
78 | const int mins = (seconds / 60) % 60; | 86 | const int mins = (seconds / 60) % 60; |
79 | const int secs = seconds % 60; | 87 | const int secs = seconds % 60; |
@@ -81,14 +89,14 @@ static int drawSevenSegmentTime_(iInt2 pos, int color, int align, int seconds) { | |||
81 | iString num; | 89 | iString num; |
82 | init_String(&num); | 90 | init_String(&num); |
83 | if (hours) { | 91 | if (hours) { |
84 | appendChar_String(&num, sevenSegmentDigit + (hours % 10)); | 92 | appendChar_String(&num, sevenSegmentDigit_ + (hours % 10)); |
85 | appendChar_String(&num, ':'); | 93 | appendChar_String(&num, ':'); |
86 | } | 94 | } |
87 | appendChar_String(&num, sevenSegmentDigit + (mins / 10) % 10); | 95 | appendChar_String(&num, sevenSegmentDigit_ + (mins / 10) % 10); |
88 | appendChar_String(&num, sevenSegmentDigit + (mins % 10)); | 96 | appendChar_String(&num, sevenSegmentDigit_ + (mins % 10)); |
89 | appendChar_String(&num, ':'); | 97 | appendChar_String(&num, ':'); |
90 | appendChar_String(&num, sevenSegmentDigit + (secs / 10) % 10); | 98 | appendChar_String(&num, sevenSegmentDigit_ + (secs / 10) % 10); |
91 | appendChar_String(&num, sevenSegmentDigit + (secs % 10)); | 99 | appendChar_String(&num, sevenSegmentDigit_ + (secs % 10)); |
92 | iInt2 size = advanceRange_Text(font, range_String(&num)); | 100 | iInt2 size = advanceRange_Text(font, range_String(&num)); |
93 | if (align == right_Alignment) { | 101 | if (align == right_Alignment) { |
94 | pos.x -= size.x; | 102 | pos.x -= size.x; |
@@ -134,10 +142,10 @@ void draw_PlayerUI(iPlayerUI *d, iPaint *p) { | |||
134 | iRound(totalTime)); | 142 | iRound(totalTime)); |
135 | } | 143 | } |
136 | /* Scrubber. */ | 144 | /* Scrubber. */ |
137 | const int s1 = left_Rect(d->scrubberRect) + leftWidth + 6 * gap_UI; | 145 | const int s1 = left_Rect(d->scrubberRect) + leftWidth + 6 * gap_UI; |
138 | const int s2 = right_Rect(d->scrubberRect) - rightWidth - 6 * gap_UI; | 146 | const int s2 = right_Rect(d->scrubberRect) - rightWidth - 6 * gap_UI; |
139 | const float normPos = totalTime > 0 ? playTime / totalTime : 0.0f; | 147 | const float normPos = totalTime > 0 ? playTime / totalTime : 0.0f; |
140 | const int part = (s2 - s1) * normPos; | 148 | const int part = (s2 - s1) * normPos; |
141 | const int scrubMax = (s2 - s1) * streamProgress_Player(d->player); | 149 | const int scrubMax = (s2 - s1) * streamProgress_Player(d->player); |
142 | drawHLine_Paint(p, init_I2(s1, yMid), part, bright); | 150 | drawHLine_Paint(p, init_I2(s1, yMid), part, bright); |
143 | drawHLine_Paint(p, init_I2(s1 + part, yMid), scrubMax - part, dim); | 151 | drawHLine_Paint(p, init_I2(s1 + part, yMid), scrubMax - part, dim); |
@@ -182,3 +190,84 @@ void draw_PlayerUI(iPlayerUI *d, iPaint *p) { | |||
182 | dot); | 190 | dot); |
183 | } | 191 | } |
184 | } | 192 | } |
193 | |||
194 | /*----------------------------------------------------------------------------------------------*/ | ||
195 | |||
196 | static void drawSevenSegmentBytes_(iInt2 pos, int color, size_t numBytes) { | ||
197 | iString digits; | ||
198 | init_String(&digits); | ||
199 | if (numBytes == 0) { | ||
200 | appendChar_String(&digits, sevenSegmentDigit_); | ||
201 | } | ||
202 | else { | ||
203 | int magnitude = 0; | ||
204 | while (numBytes) { | ||
205 | if (magnitude == 3) { | ||
206 | prependCStr_String(&digits, "\u2024"); | ||
207 | } | ||
208 | else if (magnitude == 6) { | ||
209 | prependCStr_String(&digits, restore_ColorEscape "\u2024"); | ||
210 | } | ||
211 | else if (magnitude == 9) { | ||
212 | prependCStr_String(&digits, "\u2024"); | ||
213 | } | ||
214 | prependChar_String(&digits, sevenSegmentDigit_ + (numBytes % 10)); | ||
215 | numBytes /= 10; | ||
216 | magnitude++; | ||
217 | } | ||
218 | if (magnitude > 6) { | ||
219 | prependCStr_String(&digits, uiTextStrong_ColorEscape); | ||
220 | } | ||
221 | } | ||
222 | const int font = uiLabel_FontId; | ||
223 | const iInt2 dims = advanceRange_Text(font, range_String(&digits)); | ||
224 | drawRange_Text(font, addX_I2(pos, -dims.x), color, range_String(&digits)); | ||
225 | deinit_String(&digits); | ||
226 | } | ||
227 | |||
228 | void init_DownloadUI(iDownloadUI *d, const iDocumentWidget *doc, uint16_t mediaId, iRect bounds) { | ||
229 | d->doc = doc; | ||
230 | d->mediaId = mediaId; | ||
231 | d->bounds = bounds; | ||
232 | } | ||
233 | |||
234 | iBool processEvent_DownloadUI(iDownloadUI *d, const SDL_Event *ev) { | ||
235 | return iFalse; | ||
236 | } | ||
237 | |||
238 | void draw_DownloadUI(const iDownloadUI *d, iPaint *p) { | ||
239 | const iMedia *media = constMedia_GmDocument(document_DocumentWidget(d->doc)); | ||
240 | iGmMediaInfo info; | ||
241 | float bytesPerSecond; | ||
242 | const iString *path; | ||
243 | iBool isFinished; | ||
244 | downloadInfo_Media(media, d->mediaId, &info); | ||
245 | downloadStats_Media(media, d->mediaId, &path, &bytesPerSecond, &isFinished); | ||
246 | fillRect_Paint(p, d->bounds, uiBackground_ColorId); | ||
247 | drawRect_Paint(p, d->bounds, uiSeparator_ColorId); | ||
248 | iRect rect = d->bounds; | ||
249 | shrink_Rect(&rect, init_I2(3 * gap_UI, 0)); | ||
250 | const int fonts[2] = { uiContentBold_FontId, uiLabel_FontId }; | ||
251 | const int contentHeight = lineHeight_Text(fonts[0]) + lineHeight_Text(fonts[1]); | ||
252 | const int x = left_Rect(rect); | ||
253 | const int y1 = mid_Rect(rect).y - contentHeight / 2; | ||
254 | const int y2 = y1 + lineHeight_Text(fonts[1]); | ||
255 | if (path) { | ||
256 | drawRange_Text(fonts[0], init_I2(x, y1), uiHeading_ColorId, baseName_Path(path)); | ||
257 | } | ||
258 | draw_Text(uiLabel_FontId, | ||
259 | init_I2(x, y2), | ||
260 | isFinished ? uiTextAction_ColorId : uiTextDim_ColorId, | ||
261 | isFinished ? "Download completed." | ||
262 | : "Download will be cancelled if this tab is closed."); | ||
263 | const int x2 = right_Rect(rect); | ||
264 | drawSevenSegmentBytes_(init_I2(x2, y1), uiTextDim_ColorId, info.numBytes); | ||
265 | const iInt2 pos = init_I2(x2, y2); | ||
266 | if (bytesPerSecond > 0) { | ||
267 | drawAlign_Text(uiLabel_FontId, pos, uiTextDim_ColorId, right_Alignment, "%.3f MB/s", | ||
268 | bytesPerSecond / 1.0e6); | ||
269 | } | ||
270 | else { | ||
271 | drawAlign_Text(uiLabel_FontId, pos, uiTextDim_ColorId, right_Alignment, "\u2014 MB/s"); | ||
272 | } | ||
273 | } | ||