Derma Skin Creation

From Garry's Mod
Jump to: navigation, search

Contents

Introduction

As a developer you may be familiar with PANEL:Paint and PANEL:PaintOver. They are functions to draw your Derma objects. But one day you wanted to make your own Derma design. You may think that redrawing is too complicated: surface library, draw library, render library. So many functions, aren't they? Is there a way to make it easier and fancy? Yes, this page will show you how to create your own Derma Skin. Exactly same method uses default Derma and it's defined in Lua.

How Derma skins work?

First thing to know, they're located in "garrysmod/lua/skins/". Default Derma skin is in "default.lua".
It contains UV texture mapping, Color definitions and Derma Hooks.
UV mapping is possible through GWEN library. Some GWEN functions require a IMaterial in last argument, but it can be empty: GWEN will use SKIN.GwenTexture variable instead. Default skin texture can be found in Garry's Mod .vpk file in "materials/gwenskin/gmoddefault.png".
Inside file there're bunch of Derma Hooks. They're used in conjunction with derma.SkinHook (used in Derma_Hook).

Example

This is in "default.lua".

 

function SKIN:PaintFrame( panel, w, h )

	if ( panel.m_bPaintShadow ) then -- This is DFrame shadow

		DisableClipping( true )
		SKIN.tex.Shadow( -4, -4, w+10, h+10 ) -- This is drawing function, that contains a piece of our texture
		DisableClipping( false )

	end

	if ( panel:HasHierarchicalFocus() ) then -- Checks if DFrame is in focus and decide how to paint it

		self.tex.Window.Normal( 0, 0, w, h ) -- This is drawing function, that contains a piece of our texture

	else

		self.tex.Window.Inactive( 0, 0, w, h ) -- This is drawing function, that contains a piece of our texture

	end

end

And this is in "lua/vgui/dframe.lua" where DFrame is defined.

 

function PANEL:Paint( w, h )

    -- ...

	derma.SkinHook( "Paint", "Frame", self, w, h ) -- This creates hook to derma library, derma library is connected to our skin

    -- ...

end

Last thing that skin file does is adding skin to Derma skins list. This action is done by derma.DefineSkin.

Preparing to create Derma skin

  1. Get Adobe Photoshop
  2. Extract "materials/gwenskin/gmoddefault.psd" (You can do this with GCFScape)
  3. Copy code (or file) from "lua/skins/default.lua"
  4. Create lua file in "lua/skins/". For this tutorial we will name it "myskin.lua".
  5. Create lua file in "lua/autorun/". You can name it how you want it, just make it unique, for example "myskin_include.lua".

Code for myskin_include.lua

 

if SERVER then AddCSLuaFile("skins/myskin.lua") else include("skins/myskin.lua") end

This file adds our skin to whitelist for server and includes for client on load.

Reference

 SKIN

Table SKIN is a global variable. It's made global to work with GWEN library.

 derma.DefineSkin(skin name, skin description, SKIN table)

derma.DefineSkin( "Default", "Made to look like regular VGUI", SKIN )

This function will add your skin to list of all Derma skins.

 derma.GetSkinTable()

for k,v in pairs(derma.GetSkinTable()) do print(k) end -- Prints all defined skins


This function will clear cache from Derma objects and set their skin again.

Tester snippet

To test out your Derma skin you can use this snippet.

 

concommand.Add( "derma_setskin", function(_,_,args)
	if GetConVar("sv_allowcslua"):GetInt() == 0 then return end
	for k,v in pairs(vgui.GetWorldPanel():GetChildren()) do
		v:SetSkin(args[1])
	end
end,nil,"Sets skin for all Derma objects.")
local function deepskin(children,skin)
	for k,v in pairs(children) do
		v:SetSkin(skin)
		if #v:GetChildren() != 0 then deepskin(v:GetChildren(),skin) end
	end
end
concommand.Add( "derma_deepsetskin", function(_,_,args)
	if GetConVar("sv_allowcslua"):GetInt() == 0 then return end
	deepskin(vgui.GetWorldPanel():GetChildren(),args[1])
end,nil,"Forces skin set for all Derma objects and their children.")
concommand.Add( "derma_updateskin", function()
	if GetConVar("sv_allowcslua"):GetInt() == 0 then return end
	for k,v in pairs(derma.GetSkinTable()) do
		if v.GwenTexture then
			local tex = v.GwenTexture:GetTexture("$basetexture")
			if tex then tex:Download() end
		end
	end
	derma.RefreshSkins()
end,nil,"Updates skins for all Derma objects.")

Derma objects can't update themselves because skin that they used is cached. Due to skins are being cached, Derma objects can't update themselves while you're editing. So we need to clear cache by typing command derma_updateskin. Also its material can't update itself, to fix that, it uses ITexture:Download.
Function derma_setskin *skin name* allows you to apply Derma skin on all Derma object through the console. If some panels didn't update use derma_deepsetskin *skin name*.
For safety, you can't use these functions when sv_allowcslua is 0. You can remove this check if you don't forget to remove tester later. To test your skin you can type derma_controls to preview.

Part One: SKIN variables

SKIN table has a lot of variables. These are for info.

SKIN variables. Information variables
Key Value from "default.lua" Description
PrintName My New Skin Name for your skin to display
Author Garry Newman Author of the skin
DermaVersion 1 Version of the skin
GwenTexture
Material( "gwenskin/GModDefault.png" )
Texture path of the skin. This is used to draw Derma objects. This is internally used by GWEN library.

Next you will see lots of Color variables. But not all of them are actually visible in game.
This list contains variables which were tested for changes.

SKIN variables. Color variables
Key Value from "default.lua" Description In game
colTextEntryText
Color( 20, 20, 20 )
Used for typed text color in DTextEntry and it's derivatives DermaSkin colTextEntryText.png
NOTE

Color can display incorrectly in game.

colTextEntryTextHighlight
Color( 20, 200, 250 )
Used for highlight color in DTextEntry and it's derivatives DermaSkin colTextEntryTextHighlight.png
NOTE

Color can display incorrectly in game.

colTextEntryTextCursor
Color( 0, 0, 100 )
Used for cursor color in DTextEntry and it's derivatives DermaSkin colTextEntryTextCursor.png
colTextEntryTextPlaceholder
Color( 128, 128, 128 )
Used for SetPlaceholderText color in DTextEntry and it's derivatives DermaSkin colTextEntryTextPlaceholder.png
NOTE

Color can display incorrectly in game.

Column "In game" note: Right filled square represents real color. Left screenshot represents in-game render.
Other Color variables doesn't work because Derma objects use texture instead.

NOTE

ULX uses SKIN.text_dark for some labels

Part Two: UV Texture

Named Textures

DermaSkin UV Mapping.png
UV mapping zones. Can be found in .psd file in folder "Overlay".
NOTE

Even in UV texture not all of textures are used in GMod!


List of named layers (From left top to right bottom)
Overlay name Category in .psd file Description
Window (In Focus) Window - Active Texture of DFrame when HasHierarchicalFocus is true
Window (Out Focus) Window - Active (copy) Texture of DFrame when HasHierarchicalFocus is false
Generic Panel (Only left top is used) Panels - Generic Panel - Normal Texture of DPanel by default. This texture can be colored by SetBackgroundColor
Btn Nrml Buttons - Regular Texture of DButton when IsHovered is false and IsDown is false
Btn Hvr Buttons - Hovered Texture of DButton when IsHovered is true and IsDown is false
Btn Dsbld Buttons - Dead Texture of DButton when IsEnabled is false
Btn Down Buttons - Down Texture of DButton when IsDown is true
Chk Buttons - Checkbox - Enabled Textures of DCheckBox when IsEnabled is true
Chk Dsbld Buttons - Checkbox - Disabled Textures of DCheckBox when IsEnabled is false
Expnd Buttons - Tree Textures of DExpandButton
Tree Background Panels - Tree Panel Texture of DTree. This texture can be colored by SetBackgroundColor
Mnu rght Menu - Right Arrow Texture of Arrow in AddSubMenu option
NOTE

DMenu doesn't derive panel's skin when called by DermaMenu. So it will be always "Default" skin. Works only when you set skin for it when it's visible or in DMenuBar.

Menu Strip Menu - MenuStrip Texture of DMenuBar
NOTE

DMenu doesn't derive panel's skin when called by DermaMenu. So it will be always "Default" skin. Works only when you set skin for it when it's visible or in DMenuBar.

Menu Background Menu - With Border Texture of DMenuOption when GetDrawColumn is true
NOTE

DMenu doesn't derive panel's skin when called by DermaMenu. So it will be always "Default" skin. Works only when you set skin for it when it's visible or in DMenuBar.

Menu BG No Border Menu - Without Border Texture of DMenuOption when GetDrawColumn is false
NOTE

DMenu doesn't derive panel's skin when called by DermaMenu. So it will be always "Default" skin. Works only when you set skin for it when it's visible or in DMenuBar.

Menu Selected Menu - Hover Texture of DMenuOption when IsHovered is true
NOTE

DMenu doesn't derive panel's skin when called by DermaMenu. So it will be always "Default" skin. Works only when you set skin for it when it's visible or in DMenuBar.

Text Entry Normal Text Entry - Normal Texture of DTextEntry when IsEditing is false
Text Entry Focused Text Entry - Focus Texture of DTextEntry when IsEditing is true
Text Entry Disabled Text Entry - Disabled Texture of DTextEntry when IsEnabled is false
Scroller Track V Scrollbar - Vertical Texture of DVScrollBar track
VScrollbar - Normal Scrollbar - Vertical Texture of DVScrollBar.btnGrip when IsHovered is false and IsDown is false
VScrollbar - Hovered Scrollbar - Vertical Texture of DVScrollBar.btnGrip when IsHovered is true and IsDown is false
VScrollbar - Pressed Scrollbar - Vertical Texture of DVScrollBar.btnGrip when IsDown is true
VScrollbar - Disabled Scrollbar - Vertical Texture of DVScrollBar.btnGrip when IsEnabled is false
Tab Panel BG Tabbed - Body Texture of DPropertySheet where GetActiveTab is docked
Tab Top Tabbed - Active Texture of DTab when IsActive is true
Unfcs Top Tabbed - Inactive Texture of DTab when IsActive is false
List Box ListBox - Background Texture of DListBox. This class is deprecated, but it's still in game
NOTE

This list contains only named textures which are used in GMod! For example, RadioButton is not listed here.

Unnamed Textures

DermaSkin Textures Numbered.png
List of unnamed layers
Number Description
1 Texture of DProgress main body
2 Texture of DProgress progress body
3 Texture of DFrame outside shadow
BUG

Will be used shadow texture from last loaded skin! To fix it change SKIN in functions PaintShadow and PaintFrame to self.

4 Texture of selection for DTree and DIconBrowser
5 Texture of DTooltip
BUG

DTooltip doesn't derive panel's skin. So it will be always "Default" skin. Works only when you set skin for it when it's visible.

6 Textures of default, hovered and pressed DSlider knob
7 Unused. Can be texture of vertical slider
8 Textures of default, hovered and pressed DNumberWang
9 Texture of DMenu check icon
NOTE

DMenu doesn't derive panel's skin when called by DermaMenu. So it will be always "Default" skin. Works only when you set skin for it when it's visible or in DMenuBar.

10 Textures of default, hovered and pressed DScrollPanel:GetVBar and DHorizontalDivider. Textures of default, hovered and pressed DComboBox button
11 Texture of selected DListView_Line
12 Texture of altered DListView_Line. To separate one line from another, DListView automatically color odd lines to slight dark color. Can be called by internal function DListView_Line:SetAltLine
13 Unused. Can be textures of alternative colors for DListView_Line
14 Texture of hovered DListView_Line
15 Unused
16 Texture of default DComboBox
17 Texture of hovered DComboBox
18 Texture of pressed DComboBox
19 Texture of disabled DComboBox
20 Texture of folded DCategoryList and DCollapsibleCategory
21 Texture of unfolded DCategoryList and DCollapsibleCategory
22 Texture of DCategoryList body
23 Unused
24 Textures of DFrame.btnClose button
25 Textures of DFrame.btnMinim button
26 Textures of DFrame.btnMaxim button
27 Unused. Can be textures of DFrame "Restore" button

Color Pallete Texture

DermaSkin Color Numbered Table.png
Color Pallete Table
Column Row Description
1 A No Color / Not Used
B Color of DFrame title when HasHierarchicalFocus is true
2 A No Color / Not Used
B Color of DFrame title when HasHierarchicalFocus is false
3 A Color of DButton text when IsDown is true
B Color of DButton default text
4 A Color of DButton text when IsEnabled is false
B Color of DButton text when IsHovered is true
5 A Color of DTab text when IsActive is true and IsDown is true
B Color of DTab default text when IsActive is true
6 A Color of DTab text when IsActive is true and IsEnabled is false
B Color of DTab text when IsActive is true and IsHovered is true
7 A Color of DTab text when IsActive is false and IsDown is true
B Color of DTab default text when IsActive is false
8 A Color of DTab text when IsActive is false and IsEnabled is false
B Color of DTab text when IsActive is false and IsHovered is true
9 A Color of DLabel and DListView_Line label when GetDark is true
B Color of DLabel and DListView_Line label when default
10 A Color of DLabel and DListView_Line label when GetHighlight is true
B Color of DLabel and DListView_Line label when GetBright is true
11 A Color of DTree_Node_Button text when IsHovered is true and DForm:ControlHelp text
B Not Used. Colours.Tree.Lines
12 A Color of DTree_Node_Button text when IsSelected is true
B Color of DTree_Node_Button text when default
13 A Not Used. Colours.Properties.Line_Hover
B Not Used. Colours.Properties.Line_Normal
14 A Color of DProperties category label
B Not Used. Colours.Properties.Line_Selected
15 A Not Used. Colours.Properties.Column_Hover
B Not Used. Colours.Properties.Column_Normal
16 A Color of DProperties border between rows and columns
B Color of DProperties cell when row is being edited
17 A Not Used. Colours.Properties.Label_Hover
B Color of DProperties cell label when row isn't being edited
18 A No Color / Not Used
B Color of DProperties cell label when row is being edited
19 A Color of DCategoryHeader title when GetExpanded is false
B Not Used. Named as "ModalBackground"
20 A Color of DCategoryHeader title when GetExpanded is true
B Not Used. Named as "TooltipText" (Real tooltip text uses 27A)
21 A Color of DCollapsibleCategory:Add button text when not Atled and IsDown is true
B Color of DCollapsibleCategory:Add button text when not Atled
22 A Not Used. Colours.Category.Line.Button
B Color of DCollapsibleCategory:Add button text when not Atled and IsHovered is true
23 A Color of DCollapsibleCategory:Add button text when Atled
B Not Used. Colours.Category.Line.Button_Hover
24 A Color of DCollapsibleCategory:Add button text when Atled and IsHovered is true
B Not Used. Colours.Category.Line.Button_Selected
25 A Not Used. Colours.Category.LineAlt.Button_Hover
B Color of DCollapsibleCategory:Add button text when not Atled and IsDown is true
26 A Not Used. Colours.Category.LineAlt.Button_Selected
B Not Used. Colours.Category.LineAlt.Button
27 A Color of DTooltip text.
BUG

Currently broken.

B No Color / Not Used

Demo

For tutorial was created a Demo Addon with Windows 10 UI skin for Derma. You can download it here: Download from Steam Workshop Addon uses this hook for painting all Derma objects:

 

	hook.Add("ForceDermaSkin","Windows10SkinForce",function()
		return "Windows" -- This will paint all Derma objects to new skin
	end)

Discussion

Ask questions, share your skins and more about Derma skins you can find here: GMod Forum Thread

Personal tools
Navigation