Bug Summary

File:ctk/ctklevelbar.c
Warning:line 860, column 42
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctklevelbar.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-171502-43637-1 -x c ctklevelbar.c
1/* CTK - The GIMP Toolkit
2 * Copyright © 2012 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Cosimo Cecchi <cosimoc@gnome.org>
18 *
19 */
20
21/**
22 * SECTION:ctklevelbar
23 * @Title: CtkLevelBar
24 * @Short_description: A bar that can used as a level indicator
25 *
26 * The #CtkLevelBar is a bar widget that can be used
27 * as a level indicator. Typical use cases are displaying the strength
28 * of a password, or showing the charge level of a battery.
29 *
30 * Use ctk_level_bar_set_value() to set the current value, and
31 * ctk_level_bar_add_offset_value() to set the value offsets at which
32 * the bar will be considered in a different state. CTK will add a few
33 * offsets by default on the level bar: #CTK_LEVEL_BAR_OFFSET_LOW,
34 * #CTK_LEVEL_BAR_OFFSET_HIGH and #CTK_LEVEL_BAR_OFFSET_FULL, with
35 * values 0.25, 0.75 and 1.0 respectively.
36 *
37 * Note that it is your responsibility to update preexisting offsets
38 * when changing the minimum or maximum value. CTK+ will simply clamp
39 * them to the new range.
40 *
41 * ## Adding a custom offset on the bar
42 *
43 * |[<!-- language="C" -->
44 *
45 * static CtkWidget *
46 * create_level_bar (void)
47 * {
48 * CtkWidget *widget;
49 * CtkLevelBar *bar;
50 *
51 * widget = ctk_level_bar_new ();
52 * bar = CTK_LEVEL_BAR (widget);
53 *
54 * // This changes the value of the default low offset
55 *
56 * ctk_level_bar_add_offset_value (bar,
57 * CTK_LEVEL_BAR_OFFSET_LOW,
58 * 0.10);
59 *
60 * // This adds a new offset to the bar; the application will
61 * // be able to change its color CSS like this:
62 * //
63 * // levelbar block.my-offset {
64 * // background-color: magenta;
65 * // border-style: solid;
66 * // border-color: black;
67 * // border-style: 1px;
68 * // }
69 *
70 * ctk_level_bar_add_offset_value (bar, "my-offset", 0.60);
71 *
72 * return widget;
73 * }
74 * ]|
75 *
76 * The default interval of values is between zero and one, but it’s possible to
77 * modify the interval using ctk_level_bar_set_min_value() and
78 * ctk_level_bar_set_max_value(). The value will be always drawn in proportion to
79 * the admissible interval, i.e. a value of 15 with a specified interval between
80 * 10 and 20 is equivalent to a value of 0.5 with an interval between 0 and 1.
81 * When #CTK_LEVEL_BAR_MODE_DISCRETE is used, the bar level is rendered
82 * as a finite number of separated blocks instead of a single one. The number
83 * of blocks that will be rendered is equal to the number of units specified by
84 * the admissible interval.
85 *
86 * For instance, to build a bar rendered with five blocks, it’s sufficient to
87 * set the minimum value to 0 and the maximum value to 5 after changing the indicator
88 * mode to discrete.
89 *
90 * CtkLevelBar was introduced in CTK+ 3.6.
91 *
92 * # CtkLevelBar as CtkBuildable
93 *
94 * The CtkLevelBar implementation of the CtkBuildable interface supports a
95 * custom <offsets> element, which can contain any number of <offset> elements,
96 * each of which must have name and value attributes.
97 *
98 * # CSS nodes
99 *
100 * |[<!-- language="plain" -->
101 * levelbar[.discrete]
102 * ╰── trough
103 * ├── block.filled.level-name
104 * ┊
105 * ├── block.empty
106 * ┊
107 * ]|
108 *
109 * CtkLevelBar has a main CSS node with name levelbar and one of the style
110 * classes .discrete or .continuous and a subnode with name trough. Below the
111 * trough node are a number of nodes with name block and style class .filled
112 * or .empty. In continuous mode, there is exactly one node of each, in discrete
113 * mode, the number of filled and unfilled nodes corresponds to blocks that are
114 * drawn. The block.filled nodes also get a style class .level-name corresponding
115 * to the level for the current value.
116 *
117 * In horizontal orientation, the nodes are always arranged from left to right,
118 * regardless of text direction.
119 */
120#include "config.h"
121
122#include "ctkbuildable.h"
123#include "ctkbuilderprivate.h"
124#include "ctkcsscustomgadgetprivate.h"
125#include "ctkintl.h"
126#include "ctkorientableprivate.h"
127#include "ctklevelbar.h"
128#include "ctkmarshalers.h"
129#include "ctkstylecontext.h"
130#include "ctktypebuiltins.h"
131#include "ctkwidget.h"
132#include "ctkwidgetprivate.h"
133#include "ctkstylecontextprivate.h"
134#include "ctkcssstylepropertyprivate.h"
135#include "ctkcssnodeprivate.h"
136
137#include <math.h>
138#include <stdlib.h>
139
140#include "a11y/ctklevelbaraccessible.h"
141
142#include "fallback-c89.c"
143
144#define DEFAULT_BLOCK_SIZE3 3
145
146enum {
147 PROP_VALUE = 1,
148 PROP_MIN_VALUE,
149 PROP_MAX_VALUE,
150 PROP_MODE,
151 PROP_INVERTED,
152 LAST_PROPERTY,
153 PROP_ORIENTATION /* overridden */
154};
155
156enum {
157 SIGNAL_OFFSET_CHANGED,
158 NUM_SIGNALS
159};
160
161static GParamSpec *properties[LAST_PROPERTY] = { NULL((void*)0), };
162static guint signals[NUM_SIGNALS] = { 0, };
163
164typedef struct {
165 gchar *name;
166 gdouble value;
167} CtkLevelBarOffset;
168
169struct _CtkLevelBarPrivate {
170 CtkOrientation orientation;
171
172 CtkLevelBarMode bar_mode;
173
174 gdouble min_value;
175 gdouble max_value;
176 gdouble cur_value;
177
178 GList *offsets;
179
180 CtkCssGadget *trough_gadget;
181 CtkCssGadget **block_gadget;
182 guint n_blocks;
183
184 guint inverted : 1;
185};
186
187static void ctk_level_bar_set_value_internal (CtkLevelBar *self,
188 gdouble value);
189
190static void ctk_level_bar_buildable_init (CtkBuildableIface *iface);
191
192G_DEFINE_TYPE_WITH_CODE (CtkLevelBar, ctk_level_bar, CTK_TYPE_WIDGET,static void ctk_level_bar_init (CtkLevelBar *self); static void
ctk_level_bar_class_init (CtkLevelBarClass *klass); static GType
ctk_level_bar_get_type_once (void); static gpointer ctk_level_bar_parent_class
= ((void*)0); static gint CtkLevelBar_private_offset; static
void ctk_level_bar_class_intern_init (gpointer klass) { ctk_level_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkLevelBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkLevelBar_private_offset
); ctk_level_bar_class_init ((CtkLevelBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_level_bar_get_instance_private
(CtkLevelBar *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkLevelBar_private_offset)))); } GType ctk_level_bar_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_level_bar_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_level_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_widget_get_type ()), g_intern_static_string ("CtkLevelBar"
), sizeof (CtkLevelBarClass), (GClassInitFunc)(void (*)(void)
) ctk_level_bar_class_intern_init, sizeof (CtkLevelBar), (GInstanceInitFunc
)(void (*)(void)) ctk_level_bar_init, (GTypeFlags) 0); { {{ CtkLevelBar_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CtkLevelBarPrivate
)); } { const GInterfaceInfo g_implement_interface_info = { (
GInterfaceInitFunc)(void (*)(void)) ((void*)0), ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_orientable_get_type ()), &g_implement_interface_info)
; } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_level_bar_buildable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_buildable_get_type ()), &g_implement_interface_info);
};} } return g_define_type_id; }
193 G_ADD_PRIVATE (CtkLevelBar)static void ctk_level_bar_init (CtkLevelBar *self); static void
ctk_level_bar_class_init (CtkLevelBarClass *klass); static GType
ctk_level_bar_get_type_once (void); static gpointer ctk_level_bar_parent_class
= ((void*)0); static gint CtkLevelBar_private_offset; static
void ctk_level_bar_class_intern_init (gpointer klass) { ctk_level_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkLevelBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkLevelBar_private_offset
); ctk_level_bar_class_init ((CtkLevelBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_level_bar_get_instance_private
(CtkLevelBar *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkLevelBar_private_offset)))); } GType ctk_level_bar_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_level_bar_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_level_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_widget_get_type ()), g_intern_static_string ("CtkLevelBar"
), sizeof (CtkLevelBarClass), (GClassInitFunc)(void (*)(void)
) ctk_level_bar_class_intern_init, sizeof (CtkLevelBar), (GInstanceInitFunc
)(void (*)(void)) ctk_level_bar_init, (GTypeFlags) 0); { {{ CtkLevelBar_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CtkLevelBarPrivate
)); } { const GInterfaceInfo g_implement_interface_info = { (
GInterfaceInitFunc)(void (*)(void)) ((void*)0), ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_orientable_get_type ()), &g_implement_interface_info)
; } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_level_bar_buildable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_buildable_get_type ()), &g_implement_interface_info);
};} } return g_define_type_id; }
194 G_IMPLEMENT_INTERFACE (CTK_TYPE_ORIENTABLE, NULL)static void ctk_level_bar_init (CtkLevelBar *self); static void
ctk_level_bar_class_init (CtkLevelBarClass *klass); static GType
ctk_level_bar_get_type_once (void); static gpointer ctk_level_bar_parent_class
= ((void*)0); static gint CtkLevelBar_private_offset; static
void ctk_level_bar_class_intern_init (gpointer klass) { ctk_level_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkLevelBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkLevelBar_private_offset
); ctk_level_bar_class_init ((CtkLevelBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_level_bar_get_instance_private
(CtkLevelBar *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkLevelBar_private_offset)))); } GType ctk_level_bar_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_level_bar_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_level_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_widget_get_type ()), g_intern_static_string ("CtkLevelBar"
), sizeof (CtkLevelBarClass), (GClassInitFunc)(void (*)(void)
) ctk_level_bar_class_intern_init, sizeof (CtkLevelBar), (GInstanceInitFunc
)(void (*)(void)) ctk_level_bar_init, (GTypeFlags) 0); { {{ CtkLevelBar_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CtkLevelBarPrivate
)); } { const GInterfaceInfo g_implement_interface_info = { (
GInterfaceInitFunc)(void (*)(void)) ((void*)0), ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_orientable_get_type ()), &g_implement_interface_info)
; } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_level_bar_buildable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_buildable_get_type ()), &g_implement_interface_info);
};} } return g_define_type_id; }
195 G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_level_bar_init (CtkLevelBar *self); static void
ctk_level_bar_class_init (CtkLevelBarClass *klass); static GType
ctk_level_bar_get_type_once (void); static gpointer ctk_level_bar_parent_class
= ((void*)0); static gint CtkLevelBar_private_offset; static
void ctk_level_bar_class_intern_init (gpointer klass) { ctk_level_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkLevelBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkLevelBar_private_offset
); ctk_level_bar_class_init ((CtkLevelBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_level_bar_get_instance_private
(CtkLevelBar *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkLevelBar_private_offset)))); } GType ctk_level_bar_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_level_bar_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_level_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_widget_get_type ()), g_intern_static_string ("CtkLevelBar"
), sizeof (CtkLevelBarClass), (GClassInitFunc)(void (*)(void)
) ctk_level_bar_class_intern_init, sizeof (CtkLevelBar), (GInstanceInitFunc
)(void (*)(void)) ctk_level_bar_init, (GTypeFlags) 0); { {{ CtkLevelBar_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CtkLevelBarPrivate
)); } { const GInterfaceInfo g_implement_interface_info = { (
GInterfaceInitFunc)(void (*)(void)) ((void*)0), ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_orientable_get_type ()), &g_implement_interface_info)
; } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_level_bar_buildable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_buildable_get_type ()), &g_implement_interface_info);
};} } return g_define_type_id; }
196 ctk_level_bar_buildable_init))static void ctk_level_bar_init (CtkLevelBar *self); static void
ctk_level_bar_class_init (CtkLevelBarClass *klass); static GType
ctk_level_bar_get_type_once (void); static gpointer ctk_level_bar_parent_class
= ((void*)0); static gint CtkLevelBar_private_offset; static
void ctk_level_bar_class_intern_init (gpointer klass) { ctk_level_bar_parent_class
= g_type_class_peek_parent (klass); if (CtkLevelBar_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CtkLevelBar_private_offset
); ctk_level_bar_class_init ((CtkLevelBarClass*) klass); } __attribute__
((__unused__)) static inline gpointer ctk_level_bar_get_instance_private
(CtkLevelBar *self) { return (((gpointer) ((guint8*) (self) +
(glong) (CtkLevelBar_private_offset)))); } GType ctk_level_bar_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_level_bar_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_level_bar_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
ctk_widget_get_type ()), g_intern_static_string ("CtkLevelBar"
), sizeof (CtkLevelBarClass), (GClassInitFunc)(void (*)(void)
) ctk_level_bar_class_intern_init, sizeof (CtkLevelBar), (GInstanceInitFunc
)(void (*)(void)) ctk_level_bar_init, (GTypeFlags) 0); { {{ CtkLevelBar_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CtkLevelBarPrivate
)); } { const GInterfaceInfo g_implement_interface_info = { (
GInterfaceInitFunc)(void (*)(void)) ((void*)0), ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_orientable_get_type ()), &g_implement_interface_info)
; } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) ctk_level_bar_buildable_init, ((void*)0), (
(void*)0) }; g_type_add_interface_static (g_define_type_id, (
ctk_buildable_get_type ()), &g_implement_interface_info);
};} } return g_define_type_id; }
197
198static CtkLevelBarOffset *
199ctk_level_bar_offset_new (const gchar *name,
200 gdouble value)
201{
202 CtkLevelBarOffset *offset = g_slice_new0 (CtkLevelBarOffset)((CtkLevelBarOffset*) g_slice_alloc0 (sizeof (CtkLevelBarOffset
)))
;
203
204 offset->name = g_strdup (name)g_strdup_inline (name);
205 offset->value = value;
206
207 return offset;
208}
209
210static void
211ctk_level_bar_offset_free (CtkLevelBarOffset *offset)
212{
213 g_free (offset->name);
214 g_slice_free (CtkLevelBarOffset, offset)do { if (1) g_slice_free1 (sizeof (CtkLevelBarOffset), (offset
)); else (void) ((CtkLevelBarOffset*) 0 == (offset)); } while
(0)
;
215}
216
217static gint
218offset_find_func (gconstpointer data,
219 gconstpointer user_data)
220{
221 const CtkLevelBarOffset *offset = data;
222 const gchar *name = user_data;
223
224 return g_strcmp0 (name, offset->name);
225}
226
227static gint
228offset_sort_func (gconstpointer a,
229 gconstpointer b)
230{
231 const CtkLevelBarOffset *offset_a = a;
232 const CtkLevelBarOffset *offset_b = b;
233
234 return (offset_a->value > offset_b->value);
235}
236
237static gboolean
238ctk_level_bar_ensure_offset (CtkLevelBar *self,
239 const gchar *name,
240 gdouble value)
241{
242 GList *existing;
243 CtkLevelBarOffset *offset = NULL((void*)0);
244 CtkLevelBarOffset *new_offset;
245
246 existing = g_list_find_custom (self->priv->offsets, name, offset_find_func);
247 if (existing)
248 offset = existing->data;
249
250 if (offset && (offset->value == value))
251 return FALSE(0);
252
253 new_offset = ctk_level_bar_offset_new (name, value);
254
255 if (offset)
256 {
257 ctk_level_bar_offset_free (offset);
258 self->priv->offsets = g_list_delete_link (self->priv->offsets, existing);
259 }
260
261 self->priv->offsets = g_list_insert_sorted (self->priv->offsets, new_offset, offset_sort_func);
262
263 return TRUE(!(0));
264}
265
266static gboolean
267ctk_level_bar_value_in_interval (CtkLevelBar *self,
268 gdouble value)
269{
270 return ((value >= self->priv->min_value) &&
271 (value <= self->priv->max_value));
272}
273
274static gint
275ctk_level_bar_get_num_blocks (CtkLevelBar *self)
276{
277 if (self->priv->bar_mode == CTK_LEVEL_BAR_MODE_CONTINUOUS)
278 return 1;
279 else if (self->priv->bar_mode == CTK_LEVEL_BAR_MODE_DISCRETE)
280 return MAX (1, (gint) (round (self->priv->max_value) - round (self->priv->min_value)))(((1) > ((gint) (round (self->priv->max_value) - round
(self->priv->min_value)))) ? (1) : ((gint) (round (self
->priv->max_value) - round (self->priv->min_value
))))
;
281
282 return 0;
283}
284
285static gint
286ctk_level_bar_get_num_block_nodes (CtkLevelBar *self)
287{
288 if (self->priv->bar_mode == CTK_LEVEL_BAR_MODE_CONTINUOUS)
289 return 2;
290 else
291 return ctk_level_bar_get_num_blocks (self);
292}
293
294static void
295ctk_level_bar_get_min_block_size (CtkLevelBar *self,
296 gint *block_width,
297 gint *block_height)
298{
299 guint i, n_blocks;
300 gint width, height;
301
302 *block_width = *block_height = 0;
303 n_blocks = ctk_level_bar_get_num_block_nodes (self);
304
305 for (i = 0; i < n_blocks; i++)
306 {
307 ctk_css_gadget_get_preferred_size (self->priv->block_gadget[i],
308 CTK_ORIENTATION_HORIZONTAL,
309 -1,
310 &width, NULL((void*)0),
311 NULL((void*)0), NULL((void*)0));
312 ctk_css_gadget_get_preferred_size (self->priv->block_gadget[i],
313 CTK_ORIENTATION_VERTICAL,
314 -1,
315 &height, NULL((void*)0),
316 NULL((void*)0), NULL((void*)0));
317
318 *block_width = MAX (width, *block_width)(((width) > (*block_width)) ? (width) : (*block_width));
319 *block_height = MAX (height, *block_height)(((height) > (*block_height)) ? (height) : (*block_height)
)
;
320 }
321}
322
323static gboolean
324ctk_level_bar_get_real_inverted (CtkLevelBar *self)
325{
326 if (ctk_widget_get_direction (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL &&
327 self->priv->orientation == CTK_ORIENTATION_HORIZONTAL)
328 return !self->priv->inverted;
329
330 return self->priv->inverted;
331}
332
333static void
334ctk_level_bar_draw_fill_continuous (CtkLevelBar *self,
335 cairo_t *cr)
336{
337 gboolean inverted;
338
339 inverted = ctk_level_bar_get_real_inverted (self);
340
341 /* render the empty (unfilled) part */
342 ctk_css_gadget_draw (self->priv->block_gadget[inverted ? 0 : 1], cr);
343
344 /* now render the filled part on top of it */
345 if (self->priv->cur_value != 0)
346 ctk_css_gadget_draw (self->priv->block_gadget[inverted ? 1 : 0], cr);
347}
348
349static void
350ctk_level_bar_draw_fill_discrete (CtkLevelBar *self,
351 cairo_t *cr)
352{
353 gint num_blocks, i;
354
355 num_blocks = ctk_level_bar_get_num_blocks (self);
356
357 for (i = 0; i < num_blocks; i++)
358 ctk_css_gadget_draw (self->priv->block_gadget[i], cr);
359}
360
361static gboolean
362ctk_level_bar_render_trough (CtkCssGadget *gadget,
363 cairo_t *cr,
364 int x G_GNUC_UNUSED__attribute__ ((__unused__)),
365 int y G_GNUC_UNUSED__attribute__ ((__unused__)),
366 int width G_GNUC_UNUSED__attribute__ ((__unused__)),
367 int height G_GNUC_UNUSED__attribute__ ((__unused__)),
368 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
369{
370 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
371 CtkLevelBar *self = CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
;
372
373 if (self->priv->bar_mode == CTK_LEVEL_BAR_MODE_CONTINUOUS)
374 ctk_level_bar_draw_fill_continuous (self, cr);
375 else
376 ctk_level_bar_draw_fill_discrete (self, cr);
377
378 return FALSE(0);
379}
380
381static gboolean
382ctk_level_bar_draw (CtkWidget *widget,
383 cairo_t *cr)
384{
385 CtkLevelBar *self = CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
;
386
387 ctk_css_gadget_draw (self->priv->trough_gadget, cr);
388
389 return FALSE(0);
390}
391
392static void
393ctk_level_bar_measure_trough (CtkCssGadget *gadget,
394 CtkOrientation orientation,
395 int for_size G_GNUC_UNUSED__attribute__ ((__unused__)),
396 int *minimum,
397 int *natural,
398 int *minimum_baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
399 int *natural_baseline G_GNUC_UNUSED__attribute__ ((__unused__)),
400 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
401{
402 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
403 CtkLevelBar *self = CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
;
404 gint num_blocks, size;
405 gint block_width, block_height;
406
407 num_blocks = ctk_level_bar_get_num_blocks (self);
408 ctk_level_bar_get_min_block_size (self, &block_width, &block_height);
409
410 if (orientation == CTK_ORIENTATION_HORIZONTAL)
411 {
412 if (self->priv->orientation == CTK_ORIENTATION_HORIZONTAL)
413 size = num_blocks * block_width;
414 else
415 size = block_width;
416 }
417 else
418 {
419 if (self->priv->orientation == CTK_ORIENTATION_VERTICAL)
420 size = num_blocks * block_height;
421 else
422 size = block_height;
423 }
424
425 *minimum = size;
426 *natural = size;
427}
428
429static void
430ctk_level_bar_get_preferred_width (CtkWidget *widget,
431 gint *minimum,
432 gint *natural)
433{
434 ctk_css_gadget_get_preferred_size (CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
->priv->trough_gadget,
435 CTK_ORIENTATION_HORIZONTAL,
436 -1,
437 minimum, natural,
438 NULL((void*)0), NULL((void*)0));
439}
440
441static void
442ctk_level_bar_get_preferred_height (CtkWidget *widget,
443 gint *minimum,
444 gint *natural)
445{
446 ctk_css_gadget_get_preferred_size (CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
->priv->trough_gadget,
447 CTK_ORIENTATION_VERTICAL,
448 -1,
449 minimum, natural,
450 NULL((void*)0), NULL((void*)0));
451}
452
453static void
454ctk_level_bar_allocate_trough_continuous (CtkLevelBar *self,
455 const CtkAllocation *allocation,
456 int baseline,
457 CtkAllocation *out_clip)
458{
459 CtkAllocation block_area, clip;
460 gdouble fill_percentage;
461 gboolean inverted;
462 int block_min;
463
464 inverted = ctk_level_bar_get_real_inverted (self);
465
466 /* allocate the empty (unfilled) part */
467 ctk_css_gadget_allocate (self->priv->block_gadget[inverted ? 0 : 1],
468 allocation,
469 baseline,
470 out_clip);
471
472 if (self->priv->cur_value == 0)
473 return;
474
475 /* now allocate the filled part */
476 block_area = *allocation;
477 fill_percentage = (self->priv->cur_value - self->priv->min_value) /
478 (self->priv->max_value - self->priv->min_value);
479
480 ctk_css_gadget_get_preferred_size (self->priv->block_gadget[inverted ? 1 : 0],
481 self->priv->orientation, -1,
482 &block_min, NULL((void*)0),
483 NULL((void*)0), NULL((void*)0));
484
485 if (self->priv->orientation == CTK_ORIENTATION_HORIZONTAL)
486 {
487 block_area.width = (gint) floor (block_area.width * fill_percentage);
488 block_area.width = MAX (block_area.width, block_min)(((block_area.width) > (block_min)) ? (block_area.width) :
(block_min))
;
489
490 if (inverted)
491 block_area.x += allocation->width - block_area.width;
492 }
493 else
494 {
495 block_area.height = (gint) floor (block_area.height * fill_percentage);
496 block_area.height = MAX (block_area.height, block_min)(((block_area.height) > (block_min)) ? (block_area.height)
: (block_min))
;
497
498 if (inverted)
499 block_area.y += allocation->height - block_area.height;
500 }
501
502 ctk_css_gadget_allocate (self->priv->block_gadget[inverted ? 1 : 0],
503 &block_area,
504 baseline,
505 &clip);
506 cdk_rectangle_intersect (out_clip, &clip, out_clip);
507}
508
509static void
510ctk_level_bar_allocate_trough_discrete (CtkLevelBar *self,
511 const CtkAllocation *allocation,
512 int baseline,
513 CtkAllocation *out_clip)
514{
515 CtkAllocation block_area, clip;
516 gint num_blocks, i;
517 gint block_width, block_height;
518
519 ctk_level_bar_get_min_block_size (self, &block_width, &block_height);
520 num_blocks = ctk_level_bar_get_num_blocks (self);
521
522 if (num_blocks == 0)
523 return;
524
525 if (self->priv->orientation == CTK_ORIENTATION_HORIZONTAL)
526 {
527 block_width = MAX (block_width, (gint) floor (allocation->width / num_blocks))(((block_width) > ((gint) floor (allocation->width / num_blocks
))) ? (block_width) : ((gint) floor (allocation->width / num_blocks
)))
;
528 block_height = allocation->height;
529 }
530 else
531 {
532 block_width = allocation->width;
533 block_height = MAX (block_height, (gint) floor (allocation->height / num_blocks))(((block_height) > ((gint) floor (allocation->height / num_blocks
))) ? (block_height) : ((gint) floor (allocation->height /
num_blocks)))
;
534 }
535
536 block_area.x = allocation->x;
537 block_area.y = allocation->y;
538 block_area.width = block_width;
539 block_area.height = block_height;
540
541 for (i = 0; i < num_blocks; i++)
542 {
543 ctk_css_gadget_allocate (self->priv->block_gadget[i],
544 &block_area,
545 baseline,
546 &clip);
547 cdk_rectangle_intersect (out_clip, &clip, out_clip);
548
549 if (self->priv->orientation == CTK_ORIENTATION_HORIZONTAL)
550 block_area.x += block_area.width;
551 else
552 block_area.y += block_area.height;
553 }
554}
555
556static void
557ctk_level_bar_allocate_trough (CtkCssGadget *gadget,
558 const CtkAllocation *allocation,
559 int baseline,
560 CtkAllocation *out_clip,
561 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
562{
563 CtkWidget *widget = ctk_css_gadget_get_owner (gadget);
564 CtkLevelBar *self = CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
;
565
566 if (self->priv->bar_mode == CTK_LEVEL_BAR_MODE_CONTINUOUS)
567 ctk_level_bar_allocate_trough_continuous (self, allocation, baseline, out_clip);
568 else
569 ctk_level_bar_allocate_trough_discrete (self, allocation, baseline, out_clip);
570}
571
572static void
573ctk_level_bar_size_allocate (CtkWidget *widget,
574 CtkAllocation *allocation)
575{
576 CtkAllocation clip;
577
578 CTK_WIDGET_CLASS (ctk_level_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_level_bar_parent_class)), ((ctk_widget_get_type ()))
))))
->size_allocate (widget, allocation);
579
580 ctk_css_gadget_allocate (CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
->priv->trough_gadget,
581 allocation,
582 ctk_widget_get_allocated_baseline (widget),
583 &clip);
584
585 ctk_widget_set_clip (widget, &clip);
586}
587
588static void
589update_block_nodes (CtkLevelBar *self)
590{
591 CtkLevelBarPrivate *priv = self->priv;
592 CtkCssNode *trough_node = ctk_css_gadget_get_node (priv->trough_gadget);
593 guint n_blocks;
594 guint i;
595
596 n_blocks = ctk_level_bar_get_num_block_nodes (self);
597
598 if (priv->n_blocks == n_blocks)
599 return;
600 else if (n_blocks < priv->n_blocks)
601 {
602 for (i = n_blocks; i < priv->n_blocks; i++)
603 {
604 ctk_css_node_set_parent (ctk_css_gadget_get_node (priv->block_gadget[i]), NULL((void*)0));
605 g_clear_object (&priv->block_gadget[i])do { _Static_assert (sizeof *((&priv->block_gadget[i])
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->block_gadget[i]))) _pp = ((&priv->block_gadget
[i])); __typeof__ (*((&priv->block_gadget[i]))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
606 }
607 priv->block_gadget = g_renew (CtkCssGadget*, priv->block_gadget, n_blocks)((CtkCssGadget* *) g_realloc_n (priv->block_gadget, (n_blocks
), sizeof (CtkCssGadget*)))
;
608 priv->n_blocks = n_blocks;
609 }
610 else
611 {
612 priv->block_gadget = g_renew (CtkCssGadget*, priv->block_gadget, n_blocks)((CtkCssGadget* *) g_realloc_n (priv->block_gadget, (n_blocks
), sizeof (CtkCssGadget*)))
;
613 for (i = priv->n_blocks; i < n_blocks; i++)
614 {
615 priv->block_gadget[i] = ctk_css_custom_gadget_new ("block",
616 CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
,
617 priv->trough_gadget,
618 NULL((void*)0),
619 NULL((void*)0), NULL((void*)0), NULL((void*)0),
620 NULL((void*)0), NULL((void*)0));
621 ctk_css_gadget_set_state (priv->block_gadget[i], ctk_css_node_get_state (trough_node));
622 }
623 priv->n_blocks = n_blocks;
624 }
625}
626
627static void
628update_mode_style_classes (CtkLevelBar *self)
629{
630 CtkLevelBarPrivate *priv = self->priv;
631 CtkCssNode *widget_node;
632
633 widget_node = ctk_widget_get_css_node (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
634 if (priv->bar_mode == CTK_LEVEL_BAR_MODE_CONTINUOUS)
635 {
636 ctk_css_node_remove_class (widget_node, g_quark_from_static_string ("discrete"));
637 ctk_css_node_add_class (widget_node, g_quark_from_static_string ("continuous"));
638 }
639 else if (priv->bar_mode == CTK_LEVEL_BAR_MODE_DISCRETE)
640 {
641 ctk_css_node_add_class (widget_node, g_quark_from_static_string ("discrete"));
642 ctk_css_node_remove_class (widget_node, g_quark_from_static_string ("continuous"));
643 }
644}
645
646static void
647ctk_level_bar_state_flags_changed (CtkWidget *widget,
648 CtkStateFlags previous_state)
649{
650 CtkLevelBar *self = CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
;
651 CtkLevelBarPrivate *priv = self->priv;
652 CtkStateFlags state;
653 gint i;
654
655 state = ctk_widget_get_state_flags (widget);
656
657 ctk_css_gadget_set_state (priv->trough_gadget, state);
658 for (i = 0; i < priv->n_blocks; i++)
659 ctk_css_gadget_set_state (priv->block_gadget[i], state);
660
661 CTK_WIDGET_CLASS (ctk_level_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_level_bar_parent_class)), ((ctk_widget_get_type ()))
))))
->state_flags_changed (widget, previous_state);
662}
663
664static void
665update_level_style_classes (CtkLevelBar *self)
666{
667 CtkLevelBarPrivate *priv = self->priv;
668 gdouble value;
669 const gchar *classes[3] = { NULL((void*)0), NULL((void*)0), NULL((void*)0) };
670 const gchar *value_class = NULL((void*)0);
671 CtkLevelBarOffset *offset, *prev_offset;
672 GList *l;
673 gint num_filled, num_blocks, i;
674 gboolean inverted;
675
676 value = ctk_level_bar_get_value (self);
677
678 for (l = priv->offsets; l != NULL((void*)0); l = l->next)
679 {
680 offset = l->data;
681
682 /* find the right offset for our style class */
683 if (value <= offset->value)
684 {
685 if (l->prev == NULL((void*)0))
686 {
687 value_class = offset->name;
688 }
689 else
690 {
691 prev_offset = l->prev->data;
692 if (prev_offset->value < value)
693 value_class = offset->name;
694 }
695 }
696
697 if (value_class)
698 break;
699 }
700
701 inverted = ctk_level_bar_get_real_inverted (self);
702 num_blocks = ctk_level_bar_get_num_block_nodes (self);
703
704 if (priv->bar_mode == CTK_LEVEL_BAR_MODE_CONTINUOUS)
705 num_filled = 1;
706 else
707 num_filled = MIN (num_blocks, (gint) round (priv->cur_value) - (gint) round (priv->min_value))(((num_blocks) < ((gint) round (priv->cur_value) - (gint
) round (priv->min_value))) ? (num_blocks) : ((gint) round
(priv->cur_value) - (gint) round (priv->min_value)))
;
708
709 classes[0] = "filled";
710 classes[1] = value_class;
711 for (i = 0; i < num_filled; i++)
712 ctk_css_node_set_classes (ctk_css_gadget_get_node (priv->block_gadget[inverted ? num_blocks - 1 - i : i]), classes);
713
714 classes[0] = "empty";
715 classes[1] = NULL((void*)0);
716 for (; i < num_blocks; i++)
717 ctk_css_node_set_classes (ctk_css_gadget_get_node (priv->block_gadget[inverted ? num_blocks - 1 - i : i]), classes);
718}
719
720static void
721ctk_level_bar_direction_changed (CtkWidget *widget,
722 CtkTextDirection previous_dir)
723{
724 CtkLevelBar *self = CTK_LEVEL_BAR (widget)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_level_bar_get_type ()))))))
;
725
726 update_level_style_classes (self);
727
728 CTK_WIDGET_CLASS (ctk_level_bar_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_level_bar_parent_class)), ((ctk_widget_get_type ()))
))))
->direction_changed (widget, previous_dir);
729}
730
731static void
732ctk_level_bar_ensure_offsets_in_range (CtkLevelBar *self)
733{
734 CtkLevelBarOffset *offset;
735 GList *l = self->priv->offsets;
736
737 while (l != NULL((void*)0))
738 {
739 offset = l->data;
740 l = l->next;
741
742 if (offset->value < self->priv->min_value)
743 ctk_level_bar_ensure_offset (self, offset->name, self->priv->min_value);
744 else if (offset->value > self->priv->max_value)
745 ctk_level_bar_ensure_offset (self, offset->name, self->priv->max_value);
746 }
747}
748
749typedef struct {
750 CtkLevelBar *self;
751 CtkBuilder *builder;
752 GList *offsets;
753} OffsetsParserData;
754
755static void
756offset_start_element (GMarkupParseContext *context,
757 const gchar *element_name,
758 const gchar **names,
759 const gchar **values,
760 gpointer user_data,
761 GError **error)
762{
763 OffsetsParserData *data = user_data;
764
765 if (strcmp (element_name, "offsets") == 0)
766 {
767 if (!_ctk_builder_check_parent (data->builder, context, "object", error))
768 return;
769
770 if (!g_markup_collect_attributes (element_name, names, values, error,
771 G_MARKUP_COLLECT_INVALID, NULL((void*)0), NULL((void*)0),
772 G_MARKUP_COLLECT_INVALID))
773 _ctk_builder_prefix_error (data->builder, context, error);
774 }
775 else if (strcmp (element_name, "offset") == 0)
776 {
777 const gchar *name;
778 const gchar *value;
779 GValue gvalue = G_VALUE_INIT{ 0, { { 0 } } };
780 CtkLevelBarOffset *offset;
781
782 if (!_ctk_builder_check_parent (data->builder, context, "offsets", error))
783 return;
784
785 if (!g_markup_collect_attributes (element_name, names, values, error,
786 G_MARKUP_COLLECT_STRING, "name", &name,
787 G_MARKUP_COLLECT_STRING, "value", &value,
788 G_MARKUP_COLLECT_INVALID))
789 {
790 _ctk_builder_prefix_error (data->builder, context, error);
791 return;
792 }
793
794 if (!ctk_builder_value_from_string_type (data->builder, G_TYPE_DOUBLE((GType) ((15) << (2))), value, &gvalue, error))
795 {
796 _ctk_builder_prefix_error (data->builder, context, error);
797 return;
798 }
799
800 offset = ctk_level_bar_offset_new (name, g_value_get_double (&gvalue));
801 data->offsets = g_list_prepend (data->offsets, offset);
802 }
803 else
804 {
805 _ctk_builder_error_unhandled_tag (data->builder, context,
806 "CtkLevelBar", element_name,
807 error);
808 }
809}
810
811static const GMarkupParser offset_parser =
812{
813 .start_element = offset_start_element
814};
815
816static gboolean
817ctk_level_bar_buildable_custom_tag_start (CtkBuildable *buildable,
818 CtkBuilder *builder,
819 GObject *child,
820 const gchar *tagname,
821 GMarkupParser *parser,
822 gpointer *parser_data)
823{
824 OffsetsParserData *data;
825
826 if (child)
827 return FALSE(0);
828
829 if (strcmp (tagname, "offsets") != 0)
830 return FALSE(0);
831
832 data = g_slice_new0 (OffsetsParserData)((OffsetsParserData*) g_slice_alloc0 (sizeof (OffsetsParserData
)))
;
833 data->self = CTK_LEVEL_BAR (buildable)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_level_bar_get_type ()))))))
;
834 data->builder = builder;
835 data->offsets = NULL((void*)0);
836
837 *parser = offset_parser;
838 *parser_data = data;
839
840 return TRUE(!(0));
841}
842
843static void
844ctk_level_bar_buildable_custom_finished (CtkBuildable *buildable G_GNUC_UNUSED__attribute__ ((__unused__)),
845 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
846 GObject *child G_GNUC_UNUSED__attribute__ ((__unused__)),
847 const gchar *tagname,
848 gpointer user_data)
849{
850 OffsetsParserData *data = user_data;
851 CtkLevelBar *self;
852 CtkLevelBarOffset *offset;
853 GList *l;
854
855 self = data->self;
856
857 if (strcmp (tagname, "offsets") != 0)
858 goto out;
859
860 for (l = data->offsets; l != NULL((void*)0); l = l->next)
This statement is never executed
861 {
862 offset = l->data;
863 ctk_level_bar_add_offset_value (self, offset->name, offset->value);
864 }
865
866 out:
867 g_list_free_full (data->offsets, (GDestroyNotify) ctk_level_bar_offset_free);
868 g_slice_free (OffsetsParserData, data)do { if (1) g_slice_free1 (sizeof (OffsetsParserData), (data)
); else (void) ((OffsetsParserData*) 0 == (data)); } while (0
)
;
869}
870
871static void
872ctk_level_bar_buildable_init (CtkBuildableIface *iface)
873{
874 iface->custom_tag_start = ctk_level_bar_buildable_custom_tag_start;
875 iface->custom_finished = ctk_level_bar_buildable_custom_finished;
876}
877
878static void
879ctk_level_bar_set_orientation (CtkLevelBar *self,
880 CtkOrientation orientation)
881{
882 if (self->priv->orientation != orientation)
883 {
884 self->priv->orientation = orientation;
885 _ctk_orientable_set_style_classes (CTK_ORIENTABLE (self)((((CtkOrientable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_orientable_get_type ()))))))
);
886 ctk_widget_queue_resize (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
887 g_object_notify (G_OBJECT (self)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), (((GType) ((20) << (2))))))))
, "orientation");
888 }
889}
890
891static void
892ctk_level_bar_get_property (GObject *obj,
893 guint property_id,
894 GValue *value,
895 GParamSpec *pspec)
896{
897 CtkLevelBar *self = CTK_LEVEL_BAR (obj)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((ctk_level_bar_get_type ()))))))
;
898
899 switch (property_id)
900 {
901 case PROP_VALUE:
902 g_value_set_double (value, ctk_level_bar_get_value (self));
903 break;
904 case PROP_MIN_VALUE:
905 g_value_set_double (value, ctk_level_bar_get_min_value (self));
906 break;
907 case PROP_MAX_VALUE:
908 g_value_set_double (value, ctk_level_bar_get_max_value (self));
909 break;
910 case PROP_MODE:
911 g_value_set_enum (value, ctk_level_bar_get_mode (self));
912 break;
913 case PROP_INVERTED:
914 g_value_set_boolean (value, ctk_level_bar_get_inverted (self));
915 break;
916 case PROP_ORIENTATION:
917 g_value_set_enum (value, self->priv->orientation);
918 break;
919 default:
920 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec)do { GObject *_glib__object = (GObject*) ((obj)); GParamSpec *
_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctklevelbar.c", 920, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
921 break;
922 }
923}
924
925static void
926ctk_level_bar_set_property (GObject *obj,
927 guint property_id,
928 const GValue *value,
929 GParamSpec *pspec)
930{
931 CtkLevelBar *self = CTK_LEVEL_BAR (obj)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((ctk_level_bar_get_type ()))))))
;
932
933 switch (property_id)
934 {
935 case PROP_VALUE:
936 ctk_level_bar_set_value (self, g_value_get_double (value));
937 break;
938 case PROP_MIN_VALUE:
939 ctk_level_bar_set_min_value (self, g_value_get_double (value));
940 break;
941 case PROP_MAX_VALUE:
942 ctk_level_bar_set_max_value (self, g_value_get_double (value));
943 break;
944 case PROP_MODE:
945 ctk_level_bar_set_mode (self, g_value_get_enum (value));
946 break;
947 case PROP_INVERTED:
948 ctk_level_bar_set_inverted (self, g_value_get_boolean (value));
949 break;
950 case PROP_ORIENTATION:
951 ctk_level_bar_set_orientation (self, g_value_get_enum (value));
952 break;
953 default:
954 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec)do { GObject *_glib__object = (GObject*) ((obj)); GParamSpec *
_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctklevelbar.c", 954, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
955 break;
956 }
957}
958
959static void
960ctk_level_bar_finalize (GObject *obj)
961{
962 CtkLevelBar *self = CTK_LEVEL_BAR (obj)((((CtkLevelBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((ctk_level_bar_get_type ()))))))
;
963 CtkLevelBarPrivate *priv = self->priv;
964 gint i;
965
966 g_list_free_full (priv->offsets, (GDestroyNotify) ctk_level_bar_offset_free);
967
968 for (i = 0; i < priv->n_blocks; i++)
969 g_clear_object (&priv->block_gadget[i])do { _Static_assert (sizeof *((&priv->block_gadget[i])
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->block_gadget[i]))) _pp = ((&priv->block_gadget
[i])); __typeof__ (*((&priv->block_gadget[i]))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
970 g_free (priv->block_gadget);
971
972 g_clear_object (&priv->trough_gadget)do { _Static_assert (sizeof *((&priv->trough_gadget)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->trough_gadget))) _pp = ((&priv->trough_gadget
)); __typeof__ (*((&priv->trough_gadget))) _ptr = *_pp
; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
973
974 G_OBJECT_CLASS (ctk_level_bar_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_level_bar_parent_class)), (((GType) ((20) << (
2))))))))
->finalize (obj);
975}
976
977static void
978ctk_level_bar_class_init (CtkLevelBarClass *klass)
979{
980 GObjectClass *oclass = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
981 CtkWidgetClass *wclass = CTK_WIDGET_CLASS (klass)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((ctk_widget_get_type ()))))))
;
982
983 oclass->get_property = ctk_level_bar_get_property;
984 oclass->set_property = ctk_level_bar_set_property;
985 oclass->finalize = ctk_level_bar_finalize;
986
987 wclass->draw = ctk_level_bar_draw;
988 wclass->size_allocate = ctk_level_bar_size_allocate;
989 wclass->get_preferred_width = ctk_level_bar_get_preferred_width;
990 wclass->get_preferred_height = ctk_level_bar_get_preferred_height;
991 wclass->state_flags_changed = ctk_level_bar_state_flags_changed;
992 wclass->direction_changed = ctk_level_bar_direction_changed;
993
994 g_object_class_override_property (oclass, PROP_ORIENTATION, "orientation");
995
996 /**
997 * CtkLevelBar::offset-changed:
998 * @self: a #CtkLevelBar
999 * @name: the name of the offset that changed value
1000 *
1001 * Emitted when an offset specified on the bar changes value as an
1002 * effect to ctk_level_bar_add_offset_value() being called.
1003 *
1004 * The signal supports detailed connections; you can connect to the
1005 * detailed signal "changed::x" in order to only receive callbacks when
1006 * the value of offset "x" changes.
1007 *
1008 * Since: 3.6
1009 */
1010 signals[SIGNAL_OFFSET_CHANGED] =
1011 g_signal_new (I_("offset-changed")g_intern_static_string ("offset-changed"),
1012 CTK_TYPE_LEVEL_BAR(ctk_level_bar_get_type ()),
1013 G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
1014 G_STRUCT_OFFSET (CtkLevelBarClass, offset_changed)((glong) __builtin_offsetof(CtkLevelBarClass, offset_changed)
)
,
1015 NULL((void*)0), NULL((void*)0),
1016 NULL((void*)0),
1017 G_TYPE_NONE((GType) ((1) << (2))),
1018 1, G_TYPE_STRING((GType) ((16) << (2))));
1019
1020 /**
1021 * CtkLevelBar:value:
1022 *
1023 * The #CtkLevelBar:value property determines the currently
1024 * filled value of the level bar.
1025 *
1026 * Since: 3.6
1027 */
1028 properties[PROP_VALUE] =
1029 g_param_spec_double ("value",
1030 P_("Currently filled value level")g_dgettext("ctk30" "-properties","Currently filled value level"
)
,
1031 P_("Currently filled value level of the level bar")g_dgettext("ctk30" "-properties","Currently filled value level of the level bar"
)
,
1032 0.0, G_MAXDOUBLE1.7976931348623157e+308, 0.0,
1033 G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
|G_PARAM_EXPLICIT_NOTIFY);
1034
1035 /**
1036 * CtkLevelBar:min-value:
1037 *
1038 * The #CtkLevelBar:min-value property determines the minimum value of
1039 * the interval that can be displayed by the bar.
1040 *
1041 * Since: 3.6
1042 */
1043 properties[PROP_MIN_VALUE] =
1044 g_param_spec_double ("min-value",
1045 P_("Minimum value level for the bar")g_dgettext("ctk30" "-properties","Minimum value level for the bar"
)
,
1046 P_("Minimum value level that can be displayed by the bar")g_dgettext("ctk30" "-properties","Minimum value level that can be displayed by the bar"
)
,
1047 0.0, G_MAXDOUBLE1.7976931348623157e+308, 0.0,
1048 G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
|G_PARAM_EXPLICIT_NOTIFY);
1049
1050 /**
1051 * CtkLevelBar:max-value:
1052 *
1053 * The #CtkLevelBar:max-value property determaxes the maximum value of
1054 * the interval that can be displayed by the bar.
1055 *
1056 * Since: 3.6
1057 */
1058 properties[PROP_MAX_VALUE] =
1059 g_param_spec_double ("max-value",
1060 P_("Maximum value level for the bar")g_dgettext("ctk30" "-properties","Maximum value level for the bar"
)
,
1061 P_("Maximum value level that can be displayed by the bar")g_dgettext("ctk30" "-properties","Maximum value level that can be displayed by the bar"
)
,
1062 0.0, G_MAXDOUBLE1.7976931348623157e+308, 1.0,
1063 G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
|G_PARAM_EXPLICIT_NOTIFY);
1064
1065 /**
1066 * CtkLevelBar:mode:
1067 *
1068 * The #CtkLevelBar:mode property determines the way #CtkLevelBar
1069 * interprets the value properties to draw the level fill area.
1070 * Specifically, when the value is #CTK_LEVEL_BAR_MODE_CONTINUOUS,
1071 * #CtkLevelBar will draw a single block representing the current value in
1072 * that area; when the value is #CTK_LEVEL_BAR_MODE_DISCRETE,
1073 * the widget will draw a succession of separate blocks filling the
1074 * draw area, with the number of blocks being equal to the units separating
1075 * the integral roundings of #CtkLevelBar:min-value and #CtkLevelBar:max-value.
1076 *
1077 * Since: 3.6
1078 */
1079 properties[PROP_MODE] =
1080 g_param_spec_enum ("mode",
1081 P_("The mode of the value indicator")g_dgettext("ctk30" "-properties","The mode of the value indicator"
)
,
1082 P_("The mode of the value indicator displayed by the bar")g_dgettext("ctk30" "-properties","The mode of the value indicator displayed by the bar"
)
,
1083 CTK_TYPE_LEVEL_BAR_MODE(ctk_level_bar_mode_get_type ()),
1084 CTK_LEVEL_BAR_MODE_CONTINUOUS,
1085 G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
|G_PARAM_EXPLICIT_NOTIFY);
1086
1087 /**
1088 * CtkLevelBar:inverted:
1089 *
1090 * Level bars normally grow from top to bottom or left to right.
1091 * Inverted level bars grow in the opposite direction.
1092 *
1093 * Since: 3.8
1094 */
1095 properties[PROP_INVERTED] =
1096 g_param_spec_boolean ("inverted",
1097 P_("Inverted")g_dgettext("ctk30" "-properties","Inverted"),
1098 P_("Invert the direction in which the level bar grows")g_dgettext("ctk30" "-properties","Invert the direction in which the level bar grows"
)
,
1099 FALSE(0),
1100 G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
|G_PARAM_EXPLICIT_NOTIFY);
1101
1102 /**
1103 * CtkLevelBar:min-block-height:
1104 *
1105 * The min-block-height style property determines the minimum
1106 * height for blocks filling the #CtkLevelBar widget.
1107 *
1108 * Since: 3.6
1109 *
1110 * Deprecated: 3.20: Use the standard min-width/min-height CSS properties on
1111 * the block elements; the value of this style property is ignored.
1112 */
1113 ctk_widget_class_install_style_property
1114 (wclass, g_param_spec_int ("min-block-height",
1115 P_("Minimum height for filling blocks")g_dgettext("ctk30" "-properties","Minimum height for filling blocks"
)
,
1116 P_("Minimum height for blocks that fill the bar")g_dgettext("ctk30" "-properties","Minimum height for blocks that fill the bar"
)
,
1117 1, G_MAXINT2147483647, DEFAULT_BLOCK_SIZE3,
1118 G_PARAM_READWRITE|G_PARAM_DEPRECATED));
1119 /**
1120 * CtkLevelBar:min-block-width:
1121 *
1122 * The min-block-width style property determines the minimum
1123 * width for blocks filling the #CtkLevelBar widget.
1124 *
1125 * Since: 3.6
1126 *
1127 * Deprecated: 3.20: Use the standard min-width/min-height CSS properties on
1128 * the block elements; the value of this style property is ignored.
1129 */
1130 ctk_widget_class_install_style_property
1131 (wclass, g_param_spec_int ("min-block-width",
1132 P_("Minimum width for filling blocks")g_dgettext("ctk30" "-properties","Minimum width for filling blocks"
)
,
1133 P_("Minimum width for blocks that fill the bar")g_dgettext("ctk30" "-properties","Minimum width for blocks that fill the bar"
)
,
1134 1, G_MAXINT2147483647, DEFAULT_BLOCK_SIZE3,
1135 G_PARAM_READWRITE|G_PARAM_DEPRECATED));
1136
1137 g_object_class_install_properties (oclass, LAST_PROPERTY, properties);
1138
1139 ctk_widget_class_set_accessible_type (wclass, CTK_TYPE_LEVEL_BAR_ACCESSIBLE(ctk_level_bar_accessible_get_type ()));
1140 ctk_widget_class_set_css_name (wclass, "levelbar");
1141}
1142
1143static void
1144ctk_level_bar_init (CtkLevelBar *self)
1145{
1146 CtkLevelBarPrivate *priv;
1147 CtkCssNode *widget_node, *trough_node;
1148
1149 priv = self->priv = ctk_level_bar_get_instance_private (self);
1150
1151 priv->cur_value = 0.0;
1152 priv->min_value = 0.0;
1153 priv->max_value = 1.0;
1154
1155 /* set initial orientation and style classes */
1156 priv->orientation = CTK_ORIENTATION_HORIZONTAL;
1157 _ctk_orientable_set_style_classes (CTK_ORIENTABLE (self)((((CtkOrientable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_orientable_get_type ()))))))
);
1158
1159 priv->inverted = FALSE(0);
1160
1161 ctk_widget_set_has_window (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
, FALSE(0));
1162
1163 widget_node = ctk_widget_get_css_node (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
1164 priv->trough_gadget = ctk_css_custom_gadget_new ("trough",
1165 CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
,
1166 NULL((void*)0), NULL((void*)0),
1167 ctk_level_bar_measure_trough,
1168 ctk_level_bar_allocate_trough,
1169 ctk_level_bar_render_trough,
1170 NULL((void*)0), NULL((void*)0));
1171 trough_node = ctk_css_gadget_get_node (priv->trough_gadget);
1172 ctk_css_node_set_parent (trough_node, widget_node);
1173 ctk_css_node_set_state (trough_node, ctk_css_node_get_state (widget_node));
1174
1175 ctk_level_bar_ensure_offset (self, CTK_LEVEL_BAR_OFFSET_LOW"low", 0.25);
1176 ctk_level_bar_ensure_offset (self, CTK_LEVEL_BAR_OFFSET_HIGH"high", 0.75);
1177 ctk_level_bar_ensure_offset (self, CTK_LEVEL_BAR_OFFSET_FULL"full", 1.0);
1178
1179 priv->block_gadget = NULL((void*)0);
1180 priv->n_blocks = 0;
1181
1182 priv->bar_mode = CTK_LEVEL_BAR_MODE_CONTINUOUS;
1183 update_mode_style_classes (self);
1184 update_block_nodes (self);
1185 update_level_style_classes (self);
1186}
1187
1188/**
1189 * ctk_level_bar_new:
1190 *
1191 * Creates a new #CtkLevelBar.
1192 *
1193 * Returns: a #CtkLevelBar.
1194 *
1195 * Since: 3.6
1196 */
1197CtkWidget *
1198ctk_level_bar_new (void)
1199{
1200 return g_object_new (CTK_TYPE_LEVEL_BAR(ctk_level_bar_get_type ()), NULL((void*)0));
1201}
1202
1203/**
1204 * ctk_level_bar_new_for_interval:
1205 * @min_value: a positive value
1206 * @max_value: a positive value
1207 *
1208 * Utility constructor that creates a new #CtkLevelBar for the specified
1209 * interval.
1210 *
1211 * Returns: a #CtkLevelBar
1212 *
1213 * Since: 3.6
1214 */
1215CtkWidget *
1216ctk_level_bar_new_for_interval (gdouble min_value,
1217 gdouble max_value)
1218{
1219 return g_object_new (CTK_TYPE_LEVEL_BAR(ctk_level_bar_get_type ()),
1220 "min-value", min_value,
1221 "max-value", max_value,
1222 NULL((void*)0));
1223}
1224
1225/**
1226 * ctk_level_bar_get_min_value:
1227 * @self: a #CtkLevelBar
1228 *
1229 * Returns the value of the #CtkLevelBar:min-value property.
1230 *
1231 * Returns: a positive value
1232 *
1233 * Since: 3.6
1234 */
1235gdouble
1236ctk_level_bar_get_min_value (CtkLevelBar *self)
1237{
1238 g_return_val_if_fail (CTK_IS_LEVEL_BAR (self), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return (0.0); } } while (0)
;
1239
1240 return self->priv->min_value;
1241}
1242
1243/**
1244 * ctk_level_bar_get_max_value:
1245 * @self: a #CtkLevelBar
1246 *
1247 * Returns the value of the #CtkLevelBar:max-value property.
1248 *
1249 * Returns: a positive value
1250 *
1251 * Since: 3.6
1252 */
1253gdouble
1254ctk_level_bar_get_max_value (CtkLevelBar *self)
1255{
1256 g_return_val_if_fail (CTK_IS_LEVEL_BAR (self), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return (0.0); } } while (0)
;
1257
1258 return self->priv->max_value;
1259}
1260
1261/**
1262 * ctk_level_bar_get_value:
1263 * @self: a #CtkLevelBar
1264 *
1265 * Returns the value of the #CtkLevelBar:value property.
1266 *
1267 * Returns: a value in the interval between
1268 * #CtkLevelBar:min-value and #CtkLevelBar:max-value
1269 *
1270 * Since: 3.6
1271 */
1272gdouble
1273ctk_level_bar_get_value (CtkLevelBar *self)
1274{
1275 g_return_val_if_fail (CTK_IS_LEVEL_BAR (self), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return (0.0); } } while (0)
;
1276
1277 return self->priv->cur_value;
1278}
1279
1280static void
1281ctk_level_bar_set_value_internal (CtkLevelBar *self,
1282 gdouble value)
1283{
1284 self->priv->cur_value = value;
1285 g_object_notify_by_pspec (G_OBJECT (self)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), (((GType) ((20) << (2))))))))
, properties[PROP_VALUE]);
1286 ctk_widget_queue_allocate (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
1287}
1288
1289/**
1290 * ctk_level_bar_set_min_value:
1291 * @self: a #CtkLevelBar
1292 * @value: a positive value
1293 *
1294 * Sets the value of the #CtkLevelBar:min-value property.
1295 *
1296 * You probably want to update preexisting level offsets after calling
1297 * this function.
1298 *
1299 * Since: 3.6
1300 */
1301void
1302ctk_level_bar_set_min_value (CtkLevelBar *self,
1303 gdouble value)
1304{
1305 CtkLevelBarPrivate *priv = self->priv;
1306
1307 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1308 g_return_if_fail (value >= 0.0)do { if ((value >= 0.0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "value >= 0.0"); return
; } } while (0)
;
1309
1310 if (value == priv->min_value)
1311 return;
1312
1313 priv->min_value = value;
1314
1315 if (priv->min_value > priv->cur_value)
1316 ctk_level_bar_set_value_internal (self, priv->min_value);
1317
1318 update_block_nodes (self);
1319 update_level_style_classes (self);
1320 g_object_notify_by_pspec (G_OBJECT (self)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), (((GType) ((20) << (2))))))))
, properties[PROP_MIN_VALUE]);
1321}
1322
1323/**
1324 * ctk_level_bar_set_max_value:
1325 * @self: a #CtkLevelBar
1326 * @value: a positive value
1327 *
1328 * Sets the value of the #CtkLevelBar:max-value property.
1329 *
1330 * You probably want to update preexisting level offsets after calling
1331 * this function.
1332 *
1333 * Since: 3.6
1334 */
1335void
1336ctk_level_bar_set_max_value (CtkLevelBar *self,
1337 gdouble value)
1338{
1339 CtkLevelBarPrivate *priv = self->priv;
1340
1341 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1342 g_return_if_fail (value >= 0.0)do { if ((value >= 0.0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "value >= 0.0"); return
; } } while (0)
;
1343
1344 if (value == priv->max_value)
1345 return;
1346
1347 priv->max_value = value;
1348
1349 if (priv->max_value < priv->cur_value)
1350 ctk_level_bar_set_value_internal (self, priv->max_value);
1351
1352 ctk_level_bar_ensure_offsets_in_range (self);
1353 update_block_nodes (self);
1354 update_level_style_classes (self);
1355 g_object_notify_by_pspec (G_OBJECT (self)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), (((GType) ((20) << (2))))))))
, properties[PROP_MAX_VALUE]);
1356}
1357
1358/**
1359 * ctk_level_bar_set_value:
1360 * @self: a #CtkLevelBar
1361 * @value: a value in the interval between
1362 * #CtkLevelBar:min-value and #CtkLevelBar:max-value
1363 *
1364 * Sets the value of the #CtkLevelBar:value property.
1365 *
1366 * Since: 3.6
1367 */
1368void
1369ctk_level_bar_set_value (CtkLevelBar *self,
1370 gdouble value)
1371{
1372 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1373
1374 if (value == self->priv->cur_value)
1375 return;
1376
1377 ctk_level_bar_set_value_internal (self, value);
1378 update_level_style_classes (self);
1379}
1380
1381/**
1382 * ctk_level_bar_get_mode:
1383 * @self: a #CtkLevelBar
1384 *
1385 * Returns the value of the #CtkLevelBar:mode property.
1386 *
1387 * Returns: a #CtkLevelBarMode
1388 *
1389 * Since: 3.6
1390 */
1391CtkLevelBarMode
1392ctk_level_bar_get_mode (CtkLevelBar *self)
1393{
1394 g_return_val_if_fail (CTK_IS_LEVEL_BAR (self), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return (0); } } while (0)
;
1395
1396 return self->priv->bar_mode;
1397}
1398
1399/**
1400 * ctk_level_bar_set_mode:
1401 * @self: a #CtkLevelBar
1402 * @mode: a #CtkLevelBarMode
1403 *
1404 * Sets the value of the #CtkLevelBar:mode property.
1405 *
1406 * Since: 3.6
1407 */
1408void
1409ctk_level_bar_set_mode (CtkLevelBar *self,
1410 CtkLevelBarMode mode)
1411{
1412 CtkLevelBarPrivate *priv = self->priv;
1413
1414 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1415
1416 if (priv->bar_mode == mode)
1417 return;
1418
1419 priv->bar_mode = mode;
1420
1421 update_mode_style_classes (self);
1422 update_block_nodes (self);
1423 update_level_style_classes (self);
1424 ctk_widget_queue_resize (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
1425 g_object_notify_by_pspec (G_OBJECT (self)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), (((GType) ((20) << (2))))))))
, properties[PROP_MODE]);
1426
1427}
1428
1429/**
1430 * ctk_level_bar_get_inverted:
1431 * @self: a #CtkLevelBar
1432 *
1433 * Return the value of the #CtkLevelBar:inverted property.
1434 *
1435 * Returns: %TRUE if the level bar is inverted
1436 *
1437 * Since: 3.8
1438 */
1439gboolean
1440ctk_level_bar_get_inverted (CtkLevelBar *self)
1441{
1442 g_return_val_if_fail (CTK_IS_LEVEL_BAR (self), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return ((0)); } } while (0)
;
1443
1444 return self->priv->inverted;
1445}
1446
1447/**
1448 * ctk_level_bar_set_inverted:
1449 * @self: a #CtkLevelBar
1450 * @inverted: %TRUE to invert the level bar
1451 *
1452 * Sets the value of the #CtkLevelBar:inverted property.
1453 *
1454 * Since: 3.8
1455 */
1456void
1457ctk_level_bar_set_inverted (CtkLevelBar *self,
1458 gboolean inverted)
1459{
1460 CtkLevelBarPrivate *priv = self->priv;
1461
1462 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1463
1464 if (priv->inverted == inverted)
1465 return;
1466
1467 priv->inverted = inverted;
1468 ctk_widget_queue_resize (CTK_WIDGET (self)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), ((ctk_widget_get_type ()))))))
);
1469 update_level_style_classes (self);
1470 g_object_notify_by_pspec (G_OBJECT (self)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((self)), (((GType) ((20) << (2))))))))
, properties[PROP_INVERTED]);
1471}
1472
1473/**
1474 * ctk_level_bar_remove_offset_value:
1475 * @self: a #CtkLevelBar
1476 * @name: (allow-none): the name of an offset in the bar
1477 *
1478 * Removes an offset marker previously added with
1479 * ctk_level_bar_add_offset_value().
1480 *
1481 * Since: 3.6
1482 */
1483void
1484ctk_level_bar_remove_offset_value (CtkLevelBar *self,
1485 const gchar *name)
1486{
1487 CtkLevelBarPrivate *priv = self->priv;
1488 GList *existing;
1489
1490 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1491
1492 existing = g_list_find_custom (priv->offsets, name, offset_find_func);
1493 if (existing)
1494 {
1495 ctk_level_bar_offset_free (existing->data);
1496 priv->offsets = g_list_delete_link (priv->offsets, existing);
1497
1498 update_level_style_classes (self);
1499 }
1500}
1501
1502/**
1503 * ctk_level_bar_add_offset_value:
1504 * @self: a #CtkLevelBar
1505 * @name: the name of the new offset
1506 * @value: the value for the new offset
1507 *
1508 * Adds a new offset marker on @self at the position specified by @value.
1509 * When the bar value is in the interval topped by @value (or between @value
1510 * and #CtkLevelBar:max-value in case the offset is the last one on the bar)
1511 * a style class named `level-`@name will be applied
1512 * when rendering the level bar fill.
1513 * If another offset marker named @name exists, its value will be
1514 * replaced by @value.
1515 *
1516 * Since: 3.6
1517 */
1518void
1519ctk_level_bar_add_offset_value (CtkLevelBar *self,
1520 const gchar *name,
1521 gdouble value)
1522{
1523 GQuark name_quark;
1524
1525 g_return_if_fail (CTK_IS_LEVEL_BAR (self))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return; } } while (0)
;
1526 g_return_if_fail (ctk_level_bar_value_in_interval (self, value))do { if ((ctk_level_bar_value_in_interval (self, value))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "ctk_level_bar_value_in_interval (self, value)"); return;
} } while (0)
;
1527
1528 if (!ctk_level_bar_ensure_offset (self, name, value))
1529 return;
1530
1531 update_level_style_classes (self);
1532 name_quark = g_quark_from_string (name);
1533 g_signal_emit (self, signals[SIGNAL_OFFSET_CHANGED], name_quark, name);
1534}
1535
1536/**
1537 * ctk_level_bar_get_offset_value:
1538 * @self: a #CtkLevelBar
1539 * @name: (allow-none): the name of an offset in the bar
1540 * @value: (out): location where to store the value
1541 *
1542 * Fetches the value specified for the offset marker @name in @self,
1543 * returning %TRUE in case an offset named @name was found.
1544 *
1545 * Returns: %TRUE if the specified offset is found
1546 *
1547 * Since: 3.6
1548 */
1549gboolean
1550ctk_level_bar_get_offset_value (CtkLevelBar *self,
1551 const gchar *name,
1552 gdouble *value)
1553{
1554 GList *existing;
1555 CtkLevelBarOffset *offset = NULL((void*)0);
1556
1557 g_return_val_if_fail (CTK_IS_LEVEL_BAR (self), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((self)); GType __t = ((ctk_level_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_LEVEL_BAR (self)"); return (0.0); } } while (0)
;
1558
1559 existing = g_list_find_custom (self->priv->offsets, name, offset_find_func);
1560 if (existing)
1561 offset = existing->data;
1562
1563 if (!offset)
1564 return FALSE(0);
1565
1566 if (value)
1567 *value = offset->value;
1568
1569 return TRUE(!(0));
1570}