I'm developing a simple screen capture program under Mac OS, I set the main window to be transparent, and use a NSBox instance contained in main window to specify the area to be captured, here are the significant code and main interface of my program(sorry, no reputation to public image):
capturedImage = CGDisplayCreateImage( kCGDirectMainDisplay );//capture the whole screen
NSRect boxRect = [mBox borderRect];//mBox is an instance of NSBox, lies in main window
capturedImage = CGImageCreateWithImageInRect(capturedImage, boxRect);//obtain an image specified by mBox
I cannot get the right image as I want, I know there may be something wrong with the coordinates but I cannot figure it out, can someone help me with this?
another one, there are 3 buttons on the main window, I want them fixed on the right bottom of main window as I drag and resize the main window, but I have no idea about the layout schema of Interface Builder, is there any good solution? better be real useful code with comments. Thanks very much.
You need to read up about coordinate systems. Your NSBox instance is a view, and asking for its borderRect will return a rect in window coordinates.
You need the rectangle to be in the screen coordinate system, because your whole screen image uses that coordinate system. You can use this method to convert the rect:
NSRect screenBoxRect = [[mBox window] convertRectToScreen:[mBox frame]];
Related
I'm writing a program that needs to get the mouse position in the screen, (not just my view). I need to continuously update variables xPos and yPos. I've heard about subclassing nsview and adding mouseDidMove, but it is never called. (Yes, I set my window view to my custom view.) How can I do this?
You need to set the NSWindow which contains the view to window.acceptMouseMovedEvents = yes. Also if you're just looking for mouse position in the screen consider NSEvent.mouseLocation
I'm using Window Services' CGWindowListCreate and CGWindowListCreateDescriptionFromArray to get window information. When getting kCGWindowBounds in a regular Space everything works fine (I'm drawing borders around the frontmost window on the 0th level). However, when I use the same method while on a fullscreen application's Space, I get nonsense bounds: (0, 855, 480, 1).
I wouldn't care much about this if there was an easy way to tell if I'm currently at a fullscreen app's Space, because then I'd just draw a border around the screen (well... it would depend if the menu bar is showing...).
Is this a bug, or is there a reason for this behavior?
EDIT:
Figured out my problem. It's a bigger issue than I would have liked. The thing is the API goes through ALL NSWindows, even the ones that aren't, well, normal windows. Chrome's loading bar on the bottom is a window by itself, for example, and Mail also has some window on the top of the app. This is a problem because I have no way to differentiate the window that looks to be frontmost.
For my app, I would like to capture a specific window to intercept mouse events in it. I would have liked to be able to have the user press a hotkey and then click on the desired window to select, but there is no API to get the window under the cursor. I have no clue how to proceed.
Edit 2:
To better help people find a useful answer, changed title from: "Quartz Window Services returning wrong window bounds for fullscreen apps"
Have you got these methods defined for the window delegate?
- (NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
{
NSRect mainDisplayRect = [[NSScreen mainScreen] frame];
CGSize cgScreenSize = CGSizeMake(mainDisplayRect.size.width, mainDisplayRect.size.height);
return cgScreenSize;
}
- (void)windowWillEnterFullScreen:(NSNotification *)notification
{
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification
{
}
- (void)windowWillExitFullScreen:(NSNotification *)notification
{
}
I proceeded by going through the description dictionaries and checking if the current cursor position was inside the bounds of the windows. The first window to satisfy this would be the window right under the cursor, which is exactly what I needed.
Separately, to find the current top-most window, I used the iChat Apple example of the Accessibility API to register ApplicationActivatedNotification and MainWindowDidChangeNotifications. Both notifications combined would let me keep track of the main window of the active app (top-most). To get the bounds in this case, I just got the main window's position and size using the Accessibility API.
I'm trying to horizontally align my UILable for iPhone screen, by there is no x or left in mylable properties.
How can center-align it on the screen?
The property you are looking for is the frame or center property. In this case, center is probably your best bet. All you need to do is something like this:
CGPoint newCenter = myLabel.center;
newCenter.x = self.view.center.x;
myLabel.center = newCenter;
or
myLabel.center = CGPointMake ( self.view.center.x, myLabel.center.y );
There are more advanced ways of maintaining center alignment using autolayout, or the autoresizingmask. If you are interested in learning about them (autolayout being the most robust and in some ways user friendly) I recommend watching the WWDC 2012 sessions about Auto Layout
The best way to determine what types of properties an object has is to use the class reference. When you first look at UILabel class reference you'll see there are no properties for adjusting the view of the label.
But if you look at the very top you can see where UILabel inherits from. You can see it inherits from UIView, which makes sense to look at for what you need since you're asking how to adjust the labels position on the screen (the view).
Click on UIView and you'll be taken directly to it's reference. Scroll down until you see a list of "Tasks" under which there are several categories, each with a number of properties. You're interested in the "Bounds and Frame Rectangles" category in which there is a property called "frame".
By now we've determined we can set the UILabels frame via myLabel.view.frame
But you may be wondering how to set a frame and so you need to click on 'frame' in the class reference you've been looking at.
You'll see that frame is of type CGRect, so you can use CGRectMake to set the frame. But now you're asking how do I do that, so we click on the CGRect reference.
And you can see that CGRect is a struct made of a CGPoint and a CGSize and if necessary please look those up as well to understand how they are defined.
I took this time to explain the flow of using the docs so that you can do it for yourself in the future. You can survive for awhile on the help of others, but eventually you'll need to just dive into the docs and figure it out for yourself.
In short, you can set the position of your label using the following:
myLabel.frame = CGRectMake(self.view.frame.size.width/2-someWidth/2, self.view.frame.size.height/2-someHeight/2, someWidth, someHeight);
Where someWidth and someHeight are custom variables of float type and self.view is some superview you want to center the label in.
I did not test the code but believe this should work. Good luck to you.
This works:
mylabel.center = CGPointMake(CGRectGetMidX(self.view.bounds), mylabel.center.y);
I am creating an app where bombs come into the screen and blow up this thing that you have to move. How do I make these bombs fly into the screen and move in random directions automatically ? Kind of like fruit ninja where the fruits fly out at you. How do I code that ? What do I need to do ? Please also provide some code. Thank you !
Create a class, called Bomb or something and it needs to have an instance variable and property of CGRect on iOS or NSRect on Mac OS.
Then create a method that can draw the bomb on the screen, like - drawOnScreen or just - draw which knows how to draw the object. Which would contain code like [[UIImage imageNamed:#"bomb1"] drawInRect:self.frame]
Then in your game loop you simple change the coordinates of the frame of such a bomb object to make it move, of course you will need to do that before calling the draw method as it would draw the previous frame then..
There also is another way of adding a subview to the gameview every time you need a new bomb. However a view has more overhead than using the object I described above and would most likely cause your game to run slow if you have like 50/60+ ( wild guess ) bombs.
For controls on the screen like a pause button I would definitely use a view and add it as a subview.
I have a cocoa application that has a finder like feel it and is made up of five views. On the left there is a gallery which is a finder like interface to choose a given object. This view stretches across the whole height of the window. Then on the right I have a window for a 3D simulation view and then below it I have three editing views. I would like to be able to press a button and have the 3d view take over the entire window and then go into fullscreen mode, and I am wondering if a more experienced Cocoa developer could give me some advice on how I might want to try this. Should I be removing all the other subviews then resizing the window and 3d view to the size of the screen or would it make more sense to try and just stretch the 3d view to the size of the screen and push the other interface pieces off the screen that way? I would like to eliminate the menu bar when this occurs to have a real full screen feel for me 3d view.
Look up the NSView method enterFullScreenMode:withOptions:. It's easier than you think.