diff options
Diffstat (limited to 'src/screen/screen.c')
| -rw-r--r-- | src/screen/screen.c | 208 |
1 files changed, 166 insertions, 42 deletions
diff --git a/src/screen/screen.c b/src/screen/screen.c index c0527c3..ae9b001 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -24,6 +24,8 @@ #define SCREEN_LAST_CLICK_WITHIN(ns) \ (((scr)->last_click_ts != SCREEN_INVALID_TS) && (nn_get_timestamp() - (scr)->last_click_ts <= ns)) +#define SCREEN_OSD_BAR_HEIGHT 15 + static void should_close_callback(void *userdata) { struct camu_screen *scr = (struct camu_screen *)userdata; @@ -62,15 +64,15 @@ static void resize_callback(void *userdata, u32 width, u32 height) do_resize(scr, width, height); } +// @TODO: Incomplete. static struct camu_view *get_view_from_mouse_pos(struct camu_screen *scr) { struct camu_view *view = NULL; + if (scr->videos.count > 0) { + view = &al_array_last(scr->videos).view; + } struct camu_screen_video *video; al_array_foreach_ptr(scr->videos, i, video) { - if (!view) { - view = &video->view; - continue; - } if (view->zindex < video->view.zindex) { view = &video->view; } @@ -85,21 +87,26 @@ static void seek_to_percent_at_pointer(struct camu_screen *scr, f64 x) scr->callback(scr->userdata, CAMU_SCREEN_PERCENT_SEEK, &percent); } -static bool pointer_pos_callback(void *userdata, f64 x, f64 y) +static bool pointer_callback(void *userdata, u8 type, f64 x, f64 y) { struct camu_screen *scr = (struct camu_screen *)userdata; struct camu_view *view = get_view_from_mouse_pos(scr); bool queue_refresh = false; - if (SCREEN_IS_DRAGGING(scr)) { -#ifdef CAMU_SCREEN_DRAG_SEEK - u64 now = nn_get_timestamp(); - if (view && now - scr->last_seek_ts > 100000) { - seek_to_percent_at_pointer(scr, x); - scr->last_seek_ts = now; + bool have_pointer_move = scr->window->flags & STELA_WINDOW_SUPPORTS_POINTER_MOVE; + switch (type) { + case STELA_POINTER_POS: + if (scr->vr_emulation && have_pointer_move) { + break; } + if (SCREEN_IS_DRAGGING(scr)) { +#ifdef CAMU_SCREEN_DRAG_SEEK + u64 now = nn_get_timestamp(); + if (view && now - scr->last_seek_ts > 100000) { + seek_to_percent_at_pointer(scr, x); + scr->last_seek_ts = now; + } #else - if (view) { - if (SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) { + if (view && !SCREEN_MOD1(scr) && SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) { f64 dx = x - scr->last_pointer_x; f64 dy = y - scr->last_pointer_y; if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) { @@ -110,11 +117,26 @@ static bool pointer_pos_callback(void *userdata, f64 x, f64 y) scr->last_click_ts = SCREEN_INVALID_TS; } } - } #endif + } + if (SCREEN_MOD1(scr) && scr->osd.duration > 0) { + f64 dx = x - scr->last_pointer_x; + if (fabs(dx) >= 2.0 || y >= scr->height - SCREEN_OSD_BAR_HEIGHT) { + scr->osd.bar_mode = CAMU_OSD_BAR_SEEK; + } + } + scr->last_pointer_x = x; + scr->last_pointer_y = y; + break; + case STELA_POINTER_MOVE: + if (!scr->vr_emulation || !have_pointer_move) { + break; + } + scr->last_pointer_x += x * 0.75f; + scr->last_pointer_y += y * 0.75f; + queue_refresh = true; + break; } - scr->last_pointer_x = x; - scr->last_pointer_y = y; return queue_refresh; } @@ -169,7 +191,7 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y) f64 lx = scr->last_touch_x[0], lx2 = scr->last_touch_x[1]; f64 ly = scr->last_touch_y[0], ly2 = scr->last_touch_y[1]; f64 dist = distance(lx, lx2, ly, ly2); - f64 mx = x = (lx + lx2) / 2.0, my = (ly + ly2) / 2.0; + f64 mx = (lx + lx2) / 2.0, my = (ly + ly2) / 2.0; bool refresh = false; struct camu_view *view = get_view_from_mouse_pos(scr); if (view) { @@ -190,7 +212,7 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y) scr->last_pointer_x = scr->last_touch_x[1]; scr->last_pointer_y = scr->last_touch_y[1]; } - bool refresh = pointer_pos_callback(scr, x, y); + bool refresh = pointer_callback(scr, STELA_POINTER_POS, x, y); if (index == 0) { scr->last_touch_x[0] = x; scr->last_touch_y[0] = y; @@ -213,7 +235,12 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y) if (SCREEN_LAST_CLICK_WITHIN(200000)) { f64 third = scr->width / 3.0; if (x >= third && x <= third * 2.0) { - scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL); + if (scr->vr_emulation) { + scr->vr_calibrate_x = scr->last_pointer_x / scr->width; + scr->vr_calibrate_y = scr->last_pointer_y / scr->height; + } else { + scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL); + } } else { if (scr->touch_mode) { #if CAMU_HAVE_SUBTITLES @@ -246,7 +273,8 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button) break; case STELA_BUTTON_RELEASED: scr->flags &= ~CAMU_SCREEN_DRAGGING; - scr->window->set_cursor(scr->window, SCREEN_MOUSE_MOD(scr) ? STELA_CURSOR_CROSSHAIR : SCREEN_DEFAULT_CURSOR(scr)); + bool want_crosshair = SCREEN_MOUSE_MOD(scr) && scr->fullscreen; + scr->window->set_cursor(scr->window, want_crosshair ? STELA_CURSOR_CROSSHAIR : SCREEN_DEFAULT_CURSOR(scr)); if (SCREEN_LAST_CLICK_WITHIN(200000)) { if (SCREEN_MOD1(scr)) { seek_to_percent_at_pointer(scr, scr->last_pointer_x); @@ -295,6 +323,9 @@ bool scroll_callback(void *userdata, f64 y) if (SCREEN_MOD1(scr)) { f32 change = (f32)stl_scale_scroll(y, 40.0); scr->callback(scr->userdata, CAMU_SCREEN_OFFSET_VOLUME, &change); + scr->osd.bar_mode = CAMU_OSD_BAR_VOLUME; + scr->osd.bar = change; + return true; } else { struct camu_view *view = get_view_from_mouse_pos(scr); if (view) { @@ -321,14 +352,21 @@ static bool key_callback(void *userdata, u8 state, u16 button) scr->window->close(scr->window); scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL); break; + case STELA_KEY_SLASH: + scr->osd.show_binds = !scr->osd.show_binds; + break; case STELA_KEY_RIGHT: if (SCREEN_MOD1(scr)) { - f64 plus_ten_seconds = 10.0; - scr->callback(scr->userdata, CAMU_SCREEN_RELATIVE_SEEK, &plus_ten_seconds); + if (SCREEN_MOD2(scr)) { + f64 one_hundred = 100.0; + scr->callback(scr->userdata, CAMU_SCREEN_PERCENT_SEEK, &one_hundred); + } else { + f64 plus_ten_seconds = 10.0; + scr->callback(scr->userdata, CAMU_SCREEN_RELATIVE_SEEK, &plus_ten_seconds); + } break; } // fallthrough - case STELA_KEY_TAB: case STELA_KEY_D: { s32 n = 1; scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n); @@ -351,6 +389,31 @@ static bool key_callback(void *userdata, u8 state, u16 button) scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n); break; } + case STELA_KEY_LEFT_CONTROL: + case STELA_KEY_RIGHT_CONTROL: + if (scr->osd.shown_for & CAMU_OSD_VOLUME) { + scr->osd.shown_for &= ~CAMU_OSD_VOLUME; + scr->osd.shown_for |= CAMU_OSD_SEEK; + } else if (!scr->osd.show) { + scr->osd.show = true; + scr->osd.shown_for |= CAMU_OSD_SEEK; + } + if (scr->last_pointer_y >= scr->height - SCREEN_OSD_BAR_HEIGHT) { + scr->osd.bar_mode = CAMU_OSD_BAR_SEEK; + } + break; + case STELA_KEY_TAB: + if (!(scr->osd.shown_for & CAMU_OSD_SEEK)) { + if (scr->osd.flash >= 0.0) { + scr->osd.flash = 0.0; + } else { + scr->osd.show = !scr->osd.show; + scr->osd.shown_for = 0; + atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); + } + return true; + } + break; case STELA_KEY_SPACE: scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL); break; @@ -366,22 +429,22 @@ static bool key_callback(void *userdata, u8 state, u16 button) } break; case STELA_KEY_E: - if (scr->vr_emulation) { - if (scr->vr_emulation == CAMU_VR_180) { - scr->vr_left_eye = !scr->vr_left_eye; - log_info(scr->vr_left_eye ? "Left eye." : "Right eye."); - } - } else { - scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL); - } + scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL); break; case STELA_KEY_M: { - f32 volume = SCREEN_MOD1(scr) ? 1.f : -1.f; + f32 volume = SCREEN_MOD2(scr) ? 1.f : -1.f; scr->callback(scr->userdata, CAMU_SCREEN_SET_VOLUME, &volume); + scr->osd.bar_mode = CAMU_OSD_BAR_VOLUME; + scr->osd.bar = volume; + scr->osd.flash = CAMU_OSD_FLASH_FOR(0.75); + if (!scr->osd.show) { + scr->osd.show = true; + scr->osd.shown_for |= CAMU_OSD_VOLUME; + } break; } case STELA_KEY_0: - scr->callback(scr->userdata, CAMU_SCREEN_STATUS, NULL); + scr->callback(scr->userdata, CAMU_SCREEN_PRINT, NULL); break; #ifdef CAMU_SCREEN_DEBUG_KEY case STELA_KEY_P: @@ -504,9 +567,14 @@ static bool key_callback(void *userdata, u8 state, u16 button) scr->vr_emulation = CAMU_VR_DISABLED; log_info("VR disabled."); } - if (view) { - camu_view_calculate(view, scr->width, scr->height); - } + if (view) camu_view_calculate(view, scr->width, scr->height); + } + break; + } + case STELA_KEY_B: { + if (scr->vr_emulation == CAMU_VR_180) { + scr->vr_left_eye = !scr->vr_left_eye; + log_info(scr->vr_left_eye ? "Left eye." : "Right eye."); } break; } @@ -515,6 +583,17 @@ static bool key_callback(void *userdata, u8 state, u16 button) } break; case STELA_BUTTON_RELEASED: + switch (button) { + case STELA_KEY_LEFT_CONTROL: + case STELA_KEY_RIGHT_CONTROL: + if (scr->osd.shown_for & CAMU_OSD_SEEK) { + scr->osd.shown_for &= ~CAMU_OSD_SEEK; + scr->osd.show = false; + atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED); + } + scr->osd.bar_mode = CAMU_OSD_BAR_PROGRESS; + return true; + } break; default: break; @@ -529,11 +608,10 @@ static bool key_immediate_callback(void *userdata, u8 state, u16 button) case STELA_BUTTON_PRESSED: switch (button) { case STELA_KEY_F: - scr->fullscreen = !scr->fullscreen; // On X11 and Wayland, MOUSE2 will be forcefully released when entering fullscreen. - if (!SCREEN_MOUSE_MOD(scr)) { - scr->window->set_cursor(scr->window, scr->fullscreen ? STELA_CURSOR_HIDDEN : STELA_CURSOR_NORMAL); - } + scr->fullscreen = !scr->fullscreen; + bool want_crosshair = SCREEN_MOUSE_MOD(scr) && scr->fullscreen; + scr->window->set_cursor(scr->window, want_crosshair ? STELA_CURSOR_CROSSHAIR : SCREEN_DEFAULT_CURSOR(scr)); //#ifdef STELA_API_DX11 #if 0 // Stela's window_win32 fullscreen mode (borderless) is likely more desirable here. scr->renderer->set(scr->renderer, CAMU_RENDERER_FULLSCREEN, scr->fullscreen); @@ -563,18 +641,29 @@ static bool key_immediate_callback(void *userdata, u8 state, u16 button) return false; } +#ifdef STELA_DRAG_AND_DROP +static void drag_and_drop_callback(void *userdata, str *path) +{ + struct camu_screen *scr = (struct camu_screen *)userdata; + scr->callback(scr->userdata, CAMU_SCREEN_ADD, path); +} +#endif + bool camu_screen_init(struct camu_screen *scr) { atomic_store(s32)(&scr->state, CAMU_SCREEN_PAUSED, AL_ATOMIC_RELAXED); scr->window = stl_window_create(); scr->window->render_callback = render_callback; scr->window->resize_callback = resize_callback; - scr->window->pointer_pos_callback = pointer_pos_callback; + scr->window->pointer_callback = pointer_callback; scr->window->touch_callback = touch_callback; scr->window->scroll_callback = scroll_callback; scr->window->mouse_button_callback = mouse_button_callback; scr->window->key_callback = key_callback; scr->window->key_immediate_callback = key_immediate_callback; +#ifdef STELA_DRAG_AND_DROP + scr->window->drag_and_drop_callback = drag_and_drop_callback; +#endif scr->window->should_close_callback = should_close_callback; scr->window->userdata = scr; scr->renderer = NULL; @@ -592,6 +681,9 @@ bool camu_screen_init(struct camu_screen *scr) scr->last_seek_ts = 0; #endif scr->touch_mode = false; + scr->osd.show_binds = false; + scr->osd.bar = -1.0; + scr->osd.flash = -1.0; scr->vr_emulation = CAMU_VR_DISABLED; scr->vr_left_eye = false; scr->vr_calibrate_x = 0.5; @@ -849,7 +941,9 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force) { s32 state = atomic_load(s32)(&scr->state, AL_ATOMIC_RELAXED); u32 force_refresh = atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE); - bool paused = !scr->vr_emulation && state == CAMU_SCREEN_PAUSED && force_refresh == 0; + bool paused = state == CAMU_SCREEN_PAUSED && force_refresh == 0; + paused &= !scr->osd.show; + paused &= !scr->vr_emulation; bool do_render = camu_screen_poll(scr, paused) || !paused; force_refresh = atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE); do_render |= force_refresh > 0; @@ -858,6 +952,36 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force) if (force_refresh > 0) { atomic_sub(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELEASE); } + bool was_paused = scr->osd.paused; + scr->callback(scr->userdata, CAMU_SCREEN_STATUS, &scr->osd); + if (!SCREEN_MOD1(scr)) { + if (scr->osd.flash >= 0.0) { + if (nn_get_tick() >= scr->osd.flash) { + scr->osd.flash = -1.0; + scr->osd.shown_for = 0; + scr->osd.show = false; + scr->osd.bar_mode = CAMU_OSD_BAR_PROGRESS; + *force = true; + } else { + scr->osd.show = true; + } + } + } + if (scr->osd.bar_mode == CAMU_OSD_BAR_SEEK) { + f64 percent = scr->last_pointer_x / scr->width; + scr->osd.bar = CLAMP(percent, 0.0, 100.0); + } + if (was_paused != scr->osd.paused) { + if (scr->osd.paused && !scr->osd.show) { + scr->osd.show = true; + scr->osd.shown_for |= CAMU_OSD_PAUSE; + } else if (scr->osd.shown_for & CAMU_OSD_PAUSE) { + scr->osd.shown_for &= ~CAMU_OSD_PAUSE; + scr->osd.show = false; + } + *force = true; + } + *force |= scr->osd.show; return do_render; } |