Double click support for project dialogs

double clicking a project in the project dialog now performs the
specified action for the dialog (open / save) on it.
pull/3/merge
jmoenig 2013-04-21 20:40:24 +02:00
rodzic 977da0314c
commit f21416527f
4 zmienionych plików z 944 dodań i 825 usunięć

13
gui.js
Wyświetl plik

@ -68,7 +68,7 @@ sb, CommentMorph, CommandBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.gui = '2013-April-19';
modules.gui = '2013-April-21';
// Declarations
@ -3738,7 +3738,9 @@ ProjectDialogMorph.prototype.setSource = function (source) {
this.projectList.length > 0 ?
function (element) {
return element.name;
} : null
} : null,
null,
function () {myself.ok(); }
);
this.fixListFieldItemColors();
@ -3754,6 +3756,7 @@ ProjectDialogMorph.prototype.setSource = function (source) {
this.listField.action = function (item) {
var src, xml;
if (item === undefined) {return; }
if (myself.nameField) {
myself.nameField.setContents(item.name || '');
}
@ -3775,6 +3778,7 @@ ProjectDialogMorph.prototype.setSource = function (source) {
};
} else { // 'examples', 'cloud' is initialized elsewhere
this.listField.action = function (item) {
if (item === undefined) {return; }
if (myself.nameField) {
myself.nameField.setContents(item.name || '');
}
@ -3852,7 +3856,9 @@ ProjectDialogMorph.prototype.installCloudProjectList = function (pl) {
'bold',
function (proj) {return proj.Public === 'true'; }
]
]
],
null,
function () {myself.ok(); }
);
this.fixListFieldItemColors();
@ -3865,6 +3871,7 @@ ProjectDialogMorph.prototype.installCloudProjectList = function (pl) {
this.listField.drawRectBorder = InputFieldMorph.prototype.drawRectBorder;
this.listField.action = function (item) {
if (item === undefined) {return; }
if (myself.nameField) {
myself.nameField.setContents(item.ProjectName || '');
}

Wyświetl plik

@ -1647,3 +1647,5 @@ ______
130421
------
* using the percent character in variable names is now safe (fixes Github issue #65)
* Morphic: added Doubleclick support, example: inspectors
* GUI: Double clicking a project in the project dialog performs the dialog's action on it (open / save)

Wyświetl plik

@ -147,6 +147,7 @@
III. yet to implement
---------------------
- keyboard support for scroll frames and lists
- virtual keyboard support for Android and IE
IV. open issues
@ -450,6 +451,7 @@
mouseDownRight
mouseClickLeft
mouseClickRight
mouseDoubleClick
mouseEnter
mouseLeave
mouseEnterDragging
@ -1033,7 +1035,7 @@
/*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio,
FileList, getBlurredShadowSupport*/
var morphicVersion = '2013-April-19';
var morphicVersion = '2013-April-21';
var modules = {}; // keep track of additional loaded modules
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
@ -6161,7 +6163,7 @@ InspectorMorph.prototype.setTarget = function (target) {
};
InspectorMorph.prototype.buildPanes = function () {
var attribs = [], property, myself = this, ctrl, ev;
var attribs = [], property, myself = this, ctrl, ev, doubleClickAction;
// remove existing panes
this.children.forEach(function (m) {
@ -6194,6 +6196,20 @@ InspectorMorph.prototype.buildPanes = function () {
return typeof myself.target[prop] === 'function';
});
} // otherwise show all properties
doubleClickAction = function () {
var world, inspector;
if (!isObject(myself.currentProperty)) {return; }
world = myself.world();
inspector = new InspectorMorph(
myself.currentProperty
);
inspector.setPosition(world.hand.position());
inspector.keepWithin(world);
world.add(inspector);
inspector.changed();
};
this.list = new ListMorph(
this.target instanceof Array ? attribs : attribs.sort(),
null, // label getter
@ -6209,10 +6225,13 @@ InspectorMorph.prototype.buildPanes = function () {
}
]
]
: null
: null,
doubleClickAction
);
this.list.action = function (selected) {
var val, txt, cnts;
if (selected === undefined) {return; }
val = myself.target[selected];
myself.currentProperty = val;
if (val === null) {
@ -6228,6 +6247,7 @@ InspectorMorph.prototype.buildPanes = function () {
cnts.setReceiver(myself.target);
myself.detail.setContents(cnts);
};
this.list.hBar.alpha = 0.6;
this.list.vBar.alpha = 0.6;
this.list.contents.step = null;
@ -6609,7 +6629,8 @@ MenuMorph.prototype.addItem = function (
hint,
color,
bold, // bool
italic // bool
italic, // bool
doubleClickAction // optional, when used as list contents
) {
/*
labelString is normally a single-line string. But it can also be one
@ -6625,7 +6646,8 @@ MenuMorph.prototype.addItem = function (
hint,
color,
bold || false,
italic || false]);
italic || false,
doubleClickAction]);
};
MenuMorph.prototype.addLine = function (width) {
@ -6713,7 +6735,8 @@ MenuMorph.prototype.drawNew = function () {
tuple[2], // bubble help hint
tuple[3], // color
tuple[4], // bold
tuple[5] // italic
tuple[5], // italic
tuple[6] // doubleclick action
);
}
if (isLine) {
@ -7910,7 +7933,8 @@ function TriggerMorph(
hint,
labelColor,
labelBold,
labelItalic
labelItalic,
doubleClickAction
) {
this.init(
target,
@ -7922,7 +7946,8 @@ function TriggerMorph(
hint,
labelColor,
labelBold,
labelItalic
labelItalic,
doubleClickAction
);
}
@ -7936,11 +7961,13 @@ TriggerMorph.prototype.init = function (
hint,
labelColor,
labelBold,
labelItalic
labelItalic,
doubleClickAction
) {
// additional properties:
this.target = target || null;
this.action = action || null;
this.doubleClickAction = doubleClickAction || null;
this.environment = environment || null;
this.labelString = labelString || null;
this.label = null;
@ -8067,6 +8094,29 @@ TriggerMorph.prototype.trigger = function () {
}
};
TriggerMorph.prototype.triggerDoubleClick = function () {
// same as trigger() but use doubleClickAction instead of action property
// note that specifying a doubleClickAction is optional
if (!this.doubleClickAction) {return; }
if (typeof this.target === 'function') {
if (typeof this.doubleClickAction === 'function') {
this.target.call(
this.environment,
this.doubleClickAction.call(),
this
);
} else {
this.target.call(this.environment, this.doubleClickAction, this);
}
} else {
if (typeof this.doubleClickAction === 'function') {
this.doubleClickAction.call(this.target);
} else { // assume it's a String
this.target[this.doubleClickAction]();
}
}
};
// TriggerMorph events:
TriggerMorph.prototype.mouseEnter = function () {
@ -8096,6 +8146,10 @@ TriggerMorph.prototype.mouseClickLeft = function () {
this.trigger();
};
TriggerMorph.prototype.mouseDoubleClick = function () {
this.triggerDoubleClick();
};
TriggerMorph.prototype.rootForGrab = function () {
return null;
};
@ -8147,7 +8201,8 @@ function MenuItemMorph(
hint,
color,
bold,
italic
italic,
doubleClickAction // optional when used as list morph item
) {
this.init(
target,
@ -8159,7 +8214,8 @@ function MenuItemMorph(
hint,
color,
bold,
italic
italic,
doubleClickAction
);
}
@ -8859,7 +8915,7 @@ ListMorph.prototype = new ScrollFrameMorph();
ListMorph.prototype.constructor = ListMorph;
ListMorph.uber = ScrollFrameMorph.prototype;
function ListMorph(elements, labelGetter, format) {
function ListMorph(elements, labelGetter, format, doubleClickAction) {
/*
passing a format is optional. If the format parameter is specified
it has to be of the following pattern:
@ -8891,11 +8947,17 @@ function ListMorph(elements, labelGetter, format) {
}
return element.toString();
},
format || []
format || [],
doubleClickAction // optional callback
);
}
ListMorph.prototype.init = function (elements, labelGetter, format) {
ListMorph.prototype.init = function (
elements,
labelGetter,
format,
doubleClickAction
) {
ListMorph.uber.init.call(this);
this.contents.acceptsDrops = false;
@ -8909,6 +8971,7 @@ ListMorph.prototype.init = function (elements, labelGetter, format) {
this.selected = null; // actual element currently selected
this.active = null; // menu item representing the selected element
this.action = null;
this.doubleClickAction = doubleClickAction || null;
this.acceptsDrops = false;
this.buildListContents();
};
@ -8948,7 +9011,8 @@ ListMorph.prototype.buildListContents = function () {
null, // hint
color,
bold,
italic
italic,
myself.doubleClickAction
);
});
this.listContents.setPosition(this.contents.position());
@ -9340,6 +9404,7 @@ HandMorph.prototype.drop = function () {
mouseDownRight
mouseClickLeft
mouseClickRight
mouseDoubleClick
mouseEnter
mouseLeave
mouseEnterDragging
@ -9472,6 +9537,23 @@ HandMorph.prototype.processMouseUp = function () {
this.mouseButton = null;
};
HandMorph.prototype.processDoubleClick = function () {
var morph = this.morphAtPointer();
this.destroyTemporaries();
if (this.children.length !== 0) {
this.drop();
} else {
while (morph && !morph.mouseDoubleClick) {
morph = morph.parent;
}
if (morph) {
morph.mouseDoubleClick(this.bounds.origin);
}
}
this.mouseButton = null;
};
HandMorph.prototype.processMouseMove = function (event) {
var pos,
posInDocument = getDocumentPositionOf(this.world.worldCanvas),
@ -10039,6 +10121,15 @@ WorldMorph.prototype.initEventListeners = function () {
false
);
canvas.addEventListener(
"dblclick",
function (event) {
event.preventDefault();
myself.hand.processDoubleClick(event);
},
false
);
canvas.addEventListener(
"touchend",
function (event) {

Wyświetl plik

@ -9,7 +9,7 @@
Copyright (C) 2012 by Jens Mönig
this documentation last changed: November 07, 2012
this documentation last changed: April 07, 2013
This file is part of Snap!.
@ -148,6 +148,7 @@
III. yet to implement
---------------------
- keyboard support for scroll frames and lists
- virtual keyboard support for Android and IE
IV. open issues
@ -451,6 +452,7 @@
mouseDownRight
mouseClickLeft
mouseClickRight
mouseDoubleClick
mouseEnter
mouseLeave
mouseEnterDragging
@ -579,13 +581,25 @@
Drops of image elements from outside the world canvas are dispatched as
droppedImage(aCanvas, name)
droppedSVG(anImage, name)
events to interested Morphs at the mouse pointer. If you want you Morph
to e.g. import outside images you can add the droppedImage() method to
it. The parameter passed to the event handles is a new offscreen
canvas element representing a copy of the original image element which
can be directly used, e.g. by assigning it to another Morph's image
property.
to e.g. import outside images you can add the droppedImage() and / or the
droppedSVG() methods to it. The parameter passed to the event handles is
a new offscreen canvas element representing a copy of the original image
element which can be directly used, e.g. by assigning it to another
Morph's image property. In the case of a dropped SVG it is an image
element (not a canvas), which has to be rasterized onto a canvas before
it can be used. The benefit of handling SVGs as image elements is that
rasterization can be deferred until the destination scale is known, taking
advantage of SVG's ability for smooth scaling. If instead SVGs are to be
rasterized right away, you can set the
MorphicPreferences.rasterizeSVGs
preference to <true>. In this case dropped SVGs also trigger the
droppedImage() event with a canvas containing a rasterized version of the
SVG.
The same applies to drops of audio or text files from outside the world
canvas.
@ -597,6 +611,11 @@
events to interested Morphs at the mouse pointer.
if none of the above content types can be determined, the file contents
is dispatched as an ArrayBuffer to interested Morphs:
droppedBinary(anArrayBuffer, name)
(e) keyboard events
-------------------