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
CatchABus committed Nov 30, 2024
1 parent b945431 commit d7a484e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 4 deletions.
66 changes: 63 additions & 3 deletions src/FancyButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,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 @@ -69,6 +77,9 @@ export type ButtonOptions = ViewsInput & {
defaultIconAnchor?: Pos | number;
animations?: StateAnimations;
nineSlicePlane?: [number, number, number, number];
contentFittingMode?: ContentFittingMode;

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

Expand Down Expand Up @@ -417,7 +428,24 @@ export class FancyButton extends ButtonContainer
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 @@ -451,9 +479,26 @@ export class FancyButton extends ButtonContainer
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 @@ -508,6 +553,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,6 +24,7 @@ const args = {
anchorY: 0.5,
animationDuration: 100,
disabled: false,
contentFittingMode: ['default', 'fill', 'none'],
onPress: action('button was pressed! (tap or click!)')
};

Expand All @@ -43,7 +44,8 @@ export const UseNineSlicePlane = ({
defaultTextAnchorX,
defaultTextAnchorY,
defaultIconAnchorX,
defaultIconAnchorY
defaultIconAnchorY,
contentFittingMode
}: any) =>
{
const view = new Container();
Expand Down Expand Up @@ -85,6 +87,7 @@ export const UseNineSlicePlane = ({
defaultIconScale,
defaultTextAnchor: { x: defaultTextAnchorX, y: defaultTextAnchorY },
defaultIconAnchor: { x: defaultIconAnchorX, y: defaultIconAnchorY },
contentFittingMode,
animations: {
hover: {
props: {
Expand Down

0 comments on commit d7a484e

Please sign in to comment.