/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
resources/scripts/views/scrollable.lua
101 строка
3 KB
den163
Added scrollable widget. Improved error handling
30 ноя 2024, 23:46
30 ноя 2024, 23:46
5e455e6
Код
Авторство
О чём код?
---TODO: Add mask support local division = require 'division' local rect = require 'rect' local single_child_view = require 'views.single_child_view' local vec2 = require 'vec2' local constrained_size = require 'constrained_size' ---@alias scrollable.scroll_direction 'horizontal'|'vertical'|'all' ---@class scrollable.options ---@field direction scrollable.scroll_direction ---@field child view ---@class scrollable: single_child_view, scrollable.options ---@overload fun(options: scrollable.options): scrollable local scrollable = single_child_view:inherit 'scrollable' ---@class scrollable.state: single_child_view.state ---@field package _id entity_id ---@field package _prev_input_pos vec2 ---@field package _offset vec2 ---@field package _was_selected boolean ---@field package _on_update function ---@field package _render_rect rect scrollable.state = single_child_view.state:inherit 'scrollable.state' ---@param options scrollable.options function scrollable:__call(options) assert(options.child) assert( options.direction == 'horizontal' or options.direction == 'vertical' or options.direction == 'all' ) return scrollable:new(options) end function scrollable:create_state() local state = scrollable.state:new() state._id = division:create_selectable() state._prev_input_pos = vec2() state._offset = vec2() state._was_selected = false state.child_state = self.child:create_state() state._on_update = function() if state._was_selected then if division:is_mouse_button_pressed(division.mouse_button.left) then local input_pos = division:mouse_position() local input_delta = input_pos - state._prev_input_pos if self.direction == 'horizontal' or self.direction == 'all' then state._offset.x = state._offset.x + input_delta.x end if self.direction == 'vertical' or self.direction == 'all' then state._offset.y = state._offset.y + input_delta.y end state._prev_input_pos = input_pos state:render(state._render_rect, self) else state._was_selected = false end elseif division:is_mouse_button_pressed(division.mouse_button.left) and division:has_selected_id() and division:get_selected_id() == state._id then state._was_selected = true state._prev_input_pos = division:mouse_position() end end division:add_update_listener(state._on_update) return state end function scrollable.state:layout(constraints, view) return constrained_size:unconstrained() end ---@param view scrollable function scrollable.state:render(render_rect, view) self._render_rect = render_rect division:set_collision_bounds(self._id, render_rect) local render_rect_with_offset = rect(render_rect.center + self._offset, render_rect.extents) self.child_state:render(render_rect_with_offset, view.child) end function scrollable.state:destroy() division:remove_update_listener(self._on_update) division:destroy_entity(self._id) single_child_view.state.destroy(self) end return scrollable