1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2020 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/widget/ags_ruler.h>
21
22 #include <pango/pango.h>
23
24 #ifndef __APPLE__
25 #include <pango/pangofc-fontmap.h>
26 #endif
27
28 #include <math.h>
29
30 void ags_ruler_class_init(AgsRulerClass *ruler);
31 void ags_ruler_init(AgsRuler *ruler);
32 void ags_ruler_set_property(GObject *gobject,
33 guint prop_id,
34 const GValue *value,
35 GParamSpec *param_spec);
36 void ags_ruler_get_property(GObject *gobject,
37 guint prop_id,
38 GValue *value,
39 GParamSpec *param_spec);
40 void ags_ruler_show(GtkWidget *widget);
41
42 void ags_ruler_realize(GtkWidget *widget);
43 void ags_ruler_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
44 void ags_ruler_get_preferred_height(GtkWidget *widget,
45 gint *minimal_height,
46 gint *natural_height);
47
48 void ags_ruler_send_configure(AgsRuler *ruler);
49
50 gboolean ags_ruler_draw(AgsRuler *ruler, cairo_t *cr);
51
52 /**
53 * SECTION:ags_ruler
54 * @short_description: A ruler widget
55 * @title: AgsRuler
56 * @section_id:
57 * @include: ags/widget/ags_ruler.h
58 *
59 * #AgsRuler is a widget representing a #GtkAdjustment.
60 */
61
62 enum{
63 PROP_0,
64 PROP_STEP,
65 PROP_LARGE_STEP,
66 PROP_SMALL_STEP,
67 PROP_ADJUSTMENT,
68 PROP_FONT_SIZE,
69 };
70
71 static gpointer ags_ruler_parent_class = NULL;
72
73 GType
ags_ruler_get_type()74 ags_ruler_get_type()
75 {
76 static volatile gsize g_define_type_id__volatile = 0;
77
78 if(g_once_init_enter (&g_define_type_id__volatile)){
79 GType ags_type_ruler = 0;
80
81 static const GTypeInfo ags_ruler_info = {
82 sizeof(AgsRulerClass),
83 NULL, /* base_init */
84 NULL, /* base_finalize */
85 (GClassInitFunc) ags_ruler_class_init,
86 NULL, /* class_finalize */
87 NULL, /* class_data */
88 sizeof(AgsRuler),
89 0, /* n_preallocs */
90 (GInstanceInitFunc) ags_ruler_init,
91 };
92
93 ags_type_ruler = g_type_register_static(GTK_TYPE_WIDGET,
94 "AgsRuler", &ags_ruler_info,
95 0);
96
97 g_once_init_leave(&g_define_type_id__volatile, ags_type_ruler);
98 }
99
100 return g_define_type_id__volatile;
101 }
102
103 void
ags_ruler_class_init(AgsRulerClass * ruler)104 ags_ruler_class_init(AgsRulerClass *ruler)
105 {
106 GObjectClass *gobject;
107 GtkWidgetClass *widget;
108 GParamSpec *param_spec;
109
110 ags_ruler_parent_class = g_type_class_peek_parent(ruler);
111
112 /* GObjectClass */
113 gobject = (GObjectClass *) ruler;
114
115 gobject->set_property = ags_ruler_set_property;
116 gobject->get_property = ags_ruler_get_property;
117
118 /* GtkWidgetClass */
119 widget = (GtkWidgetClass *) ruler;
120
121 widget->realize = ags_ruler_realize;
122 widget->size_allocate = ags_ruler_size_allocate;
123 widget->get_preferred_height = ags_ruler_get_preferred_height;
124 widget->draw = ags_ruler_draw;
125 widget->show = ags_ruler_show;
126
127 /* properties */
128 /**
129 * AgsRuler:font-size:
130 *
131 * The font size.
132 *
133 * Since: 3.6.15
134 */
135 param_spec = g_param_spec_uint("font-size",
136 "font size",
137 "The font size",
138 0,
139 G_MAXUINT,
140 AGS_RULER_FONT_SIZE,
141 G_PARAM_READABLE | G_PARAM_WRITABLE);
142 g_object_class_install_property(gobject,
143 PROP_FONT_SIZE,
144 param_spec);
145
146 /**
147 * AgsRuler:adjustment:
148 *
149 * The adjustment.
150 *
151 * Since: 3.0.0
152 */
153 param_spec = g_param_spec_object("adjustment",
154 "assigned adjustment",
155 "The adjustment it is assigned with",
156 G_TYPE_OBJECT,
157 G_PARAM_READABLE | G_PARAM_WRITABLE);
158 g_object_class_install_property(gobject,
159 PROP_ADJUSTMENT,
160 param_spec);
161
162 /**
163 * AgsRuler:step:
164 *
165 * The step's width.
166 *
167 * Since: 3.0.0
168 */
169 param_spec = g_param_spec_uint("step",
170 "step",
171 "The width of a step",
172 0,
173 G_MAXUINT,
174 AGS_RULER_DEFAULT_STEP,
175 G_PARAM_READABLE | G_PARAM_WRITABLE);
176 g_object_class_install_property(gobject,
177 PROP_STEP,
178 param_spec);
179
180 /**
181 * AgsRuler:large-step:
182 *
183 * The large step's width.
184 *
185 * Since: 3.0.0
186 */
187 param_spec = g_param_spec_uint("large-step",
188 "large step",
189 "The width of a large step",
190 0,
191 G_MAXUINT,
192 AGS_RULER_DEFAULT_LARGE_STEP,
193 G_PARAM_READABLE | G_PARAM_WRITABLE);
194 g_object_class_install_property(gobject,
195 PROP_LARGE_STEP,
196 param_spec);
197
198 /**
199 * AgsRuler:small-step:
200 *
201 * The small step's width.
202 *
203 * Since: 3.0.0
204 */
205 param_spec = g_param_spec_uint("small-step",
206 "small step",
207 "The width of a small step",
208 0,
209 G_MAXUINT,
210 AGS_RULER_DEFAULT_SMALL_STEP,
211 G_PARAM_READABLE | G_PARAM_WRITABLE);
212 g_object_class_install_property(gobject,
213 PROP_SMALL_STEP,
214 param_spec);
215 }
216
217 void
ags_ruler_init(AgsRuler * ruler)218 ags_ruler_init(AgsRuler *ruler)
219 {
220 g_object_set(G_OBJECT(ruler),
221 "app-paintable", TRUE,
222 NULL);
223
224 ruler->flags = 0;
225
226 ruler->font_size = AGS_RULER_FONT_SIZE;
227
228 ruler->adjustment = NULL;
229
230 ruler->step = AGS_RULER_DEFAULT_STEP;
231 ruler->large_step = AGS_RULER_DEFAULT_LARGE_STEP;
232 ruler->small_step = AGS_RULER_DEFAULT_SMALL_STEP;
233
234 ruler->factor = 16.0;
235 ruler->precision = 1.0;
236 ruler->scale_precision = 1.0;
237 }
238
239
240 void
ags_ruler_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)241 ags_ruler_set_property(GObject *gobject,
242 guint prop_id,
243 const GValue *value,
244 GParamSpec *param_spec)
245 {
246 AgsRuler *ruler;
247
248 ruler = AGS_RULER(gobject);
249
250 switch(prop_id){
251 case PROP_FONT_SIZE:
252 {
253 ruler->font_size = g_value_get_uint(value);
254 }
255 break;
256 case PROP_STEP:
257 {
258 ruler->step = g_value_get_uint(value);
259 }
260 break;
261 case PROP_LARGE_STEP:
262 {
263 ruler->large_step = g_value_get_uint(value);
264 }
265 break;
266 case PROP_SMALL_STEP:
267 {
268 ruler->small_step = g_value_get_uint(value);
269 }
270 break;
271 case PROP_ADJUSTMENT:
272 {
273 GtkAdjustment *adjustment;
274
275 adjustment = (GtkAdjustment *) g_value_get_object(value);
276
277 if(ruler->adjustment == adjustment)
278 return;
279
280 if(ruler->adjustment != NULL){
281 g_object_unref(G_OBJECT(ruler->adjustment));
282 }
283
284 if(adjustment != NULL){
285 g_object_ref(G_OBJECT(adjustment));
286 }
287
288 ruler->adjustment = adjustment;
289 }
290 break;
291 default:
292 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
293 break;
294 }
295 }
296
297 void
ags_ruler_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)298 ags_ruler_get_property(GObject *gobject,
299 guint prop_id,
300 GValue *value,
301 GParamSpec *param_spec)
302 {
303 AgsRuler *ruler;
304
305 ruler = AGS_RULER(gobject);
306
307 switch(prop_id){
308 case PROP_FONT_SIZE:
309 {
310 g_value_set_uint(value, ruler->font_size);
311 }
312 break;
313 case PROP_STEP:
314 {
315 g_value_set_uint(value, ruler->step);
316 }
317 break;
318 case PROP_LARGE_STEP:
319 {
320 g_value_set_uint(value, ruler->large_step);
321 }
322 break;
323 case PROP_SMALL_STEP:
324 {
325 g_value_set_uint(value, ruler->small_step);
326 }
327 break;
328 case PROP_ADJUSTMENT:
329 {
330 g_value_set_object(value, ruler->adjustment);
331 }
332 break;
333 default:
334 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
335 break;
336 }
337 }
338
339 void
ags_ruler_realize(GtkWidget * widget)340 ags_ruler_realize(GtkWidget *widget)
341 {
342 AgsRuler *ruler;
343
344 GdkWindow *window;
345
346 GtkAllocation allocation;
347 GdkWindowAttr attributes;
348
349 gint attributes_mask;
350 gint border_left, border_top;
351
352 g_return_if_fail(widget != NULL);
353 g_return_if_fail(AGS_IS_RULER(widget));
354
355 ruler = AGS_RULER(widget);
356
357 // GTK_WIDGET_CLASS(ags_ruler_parent_class)->realize(widget);
358
359 gtk_widget_set_realized(widget, TRUE);
360
361 gtk_widget_get_allocation(widget,
362 &allocation);
363
364 /* */
365 attributes.window_type = GDK_WINDOW_CHILD;
366
367 attributes.x = allocation.x;
368 attributes.y = allocation.y;
369 attributes.width = allocation.width;
370 attributes.height = allocation.height;
371
372 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
373
374 attributes.wclass = GDK_INPUT_OUTPUT;
375 attributes.visual = gtk_widget_get_visual(widget);
376 attributes.event_mask = gtk_widget_get_events(widget);
377 attributes.event_mask |= (GDK_EXPOSURE_MASK |
378 GDK_BUTTON_PRESS_MASK |
379 GDK_BUTTON_RELEASE_MASK |
380 GDK_BUTTON1_MOTION_MASK |
381 GDK_BUTTON3_MOTION_MASK |
382 GDK_POINTER_MOTION_HINT_MASK |
383 GDK_POINTER_MOTION_MASK |
384 GDK_ENTER_NOTIFY_MASK |
385 GDK_LEAVE_NOTIFY_MASK);
386
387 window = gdk_window_new(gtk_widget_get_parent_window(widget),
388 &attributes, attributes_mask);
389
390 gtk_widget_register_window(widget, window);
391 gtk_widget_set_window(widget, window);
392
393 ags_ruler_send_configure(ruler);
394 }
395
396 void
ags_ruler_size_allocate(GtkWidget * widget,GtkAllocation * allocation)397 ags_ruler_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
398 {
399 AgsRuler *ruler;
400
401 g_return_if_fail(AGS_IS_RULER(widget));
402 g_return_if_fail(allocation != NULL);
403
404 ruler = AGS_RULER(widget);
405
406 gtk_widget_set_allocation(widget, allocation);
407
408 if(gtk_widget_get_realized(widget)){
409 gdk_window_move_resize(gtk_widget_get_window(widget),
410 allocation->x, allocation->y,
411 allocation->width, allocation->height);
412
413 ags_ruler_send_configure(ruler);
414 }
415 }
416
417 void
ags_ruler_send_configure(AgsRuler * ruler)418 ags_ruler_send_configure(AgsRuler *ruler)
419 {
420 GtkAllocation allocation;
421 GtkWidget *widget;
422 GdkEvent *event = gdk_event_new (GDK_CONFIGURE);
423
424 widget = GTK_WIDGET(ruler);
425 gtk_widget_get_allocation(widget, &allocation);
426
427 event->configure.window = g_object_ref(gtk_widget_get_window (widget));
428 event->configure.send_event = TRUE;
429 event->configure.x = allocation.x;
430 event->configure.y = allocation.y;
431 event->configure.width = allocation.width;
432 event->configure.height = allocation.height;
433
434 gtk_widget_event(widget, event);
435 gdk_event_free(event);
436 }
437
438 void
ags_ruler_show(GtkWidget * widget)439 ags_ruler_show(GtkWidget *widget)
440 {
441 GTK_WIDGET_CLASS(ags_ruler_parent_class)->show(widget);
442 }
443
444 void
ags_ruler_get_preferred_height(GtkWidget * widget,gint * minimal_height,gint * natural_height)445 ags_ruler_get_preferred_height(GtkWidget *widget,
446 gint *minimal_height,
447 gint *natural_height)
448 {
449 gint height_request;
450
451 height_request = -1;
452
453 g_object_get(widget,
454 "height-request", &height_request,
455 NULL);
456
457 if(height_request != -1){
458 minimal_height[0] =
459 natural_height[0] = height_request;
460 }else{
461 minimal_height[0] =
462 natural_height[0] = (gint) AGS_RULER_DEFAULT_HEIGHT;
463 }
464 }
465
466 /**
467 * ags_ruler_draw:
468 * @ruler an #AgsRuler
469 *
470 * draws the widget
471 */
472 gboolean
ags_ruler_draw(AgsRuler * ruler,cairo_t * cr)473 ags_ruler_draw(AgsRuler *ruler, cairo_t *cr)
474 {
475 GtkWidget *widget;
476
477 GtkAllocation allocation;
478
479 gchar *font_name;
480
481 gdouble tact_factor, zoom_factor;
482 gdouble tact;
483
484 guint offset;
485 guint step;
486 guint x0;
487 guint z;
488 guint i, i_stop;
489
490 widget = GTK_WIDGET(ruler);
491
492 // GTK_WIDGET_CLASS(ags_ruler_parent_class)->draw(widget, cr);
493
494 g_object_get(gtk_settings_get_default(),
495 "gtk-font-name", &font_name,
496 NULL);
497
498 gtk_widget_get_allocation(widget,
499 &allocation);
500
501 // cairo_surface_flush(cairo_get_target(cr));
502 cairo_push_group(cr);
503
504 /* calculate base step */
505 tact = ruler->precision;
506
507 step = ruler->step * 0.25 * ruler->factor * ruler->precision;
508
509 /* draw bg */
510 cairo_set_source_rgba(cr,
511 0.0,
512 0.0,
513 0.125,
514 1.0);
515 cairo_rectangle(cr,
516 0.0, 0.0,
517 (double) allocation.width, (double) allocation.height);
518 cairo_fill(cr);
519
520 cairo_set_source_rgba(cr,
521 1.0,
522 1.0,
523 1.0,
524 1.0);
525 cairo_set_line_width(cr,
526 1.25);
527
528 /* draw scale */
529 offset = (gtk_adjustment_get_value(ruler->adjustment) * step);
530 x0 = offset % step;
531
532 z = (guint) floor((offset - x0) / step);
533
534 i_stop = (guint) ceil((double) (allocation.width + (step + x0)) / (double) step);
535
536 for(i = 0; i < i_stop; i++, z++){
537 cairo_move_to(cr,
538 (double) (i * step - x0),
539 (double) (allocation.height));
540
541 if(tact < 1.0){
542 PangoLayout *layout;
543 PangoFontDescription *desc;
544
545 PangoRectangle ink_rect, logical_rect;
546
547 gchar *text;
548
549 text = g_strdup_printf("%u",
550 (guint) ((gdouble) z / tact));
551
552 layout = pango_cairo_create_layout(cr);
553 pango_layout_set_text(layout,
554 text,
555 -1);
556 desc = pango_font_description_from_string(font_name);
557 pango_font_description_set_size(desc,
558 ruler->font_size * PANGO_SCALE);
559 pango_layout_set_font_description(layout,
560 desc);
561 pango_font_description_free(desc);
562
563 pango_layout_get_extents(layout,
564 &ink_rect,
565 &logical_rect);
566
567 /* draw large step */
568 cairo_set_line_width(cr,
569 1.75);
570
571 cairo_line_to(cr,
572 (double) (i * step - x0),
573 (double) (allocation.height - ruler->large_step));
574
575 /* draw scale step */
576 cairo_move_to(cr,
577 (double) (i * step - x0),
578 (double) (allocation.height - ruler->large_step - (ruler->font_size + AGS_RULER_FREE_SPACE)));
579
580 pango_cairo_show_layout(cr,
581 layout);
582
583 g_object_unref(layout);
584
585 g_free(text);
586 }else{
587 if(z % (guint) floor(tact) == 0){
588 PangoLayout *layout;
589 PangoFontDescription *desc;
590
591 PangoRectangle ink_rect, logical_rect;
592
593 gchar *text;
594
595 text = g_strdup_printf("%u",
596 (guint) ((gdouble) z / tact));
597
598 layout = pango_cairo_create_layout(cr);
599 pango_layout_set_text(layout,
600 text,
601 -1);
602 desc = pango_font_description_from_string(font_name);
603 pango_font_description_set_size(desc,
604 ruler->font_size * PANGO_SCALE);
605 pango_layout_set_font_description(layout,
606 desc);
607 pango_font_description_free(desc);
608
609 pango_layout_get_extents(layout,
610 &ink_rect,
611 &logical_rect);
612
613 /* draw large step */
614 cairo_set_line_width(cr,
615 1.75);
616
617 cairo_line_to(cr,
618 (double) (i * step - x0),
619 (double) (allocation.height - ruler->large_step));
620
621 /* draw scale step */
622 cairo_move_to(cr,
623 (double) (i * step - x0),
624 (double) (allocation.height - ruler->large_step - (ruler->font_size + AGS_RULER_FREE_SPACE)));
625
626 pango_cairo_show_layout(cr,
627 layout);
628
629 g_object_unref(layout);
630
631 g_free(text);
632 }else{
633 /* draw small step */
634 cairo_set_line_width(cr,
635 1.25);
636
637 cairo_line_to(cr,
638 (double) (i * step - x0),
639 (double) (allocation.height - ruler->small_step));
640 }
641 }
642
643 cairo_stroke(cr);
644 }
645
646 g_free(font_name);
647
648 cairo_pop_group_to_source(cr);
649 cairo_paint(cr);
650
651 // cairo_surface_mark_dirty(cairo_get_target(cr));
652
653 return(FALSE);
654 }
655
656 /**
657 * ags_ruler_get_font_size:
658 * @ruler: the #AgsRuler
659 *
660 * Get font size of @ruler.
661 *
662 * Returns: the font size
663 *
664 * Since: 3.6.15
665 */
666 guint
ags_ruler_get_font_size(AgsRuler * ruler)667 ags_ruler_get_font_size(AgsRuler *ruler)
668 {
669 guint font_size;
670
671 if(!AGS_IS_RULER(ruler)){
672 return(0);
673 }
674
675 g_object_get(ruler,
676 "font-size", &font_size,
677 NULL);
678
679 return(font_size);
680 }
681
682 /**
683 * ags_ruler_set_font_size:
684 * @ruler: the #AgsRuler
685 * @font_size: the font size
686 *
687 * Set font size of @ruler.
688 *
689 * Since: 3.6.15
690 */
691 void
ags_ruler_set_font_size(AgsRuler * ruler,guint font_size)692 ags_ruler_set_font_size(AgsRuler *ruler,
693 guint font_size)
694 {
695 if(!AGS_IS_RULER(ruler)){
696 return;
697 }
698
699 g_object_set(ruler,
700 "font-size", font_size,
701 NULL);
702 }
703
704 /**
705 * ags_ruler_get_step:
706 * @ruler: the #AgsRuler
707 *
708 * Get step of @ruler.
709 *
710 * Returns: the step
711 *
712 * Since: 3.2.0
713 */
714 guint
ags_ruler_get_step(AgsRuler * ruler)715 ags_ruler_get_step(AgsRuler *ruler)
716 {
717 guint step;
718
719 if(!AGS_IS_RULER(ruler)){
720 return(0);
721 }
722
723 g_object_get(ruler,
724 "step", &step,
725 NULL);
726
727 return(step);
728 }
729
730 /**
731 * ags_ruler_set_step:
732 * @ruler: the #AgsRuler
733 * @step: the step
734 *
735 * Set step of @ruler.
736 *
737 * Since: 3.2.0
738 */
739 void
ags_ruler_set_step(AgsRuler * ruler,guint step)740 ags_ruler_set_step(AgsRuler *ruler,
741 guint step)
742 {
743 if(!AGS_IS_RULER(ruler)){
744 return;
745 }
746
747 g_object_set(ruler,
748 "step", step,
749 NULL);
750 }
751
752 /**
753 * ags_ruler_get_large_step:
754 * @ruler: the #AgsRuler
755 *
756 * Get large step of @ruler.
757 *
758 * Returns: the large step
759 *
760 * Since: 3.2.0
761 */
762 guint
ags_ruler_get_large_step(AgsRuler * ruler)763 ags_ruler_get_large_step(AgsRuler *ruler)
764 {
765 guint large_step;
766
767 if(!AGS_IS_RULER(ruler)){
768 return(0);
769 }
770
771 g_object_get(ruler,
772 "large-step", &large_step,
773 NULL);
774
775 return(large_step);
776 }
777
778 /**
779 * ags_ruler_set_large_step:
780 * @ruler: the #AgsRuler
781 * @large_step: the large step
782 *
783 * Set large step of @ruler.
784 *
785 * Since: 3.2.0
786 */
787 void
ags_ruler_set_large_step(AgsRuler * ruler,guint large_step)788 ags_ruler_set_large_step(AgsRuler *ruler,
789 guint large_step)
790 {
791 if(!AGS_IS_RULER(ruler)){
792 return;
793 }
794
795 g_object_set(ruler,
796 "large-step", large_step,
797 NULL);
798 }
799
800 /**
801 * ags_ruler_get_small_step:
802 * @ruler: the #AgsRuler
803 *
804 * Get small step of @ruler.
805 *
806 * Returns: the small step
807 *
808 * Since: 3.2.0
809 */
810 guint
ags_ruler_get_small_step(AgsRuler * ruler)811 ags_ruler_get_small_step(AgsRuler *ruler)
812 {
813 guint small_step;
814
815 if(!AGS_IS_RULER(ruler)){
816 return(0);
817 }
818
819 g_object_get(ruler,
820 "small-step", &small_step,
821 NULL);
822
823 return(small_step);
824 }
825
826 /**
827 * ags_ruler_set_small_step:
828 * @ruler: the #AgsRuler
829 * @small_step: the small step
830 *
831 * Set small step of @ruler.
832 *
833 * Since: 3.2.0
834 */
835 void
ags_ruler_set_small_step(AgsRuler * ruler,guint small_step)836 ags_ruler_set_small_step(AgsRuler *ruler,
837 guint small_step)
838 {
839 if(!AGS_IS_RULER(ruler)){
840 return;
841 }
842
843 g_object_set(ruler,
844 "small-step", small_step,
845 NULL);
846 }
847
848 /**
849 * ags_ruler_get_adjustment:
850 * @ruler: the #AgsRuler
851 *
852 * Get adjustment of @ruler.
853 *
854 * Returns: (transfer full): the #GtkAdjustment
855 *
856 * Since: 3.2.0
857 */
858 GtkAdjustment*
ags_ruler_get_adjustment(AgsRuler * ruler)859 ags_ruler_get_adjustment(AgsRuler *ruler)
860 {
861 GtkAdjustment *adjustment;
862
863 if(!AGS_IS_RULER(ruler)){
864 return(NULL);
865 }
866
867 g_object_get(ruler,
868 "adjustment", &adjustment,
869 NULL);
870
871 return(adjustment);
872 }
873
874 /**
875 * ags_ruler_set_adjustment:
876 * @ruler: the #AgsRuler
877 * @adjustment: (transfer none): the #GtkAdjustment
878 *
879 * Set adjustment of @ruler.
880 *
881 * Since: 3.2.0
882 */
883 void
ags_ruler_set_adjustment(AgsRuler * ruler,GtkAdjustment * adjustment)884 ags_ruler_set_adjustment(AgsRuler *ruler,
885 GtkAdjustment *adjustment)
886 {
887 if(!AGS_IS_RULER(ruler)){
888 return;
889 }
890
891 g_object_set(ruler,
892 "adjustment", adjustment,
893 NULL);
894 }
895
896 /**
897 * ags_ruler_new:
898 *
899 * Create a new instance of #AgsRuler
900 *
901 * Returns: the new #AgsRuler
902 *
903 * Since: 3.0.0
904 */
905 AgsRuler*
ags_ruler_new()906 ags_ruler_new()
907 {
908 AgsRuler *ruler;
909 GtkAdjustment *adjustment;
910
911 adjustment = (GtkAdjustment *) gtk_adjustment_new(0.0, 0.0, 1.0, 0.1, 0.1, 0.0);
912
913 ruler = (AgsRuler *) g_object_new(AGS_TYPE_RULER,
914 "adjustment", adjustment,
915 NULL);
916
917 return(ruler);
918 }
919