Merge branch 'master' into my-osx
[paraslash.git] / slider.c
1 /*
2 * Copyright (C) 2004-2006 Andre Noll <maan@systemlinux.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
17 */
18
19 /** \file slider.c libzmw-based stream creator for paraslash */
20
21 #include "para.h"
22 #include "zmw/zmw.h"
23 #include "math.h"
24 #include "string.h"
25
26 #define WIDTH 300
27 #define SLIDER_RATIO 6
28 #define VAL_2_SL_VAL(v) (v) * (SLIDER_RATIO - 1.0) / SLIDER_RATIO
29 #define SL_VAL_2_VAL(v) (v) * SLIDER_RATIO / (SLIDER_RATIO - 1.0)
30 #define VAL_2_SCORE(v) (v) > 0.5? 1 / (1.03 - (v)) / (1.03 - (v)) :\
31 - 1 / ((v) + 0.03) / ((v) + 0.03)
32
33 #define RGB(R,G,B) (((R)<<12) + ((G)<<6) + (B))
34
35 #define EPSILON 0.001
36 #define LASTPLAYED_FORMULA(v) \
37 1 / (pow((v), 10) + EPSILON * EPSILON) - 1 / (1 + EPSILON) + EPSILON
38
39 #define NUMPLAYED_FORMULA(v)\
40 10 * (v) + (v) / (1 - (v) * (1 - EPSILON))
41
42 static int argc;
43 static char **argv;
44 char *streamname = NULL;
45 static Zmw_Float_0_1 *slider_vals, lastplayed_val, numplayed_val;
46
47 void para_log(int ll, const char* fmt,...) /* no logging */
48 {
49 }
50
51 static void rst(void)
52 {
53 int i;
54 for (i = 1; argv[i]; i++)
55 slider_vals[i] = VAL_2_SL_VAL(.5);
56 if (streamname)
57 free(streamname);
58 streamname = para_strdup("slider");
59 //printf("rst: \n");
60 }
61
62 static char *get_value_filename(void)
63 {
64 char *ret, *home =para_homedir();
65 ret = make_message("%s/.paraslash/slide.values", home);
66 free(home);
67 return ret;
68 }
69
70 static void load(void)
71 {
72 char *tmp;
73 char att[999];
74 FILE *f;
75 int i;
76 Zmw_Float_0_1 val;
77
78 tmp = get_value_filename();
79 f = fopen(tmp, "r");
80 free(tmp);
81 if (!f)
82 return;
83 while (fscanf(f, "%900s %g", att, &val) == 2) {
84 if (!strcmp(att, "lastplayed")) {
85 lastplayed_val = val;
86 continue;
87 }
88 if (!strcmp(att, "numplayed")) {
89 numplayed_val = val;
90 continue;
91 }
92 for (i = 1; argv[i]; i++)
93 if (!strcmp(argv[i], att)) {
94 slider_vals[i] = val;
95 break;
96 }
97
98 }
99 fclose(f);
100 }
101
102 static void save(void)
103 {
104 char *filename;
105 FILE *f;
106 int i;
107
108 filename = get_value_filename();
109 f = fopen(filename, "w");
110 free(filename);
111 if (!f)
112 return;
113 fprintf(f, "lastplayed %g\n", lastplayed_val);
114 fprintf(f, "numplayed %g\n", numplayed_val);
115 for (i = 1; argv[i]; i++)
116 fprintf(f, "%s %g\n", argv[i], slider_vals[i]);
117 fclose(f);
118 }
119
120
121 static void print_score(FILE *fd)
122 {
123 int i;
124
125 for (i = 1; argv[i]; i++) {
126 if (SL_VAL_2_VAL(slider_vals[i]) > .99)
127 fprintf(fd, "deny: IS_N_SET(%s)\n", argv[i]);
128 if (slider_vals[i] < .01)
129 fprintf(fd, "deny: IS_SET(%s)\n", argv[i]);
130 }
131 fprintf(fd, "score: 0 ");
132 for (i = 1; argv[i]; i++) {
133 if (slider_vals[i] < .01)
134 continue;
135 fprintf(fd, "+ %i * IS_SET(%s) ",
136 (int) (VAL_2_SCORE(SL_VAL_2_VAL(slider_vals[i]))),
137 argv[i]
138 );
139 }
140 fprintf(fd, " + round((LASTPLAYED()/1440 - 1000 / (LASTPLAYED()/1440 + 1)) / %f"
141 " - %f * NUMPLAYED(), 2)\n",
142 LASTPLAYED_FORMULA(SL_VAL_2_VAL(lastplayed_val)),
143 NUMPLAYED_FORMULA(SL_VAL_2_VAL(numplayed_val)));
144 }
145
146 static void stradd(void)
147 {
148 FILE *pipe;
149 char *cmd = make_message("para_client stradd %s", streamname);
150
151 pipe = popen(cmd, "w");
152 free(cmd);
153 if (!pipe)
154 return;
155 print_score(pipe);
156 pclose(pipe);
157 }
158
159 static void b_save(void)
160 {
161 stradd();
162 save();
163 }
164
165 static void go(void)
166 {
167 stradd();
168 system("para_client cs slider");
169 system("para_client stop");
170 system("para_client play");
171 }
172
173 static void ok()
174 {
175 stradd();
176 system("para_client cs slider");
177 system("para_client play");
178 save();
179 zmw_main_quit(EXIT_SUCCESS);
180 }
181
182 static void make_buttons(void)
183 {
184 /* Add a frame around the box */
185 ZMW(zmw_decorator(Zmw_Decorator_Border_Embossed)) {
186 /* the buttons */
187 ZMW(zmw_hbox()) {
188 zmw_button("save");
189 if (zmw_activated())
190 b_save();
191 zmw_button("ok");
192 if (zmw_activated())
193 ok();
194 zmw_button("go!");
195 if (zmw_activated())
196 go();
197 zmw_button("rst");
198 if (zmw_activated())
199 rst();
200 // zmw_x(WIDTH);
201 zmw_button("abort");
202 if (zmw_activated())
203 zmw_main_quit(EXIT_FAILURE);
204 }
205 }
206 }
207 static void make_stream_input_field(void)
208 {
209 static char *text1 = NULL;
210 static int cursor_pos = 1; // Must be static
211 static int text1_length ;
212
213 ZMW(zmw_vbox()) {
214 if ( text1 == NULL ) {
215 // The initial value must be malloced
216 text1 = strdup("slider") ;
217 text1_length = strlen(text1) ;
218 }
219 ZMW(zmw_fixed()) {
220 zmw_y(6);
221 zmw_x(0);
222 zmw_label("stream: ");
223 zmw_color(Zmw_Color_Foreground, RGB(63, 63, 63));
224 zmw_y(0);
225 zmw_x(100);
226 zmw_width(WIDTH);
227 zmw_entry_with_cursor(&streamname, &cursor_pos);
228 if (zmw_changed())
229 text1_length = strlen(text1);
230 }
231 }
232 }
233
234 /* the sliders, one for each member in argv */
235 static void make_sliders(void)
236 {
237 int i;
238 char *txt;
239
240 zmw_height(ZMW_VALUE_UNDEFINED);
241 // zmw_horizontal_expand(Zmw_True);
242 ZMW(zmw_hbox()) {
243 ZMW(zmw_vbox()) {
244 zmw_color(Zmw_Color_Foreground, RGB(0, 63, 63)); /* font */
245 txt = make_message("lp: (%i%%)",
246 (int)(.5 + 100 * SL_VAL_2_VAL(lastplayed_val)));
247 zmw_label(txt);
248 free(txt);
249 txt = make_message("np: (%i%%)",
250 (int)(.5 + 100 * SL_VAL_2_VAL(numplayed_val)));
251 zmw_label(txt);
252 free(txt);
253 zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
254 for (i = 1; argv[i]; i++) {
255 txt = make_message("%s: (%i%%)", argv[i],
256 (int)(.5 + 100 * SL_VAL_2_VAL(slider_vals[i])));
257 zmw_label(txt);
258 free(txt);
259 }
260 }
261 ZMW(zmw_vbox()) {
262 zmw_width(200) ;
263 zmw_hscrollbar(&lastplayed_val, 1.0 / SLIDER_RATIO);
264 zmw_hscrollbar(&numplayed_val, 1.0 / SLIDER_RATIO);
265 for (i = 1; argv[i]; i++) {
266 zmw_hscrollbar(&slider_vals[i],
267 1.0 / SLIDER_RATIO);
268 }
269 }
270 }
271 }
272
273 static void anchor(void)
274 {
275
276 zmw_font_family("terminal");
277 zmw_font_size(14);
278 zmw_rgb(0.1, 0.1, 0.1);
279 zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
280 zmw_color(Zmw_Color_Background_Pushed, RGB(0, 10, 4)); /* slider bg */
281 zmw_color(Zmw_Color_Background_Poped, RGB(0, 42, 42)); /* button bg */
282 zmw_color(Zmw_Color_Border_Light, RGB(0, 7, 63)); /* slider/button border */
283
284 ZMW(zmw_window("para_slider")) {
285 ZMW(zmw_vbox()) {
286 make_buttons();
287 make_stream_input_field();
288 zmw_color(Zmw_Color_Foreground, RGB(0, 63, 63)); /* font */
289 // make_special_sliders();
290 zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
291 make_sliders();
292 }
293 }
294 }
295
296 static void get_atts(void)
297 {
298 char buf[256];
299 FILE *p = popen("para_client laa", "r");
300 argv = para_malloc(255 * sizeof(char *)); /* FIXME */
301
302 argv[0] = para_strdup("all_attributes");
303 argc = 1;
304 if (!p)
305 goto err_out;
306 while (fgets(buf, 255, p)) {
307 chop(buf);
308 argv[argc] = para_strdup(buf);
309 argc++;
310 }
311 pclose(p);
312 argv[argc] = NULL;
313 argc--;
314 if (argc > 1)
315 return; /* success */
316 err_out:
317 if (argc > 1)
318 for (argc = 1; argv[argc]; argc++)
319 free(argv[argc]);
320 free(argv);
321 argc = 1;
322 }
323
324 int main(int the_argc, char *the_argv[])
325 {
326 argc = the_argc;
327 argv = the_argv;
328 if (argc < 2) {
329 get_atts();
330 if (argc < 2)
331 return -1;
332 }
333 slider_vals = para_malloc((argc + 1) * sizeof(int*));
334 rst();
335 load();
336 // printf("argc: %d\n", argc);
337 // for (i = 1; argv[i]; i++)
338 // printf("argv[%d]: %s\n", i, argv[i]);
339 zmw_init(&argc, &argv);
340 zmw_main(anchor);
341 return 0;
342 }