summaryrefslogtreecommitdiff
path: root/src/ui/playerui.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-02-26 10:22:55 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-02-26 10:22:55 +0200
commit4708a6580e9af65cd15769e87487fdf4456f1e00 (patch)
treecab74fde5878c0b6700e32394222e05551433764 /src/ui/playerui.c
parenta77fa47a50968550a6de4058c83b0db9a4642dfb (diff)
GmDocument: Palette tuning
The greenish-yellow was a bit off-putting.
Diffstat (limited to 'src/ui/playerui.c')
-rw-r--r--src/ui/playerui.c184
1 files changed, 0 insertions, 184 deletions
diff --git a/src/ui/playerui.c b/src/ui/playerui.c
deleted file mode 100644
index 3e22a1d2..00000000
--- a/src/ui/playerui.c
+++ /dev/null
@@ -1,184 +0,0 @@
1/* Copyright 2020 Jaakko Keränen <jaakko.keranen@iki.fi>
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are met:
5
61. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
82. Redistributions in binary form must reproduce the above copyright notice,
9 this list of conditions and the following disclaimer in the documentation
10 and/or other materials provided with the distribution.
11
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
16ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19ANY 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
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22
23#include "playerui.h"
24#include "audio/player.h"
25#include "paint.h"
26#include "util.h"
27
28static const char *volumeChar_(float volume) {
29 if (volume <= 0) {
30 return "\U0001f507";
31 }
32 if (volume < 0.4f) {
33 return "\U0001f508";
34 }
35 if (volume < 0.8f) {
36 return "\U0001f509";
37 }
38 return "\U0001f50a";
39}
40
41void init_PlayerUI(iPlayerUI *d, const iPlayer *player, iRect bounds) {
42 d->player = player;
43 d->bounds = bounds;
44 const int height = height_Rect(bounds);
45 d->playPauseRect = (iRect){ addX_I2(topLeft_Rect(bounds), gap_UI / 2), init_I2(3 * height / 2, height) };
46 d->rewindRect = (iRect){ topRight_Rect(d->playPauseRect), init1_I2(height) };
47 d->menuRect = (iRect){ addX_I2(topRight_Rect(bounds), -height - gap_UI / 2), init1_I2(height) };
48 d->volumeRect = (iRect){ addX_I2(topLeft_Rect(d->menuRect), -height), init1_I2(height) };
49 d->volumeAdjustRect = d->volumeRect;
50 adjustEdges_Rect(&d->volumeAdjustRect, 0, 0, 0, -35 * gap_UI);
51 d->scrubberRect = initCorners_Rect(topRight_Rect(d->rewindRect), bottomLeft_Rect(d->volumeRect));
52 /* Volume slider. */ {
53 d->volumeSlider = shrunk_Rect(d->volumeAdjustRect, init_I2(gap_UI / 2, gap_UI));
54 adjustEdges_Rect(&d->volumeSlider, 0, -width_Rect(d->volumeRect) - 2 * gap_UI, 0, 5 * gap_UI);
55 }
56}
57
58static void drawPlayerButton_(iPaint *p, iRect rect, const char *label, int font) {
59 const iInt2 mouse = mouseCoord_Window(get_Window());
60 const iBool isHover = contains_Rect(rect, mouse);
61 const iBool isPressed = isHover && (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_LEFT) != 0;
62 const int frame = (isPressed ? uiTextCaution_ColorId : isHover ? uiHeading_ColorId : uiAnnotation_ColorId);
63 iRect frameRect = shrunk_Rect(rect, init_I2(gap_UI / 2, gap_UI));
64 drawRect_Paint(p, frameRect, frame);
65 if (isPressed) {
66 fillRect_Paint(
67 p,
68 adjusted_Rect(shrunk_Rect(frameRect, divi_I2(gap2_UI, 2)), zero_I2(), one_I2()),
69 frame);
70 }
71 const int fg = isPressed ? (permanent_ColorId | uiBackground_ColorId) : uiHeading_ColorId;
72 drawCentered_Text(font, frameRect, iTrue, fg, "%s", label);
73}
74
75static int drawSevenSegmentTime_(iInt2 pos, int color, int align, int seconds) { /* returns width */
76 const uint32_t sevenSegmentDigit = 0x1fbf0;
77 const int hours = seconds / 3600;
78 const int mins = (seconds / 60) % 60;
79 const int secs = seconds % 60;
80 const int font = uiLabel_FontId;
81 iString num;
82 init_String(&num);
83 if (hours) {
84 appendChar_String(&num, sevenSegmentDigit + (hours % 10));
85 appendChar_String(&num, ':');
86 }
87 appendChar_String(&num, sevenSegmentDigit + (mins / 10) % 10);
88 appendChar_String(&num, sevenSegmentDigit + (mins % 10));
89 appendChar_String(&num, ':');
90 appendChar_String(&num, sevenSegmentDigit + (secs / 10) % 10);
91 appendChar_String(&num, sevenSegmentDigit + (secs % 10));
92 iInt2 size = advanceRange_Text(font, range_String(&num));
93 if (align == right_Alignment) {
94 pos.x -= size.x;
95 }
96 drawRange_Text(font, pos, color, range_String(&num));
97 deinit_String(&num);
98 return size.x;
99}
100
101void draw_PlayerUI(iPlayerUI *d, iPaint *p) {
102 const int playerBackground_ColorId = uiBackground_ColorId;
103 const int playerFrame_ColorId = uiSeparator_ColorId;
104 const iBool isAdjusting = (flags_Player(d->player) & adjustingVolume_PlayerFlag) != 0;
105 fillRect_Paint(p, d->bounds, playerBackground_ColorId);
106 drawRect_Paint(p, d->bounds, playerFrame_ColorId);
107 drawPlayerButton_(p,
108 d->playPauseRect,
109 isPaused_Player(d->player) ? "\U0001f782" : "\u23f8",
110 uiContent_FontId);
111 drawPlayerButton_(p, d->rewindRect, "\u23ee", uiContent_FontId);
112 drawPlayerButton_(p, d->menuRect, "\U0001d362", uiContent_FontId);
113 if (!isAdjusting) {
114 drawPlayerButton_(
115 p, d->volumeRect, volumeChar_(volume_Player(d->player)), uiContentSymbols_FontId);
116 }
117 const int hgt = lineHeight_Text(uiLabel_FontId);
118 const int yMid = mid_Rect(d->scrubberRect).y;
119 const float playTime = time_Player(d->player);
120 const float totalTime = duration_Player(d->player);
121 const int bright = uiHeading_ColorId;
122 const int dim = uiAnnotation_ColorId;
123 int leftWidth = drawSevenSegmentTime_(
124 init_I2(left_Rect(d->scrubberRect) + 2 * gap_UI, yMid - hgt / 2),
125 isPaused_Player(d->player) ? dim : bright,
126 left_Alignment,
127 iRound(playTime));
128 int rightWidth = 0;
129 if (totalTime > 0) {
130 rightWidth =
131 drawSevenSegmentTime_(init_I2(right_Rect(d->scrubberRect) - 2 * gap_UI, yMid - hgt / 2),
132 dim,
133 right_Alignment,
134 iRound(totalTime));
135 }
136 /* Scrubber. */
137 const int s1 = left_Rect(d->scrubberRect) + leftWidth + 6 * gap_UI;
138 const int s2 = right_Rect(d->scrubberRect) - rightWidth - 6 * gap_UI;
139 const float normPos = totalTime > 0 ? playTime / totalTime : 0.0f;
140 const int part = (s2 - s1) * normPos;
141 const int scrubMax = (s2 - s1) * streamProgress_Player(d->player);
142 drawHLine_Paint(p, init_I2(s1, yMid), part, bright);
143 drawHLine_Paint(p, init_I2(s1 + part, yMid), scrubMax - part, dim);
144 const char *dot = "\u23fa";
145 const int dotWidth = advance_Text(uiLabel_FontId, dot).x;
146 draw_Text(uiLabel_FontId,
147 init_I2(s1 * (1.0f - normPos) + s2 * normPos - dotWidth / 2, yMid - hgt / 2),
148 isPaused_Player(d->player) ? dim : bright,
149 dot);
150 /* Volume adjustment. */
151 if (isAdjusting) {
152 const iInt2 mouse = mouseCoord_Window(get_Window());
153 const iBool isHover = contains_Rect(d->volumeRect, mouse) &&
154 ~flags_Player(d->player) & volumeGrabbed_PlayerFlag;
155 const iBool isPressed = (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_LEFT) != 0;
156 iRect adjRect = shrunk_Rect(d->volumeAdjustRect, init_I2(gap_UI / 2, gap_UI));
157 fillRect_Paint(p, adjRect, playerBackground_ColorId);
158 drawRect_Paint(p, adjRect, bright);
159 if (isHover) {
160 fillRect_Paint(
161 p,
162 shrunk_Rect(d->volumeRect, init_I2(gap_UI / 2 + gap_UI / 2, 3 * gap_UI / 2)),
163 isPressed ? uiTextCaution_ColorId : bright);
164 }
165 drawCentered_Text(uiContentSymbols_FontId,
166 d->volumeRect,
167 iTrue,
168 isHover ? playerBackground_ColorId : bright,
169 volumeChar_(volume_Player(d->player)));
170 const int volColor =
171 flags_Player(d->player) & volumeGrabbed_PlayerFlag ? uiTextCaution_ColorId : bright;
172 const int volPart = volume_Player(d->player) * width_Rect(d->volumeSlider);
173 const iInt2 volPos = init_I2(left_Rect(d->volumeSlider), mid_Rect(d->volumeSlider).y);
174 drawHLine_Paint(p, volPos, volPart, volColor);
175 drawHLine_Paint(p,
176 addX_I2(volPos, volPart),
177 width_Rect(d->volumeSlider) - volPart,
178 dim);
179 draw_Text(uiLabel_FontId,
180 init_I2(left_Rect(d->volumeSlider) + volPart - dotWidth / 2, yMid - hgt / 2),
181 volColor,
182 dot);
183 }
184}