Forráskód Böngészése

Exposed the Rocket::Core::ElementStyle as a ROCKETCORE_API, so that I could bind it as a Lua object.

Moved the metamethods of LuaType<T> to public, since it is silly to be able to override them, but not be able to use them as a fallback.

Made the bindings for ElementStyle. Documentation on usage is at Source/Core/Lua/ElementStyle.h
Nate Starkey 14 éve
szülő
commit
126b9432b5

BIN
Build/Rocket.ncb


+ 14 - 7
Build/RocketLua.vcproj

@@ -181,6 +181,14 @@
 				RelativePath="..\Source\Core\Lua\Element.h"
 				>
 			</File>
+			<File
+				RelativePath="..\Source\Core\Lua\ElementStyle.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\Source\Core\Lua\ElementStyle.h"
+				>
+			</File>
 			<Filter
 				Name="Document"
 				>
@@ -242,14 +250,17 @@
 				>
 			</File>
 			<File
-				RelativePath="..\Source\Core\Lua\LuaType.cpp"
+				RelativePath="..\Source\Core\Lua\LuaType.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Source\Core\Lua\LuaType.inl"
 				>
 				<FileConfiguration
 					Name="Debug|Win32"
-					ExcludedFromBuild="true"
 					>
 					<Tool
-						Name="VCCLCompilerTool"
+						Name="VCCustomBuildTool"
 					/>
 				</FileConfiguration>
 				<FileConfiguration
@@ -261,10 +272,6 @@
 					/>
 				</FileConfiguration>
 			</File>
-			<File
-				RelativePath="..\Source\Core\Lua\LuaType.h"
-				>
-			</File>
 			<File
 				RelativePath="..\Source\Core\Lua\Register.h"
 				>

+ 163 - 0
Include/Rocket/Core/ElementStyle.h

@@ -0,0 +1,163 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETCOREELEMENTSTYLE_H
+#define ROCKETCOREELEMENTSTYLE_H
+
+#include "ElementDefinition.h"
+#include <Rocket/Core/Types.h>
+
+namespace Rocket {
+namespace Core {
+
+/**
+	Manages an element's style and property information.
+	@author Lloyd Weehuizen
+ */
+
+class ROCKETCORE_API ElementStyle
+{
+public:
+	/// Constructor
+	/// @param[in] element The element this structure belongs to.
+	ElementStyle(Element* element);
+	~ElementStyle();
+
+	/// Returns the element's definition, updating if necessary.
+	const ElementDefinition* GetDefinition();
+	
+	/// Update this definition if required
+	void UpdateDefinition();
+
+	/// Sets or removes a pseudo-class on the element.
+	/// @param[in] pseudo_class The pseudo class to activate or deactivate.
+	/// @param[in] activate True if the pseudo-class is to be activated, false to be deactivated.
+	void SetPseudoClass(const String& pseudo_class, bool activate);
+	/// Checks if a specific pseudo-class has been set on the element.
+	/// @param[in] pseudo_class The name of the pseudo-class to check for.
+	/// @return True if the pseudo-class is set on the element, false if not.
+	bool IsPseudoClassSet(const String& pseudo_class) const;
+	/// Gets a list of the current active pseudo classes
+	const PseudoClassList& GetActivePseudoClasses() const;
+
+	/// Sets or removes a class on the element.
+	/// @param[in] class_name The name of the class to add or remove from the class list.
+	/// @param[in] activate True if the class is to be added, false to be removed.
+	void SetClass(const String& class_name, bool activate);
+	/// Checks if a class is set on the element.
+	/// @param[in] class_name The name of the class to check for.
+	/// @return True if the class is set on the element, false otherwise.
+	bool IsClassSet(const String& class_name) const;
+	/// Specifies the entire list of classes for this element. This will replace any others specified.
+	/// @param[in] class_names The list of class names to set on the style, separated by spaces.
+	void SetClassNames(const String& class_names);
+	/// Return the active class list.
+	/// @return A string containing all the classes on the element, separated by spaces.
+	String GetClassNames() const;
+
+	/// Sets a local property override on the element.
+	/// @param[in] name The name of the new property.
+	/// @param[in] property The new property to set.
+	bool SetProperty(const String& name, const String& value);
+	/// Sets a local property override on the element to a pre-parsed value.
+	/// @param[in] name The name of the new property.
+	/// @param[in] property The parsed property to set.
+	bool SetProperty(const String& name, const Property& property);
+	/// Removes a local property override on the element; its value will revert to that defined in
+	/// the style sheet.
+	/// @param[in] name The name of the local property definition to remove.
+	void RemoveProperty(const String& name);
+	/// Returns one of this element's properties. If this element is not defined this property, or a parent cannot
+	/// be found that we can inherit the property from, the default value will be returned.
+	/// @param[in] name The name of the property to fetch the value for.
+	/// @return The value of this property for this element, or NULL if no property exists with the given name.
+	const Property* GetProperty(const String& name);
+	/// Returns one of this element's properties. If this element is not defined this property, NULL will be
+	/// returned.
+	/// @param[in] name The name of the property to fetch the value for.
+	/// @return The value of this property for this element, or NULL if this property has not been explicitly defined for this element.
+	const Property* GetLocalProperty(const String& name);
+	/// Resolves one of this element's properties. If the value is a number or px, this is returned. If it's a 
+	/// percentage then it is resolved based on the second argument (the base value).
+	/// @param[in] name The name of the property to resolve the value for.
+	/// @param[in] base_value The value that is scaled by the percentage value, if it is a percentage.
+	/// @return The value of this property for this element.
+	float ResolveProperty(const String& name, float base_value);
+
+	/// Iterates over the properties defined on the element.
+	/// @param[inout] index Index of the property to fetch. This is incremented to the next valid index after the fetch. Indices are not necessarily incremental.
+	/// @param[out] pseudo_classes The pseudo-classes the property is defined by.
+	/// @param[out] name The name of the property at the specified index.
+	/// @param[out] property The property at the specified index.
+	/// @return True if a property was successfully fetched.
+	bool IterateProperties(int& index, PseudoClassList& pseudo_classes, String& name, const Property*& property);
+
+	/// Returns the active style sheet for this element. This may be NULL.
+	StyleSheet* GetStyleSheet() const;
+
+	/// Mark definition and all children dirty
+	void DirtyDefinition();
+	/// Dirty all child definitions
+	void DirtyChildDefinitions();
+
+	// Dirties every property.
+	void DirtyProperties();
+	// Dirties em-relative properties.
+	void DirtyEmProperties();
+	// Dirties font-size on child elements if appropriate.
+	void DirtyInheritedEmProperties();
+
+private:
+	// Sets a single property as dirty.
+	void DirtyProperty(const String& property);
+	// Sets a list of properties as dirty.
+	void DirtyProperties(const PropertyNameList& properties);
+	// Sets a list of our potentially inherited properties as dirtied by an ancestor.
+	void DirtyInheritedProperties(const PropertyNameList& properties);
+
+	// Element these properties belong to
+	Element* element;
+
+	// The list of classes applicable to this object.
+	StringList classes;
+	// This element's current pseudo-classes.
+	PseudoClassList pseudo_classes;
+
+	// Any properties that have been overridden in this element;
+	PropertyDictionary* local_properties;
+	// The definition of this element; if this is NULL one will be fetched from the element's style.
+	ElementDefinition* definition;
+	// Set if a new element definition should be fetched from the style.
+	bool definition_dirty;
+	// Set if a child element has a dirty style definition
+	bool child_definition_dirty;
+};
+
+}
+}
+
+#endif

+ 1 - 1
Source/Core/ElementStyle.h

@@ -39,7 +39,7 @@ namespace Core {
 	@author Lloyd Weehuizen
  */
 
-class ElementStyle
+class ROCKETCORE_API ElementStyle
 {
 public:
 	/// Constructor

+ 4 - 3
Source/Core/Lua/Element.cpp

@@ -1,3 +1,4 @@
+#include "LuaType.h"
 #include "precompiled.h"
 #include "Element.h"
 #include <ElementStyle.h>
@@ -201,7 +202,7 @@ int ElementScrollIntoView(lua_State* L, Element* obj)
 
 int ElementSetAttribute(lua_State* L, Element* obj)
 {
-    //fuck this
+    //do this later
     return 0;
 }
 
@@ -466,8 +467,8 @@ int ElementGetAttrscroll_width(lua_State* L)
 int ElementGetAttrstyle(lua_State* L)
 {
     Element* ele = LuaType<Element>::check(L,1);
-    //Make a "ElementStyle" object
-    return 0;
+    LuaType<ElementStyle>::push(L,ele->GetStyle(),false);
+    return 1;
 }
 
 int ElementGetAttrtag_name(lua_State* L)

+ 1 - 1
Source/Core/Lua/Element.h

@@ -54,7 +54,7 @@ int ElementGetAttrscroll_height(lua_State* L);
 int ElementGetAttrscroll_left(lua_State* L);
 int ElementGetAttrscroll_top(lua_State* L);
 int ElementGetAttrscroll_width(lua_State* L);
-int ElementGetAttrstyle(lua_State* L); //make sure to create a "style" object
+int ElementGetAttrstyle(lua_State* L);
 int ElementGetAttrtag_name(lua_State* L);
 
 //setters

+ 128 - 0
Source/Core/Lua/ElementStyle.cpp

@@ -0,0 +1,128 @@
+#include "precompiled.h"
+#include "LuaType.h"
+#include "lua.hpp"
+#include "ElementStyle.h"
+#include <ElementStyle.h>
+
+namespace Rocket {
+namespace Core {
+namespace Lua {
+
+template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index)
+{
+    lua_pushcfunction(L,ElementStyle__index);
+    lua_setfield(L,metatable_index,"__index");
+
+    lua_pushcfunction(L,ElementStyle__newindex);
+    lua_setfield(L,metatable_index,"__newindex");
+}
+
+int ElementStyle__index(lua_State* L)
+{
+    /*the table obj and the missing key are currently on the stack(index 1 & 2) as defined by the Lua language*/
+    int keytype = lua_type(L,2);
+    if(keytype == LUA_TSTRING) //if we are trying to access a string, then we will assume that it is a property
+    {
+        ElementStyle* es = LuaType<ElementStyle>::check(L,1);
+        if(es == NULL)
+        {
+            lua_pushnil(L);
+            return 1;
+        }
+        const Property* prop = es->GetProperty(lua_tostring(L,2));
+        if(prop == NULL)
+        {
+            lua_pushnil(L);
+            return 1;
+        }
+        else
+        {
+            lua_pushstring(L,prop->ToString().CString());
+            return 1;
+        }
+    }
+    else //if it wasn't trying to get a string
+    {
+        lua_settop(L,2);
+        return LuaType<ElementStyle>::index(L);
+    }
+}
+
+int ElementStyle__newindex(lua_State* L)
+{
+    //[1] = obj, [2] = key, [3] = value
+    ElementStyle* es = LuaType<ElementStyle>::check(L,1);
+    if(es == NULL)
+    {
+        lua_pushnil(L);
+        return 1;
+    }
+    int keytype = lua_type(L,2);
+    int valuetype = lua_type(L,3);
+    if(keytype == LUA_TSTRING )
+    {
+        const char* key = lua_tostring(L,2);
+        if(valuetype == LUA_TSTRING)
+        {
+            const char* value = lua_tostring(L,3);
+            lua_pushboolean(L,es->SetProperty(key,value));
+            return 1; 
+        }
+        else if (valuetype == LUA_TNIL)
+        {
+            es->RemoveProperty(key);
+            return 0;
+        }
+    }
+    //everything else returns when it needs to, so we are safe to pass it
+    //on if needed
+
+    lua_settop(L,3);
+    return LuaType<ElementStyle>::newindex(L);
+
+}
+
+
+int ElementStyleGetTable(lua_State* L, ElementStyle* obj)
+{
+    LUACHECKOBJ(obj);
+    int index = 0;
+    String key,sval;
+    const Property* value;
+    PseudoClassList pseudo;
+    lua_newtable(L);
+    while(obj->IterateProperties(index,pseudo,key,value))
+    {
+        lua_pushstring(L,key.CString());
+        value->definition->GetValue(sval,*value);
+        lua_pushstring(L,sval.CString());
+        lua_settable(L,-3);
+    }
+    return 1;
+}
+
+
+RegType<ElementStyle> ElementStyleMethods[] = 
+{
+    LUAMETHOD(ElementStyle,GetTable)
+    { NULL, NULL },
+};
+
+luaL_reg ElementStyleGetters[] = 
+{
+    { NULL, NULL },
+};
+
+luaL_reg ElementStyleSetters[] = 
+{
+    { NULL, NULL },
+};
+
+
+template<> const char* GetTClassName<ElementStyle>() { return "ElementStyle"; }
+template<> RegType<ElementStyle>* GetMethodTable<ElementStyle>() { return ElementStyleMethods; }
+template<> luaL_reg* GetAttrTable<ElementStyle>() { return ElementStyleGetters; }
+template<> luaL_reg* SetAttrTable<ElementStyle>() { return ElementStyleSetters; }
+}
+}
+}

+ 74 - 0
Source/Core/Lua/ElementStyle.h

@@ -0,0 +1,74 @@
+#pragma once
+/*
+    This is the definition of an ElementStyle Lua object
+
+    This object is returned when you have an element, and access Element.style
+    You can access it like a regular table, with the exception of iterating
+    over the properties.
+
+    A few peculiarities/rules:
+    You are unable to create an instance of this object, only use one returned by
+    the "style" value of an 'Element' item. Of course, you can store the object in
+    a local variable in Lua and still have everything be valid
+
+    When setting a property of a style, both the key and value need to be strings
+    --Examples assume "e" is an element object
+    e.style["width"] = "40px"
+    e.style.width = "40px"  --does the same as above
+
+
+    When getting a property of a style, it spits out exactly what you put in.
+    If you used the above width setting to "40px" then
+    --Examples assume "e" is an element object
+    local w = e.style["width"] --or e.style.width
+    w would be "40px"
+
+
+    If you need to iterate over the values, you'll have to call style:GetTable() 
+    Because of the way that I made the object, the following will not work
+    for k,v in pairs(element.style) do --assumes "element" is an element object
+        print(k .. " " ..v)
+    end
+    This is because I don't actually have any properties stored in the Lua table
+    To do it, you'd have to say
+    local properties = element.style:GetTable() --assumes "element" is an element object
+    for k,v in pairs(properties) do
+        print(k .. " " .. v)
+    end
+    However, the table returned from style:GetTable() is read only. Whatever changes you
+    make to that table will not be saved to the 'style' object. To do that, just do whatever
+    operation you were going to on the table before, but do it on the 'style' object instead.
+
+
+
+    At the moment, you are unable to say element.style = {} and have a table of key,value pairs
+    added to the style. That is planned for a little later
+*/
+#include "LuaType.h"
+#include "lua.hpp"
+#include <ElementStyle.h>
+
+namespace Rocket {
+namespace Core {
+namespace Lua {
+
+template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index);
+//We are going to specialize the index/newindex to work with strings, otherwise just call the
+//generalized index/newindex
+int ElementStyle__index(lua_State* L);
+int ElementStyle__newindex(lua_State* L);
+
+//methods
+int ElementStyleGetTable(lua_State* L, ElementStyle* obj);
+
+RegType<ElementStyle> ElementStyleMethods[];
+luaL_reg ElementStyleGetters[];
+luaL_reg ElementStyleSetters[];
+
+template<> const char* GetTClassName<ElementStyle>();
+template<> RegType<ElementStyle>* GetMethodTable<ElementStyle>();
+template<> luaL_reg* GetAttrTable<ElementStyle>();
+template<> luaL_reg* SetAttrTable<ElementStyle>();
+}
+}
+}

+ 15 - 12
Source/Core/Lua/LuaType.h

@@ -28,6 +28,7 @@ namespace Lua {
 #define LUASETTER(type,varname) { #varname, type##SetAttr##varname },
 
 #define CHECK_BOOL(L,narg) (lua_toboolean((L),(narg)) > 0 ? true : false )
+#define LUACHECKOBJ(obj) if(obj == NULL) { lua_pushnil(L); return 1; }
 
 
 //replacement for luaL_reg that uses a different function pointer signature, but similar syntax
@@ -57,17 +58,7 @@ public:
     static void Register(lua_State *L);
     static int push(lua_State *L, T* obj, bool gc=false);
     static T* check(lua_State* L, int narg);
-	
-    //gets called from the Register function, right before _regfunctions.
-    //If you want to inherit from another class, in the function you would want
-    //to call _regfunctions<superclass>, where method is metatable_index - 1. Anything
-    //that has the same name in the subclass will be overwrite whatever had the 
-    //same name in the superclass.
-    static inline void extra_init(lua_State* L, int metatable_index);
-    //Registers methods,getters,and setters to the type
-    static inline void _regfunctions(lua_State* L, int meta, int method);
-private:
-    LuaType(); //hide constructor
+
     //for calling a C closure with upvalues
     static int thunk(lua_State* L);
     //pointer to string
@@ -81,10 +72,22 @@ private:
     static int index(lua_State* L);
     //.__newindex
     static int newindex(lua_State* L);
+	
+    //gets called from the Register function, right before _regfunctions.
+    //If you want to inherit from another class, in the function you would want
+    //to call _regfunctions<superclass>, where method is metatable_index - 1. Anything
+    //that has the same name in the subclass will be overwrite whatever had the 
+    //same name in the superclass.
+    static inline void extra_init(lua_State* L, int metatable_index);
+    //Registers methods,getters,and setters to the type
+    static inline void _regfunctions(lua_State* L, int meta, int method);
+private:
+    LuaType(); //hide constructor
+
 };
 
 }
 }
 }
 
-#include "LuaType.cpp"
+#include "LuaType.inl"

+ 0 - 0
Source/Core/Lua/LuaType.cpp → Source/Core/Lua/LuaType.inl