Skip to content

Commit 0616aae

Browse files
committed
Fixed the touch screen bug
1 parent 5d0ad4d commit 0616aae

30 files changed

+389
-125
lines changed

build/App.js

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ var TOOLBAR_HEIGHT = 82,
6060
YELLOW = '#ffcc00',
6161
COLORS = [PURPLE, ORANGE, GREEN, RED, YELLOW];
6262

63+
function extractPosition(e) {
64+
return {
65+
x: e.clientX,
66+
y: e.clientY
67+
};
68+
}
69+
6370
var App = exports.App = function (_Component) {
6471
_inherits(App, _Component);
6572

@@ -79,8 +86,10 @@ var App = exports.App = function (_Component) {
7986
current: -1
8087
};
8188

82-
_this.onCircleMenu = _this.onCircleMenu.bind(_this);
83-
_this.onAppMenu = _this.onAppMenu.bind(_this);
89+
_this.onAppContextMenu = _this.onAppContextMenu.bind(_this);
90+
_this.onAppTouchStart = _this.onAppTouchStart.bind(_this);
91+
_this.onCircleContextMenu = _this.onCircleContextMenu.bind(_this);
92+
_this.onCircleTouchStart = _this.onCircleTouchStart.bind(_this);
8493
_this.onMenuClose = _this.onMenuClose.bind(_this);
8594
_this.executeCommand = _this.executeCommand.bind(_this);
8695
_this.onAnywhereClickOrContextMenu = _this.onAnywhereClickOrContextMenu.bind(_this);
@@ -104,11 +113,8 @@ var App = exports.App = function (_Component) {
104113

105114
}, {
106115
key: 'showMenu',
107-
value: function showMenu(e, items) {
108-
this.menuPosition = {
109-
x: e.clientX,
110-
y: e.clientY
111-
};
116+
value: function showMenu(e, position, items) {
117+
this.menuPosition = position;
112118
e.preventDefault();
113119
e.stopPropagation();
114120
this.setState({
@@ -117,15 +123,26 @@ var App = exports.App = function (_Component) {
117123
});
118124
}
119125
}, {
120-
key: 'onAppMenu',
121-
value: function onAppMenu(e) {
122-
this.showMenu(e, this.appMenuItems);
126+
key: 'onAppContextMenu',
127+
value: function onAppContextMenu(e) {
128+
this.showMenu(e, extractPosition(e), this.appMenuItems);
129+
}
130+
}, {
131+
key: 'onAppTouchStart',
132+
value: function onAppTouchStart(e) {
133+
this.showMenu(e, extractPosition(e.nativeEvent.targetTouches[0]), this.appMenuItems);
134+
}
135+
}, {
136+
key: 'onCircleContextMenu',
137+
value: function onCircleContextMenu(source, e) {
138+
this.state.current = source;
139+
this.showMenu(e, extractPosition(e), this.circleMenuItems);
123140
}
124141
}, {
125-
key: 'onCircleMenu',
126-
value: function onCircleMenu(source, e) {
142+
key: 'onCircleTouchStart',
143+
value: function onCircleTouchStart(source, e) {
127144
this.state.current = source;
128-
this.showMenu(e, this.circleMenuItems);
145+
this.showMenu(e, extractPosition(e.nativeEvent.targetTouches[0]), this.circleMenuItems);
129146
}
130147
}, {
131148
key: 'onMenuClose',
@@ -246,16 +263,29 @@ var App = exports.App = function (_Component) {
246263
this.circleMenuItems = new _CircleMenuItems.CircleMenuItems(binder);
247264
this.appMenuItems = new _AppMenuItems.AppMenuItems(binder);
248265
}
266+
}, {
267+
key: 'cancelEvent',
268+
value: function cancelEvent(e) {
269+
var e = event || window.event;
270+
e.preventDefault && e.preventDefault();
271+
e.stopPropagation && e.stopPropagation();
272+
e.cancelBubble = true;
273+
e.returnValue = false;
274+
return false;
275+
}
249276
}, {
250277
key: 'render',
251278
value: function render() {
252279
var self = this,
253280
index = 0,
254281
menu = this.state.showMenu ? _react2.default.createElement(_Menu.Menu, { items: this.state.items, position: this.menuPosition, onClose: this.onMenuClose }) : null,
255282
circles = this.state.circles.map(function (circle) {
283+
var circleIndex = index++;
284+
256285
return _react2.default.createElement(_Circle.Circle, _extends({}, circle, { key: 'circle-' + index, strokeColor: 'white',
257286
selected: self.state.current === index,
258-
onContextMenu: self.onCircleMenu.bind(this, index++),
287+
onContextMenu: self.onCircleContextMenu.bind(this, circleIndex),
288+
onTouchStart: self.onCircleTouchStart.bind(this, circleIndex),
259289
onMenuClose: self.onMenuClose }));
260290
}),
261291
renderers = {
@@ -273,7 +303,11 @@ var App = exports.App = function (_Component) {
273303

274304
return _react2.default.createElement(
275305
'div',
276-
{ onContextMenu: this.onAppMenu },
306+
{ onContextMenu: this.onAppContextMenu,
307+
onTouchStart: this.onAppTouchStart,
308+
onTouchEnd: this.cancelEvent,
309+
onTouchCancel: this.cancelEvent,
310+
onTouchMove: this.cancelEvent },
277311
_react2.default.createElement(
278312
'div',
279313
{ className: 'toolbar' },

build/components/Circle.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ var Circle = exports.Circle = function (_Component) {
3737

3838
_this.onMouseOver = _this.onMouseOver.bind(_this);
3939
_this.onMouseOut = _this.onMouseOut.bind(_this);
40+
_this.onTouchStart = _this.onTouchStart.bind(_this);
4041

4142
_this.state = {
4243
strokeWidth: _this.props.selected ? 5 : 0,
@@ -52,6 +53,14 @@ var Circle = exports.Circle = function (_Component) {
5253
hovered: true
5354
});
5455
}
56+
}, {
57+
key: 'onTouchStart',
58+
value: function onTouchStart(e) {
59+
this.setState({
60+
hovered: true
61+
});
62+
this.props.onTouchStart(e);
63+
}
5564
}, {
5665
key: 'onMouseOut',
5766
value: function onMouseOut() {
@@ -79,6 +88,7 @@ var Circle = exports.Circle = function (_Component) {
7988

8089
return _react2.default.createElement('circle', _extends({}, d, {
8190
onContextMenu: this.props.onContextMenu,
91+
onTouchStart: this.onTouchStart,
8292
onMouseOver: this.onMouseOver,
8393
onMouseOut: this.onMouseOut }));
8494
}
@@ -90,10 +100,14 @@ var Circle = exports.Circle = function (_Component) {
90100
Circle.propTypes = {
91101
strokeColorSelected: _react2.default.PropTypes.string,
92102
strokeColorHovered: _react2.default.PropTypes.string,
93-
selected: _react2.default.PropTypes.bool
103+
selected: _react2.default.PropTypes.bool,
104+
onContextMenu: _react2.default.PropTypes.func,
105+
onTouchStart: _react2.default.PropTypes.func
94106
};
95107
Circle.defaultProps = {
96108
strokeColorSelected: 'white',
97109
strokeColorHovered: 'white',
98-
selected: false
110+
selected: false,
111+
onContextMenu: function onContextMenu() {},
112+
onTouchStart: function onTouchStart() {}
99113
};

build/components/DropdownMenu.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ var _reactDom = require('react-dom');
1515

1616
var _reactDom2 = _interopRequireDefault(_reactDom);
1717

18+
var _Dom = require('./../util/Dom');
19+
1820
var _Menu = require('./Menu');
1921

2022
var _Aligner = require('./../util/Aligner.js');
@@ -31,6 +33,8 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
3133

3234
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
3335

36+
var classnames = require('classnames');
37+
3438
var MOUSE_ENTER_DELAY = 500,
3539
MOUSE_LEAVE_DELAY = 100,
3640
ALIGNER = _Aligner.Aligner,
@@ -49,6 +53,7 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
4953
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DropdownMenu).call(this, props));
5054

5155
_this.onButtonClick = _this.onButtonClick.bind(_this);
56+
_this.onButtonTouchStart = _this.onButtonTouchStart.bind(_this);
5257
_this.onButtonMouseEnter = _this.onButtonMouseEnter.bind(_this);
5358
_this.onOpen = _this.onOpen.bind(_this);
5459
_this.onClose = _this.onClose.bind(_this);
@@ -106,6 +111,13 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
106111
value: function onButtonClick() {
107112
this.tryOpenMenu();
108113
}
114+
}, {
115+
key: 'onButtonTouchStart',
116+
value: function onButtonTouchStart(e) {
117+
this.tryOpenMenu();
118+
e.preventDefault();
119+
e.stopPropagation();
120+
}
109121
}, {
110122
key: 'onButtonMouseEnter',
111123
value: function onButtonMouseEnter() {
@@ -127,9 +139,10 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
127139
key: 'renderButton',
128140
value: function renderButton() {
129141
// render a child passed from the outside, or a default button
130-
var children = this.props.children || _react2.default.createElement(
142+
var className = classnames('', _Dom.Dom.buildClassNames(this.props.classPrefix, ['menu-button'])),
143+
children = this.props.children || _react2.default.createElement(
131144
'button',
132-
{ ref: 'button', className: 'menu-button' },
145+
{ ref: 'button', className: className },
133146
this.props.buttonText
134147
),
135148
self = this;
@@ -138,6 +151,7 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
138151
return _react2.default.cloneElement(child, {
139152
ref: 'button',
140153
onClick: self.onButtonClick,
154+
onTouchStart: self.onButtonTouchStart,
141155
onContextMenu: self.onButtonContextMenu,
142156
onMouseEnter: self.onButtonMouseEnter
143157
});
@@ -146,7 +160,9 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
146160
}, {
147161
key: 'render',
148162
value: function render() {
149-
var menu = this.state.isOpen ? _react2.default.createElement(_Menu.Menu, {
163+
var buttonClassName = classnames(this.props.className, _Dom.Dom.buildClassNames(this.props.classPrefix, ['drop-down'])),
164+
menu = this.state.isOpen ? _react2.default.createElement(_Menu.Menu, {
165+
classPrefix: this.props.classPrefix,
150166
onOpen: this.onOpen,
151167
onClose: this.onClose,
152168
onItemMouseEnter: this.props.onItemMouseEnter,
@@ -164,7 +180,7 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
164180

165181
return _react2.default.createElement(
166182
'div',
167-
{ className: 'drop-down ' + this.props.className },
183+
{ className: buttonClassName },
168184
this.renderButton(),
169185
menu
170186
);
@@ -182,6 +198,7 @@ var DropdownMenu = exports.DropdownMenu = function (_Component) {
182198
}(_react.Component);
183199

184200
DropdownMenu.propTypes = {
201+
classPrefix: _react2.default.PropTypes.string, // CSS class prefix for all the classes used by this dropdown menu
185202
buttonText: _react2.default.PropTypes.string, // the text of the default button
186203
openOnMouseOver: _react2.default.PropTypes.bool.isRequired, // should menu be opened on mouse over (Mac menu is opened on first click)
187204
items: _react2.default.PropTypes.array.isRequired, // menu items (data)
@@ -196,6 +213,7 @@ DropdownMenu.propTypes = {
196213
onItemClick: _react2.default.PropTypes.func // custom item click handler
197214
};
198215
DropdownMenu.defaultProps = {
216+
classPrefix: '',
199217
buttonText: '- Menu -',
200218
openOnMouseOver: false,
201219
items: [],

build/components/Menu.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ var Menu = exports.Menu = function (_Component) {
9595
_this.processInActionDebounced = _lodash2.default.debounce(_this.processInAction.bind(_this), MOUSE_ENTER_DELAY);
9696
_this.processOutActionDebounced = _lodash2.default.debounce(_this.processOutAction.bind(_this), MOUSE_LEAVE_DELAY);
9797

98-
_this.popupFactory = new _MenuPopupFactory.MenuPopupFactory();
99-
_this.itemFactory = new _MenuItemFactory.MenuItemFactory(_lodash2.default.assign(RENDERERS, props.renderers));
98+
_this.popupFactory = new _MenuPopupFactory.MenuPopupFactory(_this.props.classPrefix);
99+
_this.itemFactory = new _MenuItemFactory.MenuItemFactory(_lodash2.default.assign(RENDERERS, props.renderers), props.classPrefix);
100100

101101
_this.state = {
102102
visible: false,
@@ -187,6 +187,7 @@ var Menu = exports.Menu = function (_Component) {
187187
key: 'onAnywhereClickOrContextMenu',
188188
value: function onAnywhereClickOrContextMenu(e) {
189189
var clickedElement = e.target;
190+
190191
if (!this.popupsContain(clickedElement)) {
191192
this.closeMenu();
192193
}
@@ -290,7 +291,7 @@ var Menu = exports.Menu = function (_Component) {
290291
}, {
291292
key: 'processInAction',
292293
value: function processInAction(hoverData, shouldFireCallback) {
293-
var childItems;
294+
var childItems, popups;
294295

295296
if (!hoverData) {
296297
return;
@@ -306,9 +307,9 @@ var Menu = exports.Menu = function (_Component) {
306307

307308
this.removeChildPopups(hoverData.popupId);
308309

309-
if (this.hoverData !== null && this.hoverData.isSiblingOf(hoverData)) {
310-
this.removeChildPopups(hoverData.popupId);
311-
}
310+
//if (this.hoverData !== null && this.hoverData.isSiblingOf(hoverData)) {
311+
// this.removeChildPopups(hoverData.popupId);
312+
//}
312313

313314
// set new hover data
314315
this.hoverData = hoverData;
@@ -319,7 +320,7 @@ var Menu = exports.Menu = function (_Component) {
319320
return;
320321
}
321322

322-
var popups = this.createPopup(childItems);
323+
popups = this.createPopup(childItems);
323324
this.setState({
324325
popups: popups
325326
});
@@ -405,6 +406,7 @@ var Menu = exports.Menu = function (_Component) {
405406
{ key: 'liberator-popup-' + level,
406407
layer: self.props.layer, layerId: self.props.layerId, autoCleanup: self.props.autoCleanup },
407408
_react2.default.createElement(_MenuPopup.MenuPopup, {
409+
classPrefix: self.props.classPrefix,
408410
key: 'menu-popup-' + data.id,
409411
popupId: data.id,
410412
items: self.state.popups[level].items,
@@ -527,6 +529,7 @@ var Menu = exports.Menu = function (_Component) {
527529

528530

529531
Menu.propTypes = {
532+
classPrefix: _react2.default.PropTypes.string, // CSS class prefix for all the classes used by this menu
530533
items: _react2.default.PropTypes.array.isRequired, // menu items (data)
531534
renderers: _react2.default.PropTypes.object, // item renderers
532535
mouseEnterDelay: _react2.default.PropTypes.number,
@@ -544,6 +547,7 @@ Menu.propTypes = {
544547
autoCleanup: _react2.default.PropTypes.bool // Liberator's empty layer auto cleanup
545548
};
546549
Menu.defaultProps = {
550+
classPrefix: '',
547551
items: [],
548552
aligner: new ALIGNER(),
549553
mouseEnterDelay: MOUSE_ENTER_DELAY,

build/components/MenuItemFactory.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,25 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
2222
var classnames = require('classnames');
2323

2424
var MenuItemFactory = exports.MenuItemFactory = function () {
25-
function MenuItemFactory(renderers) {
25+
function MenuItemFactory(renderers, classPrefix) {
2626
_classCallCheck(this, MenuItemFactory);
2727

2828
this.renderers = renderers;
29+
this.classPrefix = classPrefix;
2930
}
3031

3132
_createClass(MenuItemFactory, [{
3233
key: 'createItem',
3334
value: function createItem(data, key, classes) {
3435
var isExpandable = !!data.items,
3536
renderer = this.renderers[data.type],
36-
className = classnames(classes, {
37-
'menu-item': true,
38-
'menu-item-expandable': isExpandable
39-
});
37+
additions = {},
38+
classPrefix = this.classPrefix,
39+
className;
40+
41+
additions[this.classPrefix + 'menu-item'] = true;
42+
additions[this.classPrefix + 'menu-item-expandable'] = isExpandable;
43+
className = classnames(classes, additions);
4044

4145
if (!renderer) {
4246
throw 'Undefined renderer for type [' + data.type + ']';
@@ -46,7 +50,8 @@ var MenuItemFactory = exports.MenuItemFactory = function () {
4650
data: data,
4751
key: key,
4852
isExpandable: isExpandable,
49-
className: className
53+
className: className,
54+
classPrefix: classPrefix
5055
});
5156
}
5257
}]);

0 commit comments

Comments
 (0)