Initial commit
This commit is contained in:
330
channel/channelapp/source/browser.c
Normal file
330
channel/channelapp/source/browser.c
Normal file
@@ -0,0 +1,330 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "theme.h"
|
||||
#include "view.h"
|
||||
#include "controls.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#include "browser.h"
|
||||
|
||||
#define AE_OFFSET 4
|
||||
#define TRANS_STEPS 20
|
||||
#define MAX_COLUMNS 4
|
||||
#define ROWS 5
|
||||
|
||||
static bool first_set = true;
|
||||
static u16 top_offset = 0;
|
||||
|
||||
static view *v_browser = NULL;
|
||||
|
||||
static int columns_current = 1;
|
||||
static int columns_new = 1;
|
||||
|
||||
static bool inited_widgets = false;
|
||||
|
||||
view * browser_init(void) {
|
||||
v_browser = view_new (AE_OFFSET + (MAX_COLUMNS * ROWS * 2), NULL,
|
||||
0, 0, 0, 0);
|
||||
browser_theme_reinit();
|
||||
|
||||
return v_browser;
|
||||
}
|
||||
|
||||
void browser_deinit(void) {
|
||||
view_free(v_browser);
|
||||
inited_widgets = false;
|
||||
v_browser = NULL;
|
||||
}
|
||||
|
||||
void browser_theme_reinit(void) {
|
||||
int i;
|
||||
if (inited_widgets)
|
||||
for (i = 0; i < v_browser->widget_count; ++i)
|
||||
widget_free(&v_browser->widgets[i]);
|
||||
|
||||
widget_image (&v_browser->widgets[0], 24, 192, 0,
|
||||
theme_gfx[THEME_ARROW_LEFT], NULL, true,
|
||||
theme_gfx[THEME_ARROW_LEFT_FOCUS]);
|
||||
widget_image (&v_browser->widgets[1],
|
||||
view_width - 24 - theme_gfx[THEME_ARROW_RIGHT]->w, 192, 0,
|
||||
theme_gfx[THEME_ARROW_RIGHT], NULL, true,
|
||||
theme_gfx[THEME_ARROW_RIGHT_FOCUS]);
|
||||
widget_image (&v_browser->widgets[2],
|
||||
view_width - 32 - theme_gfx[THEME_GECKO_ACTIVE]->w -
|
||||
theme_gfx[THEME_LAN_ACTIVE]->w, 412, 0,
|
||||
theme_gfx[THEME_GECKO_ACTIVE], theme_gfx[THEME_GECKO],
|
||||
false, NULL);
|
||||
widget_image (&v_browser->widgets[3],
|
||||
view_width - 32 - theme_gfx[THEME_GECKO_ACTIVE]->w, 412, 0,
|
||||
theme_gfx[THEME_LAN_ACTIVE], theme_gfx[THEME_LAN],
|
||||
false, NULL);
|
||||
widget_set_flag (&v_browser->widgets[2], WF_ENABLED, false);
|
||||
widget_set_flag (&v_browser->widgets[3], WF_ENABLED, false);
|
||||
|
||||
widget_set_flag (&v_browser->widgets[0], WF_VISIBLE, false);
|
||||
widget_set_flag (&v_browser->widgets[1], WF_VISIBLE, false);
|
||||
|
||||
inited_widgets = true;
|
||||
}
|
||||
|
||||
static void browser_set_top_offset(const app_entry *app) {
|
||||
u32 i;
|
||||
|
||||
if (!app || (entry_count < 1)) {
|
||||
top_offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < entry_count; ++i)
|
||||
if (entries[i] == app) {
|
||||
top_offset = i;
|
||||
break;
|
||||
}
|
||||
|
||||
top_offset /= columns_new * ROWS;
|
||||
top_offset *= columns_new * ROWS;
|
||||
|
||||
if (top_offset > entry_count - 1)
|
||||
top_offset -= columns_new * ROWS;
|
||||
}
|
||||
void browser_gen_view(browser_action action, const app_entry *app) {
|
||||
bool less, more;
|
||||
app_entry *entry;
|
||||
s8 focus;
|
||||
|
||||
u32 i, j;
|
||||
u16 y;
|
||||
|
||||
u8 o1, o2;
|
||||
s16 xal, xar, x1, x2;
|
||||
float xm;
|
||||
float vala = 0;
|
||||
float val1[MAX_COLUMNS * ROWS];
|
||||
float val2[MAX_COLUMNS * ROWS];
|
||||
float stepa = M_TWOPI / TRANS_STEPS;
|
||||
float step = M_PI / (TRANS_STEPS - 6);
|
||||
s16 s;
|
||||
float f1, f2;
|
||||
|
||||
switch (action) {
|
||||
case BA_REMOVE:
|
||||
break;
|
||||
|
||||
case BA_ADD:
|
||||
case BA_REFRESH:
|
||||
browser_set_top_offset(app);
|
||||
break;
|
||||
|
||||
case BA_NEXT:
|
||||
if (entry_count <= top_offset + (columns_new * ROWS))
|
||||
return;
|
||||
top_offset += columns_current * ROWS;
|
||||
break;
|
||||
|
||||
case BA_PREV:
|
||||
if (top_offset < 1)
|
||||
return;
|
||||
if (top_offset < columns_current * ROWS)
|
||||
return;
|
||||
top_offset -= columns_current * ROWS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (action == BA_REMOVE) {
|
||||
less = false;
|
||||
more = false;
|
||||
} else {
|
||||
less = top_offset > 0;
|
||||
more = entry_count > top_offset + (columns_new * ROWS);
|
||||
}
|
||||
|
||||
memset(val1, 0, sizeof(float) * MAX_COLUMNS * ROWS);
|
||||
memset(val2, 0, sizeof(float) * MAX_COLUMNS * ROWS);
|
||||
|
||||
if (first_set) {
|
||||
o1 = AE_OFFSET;
|
||||
o2 = AE_OFFSET + (MAX_COLUMNS * ROWS);
|
||||
} else {
|
||||
o1 = AE_OFFSET + (MAX_COLUMNS * ROWS);
|
||||
o2 = AE_OFFSET;
|
||||
}
|
||||
|
||||
first_set = !first_set;
|
||||
focus = o2;
|
||||
|
||||
xal = v_browser->widgets[0].coords.x;
|
||||
xar = v_browser->widgets[1].coords.x;
|
||||
|
||||
if (columns_current == 1)
|
||||
x1 = (view_width - theme_gfx[THEME_APP_ENTRY]->w) / 2;
|
||||
else
|
||||
x1 = (view_width - (theme_gfx[THEME_GRID_APP_ENTRY]->w *
|
||||
columns_current)) / 2;
|
||||
|
||||
if (columns_new == 1)
|
||||
x2 = (view_width - theme_gfx[THEME_APP_ENTRY]->w) / 2;
|
||||
else
|
||||
x2 = (view_width - (theme_gfx[THEME_GRID_APP_ENTRY]->w *
|
||||
columns_new)) / 2;
|
||||
|
||||
if (action == BA_PREV) {
|
||||
xm = view_width / 2;
|
||||
x2 = -view_width + x2;
|
||||
} else {
|
||||
xm = -view_width / 2;
|
||||
x2 = view_width + x2;
|
||||
}
|
||||
|
||||
y = 64;
|
||||
|
||||
for (i = 0; i < (MAX_COLUMNS * ROWS); ++i)
|
||||
widget_free(&v_browser->widgets[o2 + i]);
|
||||
|
||||
if (action != BA_REMOVE)
|
||||
for (i = 0; i < (columns_new * ROWS); ++i) {
|
||||
if (entry_count > top_offset + i) {
|
||||
entry = entries[top_offset + i];
|
||||
|
||||
if (entry && (entry == app))
|
||||
focus += i;
|
||||
|
||||
if (columns_new == 1)
|
||||
widget_app_entry(&v_browser->widgets[o2 + i],
|
||||
x2, y, 0, entry);
|
||||
else
|
||||
widget_grid_app_entry(&v_browser->widgets[o2 + i],
|
||||
x2 + ((i % columns_new) *
|
||||
theme_gfx[THEME_GRID_APP_ENTRY]->w),
|
||||
y, 0, entry);
|
||||
}
|
||||
|
||||
if (((i+1) % columns_new) == 0)
|
||||
y += theme_gfx[THEME_APP_ENTRY]->h;
|
||||
}
|
||||
|
||||
for (i = 0; i < TRANS_STEPS; ++i) {
|
||||
vala += stepa;
|
||||
s = roundf (156.0 * (cosf (vala) - 1));
|
||||
|
||||
// adjust L/R button positions
|
||||
v_browser->widgets[0].coords.x = xal + s;
|
||||
v_browser->widgets[1].coords.x = xar - s;
|
||||
|
||||
for (j = 0; j < MAX_COLUMNS * ROWS; ++j) {
|
||||
if ((i > j / columns_current) &&
|
||||
(i < TRANS_STEPS - (ROWS - j / columns_current)))
|
||||
val1[j] += step;
|
||||
if ((i > j / columns_new) &&
|
||||
(i < TRANS_STEPS - (ROWS - j / columns_new)))
|
||||
val2[j] += step;
|
||||
|
||||
f1 = roundf (xm * (cosf (val1[j]) - 1));
|
||||
f2 = roundf (xm * (cosf (val2[j]) - 1));
|
||||
|
||||
v_browser->widgets[o1 + j].coords.x = x1 - f1 +
|
||||
((j % columns_current) * theme_gfx[THEME_GRID_APP_ENTRY]->w);
|
||||
v_browser->widgets[o2 + j].coords.x = x2 - f2 +
|
||||
((j % columns_new) * theme_gfx[THEME_GRID_APP_ENTRY]->w);
|
||||
}
|
||||
|
||||
view_plot (v_browser, 0, NULL, NULL, NULL);
|
||||
|
||||
if (i == TRANS_STEPS / 2) {
|
||||
widget_set_flag (&v_browser->widgets[0], WF_VISIBLE, true);
|
||||
widget_set_flag (&v_browser->widgets[1], WF_VISIBLE, true);
|
||||
widget_set_flag (&v_browser->widgets[0], WF_VISIBLE, less);
|
||||
widget_set_flag (&v_browser->widgets[1], WF_VISIBLE, more);
|
||||
|
||||
view_set_focus (v_browser, focus);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (MAX_COLUMNS * ROWS); ++i)
|
||||
widget_free(&v_browser->widgets[o1 + i]);
|
||||
|
||||
columns_current = columns_new;
|
||||
|
||||
if (action == BA_REMOVE)
|
||||
top_offset = 0;
|
||||
}
|
||||
|
||||
void browser_set_focus(u32 bd) {
|
||||
if (columns_current == 1) {
|
||||
if (bd & PADS_UP) {
|
||||
view_set_focus_prev(v_browser);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bd & PADS_DOWN) {
|
||||
view_set_focus_next(v_browser);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
if (bd & PADS_LEFT) {
|
||||
view_set_focus_prev(v_browser);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bd & PADS_RIGHT) {
|
||||
view_set_focus_next(v_browser);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bd & PADS_UP) {
|
||||
view_move_focus(v_browser, -columns_current);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bd & PADS_DOWN) {
|
||||
view_move_focus(v_browser, columns_current);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
app_entry *browser_sel(void) {
|
||||
if ((entry_count < 1) || (v_browser->focus < AE_OFFSET))
|
||||
return NULL;
|
||||
|
||||
u32 i;
|
||||
if (first_set)
|
||||
i = top_offset + v_browser->focus - AE_OFFSET;
|
||||
else
|
||||
i = top_offset + v_browser->focus - (MAX_COLUMNS * ROWS) - AE_OFFSET;
|
||||
|
||||
return entries[i];
|
||||
}
|
||||
|
||||
void browser_switch_mode(void) {
|
||||
const app_entry *app = browser_sel();
|
||||
int mode = 0;
|
||||
|
||||
if (columns_current == 1) {
|
||||
if (widescreen)
|
||||
columns_new = 4;
|
||||
else
|
||||
columns_new = 3;
|
||||
|
||||
mode = 1;
|
||||
} else {
|
||||
columns_new = 1;
|
||||
}
|
||||
|
||||
if (v_browser)
|
||||
browser_gen_view(BA_REFRESH, app);
|
||||
|
||||
if (settings.browse_mode != mode)
|
||||
settings.browse_mode = mode;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user