forked from mirrors/gecko-dev
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35884 --HG-- extra : source : 60e4496cf9699dc59f2f4738cb60f87cbdb01e67
163 lines
4.7 KiB
JavaScript
163 lines
4.7 KiB
JavaScript
/* 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/. */
|
|
|
|
/* eslint-env browser */
|
|
"use strict";
|
|
|
|
// A box with a start and a end pane, separated by a dragable splitter that
|
|
// allows the user to resize the relative widths of the panes.
|
|
//
|
|
// +-----------------------+---------------------+
|
|
// | | |
|
|
// | | |
|
|
// | S |
|
|
// | Start Pane p End Pane |
|
|
// | l |
|
|
// | i |
|
|
// | t |
|
|
// | t |
|
|
// | e |
|
|
// | r |
|
|
// | | |
|
|
// | | |
|
|
// +-----------------------+---------------------+
|
|
|
|
const { Component } = require("devtools/client/shared/vendor/react");
|
|
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
|
const { assert } = require("devtools/shared/DevToolsUtils");
|
|
|
|
class HSplitBox extends Component {
|
|
static get propTypes() {
|
|
return {
|
|
// The contents of the start pane.
|
|
start: PropTypes.any.isRequired,
|
|
|
|
// The contents of the end pane.
|
|
end: PropTypes.any.isRequired,
|
|
|
|
// The relative width of the start pane, expressed as a number between 0 and
|
|
// 1. The relative width of the end pane is 1 - startWidth. For example,
|
|
// with startWidth = .5, both panes are of equal width; with startWidth =
|
|
// .25, the start panel will take up 1/4 width and the end panel will take
|
|
// up 3/4 width.
|
|
startWidth: PropTypes.number,
|
|
|
|
// A minimum css width value for the start and end panes.
|
|
minStartWidth: PropTypes.any,
|
|
minEndWidth: PropTypes.any,
|
|
|
|
// A callback fired when the user drags the splitter to resize the relative
|
|
// pane widths. The function is passed the startWidth value that would put
|
|
// the splitter underneath the users mouse.
|
|
onResize: PropTypes.func.isRequired,
|
|
};
|
|
}
|
|
|
|
static get defaultProps() {
|
|
return {
|
|
startWidth: 0.5,
|
|
minStartWidth: "20px",
|
|
minEndWidth: "20px",
|
|
};
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.state = {
|
|
mouseDown: false,
|
|
};
|
|
|
|
this._onMouseDown = this._onMouseDown.bind(this);
|
|
this._onMouseUp = this._onMouseUp.bind(this);
|
|
this._onMouseMove = this._onMouseMove.bind(this);
|
|
}
|
|
|
|
componentDidMount() {
|
|
document.defaultView.top.addEventListener("mouseup", this._onMouseUp);
|
|
document.defaultView.top.addEventListener("mousemove", this._onMouseMove);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
document.defaultView.top.removeEventListener("mouseup", this._onMouseUp);
|
|
document.defaultView.top.removeEventListener(
|
|
"mousemove",
|
|
this._onMouseMove
|
|
);
|
|
}
|
|
|
|
_onMouseDown(event) {
|
|
if (event.button !== 0) {
|
|
return;
|
|
}
|
|
|
|
this.setState({ mouseDown: true });
|
|
event.preventDefault();
|
|
}
|
|
|
|
_onMouseUp(event) {
|
|
if (event.button !== 0 || !this.state.mouseDown) {
|
|
return;
|
|
}
|
|
|
|
this.setState({ mouseDown: false });
|
|
event.preventDefault();
|
|
}
|
|
|
|
_onMouseMove(event) {
|
|
if (!this.state.mouseDown) {
|
|
return;
|
|
}
|
|
|
|
const rect = this.refs.box.getBoundingClientRect();
|
|
const { left, right } = rect;
|
|
const width = right - left;
|
|
const direction = this.refs.box.ownerDocument.dir;
|
|
const relative =
|
|
direction == "rtl" ? right - event.clientX : event.clientX - left;
|
|
this.props.onResize(relative / width);
|
|
|
|
event.preventDefault();
|
|
}
|
|
|
|
render() {
|
|
/* eslint-disable no-shadow */
|
|
const { start, end, startWidth, minStartWidth, minEndWidth } = this.props;
|
|
assert(
|
|
startWidth => 0 && startWidth <= 1,
|
|
"0 <= this.props.startWidth <= 1"
|
|
);
|
|
/* eslint-enable */
|
|
return dom.div(
|
|
{
|
|
className: "h-split-box",
|
|
ref: "box",
|
|
},
|
|
|
|
dom.div(
|
|
{
|
|
className: "h-split-box-pane",
|
|
style: { flex: startWidth, minWidth: minStartWidth },
|
|
},
|
|
start
|
|
),
|
|
|
|
dom.div({
|
|
className: "devtools-side-splitter",
|
|
onMouseDown: this._onMouseDown,
|
|
}),
|
|
|
|
dom.div(
|
|
{
|
|
className: "h-split-box-pane",
|
|
style: { flex: 1 - startWidth, minWidth: minEndWidth },
|
|
},
|
|
end
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = HSplitBox;
|