<commit_before>// Copyright 2020-2022, University of Colorado Boulder

/**
 * ButtonNode is the base class for the sun button hierarchy.
 *
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 */

import DerivedProperty from '../../../axon/js/DerivedProperty.js';
import IReadOnlyProperty from '../../../axon/js/IReadOnlyProperty.js';
import Multilink from '../../../axon/js/Multilink.js';
import Bounds2 from '../../../dot/js/Bounds2.js';
import Dimension2 from '../../../dot/js/Dimension2.js';
import merge from '../../../phet-core/js/merge.js';
import optionize from '../../../phet-core/js/optionize.js';
import { AlignBox, AlignBoxXAlign, AlignBoxYAlign, Brightness, Color, Contrast, Grayscale, IColor, isHeightSizable, isWidthSizable, Node, NodeOptions, PaintableNode, PaintColorProperty, Path, PressListener, PressListenerOptions, SceneryConstants, Sizable, SizableOptions, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
import Tandem from '../../../tandem/js/Tandem.js';
import ColorConstants from '../ColorConstants.js';
import sun from '../sun.js';
import ButtonInteractionState from './ButtonInteractionState.js';
import ButtonModel from './ButtonModel.js';
import TButtonAppearanceStrategy from './TButtonAppearanceStrategy.js';
import TContentAppearanceStrategy from './TContentAppearanceStrategy.js';

// constants
const CONTRAST_FILTER = new Contrast( 0.7 );
const BRIGHTNESS_FILTER = new Brightness( 1.2 );

// if there is content, style can be applied to a containing Node around it.
type EnabledAppearanceStrategy = ( enabled: boolean, button: Node, background: Node, content: Node | null ) => void;

type SelfOptions = {

  // what appears on the button (icon, label, etc.)
  content?: Node | null;

  // margin in x direction, i.e. on left and right
  xMargin?: number;

  // margin in y direction, i.e. on top and bottom
  yMargin?: number;

  // Alignment, relevant only when options minWidth or minHeight are greater than the size of options.content
  xAlign?: AlignBoxXAlign;
  yAlign?: AlignBoxYAlign;

  // When a button's non-stroked size is specified (used by RectangularButton etc., not for general use)
  buttonSize?: Dimension2 | null;

  // By default, icons are centered in the button, but icons with odd
  // shapes that are not wrapped in a normalizing parent node may need to
  // specify offsets to line things up properly
  xContentOffset?: number;
  yContentOffset?: number;

  // Options that will be passed through to the main input listener (PressListener)
  listenerOptions?: PressListenerOptions | null;

  // initial color of the button's background
  baseColor?: IColor;

  // Color when disabled
  disabledColor?: IColor;

  // default cursor
  cursor?: string;

  // Class that determines the button's appearance for the values of interactionStateProperty.
  // Constructor is {function( backgroundNode:Node, interactionStateProperty:Property, options:*)},
  // and the class has an optional dispose method.
  // See ButtonNode.FlatAppearanceStrategy for an example.
  buttonAppearanceStrategy?: TButtonAppearanceStrategy;

  // Optional class that determines the content's appearance for the values of interactionStateProperty.
  // Constructor is {function( content:Node, interactionStateProperty:Property, options:*)},
  // and the class has an optional dispose method.
  // See RectangularRadioButton.ContentAppearanceStrategy for an example.
  contentAppearanceStrategy?: TContentAppearanceStrategy | null;

  // Alter the appearance when changing the enabled of the button.
  enabledAppearanceStrategy?: EnabledAppearanceStrategy;
};
type ParentOptions = SizableOptions & VoicingOptions & NodeOptions;<commit_msg>ButtonNode should not be redefining option cursor, it comes with NodeOptions<commit_after>// Copyright 2020-2022, University of Colorado Boulder

/**
 * ButtonNode is the base class for the sun button hierarchy.
 *
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 */

import DerivedProperty from '../../../axon/js/DerivedProperty.js';
import IReadOnlyProperty from '../../../axon/js/IReadOnlyProperty.js';
import Multilink from '../../../axon/js/Multilink.js';
import Bounds2 from '../../../dot/js/Bounds2.js';
import Dimension2 from '../../../dot/js/Dimension2.js';
import merge from '../../../phet-core/js/merge.js';
import optionize from '../../../phet-core/js/optionize.js';
import { AlignBox, AlignBoxXAlign, AlignBoxYAlign, Brightness, Color, Contrast, Grayscale, IColor, isHeightSizable, isWidthSizable, Node, NodeOptions, PaintableNode, PaintColorProperty, Path, PressListener, PressListenerOptions, SceneryConstants, Sizable, SizableOptions, Voicing, VoicingOptions } from '../../../scenery/js/imports.js';
import Tandem from '../../../tandem/js/Tandem.js';
import ColorConstants from '../ColorConstants.js';
import sun from '../sun.js';
import ButtonInteractionState from './ButtonInteractionState.js';
import ButtonModel from './ButtonModel.js';
import TButtonAppearanceStrategy from './TButtonAppearanceStrategy.js';
import TContentAppearanceStrategy from './TContentAppearanceStrategy.js';

// constants
const CONTRAST_FILTER = new Contrast( 0.7 );
const BRIGHTNESS_FILTER = new Brightness( 1.2 );

// if there is content, style can be applied to a containing Node around it.
type EnabledAppearanceStrategy = ( enabled: boolean, button: Node, background: Node, content: Node | null ) => void;

type SelfOptions = {

  // what appears on the button (icon, label, etc.)
  content?: Node | null;

  // margin in x direction, i.e. on left and right
  xMargin?: number;

  // margin in y direction, i.e. on top and bottom
  yMargin?: number;

  // Alignment, relevant only when options minWidth or minHeight are greater than the size of options.content
  xAlign?: AlignBoxXAlign;
  yAlign?: AlignBoxYAlign;

  // When a button's non-stroked size is specified (used by RectangularButton etc., not for general use)
  buttonSize?: Dimension2 | null;

  // By default, icons are centered in the button, but icons with odd
  // shapes that are not wrapped in a normalizing parent node may need to
  // specify offsets to line things up properly
  xContentOffset?: number;
  yContentOffset?: number;

  // Options that will be passed through to the main input listener (PressListener)
  listenerOptions?: PressListenerOptions | null;

  // initial color of the button's background
  baseColor?: IColor;

  // Color when disabled
  disabledColor?: IColor;

  // Class that determines the button's appearance for the values of interactionStateProperty.
  // Constructor is {function( backgroundNode:Node, interactionStateProperty:Property, options:*)},
  // and the class has an optional dispose method.
  // See ButtonNode.FlatAppearanceStrategy for an example.
  buttonAppearanceStrategy?: TButtonAppearanceStrategy;

  // Optional class that determines the content's appearance for the values of interactionStateProperty.
  // Constructor is {function( content:Node, interactionStateProperty:Property, options:*)},
  // and the class has an optional dispose method.
  // See RectangularRadioButton.ContentAppearanceStrategy for an example.
  contentAppearanceStrategy?: TContentAppearanceStrategy | null;

  // Alter the appearance when changing the enabled of the button.
  enabledAppearanceStrategy?: EnabledAppearanceStrategy;
};
type ParentOptions = SizableOptions & VoicingOptions & NodeOptions;
{'fraction_non_alphanumeric': 0.10948423690805963, 'fraction_numerical': 0.004484896451655455, 'mean_word_length': 4.261623872310895, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3066710', 'n_tokens_mistral': 2060, 'n_tokens_neox': 2019, 'n_words': 751}