Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/devtools/client/shared/components/splitter/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 11 kB image not shown  

Quelle  SplitBox.js   Sprache: JAVA

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


"use strict";

const {
  Component,
  createFactory,
} = require("resource://devtools/client/shared/vendor/react.js");
const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js");
const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");

const Draggable = createFactory(
  require("resource://devtools/client/shared/components/splitter/Draggable.js")
);

/**
 * This component represents a Splitter. The splitter supports vertical
 * as well as horizontal mode.
 */

class SplitBox extends Component {
  static get propTypes() {
    return {
      // Custom class name. You can use more names separated by a space.
      className: PropTypes.string,
      // Initial size of controlled panel.
      initialSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      // Initial width of controlled panel.
      initialWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      // Initial height of controlled panel.
      initialHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      // Left/top panel
      startPanel: PropTypes.any,
      // Left/top panel collapse state.
      startPanelCollapsed: PropTypes.bool,
      // Min panel size.
      minSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      // Max panel size.
      maxSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      // Right/bottom panel
      endPanel: PropTypes.any,
      // Right/bottom panel collapse state.
      endPanelCollapsed: PropTypes.bool,
      // True if the right/bottom panel should be controlled.
      endPanelControl: PropTypes.bool,
      // Size of the splitter handle bar.
      splitterSize: PropTypes.number,
      // True if the splitter bar is vertical (default is vertical).
      vert: PropTypes.bool,
      // Style object.
      style: PropTypes.object,
      // Call when controlled panel was resized.
      onControlledPanelResized: PropTypes.func,
      // Optional callback when splitbox resize stops
      onResizeEnd: PropTypes.func,
      // Retrieve DOM reference to the start panel element
      onSelectContainerElement: PropTypes.any,
    };
  }

  static get defaultProps() {
    return {
      splitterSize: 5,
      vert: true,
      endPanelControl: false,
    };
  }

  static getDerivedStateFromProps(props, state) {
    if (
      props.endPanelControl === state.prevEndPanelControl &&
      props.splitterSize === state.prevSplitterSize &&
      props.vert === state.prevVert
    ) {
      return null;
    }

    const newState = {};
    if (props.endPanelControl !== state.prevEndPanelControl) {
      newState.endPanelControl = props.endPanelControl;
      newState.prevEndPanelControl = props.endPanelControl;
    }
    if (props.splitterSize !== state.prevSplitterSize) {
      newState.splitterSize = props.splitterSize;
      newState.prevSplitterSize = props.splitterSize;
    }
    if (props.vert !== state.prevVert) {
      newState.vert = props.vert;
      newState.prevVert = props.vert;
    }

    return newState;
  }

  constructor(props) {
    super(props);

    /**
     * The state stores whether or not the end panel should be controlled, the current
     * orientation (vertical or horizontal), the splitter size, and the current size
     * (width/height). All these values can change during the component's life time.
     */

    this.state = {
      // True if the right/bottom panel should be controlled.
      endPanelControl: props.endPanelControl,
      // True if the splitter bar is vertical (default is vertical).
      vert: props.vert,
      // Size of the splitter handle bar.
      splitterSize: props.splitterSize,
      // The state for above 3 properties are derived from props, but also managed by the component itself.
      // SplitBox manages it's own state but sometimes the parent will pass in new props which will
      // override the current state of the component. So we need track the prev value of these props so that
      // compare them to the props change and derive new state whenever these 3 props change.
      prevEndPanelControl: props.endPanelControl,
      prevVert: props.vert,
      prevSplitterSize: props.splitterSize,
      // Width of controlled panel.
      width: props.initialWidth || props.initialSize,
      // Height of controlled panel.
      height: props.initialHeight || props.initialSize,
    };

    this.onStartMove = this.onStartMove.bind(this);
    this.onStopMove = this.onStopMove.bind(this);
    this.onMove = this.onMove.bind(this);
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (
      nextState.width != this.state.width ||
      nextState.endPanelControl != this.props.endPanelControl ||
      nextState.height != this.state.height ||
      nextState.vert != this.state.vert ||
      nextState.splitterSize != this.state.splitterSize ||
      nextProps.startPanel != this.props.startPanel ||
      nextProps.endPanel != this.props.endPanel ||
      nextProps.minSize != this.props.minSize ||
      nextProps.maxSize != this.props.maxSize
    );
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.onControlledPanelResized &&
      (prevState.width !== this.state.width ||
        prevState.height !== this.state.height)
    ) {
      this.props.onControlledPanelResized(this.state.width, this.state.height);
    }
  }

  // Dragging Events

  /**
   * Set 'resizing' cursor on entire document during splitter dragging.
   * This avoids cursor-flickering that happens when the mouse leaves
   * the splitter bar area (happens frequently).
   */

  onStartMove() {
    const doc = this.splitBox.ownerDocument;
    const defaultCursor = doc.documentElement.style.cursor;
    doc.documentElement.style.cursor = this.state.vert
      ? "ew-resize"
      : "ns-resize";

    this.splitBox.classList.add("dragging");

    this.setState({
      defaultCursor,
    });
  }

  onStopMove() {
    const doc = this.splitBox.ownerDocument;
    doc.documentElement.style.cursor = this.state.defaultCursor;

    this.splitBox.classList.remove("dragging");

    if (this.props.onResizeEnd) {
      this.props.onResizeEnd(
        this.state.vert ? this.state.width : this.state.height
      );
    }
  }

  /**
   * Adjust size of the controlled panel. Depending on the current
   * orientation we either remember the width or height of
   * the splitter box.
   */

  onMove(x, y) {
    const nodeBounds = this.splitBox.getBoundingClientRect();

    let size;
    let { endPanelControl, vert } = this.state;

    if (vert) {
      // Use the document owning the SplitBox to detect rtl. The global document might be
      // the one bound to the toolbox shared BrowserRequire, which is irrelevant here.
      const doc = this.splitBox.ownerDocument;

      // Switch the control flag in case of RTL. Note that RTL
      // has impact on vertical splitter only.
      if (doc.dir === "rtl") {
        endPanelControl = !endPanelControl;
      }

      size = endPanelControl
        ? nodeBounds.left + nodeBounds.width - x
        : x - nodeBounds.left;

      this.setState({
        width: this.getConstrainedSizeInPx(size, nodeBounds.width),
      });
    } else {
      size = endPanelControl
        ? nodeBounds.top + nodeBounds.height - y
        : y - nodeBounds.top;

      this.setState({
        height: this.getConstrainedSizeInPx(size, nodeBounds.height),
      });
    }
  }

  /**
   * Calculates the constrained size taking into account the minimum width or
   * height passed via this.props.minSize.
   *
   * @param {Number} requestedSize
   *        The requested size
   * @param {Number} splitBoxWidthOrHeight
   *        The width or height of the splitBox
   *
   * @return {Number}
   *         The constrained size
   */

  getConstrainedSizeInPx(requestedSize, splitBoxWidthOrHeight) {
    let minSize = this.props.minSize + "";

    if (minSize.endsWith("%")) {
      minSize = (parseFloat(minSize) / 100) * splitBoxWidthOrHeight;
    } else if (minSize.endsWith("px")) {
      minSize = parseFloat(minSize);
    }
    return Math.max(requestedSize, minSize);
  }

  // Rendering

  // eslint-disable-next-line complexity
  render() {
    const { endPanelControl, splitterSize, vert } = this.state;
    const {
      startPanel,
      startPanelCollapsed,
      endPanel,
      endPanelCollapsed,
      minSize,
      maxSize,
      onSelectContainerElement,
    } = this.props;

    const style = Object.assign(
      {
        // Set the size of the controlled panel (height or width depending on the
        // current state). This can be used to help with styling of dependent
        // panels.
        "--split-box-controlled-panel-size": `${
          vert ? this.state.width : this.state.height
        }`,
      },
      this.props.style
    );

    // Calculate class names list.
    let classNames = ["split-box"];
    classNames.push(vert ? "vert" : "horz");
    if (this.props.className) {
      classNames = classNames.concat(this.props.className.split(" "));
    }

    let leftPanelStyle;
    let rightPanelStyle;

    // Set proper size for panels depending on the current state.
    if (vert) {
      leftPanelStyle = {
        maxWidth: endPanelControl ? null : maxSize,
        minWidth: endPanelControl ? null : minSize,
        width: endPanelControl ? null : this.state.width,
      };
      rightPanelStyle = {
        maxWidth: endPanelControl ? maxSize : null,
        minWidth: endPanelControl ? minSize : null,
        width: endPanelControl ? this.state.width : null,
      };
    } else {
      leftPanelStyle = {
        maxHeight: endPanelControl ? null : maxSize,
        minHeight: endPanelControl ? null : minSize,
        height: endPanelControl ? null : this.state.height,
      };
      rightPanelStyle = {
        maxHeight: endPanelControl ? maxSize : null,
        minHeight: endPanelControl ? minSize : null,
        height: endPanelControl ? this.state.height : null,
      };
    }

    // Calculate splitter size
    const splitterStyle = {
      flex: "0 0 " + splitterSize + "px",
    };

    return dom.div(
      {
        className: classNames.join(" "),
        ref: div => {
          this.splitBox = div;
        },
        style,
      },
      startPanel && !startPanelCollapsed
        ? dom.div(
            {
              className: endPanelControl ? "uncontrolled" : "controlled",
              style: leftPanelStyle,
              role: "presentation",
              ref: div => {
                this.startPanelContainer = div;
                if (onSelectContainerElement) {
                  onSelectContainerElement(div);
                }
              },
            },
            startPanel
          )
        : null,
      splitterSize > 0
        ? Draggable({
            className: "splitter",
            style: splitterStyle,
            onStart: this.onStartMove,
            onStop: this.onStopMove,
            onMove: this.onMove,
          })
        : null,
      endPanel && !endPanelCollapsed
        ? dom.div(
            {
              className: endPanelControl ? "controlled" : "uncontrolled",
              style: rightPanelStyle,
              role: "presentation",
              ref: div => {
                this.endPanelContainer = div;
              },
            },
            endPanel
          )
        : null
    );
  }
}

module.exports = SplitBox;

98%


¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.