Skip to content

feat: implement CircularScale widget#156

Merged
its-darsh merged 8 commits intoFabric-Development:mainfrom
amansxcalibur:main
Apr 17, 2026
Merged

feat: implement CircularScale widget#156
its-darsh merged 8 commits intoFabric-Development:mainfrom
amansxcalibur:main

Conversation

@amansxcalibur
Copy link
Copy Markdown
Contributor

This PR introduces a new widget, CircularScale which aims to behave as a circular analogue to Scale.

Features

The Circular Scale has three gadgets (all the same level in hierarchy, unlike Scale):

CircularScale
├── trough
├── highlight
└── slider
Gadget Property Effect
slider min-width Slider thickness
min-height Slider height
margin-left Angular gap before the slider and before the start of the progress arc
margin-right Angular gap after the slider and after the end of the trough arc
border-radius Rounded corners
highlight background-color Color of the progress arc
min-width/height/border-width Thickness of the progress arc
trough background-color Color of the trough arc
min-width/height/border-width Thickness of the trough arc
Base styles
background-color Background color of the widget (circular)

Performance

The CircularScale is approximately 5.8x faster in draw cycles compared to CircularProgressBar. Its probably because of the gadgets usage.

Suggestions

  • Add independant margin support to the progress and trought arc
    As of now, the arcs reflect the margins of the slider, which works fine, but adding it would make the widget more configurable.
  • More styling (borders, gradients, background-image, etc).
cir-scale-demo-2.mp4

@amansxcalibur
Copy link
Copy Markdown
Contributor Author

amansxcalibur commented Jan 9, 2026

Examples are also up. Override do_draw_trough_arc, do_draw_progress_arc and do_draw_slider for custom logic.

Copy link
Copy Markdown
Contributor

@its-darsh its-darsh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look pal, I love you and all, but you know the rules. If you wanna get this merged, you gotta hurt your fingers and add LOTs of typing defs.

Comment thread fabric/widgets/circularscale.py Outdated
self.slider_ctx = self.do_create_gadget_context("slider")
self.highlight_ctx = self.do_create_gadget_context("highlight")

def do_get_thickness_from_context(self, context, state):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming of this function is just too broad, use do_get_border_width, and please add function typing for the signature (each parameter and return type.)

Comment thread fabric/widgets/circularscale.py Outdated
Comment on lines +18 to +20
self.trough_ctx = self.do_create_gadget_context("trough")
self.slider_ctx = self.do_create_gadget_context("slider")
self.highlight_ctx = self.do_create_gadget_context("highlight")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use _ prefixes for private variables.

Comment thread fabric/widgets/circularscale.py Outdated


class CircularScale(CircularProgressBar):
NON_ROUND_CAP_DELTA = 0.01
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a class input parameter with a default value instead.

Comment thread fabric/widgets/circularscale.py Outdated
Comment on lines +15 to +16
def __init__(self, **kwargs):
super().__init__(**kwargs)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to provide a full signature for the class, we do not take typing easily.

Comment thread fabric/widgets/circularscale.py Outdated
def do_calculate_safe_radius(
self, delta, slider_height, progress_thickness, trough_thickness
):
max_thickness = max(slider_height, progress_thickness, trough_thickness)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useless variable, inline it instead.

Comment thread fabric/widgets/circularscale.py Outdated
else:
rtl, rtr, rbr, rbl = map(float, radius)

rtl, rtr, rbr, rbl = [max(0.0, v) for v in [rtl, rtr, rbr, rbl]]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a tuple notation instead of a list, saves on memory.

Comment thread fabric/widgets/circularscale.py Outdated
cr.restore()
return False

def do_create_gadget_context(self, node_name):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function signature missing.

Comment thread fabric/widgets/circularscale.py Outdated
ctx.set_path(path)
return ctx

def do_draw_rounded_rect(self, cr, x, y, width, height, radius):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function signature missing.

Comment thread fabric/widgets/circularscale.py Outdated
Comment on lines +323 to +342
factor = 1.0

# top edge
if (rtl + rtr) > width:
factor = min(factor, width / (rtl + rtr))
# bottom edge
if (rbl + rbr) > width:
factor = min(factor, width / (rbl + rbr))
# left edge
if (rtl + rbl) > height:
factor = min(factor, height / (rtl + rbl))
# right edge
if (rtr + rbr) > height:
factor = min(factor, height / (rtr + rbr))

if factor < 1.0:
rtl *= factor
rtr *= factor
rbr *= factor
rbl *= factor
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge into a single inline expression using inline ifs.

Comment thread fabric/widgets/circularscale.py Outdated
if rtl > 0:
cr.arc(x + rtl, y + rtl, rtl, math.pi, 3 * math.pi / 2)

cr.close_path()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving do_draw() below all class' methods.

@its-darsh its-darsh self-assigned this Jan 10, 2026
@its-darsh its-darsh added enhancement New feature or request on hold On hold, usually in wait for a PR to be merged. or something... help wanted Extra attention is needed labels Jan 10, 2026
@amansxcalibur
Copy link
Copy Markdown
Contributor Author

The widget needs css class type support for gadgets. Will update soon.

@its-darsh
Copy link
Copy Markdown
Contributor

Should it be a draft instead?

@amansxcalibur
Copy link
Copy Markdown
Contributor Author

Yes, I'll let u know once it's ready for review

Comment thread fabric/widgets/circularscale.py Outdated
Comment on lines +47 to +71
super().__init__(
value=value,
min_value=min_value,
max_value=max_value,
start_angle=start_angle,
end_angle=end_angle,
line_width=line_width,
line_style=line_style,
pie=pie,
invert=invert,
child=child,
name=name,
visible=visible,
all_visible=all_visible,
style=style,
style_classes=style_classes,
tooltip_text=tooltip_text,
tooltip_markup=tooltip_markup,
h_align=h_align,
v_align=v_align,
h_expand=h_expand,
v_expand=v_expand,
size=size,
**kwargs,
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use CircularProgressBar.__init__(self, <STUFF>) and do not use keyword arguments.

Comment on lines +255 to +293
self.do_draw_progress_arc(
cr=cr,
center_x=center_x,
center_y=center_y,
safe_radius=safe_radius,
start_angle=start_angle,
progress_angle=progress_angle,
progress_color=progress_color,
progress_thickness=progress_thickness,
progress_line_width_angle=progress_line_width_angle,
slider_thickness_angle=slider_thickness_angle,
left_gap_angle=left_gap_angle,
)

self.do_draw_slider(
cr=cr,
center_x=center_x,
center_y=center_y,
safe_radius=safe_radius,
progress_angle=progress_angle,
slider_color=slider_color,
slider_thickness_angle=slider_thickness_angle,
slider_height=slider_height,
corner_radius=corner_radius,
)

self.do_draw_trough_arc(
cr=cr,
center_x=center_x,
center_y=center_y,
safe_radius=safe_radius,
progress_angle=progress_angle,
real_end_angle=real_end_angle,
trough_color=trough_color,
trough_thickness=trough_thickness,
trough_line_width_angle=trough_line_width_angle,
slider_thickness_angle=slider_thickness_angle,
right_gap_angle=right_gap_angle,
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@its-darsh
Copy link
Copy Markdown
Contributor

Are we ready, son?

@amansxcalibur
Copy link
Copy Markdown
Contributor Author

@its-darsh I told you about the implementation issues right. I haven't really checked on it since then.

@its-darsh its-darsh reopened this Apr 10, 2026
@its-darsh
Copy link
Copy Markdown
Contributor

Once you finish this hit me up with a mention, also don't forget to run ruff with ruff.toml as your config.

@amansxcalibur
Copy link
Copy Markdown
Contributor Author

@its-darsh Alright, its done. Gtk style engine optimization needs to be studied smh

@its-darsh
Copy link
Copy Markdown
Contributor

its-darsh commented Apr 14, 2026

Should I merge then?

If so I need you to do a sanity ruff lint.

@amansxcalibur
Copy link
Copy Markdown
Contributor Author

All checks passed when put against ruff.toml

@its-darsh its-darsh merged commit 23cab85 into Fabric-Development:main Apr 17, 2026
@its-darsh
Copy link
Copy Markdown
Contributor

Every person gets one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request help wanted Extra attention is needed on hold On hold, usually in wait for a PR to be merged. or something...

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants