mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-06-11 02:29:55 +00:00
Add test for steps easing function value calculation
This commit is contained in:
parent
e927f8da62
commit
39dfa75fe7
4 changed files with 53 additions and 9 deletions
|
|
@ -41,6 +41,7 @@ typedef struct Animation {
|
|||
|
||||
|
||||
#include "animation.h"
|
||||
#include "state.h"
|
||||
|
||||
Animation*
|
||||
alloc_animation(void) {
|
||||
|
|
@ -178,6 +179,8 @@ apply_easing_curve(const Animation *a, double val, monotonic_t duration) {
|
|||
if (!a->count) return val;
|
||||
size_t idx = MIN((size_t)(val * a->count), a->count - 1);
|
||||
animation_function *f = a->functions + idx;
|
||||
double interval_size = 1. / a->count, interval_start = val - idx * interval_size;
|
||||
val = (val - interval_start) / interval_size;
|
||||
double ans = f->curve(&f->params, val, duration);
|
||||
return f->y_at_start + unit_value(ans) * f->y_size;
|
||||
}
|
||||
|
|
@ -244,13 +247,10 @@ add_steps_animation(Animation *a, double y_at_start, double y_at_end, size_t cou
|
|||
double jump_size = 1. / count, start_value = 0.;
|
||||
size_t num_of_buckets = count;
|
||||
switch (step) {
|
||||
case EASING_STEP_START:
|
||||
start_value = jump_size;
|
||||
num_of_buckets--;
|
||||
break;
|
||||
case EASING_STEP_START: start_value = jump_size; break;
|
||||
case EASING_STEP_END: break;
|
||||
case EASING_STEP_NONE:
|
||||
num_of_buckets--;
|
||||
jump_size = 1. / (num_of_buckets - 1);
|
||||
break;
|
||||
case EASING_STEP_BOTH:
|
||||
num_of_buckets++;
|
||||
|
|
@ -264,3 +264,28 @@ add_steps_animation(Animation *a, double y_at_start, double y_at_end, size_t cou
|
|||
animation_function *f = init_function(a, y_at_start, y_at_end, step_easing_curve);
|
||||
f->params = p;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
test_cursor_blink_easing_function(PyObject *self UNUSED, PyObject *args) {
|
||||
Animation *a = OPT(animation.cursor);
|
||||
if (!animation_is_valid(a)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "must set a cursor blink animation on the global options object first");
|
||||
return NULL;
|
||||
}
|
||||
double t, duration_s = 0.5;
|
||||
if (!PyArg_ParseTuple(args, "d|d", &t, &duration_s)) return NULL;
|
||||
monotonic_t duration = s_double_to_monotonic_t(duration_s);
|
||||
animation_function f = a->functions[0];
|
||||
return PyFloat_FromDouble(f.curve(f.params, t, duration));
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
METHODB(test_cursor_blink_easing_function, METH_VARARGS),
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
bool init_animations(PyObject *module) {
|
||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -488,6 +488,7 @@ extern bool init_child_monitor(PyObject *);
|
|||
extern int init_Line(PyObject *);
|
||||
extern int init_ColorProfile(PyObject *);
|
||||
extern int init_Screen(PyObject *);
|
||||
extern bool init_animations(PyObject*);
|
||||
extern bool init_fontconfig_library(PyObject*);
|
||||
extern bool init_crypto_library(PyObject*);
|
||||
extern bool init_desktop(PyObject*);
|
||||
|
|
@ -573,6 +574,7 @@ PyInit_fast_data_types(void) {
|
|||
if (!init_loop_utils(m)) return NULL;
|
||||
if (!init_crypto_library(m)) return NULL;
|
||||
if (!init_systemd_module(m)) return NULL;
|
||||
if (!init_animations(m)) return NULL;
|
||||
|
||||
CellAttrs a;
|
||||
#define s(name, attr) { a.val = 0; a.attr = 1; PyModule_AddIntConstant(m, #name, shift_to_first_set_bit(a)); }
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ add_easing_function(Animation *a, PyObject *e, double y_at_start, double y_at_en
|
|||
if (x) {
|
||||
double *y = x + count;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
x[i] = D(linear_x, i); y[i] = D(y, i);
|
||||
x[i] = D(linear_x, i); y[i] = D(linear_y, i);
|
||||
}
|
||||
add_linear_animation(a, y_at_start, y_at_end, count, x, y);
|
||||
}
|
||||
|
|
@ -158,9 +158,9 @@ add_easing_function(Animation *a, PyObject *e, double y_at_start, double y_at_en
|
|||
|
||||
static inline void
|
||||
cursor_blink_interval(PyObject *src, Options *opts) {
|
||||
free_animation(opts->animation.cursor);
|
||||
opts->cursor_blink_interval = parse_s_double_to_monotonic_t(PyTuple_GET_ITEM(src, 0));
|
||||
if (PyObject_IsTrue(PyTuple_GET_ITEM(src, 1))) {
|
||||
free_animation(opts->animation.cursor);
|
||||
if (PyObject_IsTrue(PyTuple_GET_ITEM(src, 1)) && (opts->animation.cursor = alloc_animation()) != NULL) {
|
||||
add_easing_function(opts->animation.cursor, PyTuple_GET_ITEM(src, 1), 1, 0);
|
||||
if (PyObject_IsTrue(PyTuple_GET_ITEM(src, 2))) {
|
||||
add_easing_function(opts->animation.cursor, PyTuple_GET_ITEM(src, 2), 0, 1);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
from kitty.fast_data_types import Color
|
||||
from kitty.fast_data_types import Color, test_cursor_blink_easing_function
|
||||
from kitty.options.utils import DELETE_ENV_VAR, EasingFunction
|
||||
from kitty.utils import log_error
|
||||
|
||||
|
|
@ -155,3 +155,20 @@ class TestConfParsing(BaseTest):
|
|||
cb('linear(0, 0.25, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.5, 1.0), linear_y=(0, 0.25, 1.0)))
|
||||
cb('linear(0, 0.25 75%, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.75, 1.0), linear_y=(0, 0.25, 1.0)))
|
||||
cb('linear(0, 0.25 25% 75%, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.25, 0.75, 1.0), linear_y=(0, 0.25, 0.25, 1.0)))
|
||||
|
||||
# test that easing functions give expected values
|
||||
def ef(spec, tests, duration=0.5):
|
||||
cfv = p('cursor_blink_interval ' + spec).cursor_blink_interval
|
||||
self.set_options({'cursor_blink_interval': cfv})
|
||||
for t, expected in tests.items():
|
||||
actual = test_cursor_blink_easing_function(t, duration)
|
||||
self.ae(expected, actual, f'Failed for {spec=} with {t=}: {expected} != {actual}')
|
||||
|
||||
ef('linear(0, 0.25 25% 75%, 1)', {0: 0, 0.25: 0.25, 0.3: 0.25, 0.75: 0.25, 1:1})
|
||||
for spec in ('linear', 'linear(0, 1)'):
|
||||
ef(spec, {0: 0, 1: 1, 0.1234: 0.1234, 0.6453: 0.6453})
|
||||
|
||||
ef('steps(5)', {0: 0, 0.1: 0, 0.3: 0.2, 0.9:0.8})
|
||||
ef('steps(5, start)', {0: 0.2, 0.1: 0.2, 0.3: 0.4, 0.9:1})
|
||||
ef('steps(4, jump-both)', {0: 0.2, 0.1: 0.2, 0.3: 0.4, 0.9:1})
|
||||
ef('steps(6, jump-none)', {0: 0, 0.1: 0.0, 0.3: 0.2, 0.9:1})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue