Backbone.Marionette overriding methods - coffeescript

In 0.9.3, the region manager has changed with the following entry in the changelog:
BREAKING Changed the implementation of Region to allow easier
overriding of how the new view is added to the DOM
What is the best way of overriding the open method?
Currently I am doing the following which does work but I am curious to know what the recommended way is:
_.extend(Backbone.Marionette.Region.prototype, {
open: (view) ->
#$el.after(view.el)
})
This change has also broken some code for me because in some cases I was calling show like this:
region.show(documentsView, 'after')
And in others I was calling it like this:
region.show unitsView
How can I override open to take both these instances into account or do I need to override show?

This works:
_.extend(Backbone.Marionette.Region.prototype, {
show: (view, appendMethod) ->
#ensureEl()
#close()
view.render()
#open(view, appendMethod)
#currentView = view
open: (view, appendMethod) ->
appendMethod = appendMethod || "html"
#$el[appendMethod](view.el)
})

Related

How to override/disable "escapeHandler" of "Dialog" via XML-template in UI5?

I know to override in UI5 the default behavior of sap.m.Dialog's escapeHandler via controller, e.g.:
this._oDialog.setEscapeHandler((oEscapeHandler) => {
oEscapeHandler.reject();
});
The question is it possible to provide an alternative escapeHandler behavior via XML-template without using of setEscapeHandler?
Ideally, it should be something like escapeHandler = "none/customFunction", e.g.:
<Dialog
id = "authDialog"
title = "{i18n>DIALOG_TITLE}"
type = "Message"
escapeHandler = "%CUSTOM_ESCAPE_HANDLER%">
</Dialog>
Particularly, I want to disable a Dialog closing on Esc button press and to do it in an elegant, declarative manner via XML-template, e.g. escapeHandler = "none".
There was a new commit (merged today) that enables assigning controller function to escapeHandler. With that, the below code is now possible:
<Dialog xmlns="sap.m"
id="authDialog"
title="{i18n>DIALOG_TITLE}"
type="Message"
escapeHandler=".handleEscape"
>
handleEscape: function(pEscapePending) {
// Depending on the use case, call pEscapePending.resolve() or pEscapePending.reject() to overwrite the default behavior.
},
The fix should be available with the 1.86 release.
I solved this issue by putting the property escapeHandler = "customFunction" and then having a function with no implementation in the controller. Basically in customFunction I had a comment explaining that this is used to override the default escape behaviour.

validateMenuItem not called for every menu item

I have main menu that has several menu items (File, Edit, View, Window - and more). All menu items have their action set to an operation in FirstResponder.
The application has a single window and that window is of the type MyWindow that inherits from NSWindow (see below).
Note that NSWindow implements NSMenuValidation and hence it is flagged as an error when MyWindow would declare conformance to NSMenuValidation.
I have overriden the function validateMenuItem as follows:
class MyWindow: NSWindow, NSMenuDelegate {
...
override func validateMenuItem(_ item: NSMenuItem) -> Bool {
Log.atDebug?.log("\(item.title)")
....
}
}
When I run the application the validateMenuItem function is called for the File and the Window menu items but not for the Edit and View items.
Note: Log is an instance of a logging framework (SwifterLog).
The actions for all menu items are called correctly. (Also for the menu items for which the validateMenuItem is not called)
It is not difficult for me to work around this problem (the function menuNeedsUpdate is called for all menu's and can be used for this), but I would like to know why this behaviour occurs.
Answer can be found here:
validateMenuItem or menuWillOpen not called for NSMenu
validateMenuItem: belongs to the NSMenuValidation informal protocol;
for it to be called the relevant menu items must have a target.
This is not an answer, but to anyone interested in a work-around:
#objc func menuNeedsUpdate(_ menu: NSMenu) {
Log.atDebug?.log("\(menu.title)")
... // do other stuff
menu.items.forEach( { $0.isEnabled = validateMenuItem($0) } )
}
You must als set the delegate of each menu that must be handled to the MyWindow object (in this example). In my example, the menu of the menu item View must have its delegate set to MyWindow.

On property change event handler

In a VSCode extension I'm looking for a way to react when the user modify an extension property defined in contributes.configuration section of package.json.
Does it exists an event like onPropertyChange or some other way to register an event handler?
After re-reading vscode documentation I found myself an answer:
workspace.onDidChangeConfiguration callback receive a ConfigurationChangeEvent when a config property is modified.
with the method affectsConfiguration it is then possible to react at the specific property change, for example:
export function activate(context: vscode.ExtensionContext) {
vscode.workspace.onDidChangeConfiguration(event => {
let affected = event.affectsConfiguration("riot.compiler");
if (affected) {
// rebuild cpp project settings
setup();
}
})
...

How to setup printing in cocoa, swift?

I have made printing functionality for custom NSView of NSPopover by the assigning the following action to button for this NSView in mainController:
#IBOutlet var plasmidMapIBOutlet: PlasmidMapView!
#IBAction func actionPrintfMap(sender: AnyObject)
{
plasmidMapIBOutlet.print(sender)
}
It is working, but the print window has no option for Paper Size and Orientation, see screenshot below.
What should I do to get these options in the print window?
And, how to make the NSView fitting to the printable area? Now it is not fitting.
I have figured out some moments, but not completely. So, I can setup the printing by the following code
#IBAction func actionPrintMap(sender: AnyObject)
{
let printInfo = NSPrintInfo.sharedPrintInfo()
let operation: NSPrintOperation = NSPrintOperation(view: plasmidMapIBOutlet, printInfo: printInfo)
operation.printPanel.options = NSPrintPanelOptions.ShowsPaperSize
operation.printPanel.options = NSPrintPanelOptions.ShowsOrientation
operation.runOperation()
//plasmidMapIBOutlet.print(sender)
}
But, I still have problem. From the code above I can get only orientation (the last, ShowsOrientation), but not both PaperSize and Orientation. How can I manage both ShowsPaperSize and ShowsOrientation?
Finally I have found the answer which is simple to write but it is not really obvious from apple documentation.
operation.printPanel.options.insert(NSPrintPanelOptions.showsPaperSize)
operation.printPanel.options.insert(NSPrintPanelOptions.showsOrientation)
The problem in the code originally posted is that options is being assigned twice, so the first value assigned, ShowsPaperSize is overwritten by the value ShowsOrientation. That's why you only see the ShowsOrientation option in the dialog.
By using multiple insert operations, you are adding options rather than overwriting each time. You can also do it this way which I think reads better:
operation.printPanel.options.insert([.showsPaperSize, .showsOrientation])
And finally, it also works to "set" the options, and by supplying the existing options as the first array value, you achieve the affect of appending:
operation.printPanel.options = [
operation.printPanel.options,
.showsPaperSize,
.showsOrientation
]
(The first array element operation.printPanel.options means that the old options are supplied in the list of new options.)

Find out if a leaflet control has already been added to the map

I wrote a custom Leaflet control. It's some kind of legend that may be added for each layer. The control itself has a close button to remove it from the map (like a popup).
The control can be added by clicking a button.
My problem is that the user may add the same control to the map several times. So what I need is to test if this specific control has already been added to the map and, if so, don't add it again.
I create a control for each layer, passing some options
var control = L.control.customControl(mylayer);
and add it to my map on button click
control.addTo(map);
Now imagine the control has a close button and may be closed. Now if the user clicks the button again, I only want to add the control if it's not already on the map - something like this (hasControl is pseudocode, there is afaik no such function)
if(!(map.hasControl(control))) {
control.addTo(map);
}
For simplicity I made an example where I create a zoom control and add it twice here.
Easiest way is to check for the existence of the _map property on your control instance:
var customControl = new L.Control.Custom();
console.log(customControl._map); // undefined
map.addControl(customControl);
console.log(customControl._map); // returns map instance
But please keep in mind, when using the _map property, that the _ prefix of the property implies that it's a private property, which you are normally not supposed to use. It could be changed or removed in future versions of Leaflet. You're not going to encounter that if you use the follow approach:
Attaching a reference of your custom control to your L.Map instance:
L.Control.Custom = L.Control.extend({
options: {
position: 'bottomleft'
},
onAdd: function (map) {
// Add reference to map
map.customControl = this;
return L.DomUtil.create('div', 'my-custom-control');
},
onRemove: function (map) {
// Remove reference from map
delete map.customControl;
}
});
Now you can check for the reference on your map instance like so:
if (map.customControl) { ... }
Or create a method and include it in L.Map:
L.Map.include({
hasCustomControl: function () {
return (this.customControl) ? true : false;
}
});
That would work like this:
var customControl = new L.Control.Custom();
map.addControl(customControl);
map.hasCustomControl(); // returns true
map.removeControl(customControl);
map.hasCustomControl(); // returns false
Here's a demo of the concept on Plunker: http://plnkr.co/edit/nH8pZzkB1TzuTk1rnrF0?p=preview