Преглед на файлове

Added theme change support to mojo.app.

Mark Sibly преди 9 години
родител
ревизия
3272066277

+ 20 - 8
modules/mojo/app/app.monkey2

@@ -157,9 +157,24 @@ Class AppInstance
 		
 		SDL_GL_MakeCurrent( _sdlWindow,_sdlGLContext )
 #Endif
-		_defaultFont=Font.Open( "DejaVuSans",16 )
+		_defaultFont=_res.OpenFont( "DejaVuSans",16 )
 		
-		_theme=Theme.Load( GetConfig( "initialTheme","asset::themes/default.json" ) )
+		_theme=New Theme
+		
+		Local themePath:=GetConfig( "initialTheme","default" )
+		
+		Local themeScale:=Float( GetConfig( "initialThemeScale",1 ) )
+		
+		_theme.Load( themePath,New Vec2f( themeScale ) )
+		
+		_theme.ThemeChanged+=Lambda()
+
+			ThemeChanged()
+			
+			RequestRender()
+			
+			UpdateWindows()
+		End
 	End
 	
 	#rem monkeydoc Fallback font.
@@ -174,12 +189,6 @@ Class AppInstance
 	Property Theme:Theme()
 	
 		Return _theme
-		
-	Setter( theme:Theme )
-	
-		_theme=theme
-		
-		ThemeChanged()
 	End
 	
 	#rem monkeydoc True if clipboard text is empty.
@@ -222,6 +231,8 @@ Class AppInstance
 	#end
 	Property KeyView:View()
 	
+		If Not _active Return Null
+	
 		If IsActive( _keyView ) Return _keyView
 		
 		If _modalView Return _modalView
@@ -528,6 +539,7 @@ Class AppInstance
 	Field _touchMouse:Bool=False		'Whether mouse is really touch
 	Field _captureMouse:Bool=False		'Whether to use SDL_CaptureMouse
 	
+	Field _res:=New ResourceManager
 	Field _defaultFont:Font
 	Field _theme:Theme
 

+ 1 - 1
modules/mojo/app/sdl_rwstream.monkey2

@@ -39,7 +39,7 @@ Class SDL_RWStream Extends Stream
 	Closing the filestream also sets its position and length to 0.
 	
 	#end
-	Method Close() Override
+	Method OnClose() Override
 		If Not _rwops Return
 		SDL_RWclose( _rwops )
 		_rwops=Null

+ 48 - 32
modules/mojo/app/skin.monkey2

@@ -1,9 +1,11 @@
 
 Namespace mojo.app
 
+Using std.resource
+
 #rem monkeydoc @hidden
 #end
-Class Skin
+Class Skin Extends Resource
 
 	Property Image:Image()
 		Return _image
@@ -41,11 +43,9 @@ Class Skin
 
 	Function Load:Skin( path:String )
 	
-		Local pixmap:=Pixmap.Load( path )
+		Local pixmap:=Pixmap.Load( path,,True )
 		If Not pixmap Return Null
 		
-		pixmap.PremultiplyAlpha()
-		
 		Return New Skin( pixmap )
 	End
 	
@@ -53,67 +53,83 @@ Class Skin
 	
 	Field _image:Image
 	Field _bounds:Recti
-	Field _rect:Recti
 	
 	Field _x0:Int,_x1:Int,_x2:Int,_x3:Int
 	Field _y0:Int,_y1:Int,_y2:Int,_y3:Int
 	
 	Method New( pixmap:Pixmap )
 	
-		Local _scale:Recti
-		Local _fill:Recti
+		Local stretch:Recti
+		Local padding:Recti
 	
 		For Local x:=1 Until pixmap.Width-1
 			Local p:=pixmap.GetPixelARGB( x,0 )
 			If p=UInt( $ff000000 )
-				If Not _scale.min.x _scale.min.x=x
-				_scale.max.x=x+1
+				If Not stretch.min.x stretch.min.x=x
+				stretch.max.x=x+1
 			Endif
 			p=pixmap.GetPixelARGB( x,pixmap.Height-1 )
 			If p=UInt( $ff000000 )
-				If Not _fill.min.x _fill.min.x=x
-				_fill.max.x=x+1
+				If Not padding.min.x padding.min.x=x
+				padding.max.x=x+1
 			Endif
 		Next
 		
 		For Local y:=1 Until pixmap.Height-1
 			Local p:=pixmap.GetPixelARGB( 0,y )
 			If p=UInt( $ff000000 )
-				If Not _scale.min.y _scale.min.y=y
-				_scale.max.y=y+1
+				If Not stretch.min.y stretch.min.y=y
+				stretch.max.y=y+1
 			Endif
 			p=pixmap.GetPixelARGB( pixmap.Width-1,y )
 			If p=UInt( $ff000000 )
-				If Not _fill.min.y _fill.min.y=y
-				_fill.max.y=y+1
+				If Not padding.min.y padding.min.y=y
+				padding.max.y=y+1
 			Endif
 		Next
 		
-		If _scale.min.x And _scale.min.y
-			pixmap=pixmap.Window( 1,1,pixmap.Width-2,pixmap.Height-2 )
-			If Not _fill.min.x Or Not _fill.min.y _fill=_scale
-			_scale-=New Vec2i( 1,1 )
-			_fill-=New Vec2i( 1,1 )
+		If stretch.min.x And stretch.min.y
+			pixmap=pixmap.Window( 1,1,pixmap.Width-2,pixmap.Height-2 ).Copy()
+			If Not padding.min.x Or Not padding.min.y padding=stretch
+			stretch-=New Vec2i( 1,1 )
+			padding-=New Vec2i( 1,1 )
 		Else
-			_scale=New Recti( pixmap.Width/3,pixmap.Height/3,pixmap.Width*2/3,pixmap.Height*2/3 )
-			_fill=_scale
+			stretch=New Recti( pixmap.Width/2,pixmap.Height/2,pixmap.Width*2+1,pixmap.Height*2+1 )
+			padding=stretch
 		Endif
 		
-		_rect=New Recti( 0,0,pixmap.Width,pixmap.Height )
-		
 		_x0=0
-		_x1=_scale.min.x
-		_x2=_scale.max.x
-		_x3=_rect.max.x
+		_x1=stretch.min.x
+		_x2=stretch.max.x
+		_x3=pixmap.Width
 		
 		_y0=0
-		_y1=_scale.min.y
-		_y2=_scale.max.y
-		_y3=_rect.max.y
+		_y1=stretch.min.y
+		_y2=stretch.max.y
+		_y3=pixmap.Height
 		
 		_image=New Image( pixmap )
-		_bounds=New Recti( -_fill.min,_rect.max-_fill.max )
-	
+
+		_bounds=New Recti( -padding.min.x,-padding.min.y,_x3-padding.max.x,_y3-padding.max.y )
+		
+		AddDependancy( _image )
 	End
 End
 
+Class ResourceManager Extension
+
+	Method OpenSkin:Skin( path:String )
+	
+		Local slug:="Skin:name="+StripDir( StripExt( path ) )
+		
+		Local skin:=Cast<Skin>( OpenResource( slug ) )
+		If skin Return skin
+		
+		Local pixmap:=OpenPixmap( path,,True )
+		If pixmap skin=New Skin( pixmap )
+
+		AddResource( slug,skin )
+		Return skin
+	End
+
+End

+ 11 - 1
modules/mojo/app/style.monkey2

@@ -12,10 +12,19 @@ Class Style
 		Init( style )
 	End
 	
+	Method New( name:String,style:Style )
+		_name=name
+		Init( style )
+	End
+	
 	Method Copy:Style()
 		Return New Style( Self )
 	End
 	
+	Method Set( style:Style )
+		Init( style )
+	End
+	
 	Method GetState:Style( name:String )
 		Local state:=_states[name]
 		If Not state Return Self
@@ -256,7 +265,7 @@ Class Style
 		Local bgcolor:=BackgroundColor
 		If bgcolor.a
 			canvas.Color=bgcolor
-			canvas.DrawRect( bounds.X,bounds.Y,bounds.Width,bounds.Height )
+			canvas.DrawRect( bounds )
 		Endif
 		
 		Local skin:=Skin
@@ -309,6 +318,7 @@ Class Style
 		_iconColor=style._iconColor
 		_icons=style._icons.Slice( 0 )
 		_font=style._font
+		_states.Clear()
 		If style._states
 			For Local it:=Eachin style._states
 				_states[it.Key]=New Style( it.Value )

+ 146 - 110
modules/mojo/app/theme.monkey2

@@ -3,26 +3,28 @@ Namespace mojo.app
 
 Class Theme
 
-	Property Path:String()
+	Field ThemeChanged:Void()
 
-		Return _themePath
+	Method New()
+		_defaultStyle=New Style
+		_defaultStyle.Font=App.DefaultFont
 	End
 	
-	Property DefaultStyle:Style()
-	
-		Return _defaultStyle
-	End
+	Property Scale:Vec2f()
 	
-	#rem monkeydoc Gets a color from the theme.
+		Return _themeScale
 	
-	If no color named `name` is found, [[Color.Grey]] is returned.
+	Setter( scale:Vec2f )
+		If scale=_themeScale Return
+		
+		_themeScale=scale
+		
+		Reload()
+	End
 	
-	#end
-	Method GetColor:Color( name:String )
+	Property DefaultStyle:Style()
 	
-		If _colors.Contains( name ) Return _colors[name]
-		
-		Return Color.Grey
+		Return _defaultStyle
 	End
 	
 	#rem monkeydoc Gets a font from the theme.
@@ -38,6 +40,18 @@ Class Theme
 		Return App.DefaultFont
 	End
 	
+	#rem monkeydoc Gets a color from the theme.
+	
+	If no color named `name` is found, [[Color.Grey]] is returned.
+	
+	#end
+	Method GetColor:Color( name:String )
+	
+		If _colors.Contains( name ) Return _colors[name]
+		
+		Return Color.Grey
+	End
+	
 	#rem monkeydoc Gets a style from the theme.
 	
 	If no style named `name` is found, the [[DefaultStyle]] for the theme is returned.
@@ -62,26 +76,30 @@ Class Theme
 	* The asset::fonts/ directory.
 	
 	#end
-	Method LoadFont:Font( file:String,size:Int )
+	Method OpenFont:Font( path:String,size:Float )
 	
-		size*=_themeScale
-	
-		Local font:Font
-		
-		If ExtractRootDir( file )
-			font=Font.Open( file,size )
-		Else
-			font=Font.Open( _themeDir+file,size )
-			If Not font 
-				font=Font.Open( "asset::fonts/"+file,size )
-			Endif
-		Endif
+		size*=_themeScale.y
 		
+		Local font:Font
+		If Not ExtractRootDir( path ) font=_res.OpenFont( "theme::"+path,size )
+		If Not font font=_res.OpenFont( path,size )
 		If Not font Return App.DefaultFont
 		
 		Return font
 	End
 	
+	Method OpenImage:Image( path:String )
+	
+		Local image:Image
+		If Not ExtractRootDir( path ) image=_res.OpenImage( "theme::"+path )
+		If Not image image=_res.OpenImage( path )
+		If Not image Return null
+		
+		image.Scale=_themeScale
+		
+		Return image
+	End
+	
 	#rem monkeydoc Loads an array of icon images from a file.
 	
 	Loads an array of icons from an image file.
@@ -92,41 +110,39 @@ Class Theme
 	
 	The number of icons loaded is the width of the image file divided by its height.
 	
-	If `file` is not an absolute path, the file is searched for in the following locations:
-	
-	* The theme's directory.
-	
-	* The asset::images/ directory.
-	
 	#end
-	Method LoadIcons:Image[]( file:String )
+	Method OpenIcons:Image[]( path:String )
 	
-		Local atlas:Image
+		Local slug:="Icons:"+StripDir( StripExt( path ) )
 		
-		If ExtractRootDir( file )
-			atlas=Image.Load( file )
-		Else
-			atlas=Image.Load( _themeDir+file )
-			If Not atlas
-				atlas=Image.Load( "asset::images/"+file )
-			Endif
-		Endif
+		Local icons:=Cast<Icons>( _res.OpenResource( slug ) )
+		If Not icons
 
-		If Not atlas Return Null
-		
-		atlas.Scale=New Vec2f( _themeScale,_themeScale )
-		
-		Local size:=atlas.Height
-		
-		Local n:=atlas.Width/size
+			Local atlas:=OpenImage( path )
+			If Not atlas Return Null
 		
-		Local icons:=New Image[n]
+			Local size:=atlas.Rect.Height
+			Local n:=atlas.Rect.Width/size
+	
+			icons=New Icons
+			icons.atlas=atlas
+			icons.images=New Image[n]
+			
+			For Local i:=0 Until n
+				Local image:=New Image( atlas,New Recti( i*size,0,i*size+size,size ) )
+				icons.images[i]=image
+			Next
+			
+			icons.AddDependancy( atlas )
+
+			_res.AddResource( slug,icons )
+		Endif
 		
-		For Local i:=0 Until n
-			icons[i]=New Image( atlas,New Recti( i*size,0,i*size+size,atlas.Height ) )
+		For Local image:=Eachin icons.images
+			image.Scale=_themeScale
 		Next
 		
-		Return icons
+		Return icons.images
 	End
 	
 	#rem monkeydoc Loads a skin from a file.
@@ -140,77 +156,80 @@ Class Theme
 	* The asset::images/ directory.
 	
 	#end
-	Method LoadSkin:Skin( file:String )
+	Method OpenSkin:Skin( path:String )
 	
 		Local skin:Skin
-
-		If ExtractRootDir( file )
-			skin=Skin.Load( file )
-		Else
-			skin=Skin.Load( _themeDir+file )
-			If Not skin skin=Skin.Load( "asset::images/"+file )
-		Endif
+		If Not ExtractRootDir( path ) skin=_res.OpenSkin( "theme::"+path )
+		If Not skin skin=_res.OpenSkin( path )
 		
 		If Not skin Return Null
 		
-		skin.Image.Scale=New Vec2f( _themeScale,_themeScale )
+		skin.Image.Scale=_themeScale
 		
 		Return skin
 	End
-
-	#rem monkeydoc Loads a theme from a file.
 	
-	#end
-	Function Load:Theme( path:String )
+	Method Load:Bool( path:String,scale:Vec2f=New Vec2f( 1 ) )
+	
+		If Not ExtractRootDir( path ) path="theme::"+path
+		
+		If Not ExtractExt( path ) path+=".json"
 	
 		Local jobj:=JsonObject.Load( path )
-		If Not jobj 
+		If Not jobj
 			Print "Failed to load theme:"+path
-			return New Theme
+			return False
 		Endif
 		
-		Return New Theme( path,jobj )
+		_jcolors=jobj["colors"].ToObject()
+		_jfonts=jobj["fonts"].ToObject()
+		_jstyles=jobj["styles"].ToObject()
+		
+		_themeScale=scale
+		
+		Reload()
+		
+		Return True
 	End
 
 	Private
 	
+	Class Icons Extends Resource
+		Field atlas:Image
+		Field images:Image[]
+	End
+	
 	Const _jdefault:=New JsonString( "default" )
+	
+	Field _res:ResourceManager
 
-#if __TARGET__="android"	
-	Field _themeScale:Int=2
-#else
-	Field _themeScale:Int=1
-#endif
-
-	Field _themePath:String
-	Field _themeDir:String
+	Field _themeScale:Vec2f=New Vec2f( 1,1 )
+	
+	Field _jcolors:StringMap<JsonValue>
+	Field _jfonts:StringMap<JsonValue>
+	Field _jstyles:StringMap<JsonValue>
 	
 	Field _defaultStyle:Style
 	
-	Field _colors:=New StringMap<Color>
 	Field _fonts:=New StringMap<Font>
+	Field _colors:=New StringMap<Color>
 	Field _styles:=New StringMap<Style>
+	Field _cstyles:=New StringMap<Style>
 	
-	Field _jcolors:StringMap<JsonValue>
-	Field _jfonts:StringMap<JsonValue>
-	Field _jstyles:StringMap<JsonValue>
-	
-	Method New()
-		_themePath=""
-		_themeDir=""
-		_defaultStyle=New Style
-		_defaultStyle.Font=App.DefaultFont
+	Method Unload()
+		_fonts.Clear()
+		_colors.Clear()
+		_styles.Clear()
+		_defaultStyle=Null
 	End
 	
-	Method New( path:String,jobj:JsonObject )
-		Self.New()
-	
-		_themePath=path
-		_themeDir=ExtractDir( _themePath )
+	Method Reload()
 	
-		_jcolors=jobj["colors"].ToObject()
-		_jfonts=jobj["fonts"].ToObject()
-		_jstyles=jobj["styles"].ToObject()
+		Unload()
+		
+		Local res:=_res
+		
+		_res=New ResourceManager
 		
 		_defaultStyle=LoadStyle( _jdefault )
 		
@@ -226,9 +245,9 @@ Class Theme
 			LoadStyle( New JsonString( it.Key ) )
 		Next
 		
-		_jcolors=Null
-		_jfonts=Null
-		_jstyles=Null
+		If res res.Discard()
+		
+		ThemeChanged()
 	End
 	
 	Method ToRect:Recti( jrect:JsonValue )
@@ -251,10 +270,10 @@ Class Theme
 			b=arr[3].ToNumber()
 		End
 		
-		l*=_themeScale
-		t*=_themeScale
-		r*=_themeScale
-		b*=_themeScale
+		l=l*_themeScale.x
+		t=t*_themeScale.y
+		r=r*_themeScale.x
+		b=b*_themeScale.y
 		
 		Return New Recti( -l,-t,r,b )
 	End
@@ -349,8 +368,8 @@ Class Theme
 			fname=fname.Slice( 0,i )
 		Endif
 
-		Local font:=LoadFont( fname,fsize )
-
+		Local font:=OpenFont( fname,fsize )
+		
 		_fonts[str]=font
 		
 		Return font
@@ -368,8 +387,8 @@ Class Theme
 		If jstyle.Contains( "border" ) style.Border=ToRect( jstyle["border"] )
 		If jstyle.Contains( "margin" ) style.Margin=ToRect( jstyle["margin"] )
 		
-		If jstyle.Contains( "icons" ) style.Icons=LoadIcons( jstyle["icons"].ToString() )
-		If jstyle.Contains( "skin" ) style.Skin=LoadSkin( jstyle["skin"].ToString() )
+		If jstyle.Contains( "icons" ) style.Icons=OpenIcons( jstyle["icons"].ToString() )
+		If jstyle.Contains( "skin" ) style.Skin=OpenSkin( jstyle["skin"].ToString() )
 
 		If jstyle.Contains( "font" ) style.Font=LoadFont( jstyle["font"] )
 	End
@@ -385,6 +404,8 @@ Class Theme
 		
 		Local jstyle:=jobj.ToObject()
 		
+		'get parent style
+		'
 		Local pstyle:Style
 		
 		If jstyle.Contains( "extends" )
@@ -392,9 +413,21 @@ Class Theme
 		Else
 			pstyle=_defaultStyle
 		Endif
-		
-		Local style:=New Style( pstyle )
-		
+
+		'create new style
+		'		
+		Local style:Style
+		
+		Local cstyle:=_cstyles[str]
+		If cstyle
+			style=cstyle
+			style.Set( pstyle )
+		Else
+			style=New Style( str,pstyle )
+		Endif
+
+		'initialize
+		'		
 		SetStyle( style,jstyle )
 		
 		For Local it:=Eachin style.States
@@ -402,6 +435,8 @@ Class Theme
 			SetStyle( it.Value,jstyle )
 		Next
 		
+		'create states
+		'
 		If jstyle.Contains( "states" )
 		
 			local jstates:=jstyle["states"].ToObject()
@@ -414,7 +449,8 @@ Class Theme
 			Next
 		
 		Endif
-
+		
+		_cstyles[str]=style
 		_styles[str]=style
 		
 		Return style

+ 29 - 25
modules/mojo/app/view.monkey2

@@ -8,8 +8,8 @@ Class View
 	#rem monkeydoc Invoked when a view becomes visble and active.
 	#end
 	Field Activated:Void()
-	
-	#rem monkeydoc Invoked when a view becomes is not longer visble or active.
+
+	#rem monkeydoc Invoked when a view is no longer visble or active.
 	#end
 	Field Deactivated:Void()
 
@@ -19,12 +19,14 @@ Class View
 			_themeSeq=1
 			App.ThemeChanged+=Lambda()
 				_themeSeq+=1
-				If _themeSeq<0 _themeSeq=1
+				If _themeSeq=$40000000 _themeSeq=1
 			End
 		Endif
 		
 		_style=New Style( App.Theme.DefaultStyle )
 		
+		_styleSeq=_themeSeq
+		
 		InvalidateStyle()
 	End
 
@@ -144,7 +146,7 @@ Class View
 	| "float"			| View floats within its layout frame according to the view [[Gravity]].
 	| "fill-x"			| View is resized on the x axis and floats on the y axis.
 	| "fill-y"			| View is resized on the y axis and floats on the x axs.
-	| "stretch"			| View is stretched to fit its layout frame.
+	| "stretch"			| View is stretched non-uniformly to fit its layout frame.
 	| "letterbox"		| View is uniformly stretched on both axii and centered within its layout frame.
 	| "letterbox-int"	| View is uniformly stretched on both axii and centered within its layout frame. Scale factors are integrized.
 
@@ -328,11 +330,9 @@ Class View
 	
 	#rem monkeydoc Adds a child view to this view.
 	
-	AddChildView is normally used internally by 'layout' views. However you can also add a child view to any view
-	directly by calling this method.
+	AddChildView is normally used internally by 'layout' views. However you can also add a child view to any view directly by calling this method.
 	
-	If you use this method to add a child view to a view, it is your responsiblity to also manage the child view's frame using
-	the [[Frame]] property.
+	If you use this method to add a child view to a view, it is your responsiblity to also manage the child view's frame using the [[Frame]] property.
 
 	#end
 	Method AddChildView( view:View )
@@ -540,7 +540,7 @@ Class View
 	#end
 	Method InvalidateStyle()
 	
-		_styleSeq=-1
+		_styleSeq|=$40000000
 		
 		App.RequestRender()
 	End
@@ -551,15 +551,9 @@ Class View
 	
 		If _styleSeq=_themeSeq Return
 		
-		If _styleSeq<>-1
+		Local themeChanged:=(_styleSeq & $3fffffff<>_themeSeq)
 		
-			Local name:=_style.Name
-			If name
-				Local style:=App.Theme.GetStyle( name )
-				If style _style=style
-			Endif
-
-		Endif
+		_styleSeq=_themeSeq
 	
 		_rstyle=_style
 		
@@ -571,8 +565,8 @@ Class View
 		
 		_styleBounds=_rstyle.Bounds
 		
-		_styleSeq=_themeSeq
-				
+		If themeChanged OnThemeChanged()
+		
 		OnValidateStyle()
 	End
 	
@@ -599,10 +593,12 @@ Class View
 		
 		Local size:=OnMeasure()
 		
-		If _minSize.x size.x=Max( size.x,_minSize.x )
-		If _minSize.y size.y=Max( size.y,_minSize.y )
-		If _maxSize.x size.x=Min( size.x,_maxSize.x )
-		If _maxSize.y size.y=Min( size.y,_maxSize.y )
+		Local scale:=App.Theme.Scale
+		
+		If _minSize.x size.x=Max( size.x,Int( _minSize.x*scale.x ) )
+		If _minSize.y size.y=Max( size.y,Int( _minSize.y*scale.y ) )
+		If _maxSize.x size.x=Min( size.x,Int( _maxSize.x*scale.x ) )
+		If _maxSize.y size.y=Min( size.y,Int( _maxSize.y*scale.y ) )
 		
 		_measuredSize=size
 		
@@ -726,7 +722,7 @@ Class View
 	#rem monkeydoc @hidden
 	#end
 	Method Render( canvas:Canvas )
-
+	
 		If Not _visible Return
 		
 		canvas.BeginRender( _bounds,_matrix )
@@ -746,6 +742,14 @@ Class View
 
 	Protected
 	
+	#rem monkeydoc Called during layout if theme has changed.
+	
+	This is called immediately before [[OnValidateStyle]] if the theme has changed.
+
+	#end
+	Method OnThemeChanged() Virtual
+	End
+	
 	#rem monkeydoc Called during layout if [[Style]] or [[StyleState]] have changed.
 
 	Views can use this method to cache [[RenderStyle]] properties if necessary.
@@ -883,7 +887,7 @@ Class View
 	
 	Global _themeSeq:Int
 	
-	Field _styleSeq:Int=-1
+	Field _styleSeq:Int=0
 	
 	Field _parent:View
 	Field _window:Window

+ 10 - 2
modules/mojo/app/window.monkey2

@@ -188,6 +188,13 @@ Class Window Extends View
 	
 	Protected
 	
+	#rem monkeydoc @hidden
+	#end
+	Method OnThemeChanged() override
+	
+		_clearColor=App.Theme.GetColor( "windowClearColor" )
+	End
+	
 	#rem monkeydoc Window event handler.
 	
 	Called when the window is sent a window event.
@@ -358,6 +365,7 @@ Class Window Extends View
 	End
 	
 	Method Init( title:String,rect:Recti,flags:WindowFlags )
+		Style=GetStyle( "Window" )
 	
 		Local x:=(flags & WindowFlags.CenterX) ? SDL_WINDOWPOS_CENTERED Else rect.X
 		Local y:=(flags & WindowFlags.CenterY) ? SDL_WINDOWPOS_CENTERED Else rect.Y
@@ -400,10 +408,10 @@ Class Window Extends View
 		_frame=GetFrame()
 		Frame=_frame
 		
-		_canvas=New Canvas( _frame.Width,_frame.Height )
-		
 		_clearColor=App.Theme.GetColor( "windowClearColor" )
 		
+		_canvas=New Canvas( _frame.Width,_frame.Height )
+		
 		SetWindow( Self )
 		
 		UpdateActive()