summaryrefslogtreecommitdiff
path: root/src/ui/mediaui.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-02-26 10:24:09 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-02-26 10:24:09 +0200
commit91a6225d8508db01574d7da2c013cb30d6a87ec8 (patch)
treee3bd2c2f24a22c694c1c23aefd5fc531ae108723 /src/ui/mediaui.c
parent4708a6580e9af65cd15769e87487fdf4456f1e00 (diff)
DocumentWidget: Inline downloads
Diffstat (limited to 'src/ui/mediaui.c')
-rw-r--r--src/ui/mediaui.c111
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
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 21SOFTWARE, 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
28static const char *volumeChar_(float volume) { 33static 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
80static const uint32_t sevenSegmentDigit_ = 0x1fbf0;
81
82static const char *sevenSegmentStr_ = "\U0001fbf0";
83
75static int drawSevenSegmentTime_(iInt2 pos, int color, int align, int seconds) { /* returns width */ 84static 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
196static 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
228void 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
234iBool processEvent_DownloadUI(iDownloadUI *d, const SDL_Event *ev) {
235 return iFalse;
236}
237
238void 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}