[IMG]http://i182.photobucket.com/albums/x305/Entoros/dml-logo.png[/IMG]
Derma Markup Language, or DML, is an easy-to-use way to create Derma menus with markup similar to HTML. Compare the following two code snippets, and then decide for yourself which one is more conducive to menu creation.
[lua]local frame = vgui.Create("DFrame");
frame:SetSize( 500, 500 );
frame:Center();
frame:SetTitle("My sad little derma frame");
frame:MakePopup();
frame:SetBackgroundBlur(true);
local panel = vgui.Create("DPanel",frame);
panel:SetPos( 5, 25 );
panel:SetSize( 490, 470 );
local label = vgui.Create("DLabel",panel);
label:SetPos(5,5);
label:SetText("I'm a sad label :(");
label:SetFont("ScoreboardText");
label:SetTextColor( Color(255, 0, 0) );
label:SetExpensiveShadow(true);[/lua]
This transforms into:
[html]<frame width="500" height="500" title="My happy DML frame" blur="true">
<panel x="5" y="25" width="490" height="470">
<label x="5" y="5" font="ScoreboardText" color="FF0000" shadow="true">
I'm a happy label :)
</label>
</panel>
</frame>[/html]
DML eliminates a lot of the unnecessary steps required in making Derma menus, giving advanced developers an easier time with simpler tasks and allowing newer coders with any HTML experience to jump right into Garry's Mod.
[b]Other features include:[/b]
[list]
[*]20+ different tags and counting
[*]Extensive documentation
[*]Simple addon install
[*]Little Lua required
[*]Easy to make new tags
[/list]
For in-depth documentation on using and developing DML, check the Wiki: [url]http://wiki.garrysmod.com/?title=DML_Tutorial[/url] (I will be updating this more in the coming days).
Also, make sure you read the top of the "dml.lua" file in lua/autorun.
[b]To install:[/b]
SVN: [url]http://dml.googlecode.com/svn/trunk/[/url]
Checkout to a folder in your addons.
I'm hesitating to put up a garrysmod.org download just yet because I want to release it first, find the first tirade of bugs, and then hand it out to the unwitting public.
[b]Tag list:[/b][list]
[*]avatar -- Display a player's Steam avatar (AvatarImage).
[*]box -- An item in a <combobox>.
[*]button -- Clickable text element (DButton).
[*]column -- Column name of a DListView.
[*]combobox -- Selectable list of text. (DComboBox)
[*]frame -- Usually your main container for all items (DFrame).
[*]iframe -- An HTML display (HTML).
[*]img -- Displays materials (DImage).
[*]imgbutton -- Displays materials clickably (DImageButton).
[*]label -- Shows text (DLabel).
[*]listitem -- Child of a DPanelList.
[*]listline -- Container for row text in a DListView.
[*]lua -- Runs a Lua script.
[*]marquee -- IE5 YEEHAWW
[*]numslider -- User can select numbers on a number line (DNumSlider).
[*]option -- Child of a <select>.
[*]panel -- Container for objects, similar to HTML <div> (DPanel).
[*]panellist -- Holds items, uses <listitem> for top-level child.
[*]row -- A single row of text in a <listline>.
[*]select -- Has options to choose from (DMultiChoice).
[*]sheet -- Allows tabbed pages (DPropertySheet).
[*]spawnicon -- Displays a model (SpawnIcon).
[*]style -- Emulates CSS. Still a WIP.
[*]sysbutton -- A button, except has little icons.
[*]tab -- A single tab of a <sheet>.[/list]
[b]Sample DML:[/b]
This shows how you can incorporate Lua into your DML (through Panel events like Paint and through the markup itself).
[lua]function drawFrame()
-- DML.This is (currently) the universal reference to the current object to paint.
local self = DML.This;
-- draw code
end
function drawPanel()
-- draw code
end
/* Here's where we start the actual DML. */
-- This creates a new DMLReader.
local dml = DML.New();
local mkup = [[
<frame width="300" height="300" title="DML Example" color="666666" Paint="drawFrame()">
<panel x="10" y="30" width="280" height="260" Paint="drawPanel()">
<numslider x="5" y="5" width="270" min="0" max="600" convar="sv_gravity" text="Gravity"></numslider>
<combobox x="5" y="50" width="130" height="180">
]]
-- You can indeed use Lua in your markup! It does get a bit messy though. It's not quite like PHP and HTML.
for _,v in pairs(player.GetAll()) do mkup = mkup .. "<box>" .. v:Nick() .. "</box>"; end
mkup = mkup .. [[
</combobox>
<button x="5" y="235" width="130">Slay</button>
<listview x="140" y="50" width="135" height="200">
<column>Name</column>
<column>Frags</column>
]]
for _,v in pairs(player.GetAll()) do mkup = mkup .. "<listline><row>" .. v:Nick() .. "</row><row>" .. v:Frags() .. "</row></listline>"; end
mkup = mkup.. [[
</listview>
</panel>
</frame>
]];
-- This reads in the markup.
dml:Read(mkup);
-- This runs the markup.
dml:Open();[/lua]
This produces:
[IMG]http://i182.photobucket.com/albums/x305/Entoros/dml3.png[/IMG]
Yes!!
Fantastic job.
Or you could use DermaDes- uh, nevermind.
All joking aside, this is very cool and appears a lot easier than hand coding a UI. Could you put up a list of tags?
holy shit i just cried tears of joy
How would someone do, for example, frame:GetWide() now?
Or listview:GetSelected()?
[QUOTE=xThaWolfx;27171423]How would someone do, for example, frame:GetWide() now?
Or listview:GetSelected()?[/QUOTE]
:iiam:
This is an interesting concept, however you sacrifice a lot of freedom for simplicity. It is great for beginners however.
[editline]3rd January 2011[/editline]
Looking through your code I have found a potential problem. It doesn't really make a difference in this case because generally you will only have a few instances of the DMLObject, but you should be placing all of your DMLObject methods in a metatable and use setmetatable instead of creating a new set of methods every DML.New call. As you can see from the following example, the way you are currently doing it will create many times more functions than needed, whereas using metatables will only create one set and share them among all of the instances of DMLObject.
[lua]local function newObjectNoMeta()
local obj = {}
function obj:Method()
-- Do something
end
return obj
end
local a = newObjectNoMeta()
local b = newObjectNoMeta()
local c = newObjectNoMeta()
local d = newObjectNoMeta()
print(a.Method)
print(b.Method)
print(c.Method)
print(d.Method)
print("")
local meta = {}
meta.__index = meta
function meta:Method()
-- Do something
end
function newObjectWithMeta()
local obj = {}
return setmetatable(obj, meta)
end
local e = newObjectWithMeta()
local f = newObjectWithMeta()
local g = newObjectWithMeta()
local h = newObjectWithMeta()
print(e.Method)
print(f.Method)
print(g.Method)
print(h.Method)[/lua]
Example output:
[code]function: 006A4B98
function: 006A4BB8
function: 006A4BD8
function: 006A4BF8
function: 006A4C38
function: 006A4C38
function: 006A4C38
function: 006A4C38[/code]
[QUOTE=MakeR;27171710]This is an interesting concept, however you sacrifice a lot of freedom for simplicity. It is great for beginners however.
[editline]3rd January 2011[/editline]
Looking through your code I have found a potential problem. It doesn't really make a difference in this case because generally you will only have a few instances of the DMLObject, but you should be placing all of your DMLObject methods in a metatable and use setmetatable instead of creating a new set of methods every DML.New call. As you can see from the following example, the way you are currently doing it will create many times more functions than needed, whereas using metatables will only create one set and share them among all of the instances of DMLObject.
code[/QUOTE]
Thanks for that. It's now implemented.
[QUOTE=xThaWolfx;27171423]How would someone do, for example, frame:GetWide() now?
Or listview:GetSelected()?[/QUOTE]
You can still access the Derma objects via Lua. I'm currently working on a system such that you can do DML.GetByID(id) to find a specific element's derma object.
I've updated the SVN. I significantly changed the file structure, and added an example (shown in OP).
[QUOTE=Entoros;27186894]Thanks for that. It's now implemented.
You can still access the Derma objects via Lua. I'm currently working on a system such that you can do DML.GetByID(id) to find a specific element's derma object.
I've updated the SVN. I significantly changed the file structure, and added an example (shown in OP).[/QUOTE]
Could you post a pic of what that example makes?
[QUOTE=c-unit;27186931]Could you post a pic of what that example makes?[/QUOTE]
Already there. :eng101:
[QUOTE=Entoros;27187020]Already there. :eng101:[/QUOTE]
That menu is sexy.
In the first example what centers the menu?
[QUOTE=zzaacckk;27190724]In the first example what centers the menu?[/QUOTE]
I'm guessing that if you don't include a x, y parameter then it will auto centre.
Very interesting addon.
This. This is just pure awesomeness.
[QUOTE=zzaacckk;27190724]In the first example what centers the menu?[/QUOTE]
Vexx was correct. All the elements have default values assigned for things like x, y, width, height. The default x,y is (0,0) and default width/height is 100/100. The frame is specially set to center if x or y aren't specified.
Wow! I wish I had seen this closer to when you released this. A neat feature to add could be something along the lines of converting the dml language to Lua (even if it isn't pretty) because any addon thinking to use this would have to package dml with it which isn't prefferable.
[QUOTE=TGiFallen;27508941]Wow! I wish I had seen this closer to when you released this. A neat feature to add could be something along the lines of converting the dml language to Lua (even if it isn't pretty) because any addon thinking to use this would have to package dml with it which isn't prefferable.[/QUOTE]
But... but... :ohdear:
You forgot tooltip for DPropertySheet.AddTab
This seems like a really neat idea, and since I'm much more of a HTML coder than a Lua coder this would be right up my alley.
[QUOTE=TGiFallen;27508941]Wow! I wish I had seen this closer to when you released this. A neat feature to add could be something along the lines of converting the dml language to Lua (even if it isn't pretty) because any addon thinking to use this would have to package dml with it which isn't prefferable.[/QUOTE]
Or a binary module, that would be legit.
[QUOTE=Deuces;27546330]Or a binary module, that would be legit.[/QUOTE]
Uhhh? So you want him to make it so that this Lua script can compile binary modules? Do you have any idea what you are talking about?
[QUOTE=TGiFallen;27550658]Uhhh? So you want him to make it so that this Lua script can compile binary modules? Do you have any idea what you are talking about?[/QUOTE]
I said it would be cool if he made a module that made DML possible, not make his lua compile c++ -_-
[QUOTE=Deuces;27554900]I said it would be cool if he made a module that made DML possible, not make his lua compile c++ -_-[/QUOTE]
DML is already possible, with this Lua script, why make a binary module to do it?
[QUOTE=TGiFallen;27557252]DML is already possible, with this Lua script, why make a binary module to do it?[/QUOTE]
Why not? Less files.
[QUOTE=Deuces;27558192]Why not? Less files.[/QUOTE]
I'm sure you could compile it into one lua file; it dosent have to be binary.
[QUOTE=zzaacckk;27558499]I'm sure you could compile it into one lua file; it dosent have to be binary.[/QUOTE]
how do you compile multiple lua files into one lua file?
holy SHIT that would be messy
[QUOTE=Deuces;27558918]how do you compile multiple lua files into one lua file?[/QUOTE]
Are you serious? You cut and paste the damn code into one file.
[QUOTE=TGiFallen;27577728]Are you serious? You cut and paste the damn code into one file.[/QUOTE]
That's retarded.
Sorry, you need to Log In to post a reply to this thread.