feat(ags osk): add cairo arc for fun
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
7775cb71b6
commit
88d0a52a4e
4 changed files with 219 additions and 95 deletions
|
@ -132,6 +132,7 @@ export default tseslint.config({
|
|||
'no-loop-func': [
|
||||
'error',
|
||||
],
|
||||
/*
|
||||
'no-magic-numbers': [
|
||||
'error',
|
||||
{
|
||||
|
@ -159,6 +160,7 @@ export default tseslint.config({
|
|||
ignoreClassFieldInitialValues: true,
|
||||
},
|
||||
],
|
||||
*/
|
||||
'no-multi-assign': [
|
||||
'error',
|
||||
],
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
.osk {
|
||||
padding-top: 4px;
|
||||
border-radius: 10px 10px 0;
|
||||
|
||||
&.hidden {
|
||||
opacity: 0;
|
||||
|
@ -83,6 +82,8 @@
|
|||
}
|
||||
|
||||
&.right-side {
|
||||
border-radius: 0 10px 0 0;
|
||||
|
||||
.key .mod {
|
||||
&.Ctrl {
|
||||
min-width: 2.4rem;
|
||||
|
@ -91,6 +92,8 @@
|
|||
}
|
||||
|
||||
&.left-side {
|
||||
border-radius: 10px 0 0 0;
|
||||
|
||||
.key .mod {
|
||||
&.Alt {
|
||||
min-width: 3rem;
|
||||
|
|
74
nixosModules/ags/config/widgets/on-screen-keyboard/arcs.tsx
Normal file
74
nixosModules/ags/config/widgets/on-screen-keyboard/arcs.tsx
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { Gtk } from 'astal/gtk3';
|
||||
import Cairo from 'cairo';
|
||||
|
||||
/* Types */
|
||||
interface Point {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
type Bezier = [number, number, number, number];
|
||||
|
||||
export default ({
|
||||
css = 'background-color: black;',
|
||||
allocation = { width: 0, height: 0 },
|
||||
}) => (
|
||||
<box>
|
||||
<drawingarea
|
||||
css={css}
|
||||
|
||||
setup={(widget) => {
|
||||
widget.set_size_request(allocation.width, allocation.height);
|
||||
|
||||
const styleContext = widget.get_style_context();
|
||||
const bgColor = styleContext.get_background_color(Gtk.StateFlags.NORMAL);
|
||||
|
||||
widget.connect('draw', (_, cairoContext: Cairo.Context) => {
|
||||
const drawBezier = (dest: Point, curve: Bezier) => {
|
||||
curve[0] *= (dest.x - cairoContext.getCurrentPoint()[0]);
|
||||
curve[0] += cairoContext.getCurrentPoint()[0];
|
||||
|
||||
curve[1] *= (dest.y - cairoContext.getCurrentPoint()[1]);
|
||||
curve[1] += cairoContext.getCurrentPoint()[1];
|
||||
|
||||
curve[2] *= (dest.x - cairoContext.getCurrentPoint()[0]);
|
||||
curve[2] += cairoContext.getCurrentPoint()[0];
|
||||
|
||||
curve[3] *= (dest.y - cairoContext.getCurrentPoint()[1]);
|
||||
curve[3] += cairoContext.getCurrentPoint()[1];
|
||||
|
||||
cairoContext.curveTo(...curve, dest.x, dest.y);
|
||||
};
|
||||
|
||||
// bottom left to top left
|
||||
cairoContext.moveTo(0, allocation.height);
|
||||
cairoContext.lineTo(0, 0);
|
||||
|
||||
// top left to middle left
|
||||
drawBezier(
|
||||
{ x: allocation.width / 3, y: allocation.height * 0.8 },
|
||||
[0.76, 0, 0.24, 1],
|
||||
);
|
||||
|
||||
// middle left to middle right
|
||||
cairoContext.lineTo((allocation.width / 3) * 2, allocation.height * 0.8);
|
||||
|
||||
// middle right to top right
|
||||
drawBezier(
|
||||
{ x: allocation.width, y: 0 },
|
||||
[0.76, 0, 0.24, 1],
|
||||
);
|
||||
|
||||
// top right to bottom right
|
||||
cairoContext.lineTo(allocation.width, allocation.height);
|
||||
|
||||
// bottom right to bottom left
|
||||
cairoContext.closePath();
|
||||
|
||||
// Add color
|
||||
cairoContext.setSourceRGBA(bgColor.red, bgColor.green, bgColor.blue, bgColor.alpha);
|
||||
cairoContext.fill();
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</box>
|
||||
);
|
|
@ -1,8 +1,10 @@
|
|||
import { bind, idle, Variable } from 'astal';
|
||||
import { Astal, astalify, Gtk, type ConstructProps, Widget } from 'astal/gtk3';
|
||||
import { register } from 'astal/gobject';
|
||||
|
||||
import Separator from '../misc/separator';
|
||||
|
||||
import Arc from './arcs';
|
||||
import Key from './keys';
|
||||
|
||||
import { defaultOskLayout, oskLayouts } from './keyboard-layouts';
|
||||
|
@ -22,110 +24,153 @@ class ToggleButton extends astalify(Gtk.ToggleButton) {
|
|||
}
|
||||
}
|
||||
|
||||
const L_KEY_PER_ROW = [8, 7, 6, 6, 6, 4]; // eslint-disable-line
|
||||
const COLOR = 'rgba(0, 0, 0, 0.3)';
|
||||
const L_KEY_PER_ROW = [8, 7, 6, 6, 6, 4];
|
||||
const SPACING = 4;
|
||||
const COLOR = 'rgba(0, 0, 0, 0.3)';
|
||||
|
||||
export default () => (
|
||||
<box vertical>
|
||||
<centerbox
|
||||
css={`background: ${COLOR};`}
|
||||
className="osk hidden"
|
||||
hexpand
|
||||
export default () => {
|
||||
const ThirdWidth = Variable(0);
|
||||
|
||||
return (
|
||||
<box
|
||||
vertical
|
||||
onRealize={(self) => idle(() => {
|
||||
ThirdWidth.set(self.get_allocated_width() / 3);
|
||||
})}
|
||||
>
|
||||
<box
|
||||
className="left-side side"
|
||||
halign={Gtk.Align.START}
|
||||
vertical
|
||||
>
|
||||
{...keyboardJson.keys.map((row, rowIndex) => {
|
||||
const keys = [] as Widget.Box[];
|
||||
|
||||
row.forEach((key, keyIndex) => {
|
||||
if (keyIndex < L_KEY_PER_ROW[rowIndex]) {
|
||||
keys.push(Key(key));
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<box vertical>
|
||||
<box className="row">
|
||||
<Separator size={SPACING} />
|
||||
|
||||
{...keys}
|
||||
</box>
|
||||
|
||||
<Separator size={SPACING} vertical />
|
||||
</box>
|
||||
);
|
||||
})}
|
||||
</box>
|
||||
|
||||
<box
|
||||
halign={Gtk.Align.CENTER}
|
||||
valign={Gtk.Align.END}
|
||||
<centerbox
|
||||
className="osk hidden"
|
||||
hexpand
|
||||
>
|
||||
{/* LEFT */}
|
||||
<box
|
||||
halign={Gtk.Align.CENTER}
|
||||
className="settings"
|
||||
widthRequest={bind(ThirdWidth)}
|
||||
css={`background: ${COLOR};`}
|
||||
className="left-side side"
|
||||
halign={Gtk.Align.START}
|
||||
vertical
|
||||
>
|
||||
<ToggleButton
|
||||
className="button"
|
||||
cursor="pointer"
|
||||
active
|
||||
valign={Gtk.Align.CENTER}
|
||||
{...keyboardJson.keys.map((row, rowIndex) => {
|
||||
const keys = [] as Widget.Box[];
|
||||
|
||||
onToggled={(self) => {
|
||||
self.toggleClassName(
|
||||
'toggled',
|
||||
self.get_active(),
|
||||
);
|
||||
|
||||
if (self.get_toplevel() === self) {
|
||||
return;
|
||||
row.forEach((key, keyIndex) => {
|
||||
if (keyIndex < L_KEY_PER_ROW[rowIndex]) {
|
||||
keys.push(Key(key));
|
||||
}
|
||||
});
|
||||
|
||||
(self.get_toplevel() as Widget.Window | undefined)
|
||||
?.set_exclusivity(
|
||||
self.get_active() ?
|
||||
Astal.Exclusivity.EXCLUSIVE :
|
||||
Astal.Exclusivity.NORMAL,
|
||||
);
|
||||
}}
|
||||
>
|
||||
Exclusive
|
||||
</ToggleButton>
|
||||
</box>
|
||||
</box>
|
||||
return (
|
||||
<box vertical>
|
||||
<box className="row">
|
||||
<Separator size={SPACING} />
|
||||
|
||||
<box
|
||||
className="right-side side"
|
||||
halign={Gtk.Align.END}
|
||||
vertical
|
||||
>
|
||||
{...keyboardJson.keys.map((row, rowIndex) => {
|
||||
const keys = [] as Widget.Box[];
|
||||
{...keys}
|
||||
</box>
|
||||
|
||||
row.forEach((key, keyIndex) => {
|
||||
if (keyIndex >= L_KEY_PER_ROW[rowIndex]) {
|
||||
keys.push(Key(key));
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<box vertical>
|
||||
<box
|
||||
className="row"
|
||||
halign={Gtk.Align.END}
|
||||
>
|
||||
{...keys}
|
||||
<Separator size={SPACING} vertical />
|
||||
</box>
|
||||
);
|
||||
})}
|
||||
</box>
|
||||
|
||||
<Separator size={SPACING} vertical />
|
||||
</box>
|
||||
);
|
||||
})}
|
||||
</box>
|
||||
</centerbox>
|
||||
</box>
|
||||
) as Widget.Box;
|
||||
{/* MIDDLE */}
|
||||
<box
|
||||
widthRequest={bind(ThirdWidth)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
valign={Gtk.Align.FILL}
|
||||
vertical
|
||||
>
|
||||
<box
|
||||
valign={Gtk.Align.START}
|
||||
>
|
||||
{bind(ThirdWidth).as((width) => (
|
||||
<Arc
|
||||
allocation={{ width, height: 160 }}
|
||||
css={`background: ${COLOR};`}
|
||||
/>
|
||||
|
||||
))}
|
||||
</box>
|
||||
|
||||
<box
|
||||
halign={Gtk.Align.FILL}
|
||||
hexpand
|
||||
vexpand
|
||||
css={`background: ${COLOR};`}
|
||||
className="settings"
|
||||
>
|
||||
<centerbox
|
||||
halign={Gtk.Align.FILL}
|
||||
hexpand
|
||||
vexpand
|
||||
>
|
||||
<box />
|
||||
|
||||
<ToggleButton
|
||||
className="button"
|
||||
cursor="pointer"
|
||||
active
|
||||
valign={Gtk.Align.CENTER}
|
||||
halign={Gtk.Align.CENTER}
|
||||
|
||||
onToggled={(self) => {
|
||||
self.toggleClassName(
|
||||
'toggled',
|
||||
self.get_active(),
|
||||
);
|
||||
|
||||
if (self.get_toplevel() === self) {
|
||||
return;
|
||||
}
|
||||
|
||||
(self.get_toplevel() as Widget.Window | undefined)
|
||||
?.set_exclusivity(
|
||||
self.get_active() ?
|
||||
Astal.Exclusivity.EXCLUSIVE :
|
||||
Astal.Exclusivity.NORMAL,
|
||||
);
|
||||
}}
|
||||
>
|
||||
Exclusive
|
||||
</ToggleButton>
|
||||
|
||||
<box />
|
||||
</centerbox>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
{/* RIGHT */}
|
||||
<box
|
||||
widthRequest={bind(ThirdWidth)}
|
||||
css={`background: ${COLOR};`}
|
||||
className="right-side side"
|
||||
halign={Gtk.Align.END}
|
||||
vertical
|
||||
>
|
||||
{...keyboardJson.keys.map((row, rowIndex) => {
|
||||
const keys = [] as Widget.Box[];
|
||||
|
||||
row.forEach((key, keyIndex) => {
|
||||
if (keyIndex >= L_KEY_PER_ROW[rowIndex]) {
|
||||
keys.push(Key(key));
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<box vertical>
|
||||
<box
|
||||
className="row"
|
||||
halign={Gtk.Align.END}
|
||||
>
|
||||
{...keys}
|
||||
</box>
|
||||
|
||||
<Separator size={SPACING} vertical />
|
||||
</box>
|
||||
);
|
||||
})}
|
||||
</box>
|
||||
</centerbox>
|
||||
</box>
|
||||
) as Widget.Box;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue