Home  Contents

Advanced widgets in GTK#

فى هذه الجزئية سنناقش بعض الويدجات المتقدمة فى GTK#

IconView

يستخدم الويدجت IconView لعرض مجموعة من الأيكونات فى صورة شبكة

iconview.cs
 
using System;
using System.IO;
using Gtk;


public class SharpApp : Window
{
    const int COL_PATH = 0;
    const int COL_DISPLAY_NAME = 1;
    const int COL_PIXBUF = 2;
    const int COL_IS_DIRECTORY = 3;

    DirectoryInfo root = new DirectoryInfo("/");
    Gdk.Pixbuf dirIcon, fileIcon;
    ListStore store;
    ToolButton upButton;

    public SharpApp() : base("IconView")
    {
        SetDefaultSize(650, 400);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };

        VBox vbox = new VBox(false, 0);
        Add(vbox);

        Toolbar toolbar = new Toolbar();
        vbox.PackStart(toolbar, false, false, 0);

        upButton = new ToolButton(Stock.GoUp);
        upButton.IsImportant = true;
        upButton.Sensitive = false;
        toolbar.Insert(upButton, -1);

        ToolButton homeButton = new ToolButton(Stock.Home);
        homeButton.IsImportant = true;
        toolbar.Insert(homeButton, -1);

        fileIcon = GetIcon(Stock.File);
        dirIcon = GetIcon(Stock.Open);

        ScrolledWindow sw = new ScrolledWindow();
        sw.ShadowType = ShadowType.EtchedIn;
        sw.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);
        vbox.PackStart(sw, true, true, 0);

        store = CreateStore();
        FillStore();

        IconView iconView = new IconView(store);
        iconView.SelectionMode = SelectionMode.Multiple;

        upButton.Clicked += new EventHandler(OnUpClicked);
        homeButton.Clicked += new EventHandler(OnHomeClicked);

        iconView.TextColumn = COL_DISPLAY_NAME;
        iconView.PixbufColumn = COL_PIXBUF;

        iconView.ItemActivated += OnItemActivated;
        sw.Add(iconView);
        iconView.GrabFocus();
        
        ShowAll();
    }

    Gdk.Pixbuf GetIcon(string name)
    {
        return Gtk.IconTheme.Default.LoadIcon(name, 48, (IconLookupFlags) 0);
    }

    ListStore CreateStore()
    {
        ListStore store = new ListStore(typeof (string), 
            typeof(string), typeo (Gdk.Pixbuf), typeof(bool));

        store.SetSortColumnId(COL_DISPLAY_NAME, SortType.Ascending);

        return store;
    }

    void FillStore()
    {
        store.Clear();

        if (!root.Exists)
            return;

        foreach (DirectoryInfo di in root.GetDirectories())
        {
            if (!di.Name.StartsWith("."))
                store.AppendValues(di.FullName, di.Name, dirIcon, true);
        }
        
        foreach (FileInfo file in root.GetFiles())
        {
            if (!file.Name.StartsWith("."))
                store.AppendValues(file.FullName, file.Name, fileIcon, false);
        }
    }

    void OnHomeClicked(object sender, EventArgs a)
    {
        root = new DirectoryInfo(Environment.GetFolderPath(
            Environment.SpecialFolder.Personal));
        FillStore();
        upButton.Sensitive = true;
    }

    void OnItemActivated(object sender, ItemActivatedArgs a)
    {
        TreeIter iter;
        store.GetIter(out iter, a.Path);
        string path = (string) store.GetValue(iter, COL_PATH);
        bool isDir = (bool) store.GetValue(iter, COL_IS_DIRECTORY);

        if (!isDir)
            return;

        root = new DirectoryInfo(path);
        FillStore();

        upButton.Sensitive = true;
    }

    void OnUpClicked(object sender, EventArgs a)
    {
        root = root.Parent;
        FillStore();
        upButton.Sensitive = (root.FullName == "/" ? false : true);
    }
    
    public static void Main()
    {   
        Application.Init();
        new SharpApp();
        Application.Run();
    }
}

فى هذا المثال، نعرض الأيكونات للمجلد المختار الحالى، ولديه شريط ادوات وزرين up و home ونستخدمهم لتصفح النظام



 ListStore store;

ال ListStore هو مخزن لعنصر (ويمثل بياناته بأعمدة) وهنا نستخدمه لتخزين بيانات ال IconView

 DirectoryInfo root = new DirectoryInfo("/");

هذا هو المجلد الجذر اللذى نبدأ عنده،



 ListStore store = new ListStore(typeof(string), 
     typeof(string), typeof(Gdk.Pixbuf), typeof(bool));

فى الطريقة CreateStore، ننشئ مخزن لعنصر (له 4 مكونات هم المسار، والإسم -للمجلد او الملف-، وصورة، وقيمة منطقية للتعبير عما اذا كان مجلد او ملف



 foreach (DirectoryInfo di in root.GetDirectories())
 {
     if (!di.Name.StartsWith("."))
         store.AppendValues(di.FullName, di.Name, dirIcon, true);
 }

نستخدم الطريقة FillStore لننشئ مخزن البيانات مكون من المجلدات عدا المخفية

 void OnHomeClicked(object sender, EventArgs a)
 {
     root = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
     FillStore();
     upButton.Sensitive = true;
 }

اذا ضغطنا على الزر Home، نحصل على مسار المنزل ونعيد ملء مخزن البيانات وننشط الزر up



 void OnItemActivated(object sender, ItemActivatedArgs a)
 { 
    ...
 }

فى الطريقة OnItemActivated، نتفاعل لحدث، يحدث عند الضغط على ايكون من الظاهرة على الويدجت



 string path = (string) store.GetValue(iter, COL_PATH);
 bool isDir = (bool) store.GetValue(iter, COL_IS_DIRECTORY);

 if (!isDir)
     return;

نحصل على مسار العنصر المنشط، ثم نقرر ماإذا كان مجلد او ملف -نقوم بالخروج فورا-

We get the path of the activated item. And we determine, if it is a directory or a file. If it is a file, we return.

  root = new DirectoryInfo(path);
  FillStore();

  upButton.Sensitive = true;

فى حال انه مجلد، نستبدل الجذر بالمسار الحالى ونعيد ملء مخزن البيانات وننشط حساسية الزر up



 void OnUpClicked(object sender, EventArgs a)
 {
     root = root.Parent;
     FillStore();
     upButton.Sensitive = (root.FullName == "/" ? false : true);
 }

عند الضغط على الزر up ، نستبدل مجلد الجذر بأبيه ونعيد ملء المخزن، لاحظ انه سيكون منشط فقط عند وجودنا فى اى مجلد اقل من /




IconView

Figure: IconView



ListView

فى المثال التالى، نعرض ويدجت الشجرة ليمثل list view، مرة اخرى سنستخدم ال ListStore ليمثل البيانات



listview.cs
 
using System;
using System.Collections;
using Gtk;

public class Actress
{
    public string Name;
    public string Place;
    public int Year;

    public Actress(string name, string place, int year)
    {
        Name = name;
        Place = place;
        Year = year;
    }
}

public class SharpApp : Window
{
    ListStore store;
    Statusbar statusbar;
    
    enum Column
    {
        Name,
        Place,
        Year
    }

    Actress[] actresses =
    {
        new Actress("Jessica Alba", "Pomona", 1981),
        new Actress("Sigourney Weaver", "New York", 1949),
        new Actress("Angelina Jolie", "Los Angeles", 1975),
        new Actress("Natalie Portman", "Jerusalem", 1981),
        new Actress("Rachel Weissz", "London", 1971),
        new Actress("Scarlett Johansson", "New York", 1984) 
    };

    public SharpApp() : base ("ListView")
    {
        BorderWidth = 8;

        SetDefaultSize(350, 250);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };

        VBox vbox = new VBox(false, 8);
        

        ScrolledWindow sw = new ScrolledWindow();
        sw.ShadowType = ShadowType.EtchedIn;
        sw.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);
        vbox.PackStart(sw, true, true, 0);

        store = CreateModel();

        TreeView treeView = new TreeView(store);
        treeView.RulesHint = true;
        treeView.RowActivated += OnRowActivated;
        sw.Add(treeView);

        AddColumns(treeView);
        
        statusbar = new Statusbar();
        
        vbox.PackStart(statusbar, false, false, 0);

        Add(vbox);
        ShowAll();
    }

    void OnRowActivated (object sender, RowActivatedArgs args) {

        TreeIter iter;        
        TreeView view = (TreeView) sender;   
        
        if (view.Model.GetIter(out iter, args.Path)) {
            string row = (string) view.Model.GetValue(iter, (int) Column.Name );
            row += ", " + (string) view.Model.GetValue(iter, (int) Column.Place );
            row += ", " + view.Model.GetValue(iter, (int) Column.Year );
            statusbar.Push(0, row);
        }
    }

    void AddColumns(TreeView treeView)
    {
        CellRendererText rendererText = new CellRendererText();
        TreeViewColumn column = new TreeViewColumn("Name", rendererText,
            "text", Column.Name);
        column.SortColumnId = (int) Column.Name;
        treeView.AppendColumn(column);

        rendererText = new CellRendererText();
        column = new TreeViewColumn("Place", rendererText, 
            "text", Column.Place);
        column.SortColumnId = (int) Column.Place;
        treeView.AppendColumn(column);

        rendererText = new CellRendererText();
        column = new TreeViewColumn("Year", rendererText, 
            "text", Column.Year);
        column.SortColumnId = (int) Column.Year;
        treeView.AppendColumn(column);
    }


    ListStore CreateModel()
    {
        ListStore store = new ListStore( typeof(string),
            typeof(string), typeof(int) );

        foreach (Actress act in actresses) {
            store.AppendValues(act.Name, act.Place, act.Year );
        }

        return store;
    }
    
    public static void Main()
    {
        Application.Init();
        new SharpApp();
        Application.Run();
    }
} 

فى مثالنا، سنعرض قائمة من 6 ممثلات "تمثل فى 6 صفوف" فى ويدجت الشجرة، كل صف يشمل اسم ومحل الميلاد وتاريخه



 public class Actress
 {
     public string Name;
     public string Place;
     public int Year;
  ...
 }

صف الممثلة يستخدم لتمثيل بيانات ممثلة

 ListStore CreateModel()
 {
     ListStore store = new ListStore( typeof(string), 
         typeof(string), typeof(int) );

     foreach (Actress act in actresses) {
         store.AppendValues(act.Name, act.Place, act.Year );
     }

     return store;
 }

ننشئ المودل (البيانات اللتى سيتم تمثيلها)، هنا ننشئ List Store، ولها 3 معاملات، اسم الممثلة، تاريخ ميلادها، ومحل الميلاد



 TreeView treeView = new TreeView(store);
 treeView.RulesHint = true;
 treeView.RowActivated += OnRowActivated;

هنا ننشئ ويدجت الشجرة، لاحظ انه يأخذ (ListStore)

 CellRendererText rendererText = new CellRendererText();
 TreeViewColumn column = new TreeViewColumn("Name", rendererText, "text", Column.Name);
 column.SortColumnId = (int) Column.Name;
 treeView.AppendColumn(column);

فى الطريقة AddColumns، ننشئ 3 اعمدة للنستخدمهم فى ال TreeView، الكود بالأعلى ينشئ عمود يعرض اسماء الممثلات



 if (view.Model.GetIter(out iter, args.Path)) {
     string row = (string) view.Model.GetValue(iter, (int) Column.Name );
     row += ", " + (string) view.Model.GetValue(iter, (int) Column.Place );
     row += ", " + view.Model.GetValue(iter, (int) Column.Year );
     statusbar.Push(0, row);
 }

عند الضغط على العنصر، نعرض الصف كله على شريط الحالة




ListView

Figure: ListView



Tree

فى هذه الجزئية سنتعرض لويدجت الشجرة TreeView ليمثل هيكلية البيانات

tree.cs

using Gtk;


public class SharpApp : Window
{
    
    public SharpApp() : base ("Tree")
    {
        SetDefaultSize(400, 300);
        SetPosition(WindowPosition.Center);
        DeleteEvent += delegate { Application.Quit(); };
 
        TreeView tree = new TreeView();
        
        TreeViewColumn languages = new TreeViewColumn();
        languages.Title = "Programming languages";
 
        CellRendererText cell = new CellRendererText();
        languages.PackStart(cell, true);
        languages.AddAttribute(cell, "text", 0);
 
        TreeStore treestore = new TreeStore(typeof(string), typeof(string));
 
        TreeIter iter = treestore.AppendValues("Scripting languages");
        treestore.AppendValues(iter, "Python");
        treestore.AppendValues(iter, "PHP");
        treestore.AppendValues(iter, "Perl");
        treestore.AppendValues(iter, "Ruby");
 
        iter = treestore.AppendValues("Compiling languages");
        treestore.AppendValues(iter, "C#");
        treestore.AppendValues(iter, "C++");
        treestore.AppendValues(iter, "C");
        treestore.AppendValues(iter, "Java");
 
        tree.AppendColumn(languages);
        tree.Model = treestore;
        
        Add(tree);
        ShowAll();
    }
    
    public static void Main()
    {
        Gtk.Application.Init();
        new SharpApp();
        Gtk.Application.Run();
    }
}

فى هذه المرة سنستخدم ويدجت ال TreeView لعرض بيانات هيكلية

 TreeView tree = new TreeView();

انشاء ويدجت الشجرة TreeView

 TreeViewColumn languages = new TreeViewColumn();
 languages.Title = "Programming languages";

لديها عمود واحد عنوانه Programming Languages

 CellRendererText cell = new CellRendererText();
 languages.PackStart(cell, true);
 languages.AddAttribute(cell, "text", 0);

نعرض بعض البيانات النصية

 TreeStore treestore = new TreeStore(typeof(string), typeof(string));

To store the data, we use the TreeStore object.

 TreeIter iter = treestore.AppendValues("Scripting languages");
 treestore.AppendValues(iter, "Python");
 treestore.AppendValues(iter, "PHP");



We append data to the tree. The TreeIter is for accessing data in a row.

 tree.AppendColumn(languages);

اضافة العمود

 tree.Model = treestore;

اخيرا نحدد المودل للويدجت الشجرة


Tree

Figure: Tree



فى هذا الفصل تحدثنا عن ويدجات متقدمة فى GTK#


Home ‡ Contents ‡ Top of Page