mirror of
https://github.com/labwc/labwc.git
synced 2026-02-10 04:27:47 -05:00
96 lines
2.7 KiB
C
96 lines
2.7 KiB
C
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
||
|
|
#include <assert.h>
|
||
|
|
#include <wlr/types/wlr_scene.h>
|
||
|
|
#include "common/lab-scene-rect.h"
|
||
|
|
#include "labwc.h"
|
||
|
|
#include "cycle.h"
|
||
|
|
#include "output.h"
|
||
|
|
|
||
|
|
void
|
||
|
|
cycle_osd_scroll_init(struct cycle_osd_output *osd_output, struct wlr_box bar_area,
|
||
|
|
int delta_y, int nr_cols, int nr_rows, int nr_visible_rows,
|
||
|
|
float *border_color, float *bg_color)
|
||
|
|
{
|
||
|
|
if (nr_visible_rows >= nr_rows) {
|
||
|
|
/* OSD doesn't have so many windows to scroll through */
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct cycle_osd_scroll_context *scroll = &osd_output->scroll;
|
||
|
|
scroll->nr_cols = nr_cols;
|
||
|
|
scroll->nr_rows = nr_rows;
|
||
|
|
scroll->nr_visible_rows = nr_visible_rows;
|
||
|
|
scroll->top_row_idx = 0;
|
||
|
|
scroll->bar_area = bar_area;
|
||
|
|
scroll->delta_y = delta_y;
|
||
|
|
scroll->bar_tree = wlr_scene_tree_create(osd_output->tree);
|
||
|
|
wlr_scene_node_set_position(&scroll->bar_tree->node,
|
||
|
|
bar_area.x, bar_area.y);
|
||
|
|
|
||
|
|
struct lab_scene_rect_options scrollbar_opts = {
|
||
|
|
.border_colors = (float *[1]) { border_color },
|
||
|
|
.nr_borders = 1,
|
||
|
|
.border_width = 1,
|
||
|
|
.bg_color = bg_color,
|
||
|
|
.width = bar_area.width,
|
||
|
|
.height = bar_area.height * nr_visible_rows / nr_rows,
|
||
|
|
};
|
||
|
|
scroll->bar = lab_scene_rect_create(scroll->bar_tree, &scrollbar_opts);
|
||
|
|
}
|
||
|
|
|
||
|
|
static int
|
||
|
|
get_cycle_idx(struct cycle_osd_output *osd_output)
|
||
|
|
{
|
||
|
|
struct server *server = osd_output->output->server;
|
||
|
|
|
||
|
|
int idx = 0;
|
||
|
|
struct cycle_osd_item *item;
|
||
|
|
wl_list_for_each(item, &osd_output->items, link) {
|
||
|
|
if (item->view == server->cycle.selected_view) {
|
||
|
|
return idx;
|
||
|
|
}
|
||
|
|
idx++;
|
||
|
|
}
|
||
|
|
assert(false && "selected view not found in items");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
cycle_osd_scroll_update(struct cycle_osd_output *osd_output)
|
||
|
|
{
|
||
|
|
struct cycle_osd_scroll_context *scroll = &osd_output->scroll;
|
||
|
|
if (!scroll->bar) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
int cycle_idx = get_cycle_idx(osd_output);
|
||
|
|
|
||
|
|
/* Update the range of visible rows */
|
||
|
|
int bottom_row_idx = scroll->top_row_idx + scroll->nr_visible_rows;
|
||
|
|
while (cycle_idx < scroll->top_row_idx * scroll->nr_cols) {
|
||
|
|
scroll->top_row_idx--;
|
||
|
|
bottom_row_idx--;
|
||
|
|
}
|
||
|
|
while (cycle_idx >= bottom_row_idx * scroll->nr_cols) {
|
||
|
|
scroll->top_row_idx++;
|
||
|
|
bottom_row_idx++;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Vertically move scrollbar by (bar height) / (# of total rows) */
|
||
|
|
wlr_scene_node_set_position(&scroll->bar->tree->node, 0,
|
||
|
|
scroll->bar_area.height * scroll->top_row_idx / scroll->nr_rows);
|
||
|
|
/* Vertically move items */
|
||
|
|
wlr_scene_node_set_position(&osd_output->items_tree->node, 0,
|
||
|
|
-scroll->delta_y * scroll->top_row_idx);
|
||
|
|
|
||
|
|
/* Hide items outside of visible area */
|
||
|
|
int idx = 0;
|
||
|
|
struct cycle_osd_item *item;
|
||
|
|
wl_list_for_each(item, &osd_output->items, link) {
|
||
|
|
bool visible = idx >= scroll->top_row_idx * scroll->nr_cols
|
||
|
|
&& idx < bottom_row_idx * scroll->nr_cols;
|
||
|
|
wlr_scene_node_set_enabled(&item->tree->node, visible);
|
||
|
|
idx++;
|
||
|
|
}
|
||
|
|
}
|