My app has a settings window, I want this window to be unique so that a user cannot display two settings windows at the same time. The problem is that I also want the window to be centered compared to the main window. I use this code (in the JS of the main window):
chrome.app.window.create("settings.html",
{
alwaysOnTop: true,
bounds: {
left: Math.round((window.screenX + (($(window).width() - 498) / 2))), // Perfect left position.
top: Math.round((window.screenY + (($(window).height() - 664) / 2))), // Perfect top position.
width: 498,
height: 664
},
frame : "none",
id: "settings",
resizable: false
}
);
The problem is that if an id is specified and a window with a matching id has been shown before, the remembered bounds will be used but I would prefer to set the bounds myself at every creation with the bounds option. Thus if the user moves the window and closes it the position would still be "perfect" at the next creation. Is there a solution to have this behavior?
Thanks for your help.
I'm afraid you can't override this.
You can reposition the window immediately on creation in the callback, using outerBounds.setPosition:
chrome.app.window.create(
"settings.html",
{/*...*/},
function(win) {
win.outerBounds.setPosition(
/*left, top*/
);
}
);
By the way, bounds is deprecated, you should switch to using innerBounds/outerBounds.
Alternatively, you can try to implement your own ID system. Don't use an ID, and check if the window you need is open (identifying it somehow) before creating it.
Related
I have a couple of UIKit pop-up menu buttons with identical menu items on the same screen in a Swift app. The buttons are built by calling a function that uses an array of strings to create the list of menu items.
The problem is that depending on the button's vertical position on the screen, the menu items may appear in the order specified by the function, or reversed. If the button is in the upper half of the screen, the menu items are listed in the correct order. If the button is in the lower half of the screen the menu items are listed in reverse order.
I would prefer the menu items to appear in the same order regardless of the button's position on the screen. I could check the button location and have the menu creation function reverse the order, but that seems kind of clunky. I am hoping there's a cleaner way to override this behaviour.
The code and array used to create the button menus:
let buttonMenuItems = ["Spring","Summer","Autumn","Winter"]
func createAttributeMenu(menuNumber: Int)->UIMenu {
var menuActions: [UIAction] = []
for attribute in buttonMenuItems {
let item = UIAction(title: attribute) { action in
self.updateMenu(menuID: menuNumber, selected: attribute)
}
menuActions.append(item)
}
return UIMenu(title: "", children: menuActions)
}
The result is this:
Versions I'm using now in testing: Xcode 14.1, iOS 16.1, but I have seen this behaviour on earlier versions as well. (back to iOS 14.x)
Starting with iOS 16, there is a .preferredMenuElementOrder property that can be set on the button:
case automatic
A constant that allows the system to choose an ordering strategy according to the current context.
case priority
A constant that displays menu elements according to their priority.
case fixed
A constant that displays menu elements in a fixed order.
Best I can tell (as with many Apple definitions), there is no difference between .automatic and .priority.
From the .priority docs page:
Discussion
This ordering strategy displays the first menu element in the UIMenu closest to the location of the user interaction.
So, we get "reversed" order based on the position of the menu relative to the button.
To keep your defined order:
buttonNearTop.menu = createAttributeMenu(menuNumber: 1)
buttonNearBottom.menu = createAttributeMenu(menuNumber: 2)
if #available(iOS 16.0, *) {
buttonNearBottom.preferredMenuElementOrder = .fixed
buttonNearTop.preferredMenuElementOrder = .fixed
} else {
// out of luck... you get Apple's "priority" ordering
}
I have a requirement where I have add the panel on click on a button.
In the controller function I have written the code like below. I don't get the error in console neither do I get the panel when I click the button.
However when I console.log the panel object I can see the panel is created but not sure why not reflected in the view. suggestions please.
onAddObjectiveClick: function () {
var panel = new Panel({
headerText: "Description",
visible: true,
backgroundDesign: "Solid",
content: new TextArea({
value: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
growing: true,
width: "100%",
height: "263px"
})
});
}
this.getView().addDependent(panel); // at this place I have tried setExapanded and setExpandible function too but none helped.
You are basically creating an object, assigning to a local variable and not adding it to your view.
You should have any kind of container element with an aggregation to add your Panel.
Depending on the container the aggregation name will be different and thus the method you need to call in order to add the Panel to it.
Example: If you need to add this Panel inside the aggregation content of the sap.m.Page class, you should
1) Have the Page
2) Capture it inside the controller
3) call the addContent()
despite no change to my application
programmatically trigering autosave for the window's frame and content size only works usualy once,
I tried differant combination like moving the window around and then cloisng it manualy and yet I still get the same result
I then have to make a new autosave name and then sometimes it works and sometimes it doesn't here's my code
view.window?.contentMinSize = NSSize(width: 310, height: 180) //Sets the view window minimum size.
view.window?.setContentSize(NSSize(width: 510, height: 233)) //Sets the view window normal size.
view.window?.isRestorable = true
view.window?.setFrameUsingName(NSWindow.FrameAutosaveName(rawValue: "autosaveformyapp"))
view.window?.titleVisibility = .visible
view.window?.titlebarAppearsTransparent = true
view.window?.hasShadow = true
view.window?.makeKeyAndOrderFront(nil)
view.window?.initialFirstResponder = view
update:
I also tried to place the auto save line at differant place
like before setting the window size but same result of it only working 1 time and then not working anymore
I've created an app that is a set size (around 2,000 px tall) and have a menu that calls FB.Canvas.scrollTo in order to help the user navigate the long page.
Is there any way to add a smooth scrolling effect? Facebook does not offer any solution on its developer blog.
Using #Jonny's method, you can do this a little more simply with
function scrollTo(y){
FB.Canvas.getPageInfo(function(pageInfo){
$({y: pageInfo.scrollTop}).animate(
{y: y},
{duration: 1000, step: function(offset){
FB.Canvas.scrollTo(0, offset);
}
});
});
}
Just had the same problem today - I came up with a little bit of javascript which makes use of jQuery's animate method which provides some easing - the scroll is still a touch jerky (I'm guessing that's because of the FB.Canvas.scrollTo proxy). Anyway, here's the snippet:
function scrollToTop() {
// We must call getPageInfo() async otherwise we will get stale data.
FB.Canvas.getPageInfo(function (pageInfo) {
// The scroll position of your app's iFrame.
var iFrameScrollY = pageInfo.scrollTop;
// The y position of the div you want to scroll up to.
var targetDivY = $('#targetDiv').position().top;
// Only scroll if the user has scrolled the window beneath the target y position.
if (iFrameScrollY > targetDivY) {
var animOptions = {
// This function will be invoked each 'tick' of the animation.
step: function () {
// As we don't have control over the Facebook iFrame we have to ask the Facebook JS API to
// perform the scroll for us.
FB.Canvas.scrollTo(0, this.y);
},
// How long you want the animation to last in ms.
duration: 200
};
// Here we are going to animate the 'y' property of the object from the 'iFrameScrollY' (the current
// scroll position) to the y position of your target div.
$({ y: iFrameScrollY }).animate({ y: targetDivY }, animOptions);
}
});
}
I just used Francis' technique and implemented a jQuery version
$('html,body').animate(
{scrollTop: $(".scroll_to_me").offset().top},
{duration: 1000, step: function(top_offset){
FB.Canvas.scrollTo(0, top_offset + 30);
}
});
You need to replace the .scroll_to_me with the selector you want to scroll to. Also I added in the + 30 to the offset as the iframe doesn't start at the top of the page, you may want to tweak this.
One way of doing it is by getting the current Y position, then getting the to Y position. Run a for loop with a setTimeout that will bring the user to the final Y position.
When I log myScroll.y and myScrollPagesY, I get this:
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper', {
snap: 'div',
momentum: false});
console.log(myScroll.y);
console.log(myScroll.pagesY);
}
Output:
0
0, -422, -465
So, the default numerical value is 0, but while I scroll I don't see the number change in the console.
Do I have to somehow incorporate the iScroll refresh(); method to constantly update the Y coordinate?
How would I write an if statement that basically said:
if myScroll.y = a certain number then add the class "selected" to the nav button.
Basically, as you are scrolling down the page I want the nav bar at the top to highlight when you hit a new section.
Thanks in advance!
You can use the onScrollMove-event. Attach a method to this iScroll-property. The first argument is the scrollerobject. Now read the y-value.
function onScrollMove(scroller, e) {
//read scroller.y or scroller.currPageY, or whatever property you want to use :)
};