# Derma Kullanımına Giriş

- **İngilizce aslı:** https://wiki.facepunch.com/gmod/Introduction_To_Using_Derma
- **Çeviri tarihi:** 2025-09-08

## Giriş

Bu, sizi Derma hakkında sıfır bilgiden alıp, tüm temel konular üzerinden geçirerek ilk kullanıcı arayüzü (UI) projenizi oluşturmak için sağlam bir temel atmayı amaçlayan bir dizi eğitimin ilkidir.

Garry's Mod'a özel [Kullanıcı Arayüzleri (UI)](https://en.wikipedia.org/wiki/User_interface) dünyasına hoş geldiniz. Başlamadan önce net bir kelime dağarcığı tanımlayalım. Source motoru, varsayılan olarak kullanıcı arayüzünü [VGUI (Valves Graphical User Interface)](https://developer.valvesoftware.com/wiki/VGUI_Documentation) ve CPP kullanarak çizer. Garry's Mod'da ise Lua ve Derma kullanırız. Derma, Garry ve TAD2020 tarafından UI çizmeyi kolaylaştırmak için oluşturulmuştur. Arka planda, Lua kodumuz VGUI koduna erişerek UI elemanları oluşturmamızı, özelleştirmemizi ve yok etmemizi sağlar.

## Bölüm 1: Panel (DPanel)

Paneller her şeyin köküdür, kullandığınız ve oluşturduğunuz diğer elemanların çoğu (hepsi değil) bu panellerden oluşacaktır. Motor, varsayılan olarak neredeyse hiçbir varsayılan özelliği olmayan "Panel" adında bir VGUI kontrolü sağlar. Derma, motor panelinden miras alırken işlevselliğini daha esnek olacak şekilde genişleten "DPanel" adlı bir kontrol sunar. Çoğu zaman `DPanel` kullanmak daha iyi olacaktır, bu yüzden odak noktamız bu olacak.

### Panel Oluşturma

Bir paneli kullanmak için bir tane oluşturmanız gerekir. En yaygın yöntem [vgui.Create](https://gmod.tr/wiki/vgui.Create)'tir, şu şekilde:

```lua
local myFirstPanel = vgui.Create( "DPanel" )
```

Bu kod parçacığı Lua'da bir `DPanel` nesnesi oluşturur ve ona erişebilmemiz için `myFirstPanel` değişkeninde saklar. Daha sonra bu değişkeni fonksiyonları çalıştırmak veya aşağıdaki gibi özellikleri ayarlamak için kullanabiliriz:

- Boyut - Panelin Genişliği ve Yüksekliği
- Konum - Sol-üst köşenin nerede olduğu
- Çizim Ayarları - Renk ve benzeri özellikler

### Özellikleri Ayarlama

Paneller kendi başlarına pek bir anlam ifade etmezler, bunun yerine Lego tuğlaları gibi davranarak daha büyük bileşenler oluşturmak için birden fazla örneğini birleştirmenize ve bağlamanıza olanak tanırlar.

Daha önce de belirtildiği gibi, Panellerin Boyut, Konum ve Çizim Ayarları (daha sonra ele alacağımız Paint fonksiyonu olarak daha iyi bilinir) gibi özellikleri vardır. Derma'nın yaptığı şeylerden biri de bize bu özellikleri ayarlamak için Lua fonksiyonları sağlamaktır.

İşte onlarla deneme yapabilmeniz için daha yaygın fonksiyonlardan bazılarına bir örnek.

```lua
myFirstPanel:SetSize( 200, 100 ) -- Genişliği 200 piksel ve yüksekliği 100 piksel yapar

myFirstPanel:SetPos( 50, 50 ) -- Paneli soldan 50 piksel, sonra üstten 50 piksel konumlandırır.

myFirstPanel:Center() -- Paneli ebeveyninin merkezine taşır (konumlandırma için kullanışlıdır)
```

Bunlar oldukça açıklayıcı olmalı, ancak bu fonksiyonların sayıları nasıl kullandığını akılda tutmak önemlidir. Paneller sol üstten sağ alta doğru çizilir. Bu, `:SetSize()` kullandığınızda, sol üst pikselin konumunun aynı noktada kalacağı, sağ alt pikselin ise dışarı doğru fırlayacağı anlamına gelir. Aynı şey `:SetPos()` için de geçerlidir, bu fonksiyon sol üst pikseli ekrandaki yerel koordinatlara taşıyacaktır *(ekranınızın sol üstü 0,0 olacak şekilde)*.

Bu fonksiyonlar okundukça yorumlanır. Eğer `:Center()` kullanıp ardından `:SetSize( w, h )` kullanırsam, panel önce ortalanıp sonra boyutu değiştiği için ortalanmış görünmeyecektir.

### Görünürlüğü Kontrol Etme

Bu bölümü okurken, gizli panelleri tespit etmenize yardımcı olması için `vgui_visualizelayout 1` kullanın. Bu fonksiyon, paneller **GÜNCELLENDİĞİNDE** kırmızı renkte yanıp sönmesini sağlar.

Görünürlük, elemanlar içinde neyi görüp neyi göremediğinizi kontrol etmek için önemlidir. Derma bize basit bir komut olan [Panel:SetVisible](https://gmod.tr/wiki/Panel:SetVisible)'i sağlar. Paneller, ebeveynlerinin durumuna göre otomatik olarak gösterilir ve gizlenir. Yani bir paneli gizlerseniz, tüm alt elemanları da gizlenir.

Bir panelin görünürlüğü, şeffaf bir panelden farklıdır. Şeffaf bir panel yine de güncellenir ve görünür gibi davranır, oysa gizli bir panel doğru şekilde güncellenmez.

bir `DPanel`, [DPanel:SetPaintBackground](https://gmod.tr/wiki/DPanel:SetPaintBackground) kullanılarak şeffaf hale getirilebilir.

### Sonuç

İşte bu kadar, başlamak için ihtiyacınız olan her şey. Bir sonraki bölüme başlamadan önce, [Panel](https://gmod.tr/wiki/Panel) sınıfında bulunan farklı fonksiyonlarla denemeler yaparak nelerin mümkün olduğunu görün. İyi bir kontrol noktası, daha karmaşık alanlara geçmeden önce [Panel:Remove](https://gmod.tr/wiki/Panel:Remove) ile oluşturulmuş panelleri nasıl kaldıracağınızı çözmektir.

İşte bu bölümde ele aldığımız her şeyi detaylandıran bir kod bloğu:

```lua
-- DPanel'i oluştur
local myFirstPanel = vgui.Create( "DPanel" )

-- Boyutunu ayarla (Genişlik: 200px, Yükseklik: 100px)
myFirstPanel:SetSize( 200, 100 )

-- Konumunu ayarla (X: Soldan 300px, Y: Üstten 200px)
-- (Görünürlük için biraz farklı koordinatlar deniyoruz)
myFirstPanel:SetPos( 300, 200 )

-- Arka planını boyamasını sağla
myFirstPanel:SetPaintBackground( true )

-- Arka plan rengini mavi yap (R=0, G=0, B=255, Alfa=255)
myFirstPanel:SetBackgroundColor( Color( 0, 0, 255, 255 ) )

-- Görünür olduğundan emin ol (genellikle gizli bir panele ebeveynlenmemişse varsayılan olarak görünürdür)
myFirstPanel:SetVisible( true )
```

## Bölüm 2: Etiketler ve Düğmeler (DLabel / DButton)

Son bölüm tamamen dikdörtgenler oluşturmakla ilgiliydi, ancak kullanıcı arayüzleri sadece dikdörtgenlerden oluşmaz. Arayüzümüzün metin içermesini ve onunla bir miktar etkileşim olmasını isteriz, işte bu noktada Etiketler ve Düğmeler devreye girer. Derma için bu elemanlar [DLabel](https://gmod.tr/wiki/DLabel) ve [DButton](https://gmod.tr/wiki/DButton)'dır.

Şimdi bu elemanları kullanmaya başlamadan önce kalıtımı (inheritance) hatırlamak çok önemlidir. [DLabel](https://gmod.tr/wiki/DLabel), [Label](https://gmod.tr/wiki/Label) adında motor tabanlı bir panelden türetilirken, [DButton](https://gmod.tr/wiki/DButton) elemanı [DLabel](https://gmod.tr/wiki/DLabel)'dan türetilir. Bu kademeli kalıtımı hatırlamak önemlidir çünkü bu paneller içinde hangi fonksiyonlara erişip hangilerine erişemeyeceğinizi hatırlamanıza yardımcı olacaktır. Bu elemanların bir sonraki bölüme ayrılmasının nedeni budur.

İstisnalar olsa da, motor panelinden türeyen elemanlar genellikle düzen ve gruplama gibi şeyler için kullanılır. Motor etiket panelinden türeyen elemanlar ise daha çok fare etkileşimi için kullanılır.

### Etiket Ekleme

Etiketlerimizi ve düğmelerimizi eklemeden önce bir temel panel oluşturalım:

```lua
-- Önceki örneklerde açıklanan fonksiyonlar netlik için yorumlanmayacaktır
local myBasePanel = vgui.Create( "DPanel" )
myBasePanel:SetSize( 300, 150 )
myBasePanel:Center()
myBasePanel:SetPaintBackground( true )
myBasePanel:SetBackgroundColor( Color( 0, 0, 255, 255 ) )
myBasePanel:MakePopup() -- Üstte kalmasını ve fareyi tıklamaları yakalamak için serbest bırakmasını sağlar.
```

Şimdi bir [DLabel](https://gmod.tr/wiki/DLabel) ekleyelim

```lua
local myTitleLabel = vgui.Create( "DLabel", myBasePanel ) -- İkinci argümanı kullanarak onu 'myBasePanel'e ebeveyn yapıyoruz

-- Göstermesi gereken metni ayarla
myTitleLabel:SetText( "My Awesome Panel" )

-- Konumunu myBasePanel'in sol-üst köşesine *göreceli* olarak ayarla
myTitleLabel:SetPos( 10, 10 )

-- Etiketin genişliğini metne sığacak şekilde otomatik olarak ayarla
myTitleLabel:SizeToContents()

-- İsteğe bağlı: Metin rengini değiştir
myTitleLabel:SetTextColor( color_white ) -- Beyaz rengi elde etmek için yerleşik varsayılan rengi kullanıyoruz
```

Panelinize metin eklemek gerçekten bu kadar basit!

### Düğme Ekleme

Şimdi `myBasePanel` üzerine bir yere, paneli bizim için kapatacak bir [DButton](https://gmod.tr/wiki/DButton) ekleyelim. Umarım Bölüm 1'de panel kaldırmayı tetiklemenin bir yolunu bulmuşsunuzdur, böylece bu, panel yönetimini kolaylaştıracaktır.

```lua
local myCloseButton = vgui.Create( "DButton", myBasePanel )
myCloseButton:SetText( "Close Me" )

-- Boyutunu ayarla (Düğmeler genellikle etiketimizi ayarladığımızın aksine belirli bir boyuta ihtiyaç duyar)
myCloseButton:SetSize( 100, 30 )

-- Panelin sağ alt kısmına yakın konumlandır
-- Konumu panelin boyutuna göre hesaplıyoruz
local panelW, panelH = myBasePanel:GetSize()
myCloseButton:SetPos( panelW - 110, panelH - 40 ) -- Sağ/alttan 10px boşluk
-- ofset sayılarını 'boyut + boşluk' yaparak elde ettik,
```

Kolay! şimdi düğmemizi ayarladığımıza göre, tıklarsanız hiçbir şey yapmadığını fark edeceksiniz. Bunun nedeni, ilgili hook'larda herhangi bir davranış ayarlamamış olmamızdır.

`DButton`, metotlarını [DLabel](https://gmod.tr/wiki/DLabel)'dan miras aldığı ve [DLabel](https://gmod.tr/wiki/DLabel)'ın [DLabel:DoClick](https://gmod.tr/wiki/DLabel:DoClick) metoduna sahip olduğu için, düğmemiz için o hook'u kullanabiliriz. Eğer bu tam olarak mantıklı gelmiyorsa, bu hook'u nasıl ve neden kullanabildiğimizi anlamak için bir an durup düşünün. Kontroller daha karmaşık hale geldikçe kalıtımı şimdi anlamak çok önemlidir.

Bu fonksiyonu `myCloseButton` panelimizin oluşturulmasının altında bir yerde tanımlayalım.

```lua
-- myCloseButton tıklandığında ne olacağını tanımla
myCloseButton.DoClick = function( theButton )
  -- 'theButton' tıklanan düğmedir (bu durumda myCloseButton)
  print( "Close button clicked!" )

  -- Düğmenin tüm paneli kaldırmasını sağlayalım
  myBasePanel:Remove()
end
```

> **NOT:** fonksiyon şu şekilde de yazılabilir
>
> ```lua
> function myCloseButton:DoClick()
> 	...
> end
> ```
>
> bu ikisi arasındaki tek fark Lua Self Anahtar Kelimesi'nin nasıl ele alındığıdır

Oluşturduğumuz düğme çok basittir, sadece mesajımızı yazdırır ve ardından temel panelimizi kaldırır, bu da onun ve tüm alt elemanlarının silinmek üzere işaretlenmesine neden olur.

### Sonuç

Artık temel panel kontrolü hakkında daha da güçlü bir anlayışa sahip olmalısınız. Farklı şeyler yapan düğmeler oluşturarak denemeler yapın. Belki bir hesap makinesi? Düzen sistemini Bölüm 3'te ele alacağız.

Kodun tamamı şöyle görünür:

```lua
-- Önceki örneklerde açıklanan fonksiyonlar netlik için yorumlanmayacaktır
local myBasePanel = vgui.Create( "DPanel" )
myBasePanel:SetSize( 300, 150 )
myBasePanel:Center()
myBasePanel:SetPaintBackground( true )
myBasePanel:SetBackgroundColor( Color( 0, 0, 255, 255 ) )
myBasePanel:MakePopup()

local myTitleLabel = vgui.Create( "DLabel", myBasePanel )
myTitleLabel:SetText( "My Awesome Panel" )
myTitleLabel:SetPos( 10, 10 )
myTitleLabel:SizeToContents()
myTitleLabel:SetTextColor( color_white )

local myCloseButton = vgui.Create( "DButton", myBasePanel )
myCloseButton:SetText( "Close Me" )
myCloseButton:SetSize( 100, 30 )
local panelW, panelH = myBasePanel:GetSize()
myCloseButton:SetPos( panelW - 110, panelH - 40 )

myCloseButton.DoClick = function( theButton )
  print( "Close button clicked!" )
  myBasePanel:Remove()
end
```

## Bölüm 3: Düzen Sistemi (Layout System)

Önceki bölümler tamamen eleman oluşturmakla ilgiliydi. [Panel:SetPos](https://gmod.tr/wiki/Panel:SetPos) kullanarak bazı temel konumlandırmaları ele alsak da, bu gerçekten sadece statik elemanlar için en iyi sonucu verir. Eğer katmanlı elemanlarınız varsa ve ebeveyn boyutunu değiştirirse, alt elemanları uygun şekilde güncelleyebilmek istersiniz.

### PerformLayout

[Panel:PerformLayout](https://gmod.tr/wiki/PANEL:PerformLayout), düzen sisteminin bel kemiğidir. Bir panelin alt elemanlarını nasıl düzenleyeceğini bilmesi gerektiğinde bu hook çağrılır. Bu, panel oluşturma, yeniden boyutlandırma veya paneller eklendiğinde veya kaldırıldığında otomatik olarak çağrılabilir. Veya, [Panel:InvalidateLayout](https://gmod.tr/wiki/Panel:InvalidateLayout) ile manuel olarak çağrılabilir, ancak bu genellikle gerekli olmayacaktır.

> **UYARI:** [Panel:PerformLayout](https://gmod.tr/wiki/PANEL:PerformLayout)'ı manuel olarak çağırmanıza **asla** gerek kalmayacak, sistem düzen geçersiz kılındıktan sonra her zaman sizin için çağıracaktır. Eğer bu yapılması gerekiyorsa, bunu [Panel:InvalidateLayout](https://gmod.tr/wiki/Panel:InvalidateLayout)'ı çağırarak yapın

### Yaygın Düzen Teknikleri

Burada, `PerformLayout` hook'u içinde panellerimizi düzenlemenin en yaygın yollarından bazılarını inceleyelim.

#### 1. Manuel Konumlandırma

Bunu zaten biliyorsunuz! Bu sadece istediğiniz kesin koordinatları ve boyutları belirtmeyi içerir. Bu, hassas kontrol sunar ancak uygulayabileceğiniz esnek veya dinamik tasarım miktarını sınırlar.

Bölüm 2'den Manuel Konumlandırma Örnekleri

```lua
myTitleLabel:SetPos( 10, 10 )
myCloseButton:SetPos( panelW - 110, panelH - 40 )
myCloseButton:SetSize( 100, 30 )
```

#### 2. Yaslama (Docking)

Yaslama (Docking) çok güçlüdür. Alt elemana, ebeveyninin bir veya daha fazla kenarına yapışmasını ve mevcut geri kalan alanı doldurmasını söylersiniz.

[Panel:Dock](https://gmod.tr/wiki/Panel:Dock) fonksiyonu, panelin nasıl yaslanacağını belirtmek için 1'den 5'e kadar sayılar alır. Ancak bu sayıların ne anlama geldiğini hatırlamak yerine, kodumuzu daha okunabilir hale getirmek için [DOCK enum](https://gmod.tr/wiki/Enums/DOCK)'ını kullanabiliriz.

| Dock Enum'u | Değer | Açıklama |
|---|---|---|
| NODOCK | 0 | Yaslama |
| FILL | 1 | Diğer paneller tarafından alınmayan kalan alanın olabildiğince fazlasını doldur. |
| LEFT | 2 | Panelin yüksekliğini maksimize ederek ebeveynin sol duvarına yapış. |
| RIGHT | 3 | Panelin yüksekliğini maksimize ederek ebeveynin sağ duvarına yapış. |
| TOP | 4 | Genişliği maksimize ederek ebeveynin üst duvarına yapış. |
| BOTTOM | 5 | Genişliği maksimize ederek ebeveynin alt duvarına yapış. |

Şimdi, bu yöntemi kullanırsanız, alt elemanları yaslama sırasının önemli olduğunu unutmamanız gerekir!

```lua
-- Temel paneli oluştur (önceki gibi)
local myBasePanel = vgui.Create( "DPanel" )
myBasePanel:SetSize( 300, 150 )
myBasePanel:Center()
myBasePanel:MakePopup()
myBasePanel:SetPaintBackground( true )
myBasePanel:SetBackgroundColor( Color( 0, 50, 150, 255 ) )

-- Başlık Etiketini Oluştur
local myTitleLabel = vgui.Create( "DLabel", myBasePanel )
myTitleLabel:SetText( "My Awesome Panel" )
myTitleLabel:SetTextColor( Color( 255, 255, 255, 255 ) )
myTitleLabel:SetTall( 25 ) -- Yaslama için sabit bir yükseklik ver
myTitleLabel:Dock( TOP )    -- Üste yapış!

-- Kapat Düğmesini Oluştur
local myCloseButton = vgui.Create( "DButton", myBasePanel )
myCloseButton:SetText( "Close Me" )
myCloseButton:SetTall( 30 ) -- Yaslama için sabit bir yükseklik ver
myCloseButton:Dock( BOTTOM ) -- Alta yapış!

-- Düğme Eylemi (önceki gibi)
myCloseButton.DoClick = function( theButton )
  print( "Close button clicked!" )
  myBasePanel:Remove()
end
```

Bu kodu çalıştırdıktan sonra, başlık ve kapatma düğmelerinin ebeveyne göre otomatik olarak konumlandığını ve boyutlandığını fark edeceksiniz. Şimdi [Panel:DockMargin](https://gmod.tr/wiki/Panel:DockMargin) ve [Panel:DockPadding](https://gmod.tr/wiki/Panel:DockPadding) kullanarak bu fonksiyonların görünümünü iyileştirmeye devam edebiliriz. `Margin`, ebeveynin diğer alt elemanları arasındaki mesafeyi ifade eder. `Padding`, paneli doldurabileceği kenardan uzağa doğru küçültmeyi ifade eder. Eğer bu hala kafa karıştırıcıysa, işlevsellik aynı olduğu için web geliştirmedeki farkı araştırabilirsiniz.

```lua
myTitleLabel:DockMargin( 5, 5, 5, 0 ) -- Sol, Üst, Sağ, Alt boşluk
myCloseButton:DockMargin( 5, 0, 5, 5 ) -- Sol, Üst, Sağ, Alt boşluk
```

#### 3. İçeriğe Göre Boyutlandırma

Bazen, ebeveyni doldurmak yerine, ebeveynin alt elemanlarına göre küçülmesini istersiniz. İşte bu noktada [Panel:SizeToContents](https://gmod.tr/wiki/Panel:SizeToContents) ve [Panel:SizeToChildren](https://gmod.tr/wiki/Panel:SizeToChildren) devreye girer. `:SizeToContents()` fonksiyonunu, metnine tam sığacak kadar büyük yapmak için `DLabel`'ımızda kullandığımız Bölüm 2'den hatırlayabilirsiniz. `:SizeToChildren()`, tüm panelin alt elemanlarının sınırlayıcı kutusunu (bounding box) hesapladığı ve boyutu bu sınırlayıcı kutuyu barındırabilecek minimum boyuta ayarladığı için bundan farklıdır.

```lua
-- Yalnızca bir etiket içeren bir panel hayal edin
local container = vgui.Create( "DPanel" )
container:SetPos(100, 100)
container:SetPaintBackground(true)
container:SetBackgroundColor(Color(200, 200, 200, 255))

local label = vgui.Create( "DLabel", container )
label:SetText( "This text determines the panel size!" )
label:SetPos( 5, 5 ) -- Konteyner içinde konumlandır
label:SizeToContents() -- Etiket metnine sığar

-- Şimdi, konteyneri etikete sığdır
container:SizeToChildren( true, true ) -- Genişliği ve yüksekliği yeniden boyutlandır
```

#### 4. Hizalama

Bu fonksiyonlar, elemanları ebeveynleri tarafından ayrılan alan içinde konumlandırmaya yardımcı olur (genellikle yaslama veya bir boyut ayarladıktan *sonra* kullanılır). Örneğin, [Panel:SetContentAlignment](https://gmod.tr/wiki/Panel:SetContentAlignment) metni `DLabel`'ın sınırları *içinde* ortalardı. Birçok panel ayrıca, paneli ebeveyni içinde ortalayan [Panel:Center](https://gmod.tr/wiki/Panel:Center) gibi yardımcı fonksiyonlara sahiptir.

Diğer Hizalama Fonksiyonları:

- [Panel:AlignBottom](https://gmod.tr/wiki/Panel:AlignBottom)
- [Panel:AlignLeft](https://gmod.tr/wiki/Panel:AlignLeft)
- [Panel:AlignRight](https://gmod.tr/wiki/Panel:AlignRight)
- [Panel:AlignTop](https://gmod.tr/wiki/Panel:AlignTop)

### Konteyner Panelleri ve Düzen Mantığı

Temel `DPanel`'in `PerformLayout`'u yalnızca manuel konumlandırmalara ve yaslamaya uysa da, özel konteyner panelleri çok daha akıllı `PerformLayout` fonksiyonlarına sahiptir.

- [DPanelList](https://gmod.tr/wiki/DPanelList): `PerformLayout`'u, alt elemanları dikey olarak (bir liste gibi) düzenler ve aralığı otomatik olarak ekler.
- [DIconLayout](https://gmod.tr/wiki/DIconLayout): `PerformLayout`'u, alt elemanları bir ızgara şeklinde düzenler ve yatayda yer kalmadığında onları bir sonraki satıra kaydırır.
- [DForm](https://gmod.tr/wiki/DForm) Etiketleri ve kontrolleri genellikle ayar menüleri için kullanılan düzgün sıralar halinde düzenler.

Bu özel panelleri bir sonraki bölümde daha detaylı inceleyeceğiz.

### Perde Arkası: Düzen Nasıl Gerçekleşir

1. **Tetikleyici**: Verilen panelin düzenini geçersiz kılan bir şey olur
2. **[Panel:PerformLayout](https://gmod.tr/wiki/PANEL:PerformLayout) Çağrısı**
3. **Yürütme**: `:PerformLayout()` hook'unda ne varsa yürütülür

### Sonuç

Bu bölüm, düzen sisteminin nasıl çalıştığını ve bir kullanıcının panellerini organize etmek için kullanabileceği farklı yöntemleri ele almayı tamamladı.

Bir sonraki bölümde Özel Konteyner Panelleri'ni ele alacağız.

## Bölüm 4: Konteyner Panelleri

Bölüm 3'te farklı düzen yöntemlerini ve `:PerformLayout()` hook'unu kullanarak elemanları düzenlemeyi ele aldık. Bu, düğmeler veya etiketler gibi şeyleri yerleştirmek için harika olsa da, uzun bir öğe listemiz varsa bu yöntemler hızla gereksiz hale gelebilir. İşte bu noktada konteyner panelleri kullanışlı hale gelir. Konteyner panelleri, diğer panellerden oluşan bir koleksiyonu tutmak ve organize etmek için özel olarak tasarlanmış panellerdir.

Popüler Konteyner Panelleri: [DScrollPanel](https://gmod.tr/wiki/DScrollPanel), [DTileLayout](https://gmod.tr/wiki/DTileLayout), [DIconLayout](https://gmod.tr/wiki/DIconLayout), [DListLayout](https://gmod.tr/wiki/DListLayout), [DGrid](https://gmod.tr/wiki/DGrid), [DDrawer](https://gmod.tr/wiki/DDrawer)

### DScrollPanel ile Kaydırma

En popüler konteyner paneli [DScrollPanel](https://gmod.tr/wiki/DScrollPanel)'dir. Bu panelin tek bir amacı vardır, alt elemanları arasında gezinmenizi sağlamak. Bunu, fare kaydırmalarını algılayarak veya alt elemanları kaydırma benzeri bir şekilde yeniden konumlandırmak için kullanılabilecek bir kaydırma çubuğu oluşturarak yapar.

Genellikle gerçek interaktif elemanlarınızı `DScrollPanel`'in kendisine eklemezsiniz. Bunun yerine, temel boş bir [Panel](https://gmod.tr/wiki/Panel) oluşturur ve elemanlarınızı ona eklersiniz. Bu, `DScrollPanel`'in o görünmez gruplama panelini kaydırabilmesi ve tüm interaktif elemanları kaydırma sırasında birbirlerine göre göreceli konumlarında tutabilmesi içindir.

```lua
local frame = vgui.Create( "DFrame" )
frame:SetSize( 200, 250 )
frame:Center()
frame:SetTitle( "Scroll Example" )
frame:MakePopup()

local scroll = vgui.Create( "DScrollPanel", frame )
scroll:Dock( FILL )

local groupingPnl = vgui.Create( "DPanel", scroll )
groupingPnl:SetTall( 500 ) -- Gerçekten kaydırabilmemiz için uzun yap
groupingPnl:Dock( FILL )
groupingPnl:SetPaintBackground( false ) -- görünmez olmasını istiyoruz

-- Kaydırmak istediğiniz interaktif panelleri ekleyin
for i = 1, 20 do
  local label = vgui.Create( "DLabel", groupingPnl )
  label:SetText( "Item Number " .. i )
  label:SetPos( 10, 5 + (i-1) * 20 ) -- groupingPnl *içinde* manuel olarak konumlandır
  label:SizeToContents()
end
```

### `DIconLayout` ile Izgara Düzenleri

Peki ya öğeleri bir masaüstündeki simgeler veya bir envanter ızgarasındaki öğeler gibi bir ızgarada düzenlemek isterseniz? `DIconLayout` bunun için tasarlanmıştır. Alt elemanlarını satırlar ve sütunlar halinde düzenler.

```lua
-- Ana çerçeveyi oluştur
local frame = vgui.Create( "DFrame" )
frame:SetSize( 220, 200 ) -- Biraz daha geniş
frame:Center()
frame:SetTitle( "IconLayout Example" )
frame:MakePopup()

-- Önce bir kaydırma paneli oluştur (DIconLayout varsayılan olarak kaydırmaz)
local scroll = vgui.Create( "DScrollPanel", frame )
scroll:Dock( FILL )

-- DIconLayout'u kaydırma panelinin *içinde* oluştur
local icons = vgui.Create( "DIconLayout", scroll )
icons:Dock( FILL )
icons:SetSpaceX( 5 ) -- Simgeler arası yatay boşluk
icons:SetSpaceY( 5 ) -- Simgeler arası dikey boşluk
icons:SetBorder( 5 ) -- İç kenar etrafındaki boşluk

-- Öğeleri ekle (simgeleri temsil eden küçük düğmeler)
for i = 1, 30 do
  local iconButton = vgui.Create( "DButton", icons ) -- Ebeveyn, simgeler düzenidir
  iconButton:SetText( i )
  iconButton:SetSize( 40, 40 ) -- "Simgelere" bir boyut ver
  -- DIconLayout için AddItem çağırmaya gerek yok, sadece ebeveyni ayarla!
  -- DIconLayout, kendisine eklenen çocukları otomatik olarak algılar.
end
```

### Diğer Konteynerler (DListView, DForm, vb.)

Diğer özel konteynerler şunlardır:

- [DListView](https://gmod.tr/wiki/DListView): Sütunlar ve satırlarla elektronik tablo benzeri görünümler oluşturur. Skor tabloları veya ayrıntılı listeler için harikadır. Öğe eklemek `AddLine` ve her sütun için veri belirtmeyi içerir.
- [DForm](https://gmod.tr/wiki/DForm): Ayar menüleri oluşturmak için kullanışlıdır. Etiketleri ve kontrolleri (onay kutuları, metin girişleri gibi) düzgün sıralar halinde düzenlemeye yardımcı olur.
- [DCategoryList](https://gmod.tr/wiki/DCategoryList): Her biri diğer panelleri içeren, daraltılabilir kategoriler oluşturur.

Bunlar aynı prensipler üzerine kuruludur: Alt elemanlarını belirli şekillerde düzenlemek için özel `PerformLayout` fonksiyonlarına sahiptirler.

### Sonuç

Çoğu eleman görünür olmak ve etkileşime girilmek üzere tasarlanmış olsa da, bazıları öyle değildir; bazıları, benzer kodun birden çok örneğini tek bir noktada toplayarak geliştiricilere çok zaman ve kod karmaşıklığından tasarruf sağlar.

Bir sonraki bölüm, panellerinizin güzel görünmesini sağlamak için "skinning" ve "painting" konularını ele alacaktır.

## Bölüm 5: Görünüm (Skinning) ve Boyama (Painting)

Son bölümde konteyner panellerini ele aldığımıza göre, artık panelleri oluşturma, yönetme ve hareket ettirme ile ilgili tüm temel bilgilere sahibiz. Ancak henüz nasıl **göründüklerini** ele almadık. İşte bu noktada "painting" (boyama) ve "skinning" (görünüm) devreye girecek. Başlamadan önce bu iki terim arasındaki farkı bilmelisiniz. Painting, belirli bir paneli boyamayı ifade eder; bu genellikle [Draw](https://gmod.tr/wiki/draw) ve [Surface](https://gmod.tr/wiki/surface) gibi kütüphaneleri içerir. Skinning ise farklı bir yaklaşımdır; bu, [GWEN](https://gmod.tr/wiki/GWEN) gibi kütüphaneler kullanarak bir "skin" (görünüm) oluşturmayı ve boyama fonksiyonlarının referans alacağı UI sprite sheet'leri (arayüz resim dosyaları) oluşturmayı içerir.

Her birinin kendi güçlü ve zayıf yönleri vardır, ancak genel olarak, painting yapmak daha kolaydır ama her bir panel için ayrı ayrı yapılması gerekir. Skinning, başlangıçta daha fazla yatırım gerektirir ancak tüm elemanlarda tek bir yerden kontrol edilen tutarlı bir görünüm sağlayabilir.

### Derma'da Çizim

Skinning, tüm paneller için "varsayılan" tutarlı bir görünüm sağlar. Painting, belirli bir panel için bu görünümü geçersiz kılmanıza olanak tanır. Bir paneli boyamak, ister bir skin'den ister başka bir kaynaktan gelsin, varsayılan görünümü her zaman geçersiz kılar.

#### Paint Fonksiyonu

Her bir panelin bir `:Paint( w, h )` fonksiyonu olacaktır. Panel, nasıl görünmesi gerektiğini belirlemek için bunu kullanır. Bu hook, panelin görünür olduğu her karede çağrılır. Paint hook'u her zaman iki argümanla çağrılır: mevcut panelin genişliği ve yüksekliği *(genellikle `w` ve `h` olarak belirtilir)*.

İşte bir Paint Hook'u oluşturmanın iki yoluna bir örnek Self Açık (Explicit)

```lua
PANEL.Paint = function( self, w, h )
	...
end
```

veya self'in örtük (implicit) olması

```lua
function PANEL:Paint( w, h )
	...
end
```

Her iki seçenek de doğrudur ve kişisel tercihe bağlıdır. Self kullanımı hakkında daha fazla bilgi için [Beginner_Tutorial_Self](https://gmod.tr/wiki/Beginner_Tutorial_Self) konusuna bakın.

#### Boyama Sistemi

Çizim için kullanacağınız araçlar her zaman [Surface](https://gmod.tr/wiki/surface) kütüphanesinden gelecektir. Bu kütüphane, istediğiniz her türlü kullanıcı arayüzünü oluşturmak için ihtiyacınız olan her şeyi sağlar. Ancak bazen daha karmaşık görevleri surface'ta yapmak zor olabilir, bu yüzden [Draw](https://gmod.tr/wiki/draw) kütüphanesi oluşturulmuştur. Bu kütüphane hala altta surface kütüphanesini kullanır ancak daha kullanışlı fonksiyonlara ve arka planda daha karmaşık surface hileleri yapan fonksiyonlara sahiptir. Genel olarak, bir şey sadece surface'ta yapılabiliyorsa, onu surface'ta yapın. Eğer bir şey karmaşık ve surface'ta yapması zorsa, draw'ı kullanın.

Burada size surface'ta mevcut olan bazı (**hepsi değil**) fonksiyonları sunuyoruz:

- [Surface.SetDrawColor](https://gmod.tr/wiki/surface.SetDrawColor)
- [Surface.DrawRect](https://gmod.tr/wiki/surface.DrawRect)
- [Surface.SetFont](https://gmod.tr/wiki/surface.SetFont)
- [Surface.SetTextColor](https://gmod.tr/wiki/surface.SetTextColor)
- [Surface.SetTextPos](https://gmod.tr/wiki/surface.SetTextPos)
- [Surface.DrawText](https://gmod.tr/wiki/surface.DrawText)

[Surface.SetDrawColor](https://gmod.tr/wiki/surface.SetDrawColor) ve [Surface.SetFont](https://gmod.tr/wiki/surface.SetFont) gibi fonksiyonlarımız olduğunu fark edeceksiniz. Bunun nedeni, surface'ın `surface.DrawRect` gibi diğer tüm fonksiyonlarda kullanmak üzere bu fonksiyonlardan gelen son girdiyi saklayarak çalışmasıdır. Surface kullanarak çizim yapmaya çalışmadan önce her zaman rengi veya fontu ayarlamak isteyeceksiniz, çünkü bunu yapmamak yanlış renk/font çizilmesine neden olabilir.

İşte draw ile kullanılabilen bazı (**hepsi değil**) fonksiyonlar:

- [Draw.DrawText](https://gmod.tr/wiki/draw.DrawText)
- [Draw.RoundedBox](https://gmod.tr/wiki/draw.RoundedBox)
- [Draw.TexturedQuad](https://gmod.tr/wiki/draw.TexturedQuad)

Burada bu fonksiyonların kaynak kodunu incelerseniz, hepsinin sadece bir dizi surface fonksiyonu olduğunu görürsünüz. Bu fonksiyonları saf surface formatında yazabilir ve aynı sonuçları alabilirsiniz, ancak bu kütüphanenin amacı bu daha karmaşık surface taktiklerinin kolaylığı ve kullanım rahatlığıdır.

#### Görünüm (Skinning) Sistemi

Oluşturduğunuz her bir panelin bir boyama fonksiyonu olacaktır, ancak bunları sırf tutarlı bir görünüm elde etmek için neredeyse aynı `surface` ve `draw` fonksiyonlarıyla doldurmak inanılmaz derecede tekrarlayıcı ve israf olabilir.

İşte bu noktada **Skin'ler (Görünümler)** devreye girer. Her Skin, tüm standart Derma elemanları için varsayılan görünümü ve hissi tanımlar. Standartlaştırılmış renkler, fontlar veya hatta düğmeler, etiketler ve çerçeveler gibi farklı türdeki elemanlar için varsayılan boyama fonksiyonları içerir.

Bütün bunlar [derma.SkinHook](https://gmod.tr/wiki/derma.SkinHook) kullanılarak yapılır, bazen [Derma_Hook](https://gmod.tr/wiki/Global.Derma_Hook) kullanılır ki bu da ilk fonksiyon için süslü bir sarmalayıcıdır (wrapper) ancak burada bahsedilmeyi gerektirecek kadar sık kullanılır.

Birçok varsayılan derma panelinin boyama fonksiyonlarının içinde bu fonksiyonlardan birini şu şekilde yazılmış bulacaksınız:

```lua
derma.SkinHook( "Paint", "Button", self, w, h )
```

bu satır esasen mevcut skin'e bir düğme türü eleman için Paint işlemini nasıl gerçekleştireceğini sorar ve panel tablosunu ve boyutlarını iletir.

sonuç olarak skin içinde aşağıdaki fonksiyon çağrılır

```lua
function SKIN:PaintButton( panel, w, h )
	...
end
```

Garry's Mod, varsayılan olarak bir skin ile gelir, `default.lua` skin'i. Bu, `lua/skins/` içinde yer almaktadır. Bu skin hakkında daha ayrıntılı bir inceleme için [Derma_Skin_Creation](https://gmod.tr/wiki/Derma_Skin_Creation) konusuna bakın.

#### Paint Hook'unu Kullanma

Önceki örneklerden aşağıdaki koda aşina olmalısınız:

```lua
-- Temel çerçeveyi oluştur
local frame = vgui.Create( "DFrame" )
frame:SetSize( 200, 150 )
frame:Center()
frame:SetTitle( "Custom Paint Example" )
frame:MakePopup()

-- Standart bir DButton oluştur
local myButton = vgui.Create( "DButton", frame )
myButton:SetText( "Hover or Click Me" )
myButton:SetSize( 160, 40 )
myButton:SetPos( 20, 40 ) -- Çerçeve içine konumlandır

-- Temel eylem
myButton.DoClick = function( btn )
  print( "Button Clicked!" )
end
```

Şimdi, *bu belirli düğmeye* (`myButton`) farklı bir `Paint` fonksiyonu kullanmasını söyleyelim.

```lua
-- myButton için özel boyama fonksiyonumuzu tanımla
myButton.Paint = function( panel, w, h )
  -- 'panel' myButton'ın kendisidir
  -- 'w' düğmenin genişliğidir (160)
  -- 'h' düğmenin yüksekliğidir (40)

  --  Özel çizim kodumuz buraya gelecek!

  -- !! Önemli: Varsayılan metin çizimini durdurmak için true döndürün !!
  -- Eğer metni kendimiz çizersek, true döndürürüz.
  -- Eğer arka planımızdan sonra varsayılan skin'in metni çizmesini isteseydik,
  -- true döndürmezdik (veya false/nil döndürürdük).
  -- Bu örnek için, her şeyi kendimiz çizeceğiz.
  return true
end
```

Doğrudan `myButton.Paint`'e yeni bir fonksiyon atadık. Artık her karede, Garry's Mod varsayılan `DButton` boyama mantığını (ki bu `derma.SkinHook` kullanır) çağırmak yerine, *bizim* fonksiyonumuzu çağıracak.

Çizim kodunu özel `Paint` fonksiyonumuzun içine ekleyelim. Şunları istiyoruz:

- Normalde yeşil bir arka plan.
- Üzerine gelindiğinde daha parlak yeşil bir arka plan.
- Tıklandığında (basılı tutulduğunda) daha koyu yeşil bir arka plan.
- Beyaz metin.

```lua
-- myButton için özel boyama fonksiyonumuzu tanımla
myButton.Paint = function( panel, w, h )
  -- Düğmenin durumunu kontrol et
  local isHovered = panel:IsHovered()
  local isDown = panel:IsDown()

  -- Duruma göre arka plan rengini belirle
  local bgColor
  if isDown then
    bgColor = Color( 0, 100, 0, 255 ) -- Koyu Yeşil
  elseif isHovered then
    bgColor = Color( 0, 200, 0, 255 ) -- Parlak Yeşil
  else
    bgColor = Color( 0, 150, 0, 255 ) -- Normal Yeşil
  end

  -- Arka plan dikdörtgenini çiz
  surface.SetDrawColor( bgColor )
  surface.DrawRect( 0, 0, w, h ) -- Tüm paneli doldur (0,0'dan w,h'ye)

  -- Metni çiz
  surface.SetFont( "DermaDefault" )
  surface.SetTextColor( Color( 255, 255, 255, 255 ) ) -- Beyaz

  -- Metni ortalamak için pozisyonunu hesapla
  local text = panel:GetText() -- Düğmenin metnini al
  local textW, textH = surface.GetTextSize( text )
  local textX = (w - textW) / 2
  local textY = (h - textH) / 2
  surface.SetTextPos( textX, textY )
  surface.DrawText( text )

  -- Metin dahil her şeyi hallettik. Varsayılan çizimi durdur.
  return true
end
```

Yeşil bir düğmesi olan bir pencere görmelisiniz. Farenizi üzerine getirdiğinizde parlak yeşile döner. Tıklayıp basılı tuttuğunuzda koyu yeşile döner. Metin baştan sona beyaz kalır. Varsayılan düğme görünümünü başarıyla geçersiz kıldınız!

### Sonuç

Painting ve skinning konularını ele aldığımıza göre, Derma'ya giriş bilginizi tamamlamış bulunuyorsunuz. Umarız şimdiye kadar bazı temel UI elemanları oluşturmaya ve bunları kendi zevkinize göre özelleştirmeye başlamak için yeterli bilgi birikimine sahip olmuşsunuzdur.

Tebrikler ve Derma'ya hoş geldiniz!

- [GMod Wiki ana sayfası](https://gmod.tr/wiki)

---

[Tüm sunucular](https://gmod.tr/) · [GmodTR Launcher](https://gmod.tr/launcher) · [Rehber](https://gmod.tr/rehber) · [GMod Wiki](https://gmod.tr/wiki) · [GmodTR nedir?](https://gmod.tr/hakkinda) · [Sunucu ekle](https://gmod.tr/sunucu-ekle) · [Discord](https://discord.gg/gmodtr)

Kaynak: https://gmod.tr/wiki/Introduction_To_Using_Derma
