Skip to content

Commit

Permalink
Add Content Fitting Mode Option on Fancy Button
Browse files Browse the repository at this point in the history
  • Loading branch information
bbazukun123 committed Oct 28, 2024
1 parent a602adb commit bacd787
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 6 deletions.
70 changes: 65 additions & 5 deletions src/FancyButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ type ViewsInput = BasicViewsInput & {
icon?: ButtonView;
};

type ContentFittingMode =
// Fits the text/icon content inside the button.
| 'default'
// Fill the button with the text/icon content, scaling it up to fill the view space with padding accounted for.
| 'fill'
// Only apply the default scaling and anchoring, without constraining to the button view's dimensions.
| 'none';

export type ButtonOptions = ViewsInput & {
padding?: number;
scale?: number;
Expand All @@ -68,6 +76,9 @@ export type ButtonOptions = ViewsInput & {
defaultIconAnchor?: Pos | number;
animations?: StateAnimations;
nineSliceSprite?: [number, number, number, number];
contentFittingMode?: ContentFittingMode;

/** @deprecated refer to contentFittingMode instead */
ignoreRefitting?: boolean;
};

Expand Down Expand Up @@ -413,12 +424,29 @@ export class FancyButton extends ButtonContainer

if (activeView)
{
if (!this.options?.ignoreRefitting)
if (!this.options.ignoreRefitting)
{
this._views.textView.scale.set(this._defaultTextScale.x, this._defaultTextScale.y);
}

fitToView(activeView, this._views.textView, this.padding, false);
if (this.contentFittingMode === 'default')
{
fitToView(activeView, this._views.textView, this.padding, false);
}

if (this.contentFittingMode === 'fill')
{
// reset to base dimensions for calculations
this._views.textView.scale.set(1);

const availableWidth = activeView.width - (this.padding * 2);
const availableHeight = activeView.height - (this.padding * 2);
const targetScaleX = availableWidth / this._views.textView.width;
const targetScaleY = availableHeight / this._views.textView.height;
const scale = Math.min(targetScaleX, targetScaleY);

this._views.textView.scale.set(scale * this._defaultTextScale.x, scale * this._defaultTextScale.y);
}

this._views.textView.x = activeView.x + (activeView.width / 2);
this._views.textView.y = activeView.y + (activeView.height / 2);
Expand Down Expand Up @@ -447,14 +475,31 @@ export class FancyButton extends ButtonContainer
return;
}

if (!this.options?.ignoreRefitting)
if (!this.options.ignoreRefitting)
{
this._views.iconView.scale.set(this._defaultIconScale.x, this._defaultIconScale.y);
}

const { x: anchorX, y: anchorY } = this._defaultIconAnchor;
if (this.contentFittingMode === 'default')
{
fitToView(activeView, this._views.iconView, this.padding, false);
}

if (this.contentFittingMode === 'fill')
{
// reset to base dimensions for calculations
this._views.iconView.scale.set(1);

const availableWidth = activeView.width - (this.padding * 2);
const availableHeight = activeView.height - (this.padding * 2);
const targetScaleX = availableWidth / this._views.iconView.width;
const targetScaleY = availableHeight / this._views.iconView.height;
const scale = Math.min(targetScaleX, targetScaleY);

fitToView(activeView, this._views.iconView, this.padding, false);
this._views.iconView.scale.set(scale * this._defaultIconScale.x, scale * this._defaultIconScale.y);
}

const { x: anchorX, y: anchorY } = this._defaultIconAnchor;

if ('anchor' in this._views.iconView)
{
Expand Down Expand Up @@ -509,6 +554,21 @@ export class FancyButton extends ButtonContainer
this.adjustTextView(this.state);
}

/**
* Sets the fitting mode for the button's content.
* @param {ContentFittingMode} mode - fitting mode type.
*/
set contentFittingMode(mode: ContentFittingMode)
{
this.options.contentFittingMode = mode;
}

/** Returns the fitting mode for the button's content, defaulting to 'default'. */
get contentFittingMode(): ContentFittingMode
{
return this.options.contentFittingMode ?? 'default';
}

/**
* Sets the default view of the button.
* @param { string | Container } view - string (path to the image) or a Container-based view
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ const args = {
anchorY: 0.5,
animationDuration: 100,
disabled: false,
contentFittingMode: ["default", "fill", "none"],
onPress: action("button was pressed! (tap or click!)"),
};

export const UseNineSliceSprite: StoryFn<typeof args> = (
export const UseNineSliceSprite: StoryFn<typeof args & { contentFittingMode: "default" | "fill" | "none" }> = (
{
text,
textColor,
Expand All @@ -45,6 +46,7 @@ export const UseNineSliceSprite: StoryFn<typeof args> = (
defaultTextAnchorY,
defaultIconAnchorX,
defaultIconAnchorY,
contentFittingMode,
},
context,
) =>
Expand Down Expand Up @@ -98,6 +100,7 @@ export const UseNineSliceSprite: StoryFn<typeof args> = (
duration: animationDuration,
},
},
contentFittingMode,
});

button.iconView = new MaskedFrame({
Expand Down

0 comments on commit bacd787

Please sign in to comment.