motion-kit / motion-kit

The RubyMotion layout and styling gem. Follow @MotionKit on twitter for updates and commit notifications
MIT License
317 stars 30 forks source link

No top level view specified (missing outer 'create' method?) #98

Closed holgersindbaek closed 9 years ago

holgersindbaek commented 9 years ago

I'm creating an OS X application using the latest motion kit and promotion and I'm getting this error whenever I try to apply some layer styles to one of my views:

2014-12-19 11:54:11.160 Jigsaw • Puzzle[96099:2410487] tree_layout.rb:457:in `create_default_root_context': No top level view specified (missing outer 'create' method?) (MotionKit::NoContextError)
  from base_layout.rb:58:in `target'
  from base_layout.rb:231:in `apply:'
  from base_layout.rb:175:in `method_missing:'
  from main_window_layout.rb:35:in `block in wrapper_style'
  from base_layout.rb:116:in `context:'
  from base_layout.rb:265:in `apply_with_context:'
  from base_layout.rb:250:in `apply:'
  from base_layout.rb:175:in `method_missing:'
  from main_window_layout.rb:34:in `wrapper_style'
  from tree_layout.rb:535:in `block in style_and_context:'
  from base_layout.rb:116:in `context:'
  from tree_layout.rb:533:in `style_and_context:'
  from tree_layout.rb:230:in `add:'
  from main_window_layout.rb:7:in `block in layout'
  from tree_layout.rb:539:in `block in style_and_context:'
  from base_layout.rb:116:in `context:'
  from tree_layout.rb:533:in `style_and_context:'
  from tree_layout.rb:123:in `root:'
  from main_window_layout.rb:6:in `layout'
  from tree_layout.rb:470:in `build_view'
  from tree_layout.rb:72:in `view'
  from nswindow_helpers.rb:9:in `window'
  from main_window_controller.rb:6:in `block in init'
  from main_window_controller.rb:4:in `init'
  from app_delegate.rb:8:in `applicationDidFinishLaunching:'
(main)> 2014-12-19 11:54:11.423 Jigsaw • Puzzle[96099:2410487] base_layout.rb:233:in `apply:': undefined method `corner_radius' for #<MainWindowLayout:0x102fdac90>:MainWindowLayout (NoMethodError)
  from base_layout.rb:175:in `method_missing:'
  from main_window_layout.rb:35:in `block in wrapper_style'
  from base_layout.rb:116:in `context:'
  from base_layout.rb:265:in `apply_with_context:'
  from base_layout.rb:250:in `apply:'
  from base_layout.rb:175:in `method_missing:'
  from main_window_layout.rb:34:in `wrapper_style'
  from tree_layout.rb:535:in `block in style_and_context:'
  from base_layout.rb:116:in `context:'
  from tree_layout.rb:533:in `style_and_context:'
  from tree_layout.rb:230:in `add:'
  from main_window_layout.rb:7:in `block in layout'
  from tree_layout.rb:539:in `block in style_and_context:'
  from base_layout.rb:116:in `context:'
  from tree_layout.rb:533:in `style_and_context:'
  from tree_layout.rb:123:in `root:'
  from main_window_layout.rb:6:in `layout'
  from tree_layout.rb:470:in `build_view'
  from tree_layout.rb:72:in `view'
  from nswindow_helpers.rb:9:in `window'
  from main_window_controller.rb:6:in `block in init'
  from main_window_controller.rb:4:in `init'
  from app_delegate.rb:8:in `applicationDidFinishLaunching:'
2014-12-19 11:54:11.423 Jigsaw • Puzzle[96099:2410487] *nil description*

This is my main_window_controller.rb:

    class MainWindowController < NSWindowController

      def init
        super.tap do
          @layout = MainWindowLayout.new
          self.window = @layout.window
        end
      end
    end

And my main_window_layout.rb:

    class MainWindowLayout < MK::WindowLayout
      def layout
        root(INAppStoreWindow.alloc.initWithContentRect([[0, 0], [1150, 770]],
          styleMask: NSBorderlessWindowMask,
          backing: NSBackingStoreBuffered,
          defer: false), :window) do
          add NSView, :wrapper do
            add NSImageView, :overlay
          end
        end
      end

      def window_style
        width 1150
        height 780
        frame from_center
        opaque false
        movable true
        collection_behavior NSWindowCollectionBehaviorDefault
        level NSFloatingWindowLevel
        alpha_value 1
        hasShadow false
        delegate self
        background_color NSColor.colorWithPatternImage('Background'.nsimage)
        movable_by_window_background true
        level NSNormalWindowLevel
      end

      def wrapper_style
        top 10
        left 10
        width 1130
        height 760
        layer do
          corner_radius 7.0
        end
      end

      def overlay_style
        top 0
        left 0
        width 1130
        height 740
        image 'Overlay'.nsimage
        layer do
          border_width 1.0
        end
      end
    end

I'm using a custom NSWindow class and I think that might have something to do with it. Any guesses on what this might be about?

jamonholmgren commented 9 years ago

Edited code blocks for formatting.

holgersindbaek commented 9 years ago

@jamonholmgren Any suggestions to what this might be about? Is there anything I'm doing wrong?

holgersindbaek commented 9 years ago

@jamonholmgren No suggestions whatsoever?

colinta commented 9 years ago

Ah, I think I see. layer returns nil. So nil is the context in the block your trace mentions.

holgersindbaek commented 9 years ago

@colinta Ok. I still don't understand what I'm doing wrong here?

colinta commented 9 years ago
      def wrapper_style
        top 10
        left 10
        width 1130
        height 760
        layer do  # <= layer is nil
          corner_radius 7.0
        end
      end

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/index.html#//apple_ref/doc/uid/20000014-SW58

Fix:
        wants_layer true  # add this and...
        layer do  # ...layer is no longer nil!
holgersindbaek commented 9 years ago

@colinta @jamonholmgren That worked. Silly me. Thanks a lot.