Skip to content

Commit

Permalink
Merge pull request #630 from tuanchauict/appearance-js
Browse files Browse the repository at this point in the history
Link appearance's fill + border + stroke with UI interaction
  • Loading branch information
tuanchauict authored Dec 17, 2024
2 parents 695b1b6 + db4c3cb commit ecfe690
Show file tree
Hide file tree
Showing 15 changed files with 311 additions and 210 deletions.
3 changes: 3 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions monosketch-svelte/src/lib/mono/action-manager/one-time-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ export const OneTimeAction = {
newBorderStyleId,
}),

ChangeShapeBorderDashPatternExtra: (dash?: number, gap?: number, offset?: number): OneTimeActionType => ({
ChangeShapeBorderDashPatternExtra: ({ dash, gap, offset }: {
dash?: number,
gap?: number,
offset?: number
}): OneTimeActionType => ({
type: 'ChangeShapeBorderDashPatternExtra',
dash,
gap,
Expand All @@ -160,13 +164,17 @@ export const OneTimeAction = {
isEnabled,
newStrokeStyleId,
}),
ChangeLineStrokeDashPatternExtra: (dash?: number, gap?: number, offset?: number): OneTimeActionType => ({
ChangeLineStrokeDashPatternExtra: ({ dash, gap, offset }: {
dash?: number,
gap?: number,
offset?: number
}): OneTimeActionType => ({
type: 'ChangeLineStrokeDashPatternExtra',
dash,
gap,
offset,
}),
ChangeLineStrokeCornerExtra: (isRoundedCorner: boolean) => ({
ChangeLineStrokeCornerExtra: (isRoundedCorner: boolean): OneTimeActionType => ({
type: 'ChangeLineStrokeCornerExtra',
isRoundedCorner,
}),
Expand Down
50 changes: 4 additions & 46 deletions monosketch-svelte/src/lib/mono/shape/extra/extra-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,49 +37,7 @@ export interface IRectangleExtra {
corner: RectangleBorderCornerPattern;
}

interface IShapeExtraManager {
defaultRectangleExtra: IRectangleExtra;
defaultLineExtra: ILineExtra;
defaultTextAlign: TextAlign;
defaultExtraStateUpdateFlow: Flow<void>;

setDefaultValues(params: {
isFillEnabled?: boolean;
fillStyleId?: string;
isBorderEnabled?: boolean;
borderStyleId?: string;
isBorderRoundedCorner?: boolean;
borderDashPattern?: StraightStrokeDashPattern;
isLineStrokeEnabled?: boolean;
lineStrokeStyleId?: string;
isLineStrokeRoundedCorner?: boolean;
lineDashPattern?: StraightStrokeDashPattern;
isStartHeadAnchorCharEnabled?: boolean;
startHeadAnchorCharId?: string;
isEndHeadAnchorCharEnabled?: boolean;
endHeadAnchorCharId?: string;
textHorizontalAlign?: TextHorizontalAlign;
textVerticalAlign?: TextVerticalAlign;
}): void;

getRectangleFillStyle(id?: string, defaultStyle?: RectangleFillStyle): RectangleFillStyle;

getAllPredefinedRectangleFillStyles(): RectangleFillStyle[];

getRectangleBorderStyle(id?: string, defaultStyle?: StraightStrokeStyle): StraightStrokeStyle;

getLineStrokeStyle(id?: string, defaultStyle?: StraightStrokeStyle): StraightStrokeStyle;

getAllPredefinedStrokeStyles(): StraightStrokeStyle[];

getStartHeadAnchorChar(id?: string, defaultChar?: AnchorChar): AnchorChar;

getEndHeadAnchorChar(id?: string, defaultChar?: AnchorChar): AnchorChar;

getAllPredefinedAnchorChars(): AnchorChar[];
}

class ShapeExtraManagerImpl implements IShapeExtraManager {
class ShapeExtraManagerImpl {
defaultRectangleExtra: IRectangleExtra = {
isFillEnabled: false,
userSelectedFillStyle: PredefinedRectangleFillStyle.PREDEFINED_STYLES[0],
Expand All @@ -105,8 +63,8 @@ class ShapeExtraManagerImpl implements IShapeExtraManager {
TextVerticalAlign.MIDDLE,
);

private defaultExtraStateUpdateMutableFlow = new Flow<void>();
defaultExtraStateUpdateFlow: Flow<void> = this.defaultExtraStateUpdateMutableFlow.immutable();
private readonly defaultExtraStateUpdateMutableFlow = new Flow(0);
readonly defaultExtraStateUpdateFlow: Flow<number> = this.defaultExtraStateUpdateMutableFlow.immutable();

setDefaultValues({
isFillEnabled,
Expand Down Expand Up @@ -172,7 +130,7 @@ class ShapeExtraManagerImpl implements IShapeExtraManager {
textVerticalAlign ?? this.defaultTextAlign.verticalAlign,
);

this.defaultExtraStateUpdateMutableFlow.value = undefined;
this.defaultExtraStateUpdateMutableFlow.value = this.defaultExtraStateUpdateFlow.value! + 1;
}

getRectangleFillStyle(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ export class PredefinedStraightStrokeStyle {
return PredefinedStraightStrokeStyle.ID_TO_STYLE_MAP[adjustedId];
}

static isCornerRoundable(id: string): boolean {
static isCornerRoundable(id: string | null | undefined): boolean {
if (id === null || id === undefined) {
return false;
}
return id in PredefinedStraightStrokeStyle.STYLE_TO_ROUNDED_CORNER_STYLE_MAP;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export let value: number;
export let minValue: number | null = null;
export let isEnabled: boolean = true;
export let boundIncludesLabel = false;
export let onChange: () => void;
</script>

<div class:child-bounds="{!boundIncludesLabel}">
Expand All @@ -12,6 +14,7 @@ export let boundIncludesLabel = false;
type="number"
bind:value
disabled="{!isEnabled}"
on:change={onChange}
min="{minValue !== null ? minValue : ''}"
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,61 @@
<script lang="ts">
import CommonBorderTool from './common/CommonBorderTool.svelte';
import CommonBorderTool from './common/CommonBorderTool.svelte';
import { getContext, onDestroy, onMount } from "svelte";
import { ShapeToolViewModel } from "$ui/pannel/shapetool/viewmodel/shape-tool-viewmodel";
import { SHAPE_TOOL_VIEWMODEL } from "$ui/pannel/shapetool/constants";
import { LifecycleOwner } from "$libs/flow";
import type { StrokeDashPattern } from "$ui/pannel/shapetool/viewmodel/models";
import { OneTimeAction } from "$mono/action-manager/one-time-actions";
let selectedId = 'B1';
let cornerRounded = false;
let viewModel = getContext<ShapeToolViewModel>(SHAPE_TOOL_VIEWMODEL);
let lifecycleOwner = new LifecycleOwner();
let dashDash = 1;
let dashGap = 0;
let dashShift = 0;
let selectedStrokeItem = viewModel.shapeBorderTypeFlow.value;
let cornerRounded = viewModel.shapeBorderRoundedCornerFlow.value;
function onItemSelect(id: string) {
selectedId = id;
}
let dashPattern: StrokeDashPattern | null | undefined = viewModel.shapeBorderDashTypeFlow.value;
function onCornerRoundedChange(value: boolean) {
cornerRounded = value;
}
function onItemSelect(id: string | null) {
viewModel.update(OneTimeAction.ChangeShapeBorderExtra({ newBorderStyleId: id, isEnabled: id !== null }));
}
function onCornerRoundedChange(value: boolean) {
viewModel.update(OneTimeAction.ChangeShapeBorderCornerExtra(value));
}
function onDashPatternChange(dashPattern: StrokeDashPattern) {
viewModel.update(OneTimeAction.ChangeShapeBorderDashPatternExtra(dashPattern));
}
onMount(() => {
lifecycleOwner.onStart();
viewModel.shapeBorderTypeFlow.observe(lifecycleOwner, (value) => {
selectedStrokeItem = value;
});
viewModel.shapeBorderRoundedCornerFlow.observe(lifecycleOwner, (value) => {
cornerRounded = value;
});
viewModel.shapeBorderDashTypeFlow.observe(lifecycleOwner, (value) => {
dashPattern = value;
});
});
onDestroy(() => {
lifecycleOwner.onStop();
});
</script>

<CommonBorderTool
title="Border"
{onItemSelect}
{selectedId}
{cornerRounded}
onCornerRounded="{onCornerRoundedChange}"
bind:dashDash
bind:dashGap
bind:dashShift
/>
{#if selectedStrokeItem && cornerRounded !== undefined && dashPattern !== undefined}
<CommonBorderTool
title="Border"
{onItemSelect}
selectedId="{selectedStrokeItem.selectedId}"
{cornerRounded}
onCornerRounded="{onCornerRoundedChange}"
{dashPattern}
{onDashPatternChange}
/>
{/if}
Original file line number Diff line number Diff line change
@@ -1,36 +1,60 @@
<script lang="ts">
import Tool from './common/Tool.svelte';
import CloudItem from './common/CloudItem.svelte';
import type { ShapeToolViewModel } from "$ui/pannel/shapetool/viewmodel/shape-tool-viewmodel";
import { getContext } from "svelte";
import { SHAPE_TOOL_VIEWMODEL } from "$ui/pannel/shapetool/constants";
import Tool from './common/Tool.svelte';
import CloudItem from './common/CloudItem.svelte';
import type { ShapeToolViewModel } from "$ui/pannel/shapetool/viewmodel/shape-tool-viewmodel";
import { getContext, onDestroy, onMount } from "svelte";
import { SHAPE_TOOL_VIEWMODEL } from "$ui/pannel/shapetool/constants";
import { LifecycleOwner } from "$libs/flow";
import { OneTimeAction } from "$mono/action-manager/one-time-actions";
import type { CloudItemSelectionState } from "$ui/pannel/shapetool/viewmodel/models";
let viewModel = getContext<ShapeToolViewModel>(SHAPE_TOOL_VIEWMODEL);
let viewModel = getContext<ShapeToolViewModel>(SHAPE_TOOL_VIEWMODEL);
let lifecycleOwner = new LifecycleOwner();
let selectedId = 'F0';
let shapeFillToolSelectionState: CloudItemSelectionState | null | undefined = viewModel.shapeFillTypeFlow.value;
function onItemSelect(id: string) {
selectedId = id;
}
</script>
onMount(() => {
lifecycleOwner.onStart();
viewModel.shapeFillTypeFlow.observe(lifecycleOwner, (value) => {
shapeFillToolSelectionState = value;
});
});
onDestroy(() => {
lifecycleOwner.onStop();
});
<Tool title="Fill" available="{true}">
<div>
{#each viewModel.fillOptions as option}
function onItemSelect(id: string | null) {
viewModel.update(OneTimeAction.ChangeShapeFillExtra({ isEnabled: id !== null, newFillStyleId: id }));
}
</script>
{#if shapeFillToolSelectionState}
<Tool title="Fill" available="{true}">
<div>
<!-- Disable-item -->
<CloudItem
id="{option.id}"
selected="{option.id === selectedId}"
useDashBorder="{option.useDashBorder}"
onSelect="{onItemSelect}">{option.name}</CloudItem
>
{/each}
</div>
</Tool>
id="{null}"
selected="{shapeFillToolSelectionState.selectedId === null}"
useDashBorder="{true}"
onSelect="{onItemSelect}"
</CloudItem>

{#each viewModel.fillOptions as option}
<CloudItem
id="{option.id}"
selected="{option.id === shapeFillToolSelectionState.selectedId}"
onSelect="{onItemSelect}">{option.name}</CloudItem
>
{/each}
</div>
</Tool>
{/if}

<style lang="scss">
div {
display: flex;
flex-wrap: wrap;
gap: 7px;
}
div {
display: flex;
flex-wrap: wrap;
gap: 7px;
}
</style>
Original file line number Diff line number Diff line change
@@ -1,29 +1,60 @@
<script lang="ts">
import CommonBorderTool from './common/CommonBorderTool.svelte';
import CommonBorderTool from './common/CommonBorderTool.svelte';
import { SHAPE_TOOL_VIEWMODEL } from "$ui/pannel/shapetool/constants";
import { getContext, onDestroy, onMount } from "svelte";
import { ShapeToolViewModel } from "$ui/pannel/shapetool/viewmodel/shape-tool-viewmodel";
import { LifecycleOwner } from "$libs/flow";
import { OneTimeAction } from "$mono/action-manager/one-time-actions";
import type { StrokeDashPattern } from "$ui/pannel/shapetool/viewmodel/models";
let selectedId = 'B1';
let cornerRounded = false;
let viewModel = getContext<ShapeToolViewModel>(SHAPE_TOOL_VIEWMODEL);
let lifecycleOwner = new LifecycleOwner();
let dashDash = 1;
let dashGap = 0;
let dashShift = 0;
let selectedStrokeItem = viewModel.lineStrokeTypeFlow.value;
let cornerRounded = viewModel.lineStrokeRoundedCornerFlow.value;
function onItemSelect(id: string) {
selectedId = id;
}
let dashPattern: StrokeDashPattern | null | undefined = viewModel.lineStrokeDashTypeFlow.value;
function onCornerRoundedChange(value: boolean) {
cornerRounded = value;
}
</script>
function onItemSelect(id: string | null) {
viewModel.update(OneTimeAction.ChangeLineStrokeExtra({ newStrokeStyleId: id, isEnabled: id !== null }));
}
function onCornerRoundedChange(value: boolean) {
viewModel.update(OneTimeAction.ChangeLineStrokeCornerExtra(value));
}
function onDashPatternChange(dashPattern: StrokeDashPattern) {
viewModel.update(OneTimeAction.ChangeLineStrokeDashPatternExtra(dashPattern));
}
onMount(() => {
lifecycleOwner.onStart();
<CommonBorderTool
title="Stroke"
{onItemSelect}
{selectedId}
{cornerRounded}
onCornerRounded="{onCornerRoundedChange}"
bind:dashDash
bind:dashGap
bind:dashShift
/>
viewModel.lineStrokeTypeFlow.observe(lifecycleOwner, (value) => {
selectedStrokeItem = value;
});
viewModel.lineStrokeRoundedCornerFlow.observe(lifecycleOwner, (value) => {
cornerRounded = value;
});
viewModel.lineStrokeDashTypeFlow.observe(lifecycleOwner, (value) => {
dashPattern = value;
});
});
onDestroy(() => {
lifecycleOwner.onStop();
});
</script>
{#if selectedStrokeItem && cornerRounded !== undefined && dashPattern !== undefined}
<CommonBorderTool
title="Stroke"
{onItemSelect}
selectedId="{selectedStrokeItem.selectedId}"
{cornerRounded}
onCornerRounded="{onCornerRoundedChange}"
{dashPattern}
{onDashPatternChange}
/>
{/if}
Loading

0 comments on commit ecfe690

Please sign in to comment.