123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- //
- // MAAttachedWindow.h
- //
- // Created by Matt Gemmell on 27/09/2007.
- // Copyright 2007 Magic Aubergine.
- //
- #import <Cocoa/Cocoa.h>
- /*
- Below are the positions the attached window can be displayed at.
-
- Note that these positions are relative to the point passed to the constructor,
- e.g. MAPositionBottomRight will put the window below the point and towards the right,
- MAPositionTop will horizontally center the window above the point,
- MAPositionRightTop will put the window to the right and above the point,
- and so on.
-
- You can also pass MAPositionAutomatic (or use an initializer which omits the 'onSide:'
- argument) and the attached window will try to position itself sensibly, based on
- available screen-space.
-
- Notes regarding automatically-positioned attached windows:
-
- (a) The window prefers to position itself horizontally centered below the specified point.
- This gives a certain enhanced visual sense of an attachment/relationship.
-
- (b) The window will try to align itself with its parent window (if any); i.e. it will
- attempt to stay within its parent window's frame if it can.
-
- (c) The algorithm isn't perfect. :) If in doubt, do your own calculations and then
- explicitly request that the window attach itself to a particular side.
- */
- typedef enum _MAWindowPosition {
- // The four primary sides are compatible with the preferredEdge of NSDrawer.
- MAPositionLeft = NSMinXEdge, // 0
- MAPositionRight = NSMaxXEdge, // 2
- MAPositionTop = NSMaxYEdge, // 3
- MAPositionBottom = NSMinYEdge, // 1
- MAPositionLeftTop = 4,
- MAPositionLeftBottom = 5,
- MAPositionRightTop = 6,
- MAPositionRightBottom = 7,
- MAPositionTopLeft = 8,
- MAPositionTopRight = 9,
- MAPositionBottomLeft = 10,
- MAPositionBottomRight = 11,
- MAPositionAutomatic = 12
- } MAWindowPosition;
- @interface MAAttachedWindow : NSWindow {
- NSColor *borderColor;
- float borderWidth;
- float viewMargin;
- float arrowBaseWidth;
- float arrowHeight;
- BOOL hasArrow;
- float cornerRadius;
- BOOL drawsRoundCornerBesideArrow;
-
- @private
- NSColor *_MABackgroundColor;
- __weak NSView *_view;
- __weak NSWindow *_window;
- NSPoint _point;
- MAWindowPosition _side;
- float _distance;
- NSRect _viewFrame;
- BOOL _resizing;
- }
- /*
- Initialization methods
-
- Parameters:
-
- view The view to display in the attached window. Must not be nil.
-
- point The point to which the attached window should be attached. If you
- are also specifying a parent window, the point should be in the
- coordinate system of that parent window. If you are not specifying
- a window, the point should be in the screen's coordinate space.
- This value is required.
-
- window The parent window to attach this one to. Note that no actual
- relationship is created (particularly, this window is not made
- a childWindow of the parent window).
- Default: nil.
-
- side The side of the specified point on which to attach this window.
- Default: MAPositionAutomatic.
-
- distance How far from the specified point this window should be.
- Default: 0.
- */
- - (MAAttachedWindow *)initWithView:(NSView *)view // designated initializer
- attachedToPoint:(NSPoint)point
- inWindow:(NSWindow *)window
- onSide:(MAWindowPosition)side
- atDistance:(float)distance;
- - (MAAttachedWindow *)initWithView:(NSView *)view
- attachedToPoint:(NSPoint)point
- inWindow:(NSWindow *)window
- atDistance:(float)distance;
- - (MAAttachedWindow *)initWithView:(NSView *)view
- attachedToPoint:(NSPoint)point
- onSide:(MAWindowPosition)side
- atDistance:(float)distance;
- - (MAAttachedWindow *)initWithView:(NSView *)view
- attachedToPoint:(NSPoint)point
- atDistance:(float)distance;
- - (MAAttachedWindow *)initWithView:(NSView *)view
- attachedToPoint:(NSPoint)point
- inWindow:(NSWindow *)window;
- - (MAAttachedWindow *)initWithView:(NSView *)view
- attachedToPoint:(NSPoint)point
- onSide:(MAWindowPosition)side;
- - (MAAttachedWindow *)initWithView:(NSView *)view
- attachedToPoint:(NSPoint)point;
- // Accessor methods
- - (void)setPoint:(NSPoint)point side:(MAWindowPosition)side;
- - (NSColor *)borderColor;
- - (void)setBorderColor:(NSColor *)value;
- - (float)borderWidth;
- - (void)setBorderWidth:(float)value; // See note 1 below.
- - (float)viewMargin;
- - (void)setViewMargin:(float)value; // See note 2 below.
- - (float)arrowBaseWidth;
- - (void)setArrowBaseWidth:(float)value; // See note 2 below.
- - (float)arrowHeight;
- - (void)setArrowHeight:(float)value; // See note 2 below.
- - (float)hasArrow;
- - (void)setHasArrow:(float)value;
- - (float)cornerRadius;
- - (void)setCornerRadius:(float)value; // See note 2 below.
- - (float)drawsRoundCornerBesideArrow; // See note 3 below.
- - (void)setDrawsRoundCornerBesideArrow:(float)value; // See note 2 below.
- - (void)setBackgroundImage:(NSImage *)value;
- - (NSColor *)windowBackgroundColor; // See note 4 below.
- - (void)setBackgroundColor:(NSColor *)value;
- /*
- Notes regarding accessor methods:
-
- 1. The border is drawn inside the viewMargin area, expanding inwards; it does not
- increase the width/height of the window. You can use the -setBorderWidth: and
- -setViewMargin: methods together to achieve the exact look/geometry you want.
- (viewMargin is the distance between the edge of the view and the window edge.)
-
- 2. The specified setter methods are primarily intended to be used _before_ the window
- is first shown. If you use them while the window is already visible, be aware
- that they may cause the window to move and/or resize, in order to stay anchored
- to the point specified in the initializer. They may also cause the view to move
- within the window, in order to remain centered there.
-
- Note that the -setHasArrow: method can safely be used at any time, and will not
- cause moving/resizing of the window. This is for convenience, in case you want
- to add or remove the arrow in response to user interaction. For example, you
- could make the attached window movable by its background, and if the user dragged
- it away from its initial point, the arrow could be removed. This would duplicate
- how Aperture's attached windows behave.
-
- 3. drawsRoundCornerBesideArrow takes effect when the arrow is being drawn at a corner,
- i.e. when it's not at one of the four primary compass directions. In this situation,
- if drawsRoundCornerBesideArrow is YES (the default), then that corner of the window
- will be rounded just like the other three corners, thus the arrow will be inset
- slightly from the edge of the window to allow room for the rounded corner. If this
- value is NO, the corner beside the arrow will be a square corner, and the other
- three corners will be rounded.
-
- This is useful when you want to attach a window very near the edge of another window,
- and don't want the attached window's edge to be visually outside the frame of the
- parent window.
-
- 4. Note that to retrieve the background color of the window, you should use the
- -windowBackgroundColor method, instead of -backgroundColor. This is because we draw
- the entire background of the window (rounded path, arrow, etc) in an NSColor pattern
- image, and set it as the backgroundColor of the window.
- */
- @end
|