178 auto const [aparallel, aperp] =
_orientation == Gtk::Orientation::HORIZONTAL
179 ? std::pair{dims.
x(), dims.y()}
180 : std::pair{dims.y(), dims.x()};
186 rect = {interval->
min(), 0, interval->max(), aperp};
188 rect = {0, interval->
min(), aperp, interval->max()};
196 edge_rect = {0, aperp - 1, aparallel, aperp};
198 edge_rect = {aperp - 1, 0, aperp, aparallel};
202 double const abs_size = std::abs(
_max_size);
207 int scale = std::ceil(abs_size);
208 Glib::ustring
const scale_text = std::to_string(
scale);
209 int const digits = scale_text.length() + 1;
212 double const pixels_per_unit = aparallel / abs_size;
220 unsigned scale_index;
221 for (scale_index = 0; scale_index < ruler_metric->ruler_scale.size() - 1; ++scale_index) {
222 if (ruler_metric->ruler_scale[scale_index] * pixels_per_unit >
minimum) {
228 unsigned divide_index;
229 for (divide_index = 0; divide_index < ruler_metric->subdivide.size() - 1; ++divide_index) {
230 if (ruler_metric->ruler_scale[scale_index] * pixels_per_unit < 5 * ruler_metric->subdivide[divide_index + 1]) {
235 int const subdivisions = ruler_metric->
subdivide[divide_index];
236 double const units_per_major = ruler_metric->ruler_scale[scale_index];
237 double const pixels_per_major = pixels_per_unit * units_per_major;
238 double const pixels_per_tick = pixels_per_major / subdivisions;
245 .divide_index = divide_index,
246 .pixels_per_tick = pixels_per_tick,
247 .pixels_per_major = pixels_per_major
250 auto update = [] (
auto src,
auto &dst,
auto&... to_reset) {
253 (to_reset.reset(), ...);
256 auto update_approx = [] (
auto src,
auto &dst,
auto&... to_reset) {
259 (to_reset.reset(), ...);
276 static constexpr int gradient_size = 4;
278 shadow_rect = {0, 0, aparallel, gradient_size};
279 end_point = {0, gradient_size};
281 shadow_rect = {0, 0, gradient_size, aparallel};
282 end_point = {gradient_size, 0};
285 auto shadow_snapshot = gtk_snapshot_new();
286 gtk_snapshot_append_linear_gradient(
296 gtk_snapshot_append_node(snapshot->gobj(),
_shadow_node.get());
302 auto scale_tile = gtk_snapshot_new();
304 for (
int i = 0; i < subdivisions; i++) {
306 double position = std::round(i * pixels_per_tick);
309 int size = aperp - 7;
310 for (
int j = divide_index; j > 0; --j) {
311 if (i % ruler_metric->subdivide[j] == 0) {
320 rect =
Geom::Rect(position, aperp -
size, position + 1, aperp - 1);
322 rect =
Geom::Rect(aperp -
size, position, aperp - 1, position + 1);
333 auto scale_tiles = gtk_snapshot_new();
335 for (
int i = 0; ; i++) {
337 int const pos = std::round(i * pixels_per_major);
338 if (pos >= aparallel + pixels_per_major) {
341 int const lastpos = std::round((i - 1) * pixels_per_major);
342 int const shift = pos - lastpos;
343 auto const translate =
_orientation == Gtk::Orientation::HORIZONTAL
346 gtk_snapshot_translate(scale_tiles,
geom_to_gtk(translate).gobj());
356 auto const translate =
_orientation == Gtk::Orientation::HORIZONTAL
361 gtk_snapshot_append_node(snapshot->gobj(),
_scale_node.get());
368 for (
int i =
start; i <=
end; ++i) {
369 int const label_value = std::round(i * units_per_major *
sign);
370 double const position = std::round((i -
start) * pixels_per_major);
371 bool const rotate =
_orientation != Gtk::Orientation::HORIZONTAL;
372 auto const layout = create_pango_layout(std::to_string(label_value));
376 layout->get_pixel_size(text_width, text_height);
378 std::swap(text_width, text_height);
382 int x = position + 3;
391 auto label = gtk_snapshot_new();
397 snapshot->translate(Gdk::Graphene::Point(x, y));
399 snapshot->translate(Gdk::Graphene::Point(0.0, text_height));
400 snapshot->rotate(-90);
402 gtk_snapshot_append_node(snapshot->gobj(), label_node.get());
410 constexpr auto radius = 3.0;
411 constexpr auto line_width = 2.0;
413 auto const dxy =
delta > 0 ? radius : -radius;
416 double sx0 = std::floor(aperp * 0.7);
424 if (std::abs(
delta) > 2 * radius) {
427 auto const y = std::round(sy0 - line_width / 2);
428 rect =
Geom::Rect(sx0 + dxy, y, sx1 - dxy, y + line_width);
430 auto const x = std::round(sx0 - line_width / 2);
431 rect =
Geom::Rect(x, sy0 + dxy, x + line_width, sy1 - dxy);
436 static auto const path = [] {
437 auto builder = gsk_path_builder_new();
438 gsk_path_builder_add_circle(
builder, Gdk::Graphene::Point{0.0, 0.0}.gobj(), radius);
439 return gsk_path_builder_free_to_path(
builder);
442 static auto const stroke = [] {
443 return gsk_stroke_new(line_width);
450 gtk_snapshot_append_fill(snapshot->gobj(), path, GSK_FILL_RULE_WINDING,
_select_fill.gobj());