summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/vertical_layout_view.mm
blob: f2070dbf8506a1f6452413264936ab078bbed7fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "chrome/browser/cocoa/vertical_layout_view.h"

@interface VerticalLayoutView(PrivateMethods)
- (void)layoutChildren;
@end

@implementation VerticalLayoutView

- (id)initWithFrame:(NSRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
    // Turn auto resizing off, we'll be laying out our children programatically.
    [self setAutoresizesSubviews:NO];
    [self setAutoresizingMask:NSViewNotSizable];
  }

  return self;
}

// Flip the coordinate system to arrange child views from top to bottom
// with top at 0, increasing down.  This simplifies the logic and plays
// well with containing scroll views.
- (BOOL)isFlipped {
  return YES;
}

// Override the default |viewWillDraw| to indicate to drawing machinery proper
// arrangement of subviews.
- (void)viewWillDraw {
  // Reposition child views prior to super's descent into its |viewWillDraw|
  // pass.
  [self layoutChildren];

  // Default descent into subviews.
  [super viewWillDraw];

  // Adjust children again to account for any modifications made during the
  // prior descent.  Most importantly we resize our own frame to properly
  // adjust any containing scroll view.
  [self layoutChildren];
}

@end

@implementation VerticalLayoutView(PrivateMethods)

// This method traverses the immediate subviews measuring their height and
// adjusting their frames so they are arranged vertically ordered relative
// to their sibling views.  Note the dependency here on the |isFlipped|
// state.  This code assumes |isFlipped| is YES.
- (void)layoutChildren {
  NSArray* children = [self subviews];
  int childCount = [children count];

  CGFloat yPosition = 0.0;
  for (int i = childCount-1; i >= 0; --i) {
    NSView* child = [children objectAtIndex:i];
    [child setFrameOrigin:NSMakePoint([child frame].origin.x, yPosition)];
    yPosition += [child frame].size.height;
  }

  // Resize self to reflect vertical extent of children.
  [self setFrame:NSMakeRect([self frame].origin.x,
                            [self frame].origin.y,
                            [self frame].size.width,
                            yPosition)];
}

@end