DML Tutorial

From GMod Wiki

Jump to: navigation, search
Lua: Introduction to DML
Page white text.png Description:Explains the basics of Derma Markup Language
link=User:Entoros Original Author:Entoros
Calendar.png Created:January 2nd, 2011

Contents

Preface

This is a short introduction to Derma Markup Language, designed to teach you the basics. If you have questions about specific tags, check the documentation in the tag's file. If you have questions about anything else that isn't addressed here, ask in the release thread on Facepunch.

It is necessary that you know at least a little HTML or XML before you try to use DML. Here's a great tutorial on HTML if you need to learn or just could use a refresher: http://w3schools.com/html/default.asp

The Basics

DML syntax is just like HTML. It uses tags to create objects and to indicate the "level" of an object relative to others. Here's a simple frame tag, which you will probably use as the root element in the majority of your menus.

<frame width="100" height="100" blur="true"></frame>

Let's go through each part of the tag.

  1. <frame - This is the opening part of the tag. The "<" signifies a tag, and the next word tells the parser which element to create.
  2. width="100" height="100" - These are simple attributes, width and height. Different tags have different attributes, but generally most tags have the attributes "x", "y", "width", and "height". They are equal to a value in quotes, like a string. Attributes tell the parser additional information about the element it's creating, so you can make more complex menus.
  3. blur="true" - Some attributes take different values than just numbers or strings. Some need boolean values, such as the "blur" attribute which determines whether the frame brings up the background blur. For a true/false attribute, to determine whether the string is true or false it is generally passed through the G.tobool function.
  4. ></frame> - You always need to end the opening tag with a ">" character. The "</frame>" tells the parser that the frame has ended. Any elements after the closing tag will NOT be parented to the tag's object.

With just that, you have Derma Markup. Let's try something a little more difficult now.

Children and the Tree

The core of any DML menu is the Tree. Not like an oak tree, but a computer tree. You always start with the root element, and then branch off from there. In this case, your Tree generally contains a frame and then that frame contains more children. For example,

<frame>
      <panel>
          <label>I'm a child :(</label>
      </panel>
</frame>

Here, the frame is our root element, meaning it always precedes the others and is not parented to anything. The top-level element in a tree is technically only parented to your screen. Then the frame has a panel element, and the panel is parented to the frame since it comes before the frame's closing tag. Lastly, the panel has a label element which is parented to the panel.

Generally, you indent your code each time you go down a level (that is, get a new parent).

Advanced Markup

Now that you have those concepts down, there's really not a whole lot more to teach you about creating DML. Here's a few things you should know though:

Lua in DML

Lua in DML is like PHP in HTML. Sometimes it's a little hacky, but it can be necessary to do the more complex menus and layouts (for instance if you wanted to draw names from a MySQL database or something). You use Lua to create the necessary objects for the DML to run. The DML addon offers the DML library which brings a few handy functions for DML creation. Here's how you create a DML object and parse DML:

local parser = DML.New();
parser:Read("
      <frame>
         <panel>Text goes here</panel>
      </frame>
");
parser:Open();

Note: you would use double brackets "[[" for multiline strings, but the Wiki's Lua parser isn't perfect.

So DML.New creates a new DMLObject, an object that contains several methods for reading/writing/using DML. The ones you worry about the most are DML.New, DMLObject.Read, and DMLObject.Open. New creates the object, Read parses the DML, and Open executes it.

Developing for DML

If you're very familiar with Lua and are interested in developing for DML by creating tags or that sort of thing, I'd be happy to have you. DML is always a work in progress, so all ideas are on the table. If you take a look in the lua/autorun/elements folder in the DML addon, you can find all of the DML elements snug in their own little files. If you want to create a tag, all you have to do is create a file there and register your tag.

Let's take a look at the source for the <img> tag, or the DImage spawn, for a reference.

/*---------------------------------------------------------
   Name: img
   Desc: A DImage. Displays a texture.
   Attributes:
		src: The material to display
		color: The color of the image.
   Example:
		<img src="console/gmod_logo"></img>
---------------------------------------------------------*/
 
local function createElement(class,parent,element)
	local attr,content = element.attributes,element.content;
	local img = vgui.Create("DImage",parent);
	class:SetSizePos(img,attr);
	img:SetImage(attr.src or "VGUI/swepicon");
	img:SetImageColor(attr.color and class:HexToColor(attr.color) or color_white);
	class:HookEvents(element,img,attr);
	return img;
end
 
DML.Register("img",createElement);

Here's all the elements that make up a tag file.

  1. Documentation: Docs are key so people know what the heck you're doing. You should include the name of the tag, a short description, ALL attributes (and a description of those), and a quick example of the tag in action.
  2. The function: To create a tag you only need one thing, and that's a function (a constructor, essentially). In the constructor you create the derma element you want to use and then alter it based on the attributes. In the function, you always need to return the derma object you've created so other objects can be parented to it. This function is passed three arguments:
    1. class: this is the DMLObject, the class which holds the Tree and all of the methods used (Read, Open, etc.) in DML. As shown in the example, the DMLObject has the method "HexToColor" which converts a hex string into a color object. The class also has two common methods, SetSizePos which sets the size and position of object based on the attributes (because x/y/width/height are very common) and HookEvents which allows the user to override Paint or OnMousePressed without you having to do anything.
    2. parent: This is the parent object of type Panel which you should ALWAYS parent the derma element you're creating too (even if it's nil, it'll still work).
    3. element: This is a table of data created by the parser about the tag you're creating an object from. Notably, it includes the data members "attributes" and "content". Attributes is a table of all the attributes in a tag, and content is a table of the content inside a tag.
  3. Registration: Lastly, you need to register the function and tag name with the DML library using the DML.Register function so the parser can access it.

And voila! You can now make your own DML tag to your heart's desire. If you have any questions, make sure to contact Entoros on Facepunch.

Personal tools
Namespaces
Variants
Actions
Navigation
Lua Scripting
Functions
Hooks
Toolbox