Amiga C

30. Bölüm

Cenker Özkurt

Amiga C'de bu aydan itibaren yeni konumuz geçen sayılarda da söz verdiğim gibi, 'intuition.library'. 'intuition.library' hakkında bundan önceki sayılarda çok şey söyledik. Fakat ben yine de bu konu üzerinde hala anlatacak birşeyler bulabiliyorum. Çünkü Amiga'da sonuç mükemmel.

Şimdi isterseniz Amiga'nın şu mükemmel library'lerinden biri olan 'intuition.library'nin içine bir girelim.

Intuition.library ile window, screen, gadget ve menüler kontrol ediliyor, intuition (=İçine doğma, seziş), zaten isim olarak da kendini anlatıyor. Bilgisayarın, bilgisayar kullanıcıları ile iyi bir diyalog kurmasını hedefliyor.

Intuition, bir screen'ler ve window'lar dünyası. Screen, yapay görüntümüzün temel elemanı. Screen'de kullanacağımız fontları, renkleri ve çözünürlüğü rahatlıkla seçebiliyoruz. Window'lar ise, intuition içerisinde en yüksek mertebeye sahip. Window'lar üzerindeki gadget'lar sayesinde giriş çıkış yapabiliriz. Her iki Screen ve Window yapısı üzerinde programlar ile rahatlıkla değişiklik yapabiliriz.

Bir program içerisinde intuition.library'i kullanmak istiyorsak, ilk olarak bu library'nin yapı değişkenini tanımlamamız gerekir. Bu değişken bildiğimiz 'IntuitionBase' yapı değişkenidir ve library'yi hafızaya yüklendikten sonra, yüklenmiş olan hafıza bölgesinin başlangıç adresini ve diğer parametreleri tutar. Program içerisinde bu olayı şöyle tanımlarız;

struct IntuitionBase *IntuitionBase;
Burada, IntuitionBase yapı değişkeni pointer olarak tanımlanmıştır. Daha sonra hafızaya yüklemek için,
IntuitionBase=(struct IntuitionBase *)
  OpenLibrary("intuition.library", INT_REV);
işlemlerini yaparız.

Artık intuition.library tanımlanmış ve hafızaya yüklenerek kullanılır hale gelmiştir. Bundan sonra herhangi bir intuition.library kullanan bir sistem komutunu kullanabiliriz. Örneğin bir ekran açabiliriz.

Hafızaya yükleme işlemini OpenLibrary() fonksiyonu sağlıyor. İlk parametre, açılması istenilen library adını, ikincisi ise versiyon numarasını istiyor. Burada INT_REV, intuition_revision yani intuition düzeltme numarasını içeriyor. Bu library'ler geliştirildikçe bu revision sayısı da değişiyor. Şimdi Window'ları ve Screen'leri daha derinlemesine inceleyelim.

Window ve Screen'ler:

Window'lar intuition ekranının temel elemanını oluşturuyor. Window'lardan daha üst düzeyde bir yapı yoktur. Screen'ler dahi daima Window'lar altında oluşur. Bütün giriş-çıkış hareketleri window'lar üzerinden alınır.

Window, basit bir şekilde, bir kutu olarak screen üzerinde kendini gösterir. Çok küçük bir pencere açtığınızda üzerine text ve grafik yazamazsınız. Fakat, tabii ki başka büyük window'lar açarak istediğinizi gerçekleştirebilirsiniz. Açtığınız window'a resim çizebilir, bunun ötesinde vermiş olduğunuz mesajlar sayesinde, giriş alabilirsiniz. Bütün window'lar multi-tasking olarak başka programlar çalışırken bile size hizmet verebilir. Böylece bir işlemi birçok parçalara bölerek çalıştırabilirsiniz. Fakat her an için yalnızca bir window'dan giriş yapılabilir. Bunun ötesinde her window kendisi için bir console device seçer. Böylece window'lar düzenli ve sıralı bir şekilde çalışır.

Screen'ler ise bir dereceye kadar sınırlandırılmış yapıdır. Arka fonda oluşur, üzerinde window'lar görüntülenir ve idare edilir. Window'a benzer bir şekilde, screen ekranda bir kare şeklinde görülür.

Intuition altında iki çeşit screen vardır. Bunlardan WorkBench screen'i, standart olanıdır. Bu screen'in özellikleri önceden verilmiştir. Standart ve bilinen özelliklere sahiptir.

İkincisi ise Customized screen'dir. Bu screen'nin de parçacıkları program tarafından ayarlanabilir. Customize screen, herhangi bir genişlikte olabilir.

WorkBench screen'in, customize screen'e göre belli başlı bazı avantajları vardır. Bunlardan ilki, ikonlardır. WorkBench üzerinde ikon yaratmak mümkün; fakat, customize screen'e bu olayı taşımak kolay olmayabilir.

Screen oluşturulmak istendiğinde yalnızca görüntü oluşturulmaz. Bunun yanında bir de çalışmak için hafızada istenilen boyutlarda bir yer ayrılır. Ayrıca açılan her window için de bir hafıza bölgesi ayrılır.

Window'larda olduğu gibi screen'ler de birden fazla açılarak multi-tasking olarak çalışabilir. Tabii ki açılan her screen hafızamızdan biraz götürecektir. Bu nedenle örneğin 512KB'lik bir Amiga'da 640x512'lik ölçülerde en fazla 2 ya da 3 ekran açabilirsiniz.

Window'ların oluşturulması:

Bu kısımda basit olarak bir window'un workbench screen'i üzerinde nasıl oluşturulacağını öğreneceğiz. Window oluşturmak için iki objeye ihtiyacımız vardır. Bunlar, önceden C dilinde de kullanılacak şekilde hazırlanmıştır. Bunlardan ilki NewWindow yapı değişkenidir. Bu yapıda açılmak istenen window'un özellikleri verilir. Bir intuition fonksiyonu olan OpenWindow() ile de NewWindow yapı değişkenine vermiş olduğumuz özelliklerde bir window açılır. OpenWindow() fonksiyonu window'u açtıktan sonra ikinci bir değişkeni daha oluşur. Bu yapı değişkeninin ismi 'window' dur. Bu değişken ile açılan window'u idare ederiz.

NewWindow yapı değişkeni aşağıda olduğu gibi tanımlanmıştır. Her yeni bir ekran açıldığında bu değişken yeniden kullanılır. Şimdi NewWindow yapı değişkenine bir bakalım.

struct NewWindow {
   SHORT LeftEdge,TopEdge,Width,Height;
   UBYTE DetailPen,BlockPen;
   USHORT IDCMPFlags;
   ULONG Flags;
   struct Gadget *FirstGadget;
   struct Image *ChechMark;
   UBYTE *Title;
   struct Screen *Screen;
   struct BitMap *BitMap;
   SHORT MinWidth,MinHeight,MaxWidth,MaxHeigth;
   USHORT Type;
};
NewWindow yapı değişkeninde kullanacağımız başlıca parametrelere bir göz atalım:

LeftEdge ve TopEdge değişkenleri açılmak istenen window'un sol üst koordinatlarını belirler. Window açıldığında başlangıç noktası burası olacaktır.

Width ve Height, görüntülenecek window'un genişliğini ve yüksekliğini ayarlar. Window açıldığında, bu yükseklik ve genişlikte olacaktır.

DetailPen ve BlockPen, window içerisinde kullanılacak renkleri belirler, yazmaya kalktığımızda bu renklerde yazacaktır.

Flags, kullanılacak olan aktiviteleri ayarlar.

Text, window'un başlığını oluşturur.

Type, kullanılan screen tipini saklar.

Şimdilik yukarıda açıklamadığım değişken alanlarına NULL ya da 0 değeri vererek, yani bu değişkenleri ihmal ederek bir örnek verelim.

#include <stdio.h>
#include <exec/types.h>
#include <intuition/intuitionbase.h>
struct IntuitionBase *IntuitionBase; 
struct Window *Window;

main()
{
  IntuitionBase=(struct IntuitionBase *)
  OpenLibrary("intuition.library",0);

  if(!IntuitionBase) {
    printf("Intuition Error!");
    return(0);
}

if(!create_window()) {
    printf("Window acilamadi!.");
} else {
    Delay(100);
}

if(Window) CloseWindow(Window); 
if(IntuitionBase) CloseLibrary(IntuitionBase);
}

create_window()
{
  struct NewWindow NewWindow;

  NewWindow.LeftEdge=20; 
  NewWindow.TopEdge=20;
  NewWindow.Width=300;
  NewWindow.Height=100;
  NewWindow.DetailPen=0;
  NewWindow.BlockPen=1;
  NewWindow.Title=(UBYTE *)"Basit bir Window";
  NewWindow.Flags=ACTIVATE;
  NewWindow.IDCMPFlags=0;
  NewWindow.Type=WBENCHSCREEN;
  NewWindow.FirstGadget=NULL;
  NewWindow.CheckMark=NULL; 
  NewWindow.Screen=NULL;
  NewWindow.BitMap=NULL;
  NewWindow.MinWidth=0;
  NewWindow.MinHeight=0;
  NewWindow.MaxWidth=0;
  NewWindow.MaxHeight=0;

  Window=(struct Window *) OpenWindow(&NewWindow);

  if(Window==NULL) return(0);
  return(1);
}
Yukarıdaki örneğimizde create_window() adı altında bir window açma rutini hazırladım. Bu rutini çağırdığımızda, NewWindow yapı değişkenine istenilen özellikler verilerek Window açılıyor. Vermiş olduğumuz parametreleri bir inceleyelim.

Title, bir string dizi istiyor. Daha sonra ekran açıldığında bu diziyi window'un tepesindeki bara başlık olarak atıyor. Örneğimizde "Basit bir Window" dizisini kullandık.

Type'ı WBENCHSCREEN olarak aldık, öylece window 640x200'lük screen'de açılacak.

DetailPen ve BlockPen, renk registerlerini oluşturuyor. DetailPen, yazı ve window'un çerçeve rengini tutuyor. BlockPen, arka fon rengini tutuyor. Bu değişkenlere -1 değerini verirsek, screen'in seçmiş olduğu DetailPen ve BlockPen değerlerini kullanmış oluyoruz.

Flags değişkeni, çok önemli ve dikkatli olunması gereken bir değişken. Biz burada ACTIVATE parametresini kullandık. Bu sayede window açılır açılmaz aktive edilecektir. Yani, eğer bir giriş yapılacaksa bu window'dan al anlamına gelmektedir.

LeftEdge ve TopEdge sol üst noktamızdı. Bu değişkenleri de 20-20 seçtik. Genişlik ise Width=300, Height=100.

Diğer yapı değişkenlerini kullanmadığımız için 0 veya NULL olarak eşitledik. Böylece bu değişkenlerin yapmış olduğu işlevler ihmal edilmiş oluyor.

Flag olarak ACTIVATE'i seçmiştik. Şimdi diğer flag'lara ve ne anlama geldiğini öğrenelim.

Window Flags:

ACTIVATE Window açılır açılmaz diğer Window'lara göre aktif olarak açılır.
ACTIVEWINDOW Window açıldıktan sonra eğer window aktif ise mesaj al.
BACKDROP Bütün window'ların arkasında açılmasını sağlar.
BORDERLESS Özel olarak açılan pencereye çerçeve çizmez.
INACTIVEWINDOW Window açıldıktan sonra aktif değilse bile mesaj al.
NOCAREREFRESH Window'da bir değişiklik yapılsa bile değişiklikleri tazeleme.
REPORTMOUSE Mouse hareketlerini kontrol edilebilir yap.
SIMPLE_REFRESH Window'da bir değişiklik yapıldığında değişikliği yenide tazele.
SMART_REFRESH Window'da meydana gelen değişikliği otomatik olarak tazele.
SUPER_BITMAP Kullanıcının istediği hafıza bölgesini kullan.

Yukarıdaki flag'ları kullanarak istediğiniz window'u deneyin. Son bir örnekle yazımızı bitirelim. Bu örnekte, üç adet window açıyoruz. Açılan window'lara değişik isimler attım. Ayrıca create_window() rutinimizi de biraz geliştirdim.

#include <stdio.h>
#include <exec/types.h>
#include <intuition/intuitionbase.h>

struct IntuitionBase *IntuitionBase;
struct Window *Win0,*Win1,*Win2;

main()
{
  SHORT x,y;
  UBYTEname[20];

  IntuitionBase=(struct IntuitionBase *)
  OpenLibrary("intuition.library",0);
 
  if(!IntuitionBase) {
    printf("Intuition Error!");
    return(0);
  }

  x=y=20;
  strcpy(name,"Window 0");
  Win0=(struct Window *) create_window(x,y,name);

  x=y=40;
  strcpy(name,"Window 1");
  Win1=(struct Window *) create_window(x,y,name);

  x=y=60;
  strcpy(name,"Window 2");
  Win2=(struct Window *) create_window(x,y,name);

  Delay(100);
  if(Win0) CloseWindow(Win0);
  Delay(100);
  if(Win1) CloseWindow(Win1);
  Delay(100);
  if(Win2) CloseWindow(Win2);

  if(IntuitionBase) CloseLibrary(IntuitionBase);
}

create_window(x,y,name) 
SHORT x,y; 
UBYTE *name;
{
  struct NewWindow NewWindow;

  NewWindow.LeftEdge=x;
  NewWindow.TopEdge=y;
  NewWindow.Width=300;
  NewWindow.Height=100;
  NewWindow.DetailPen=-1;
  NewWindow.BlockPen=-1;
  NewWindow.Title=name;
  NewWindow.Flags=ACTIVATE;
  NewWindow.IDCMPFlags=0;
  NewWindow.Type=WBENCHSCREEN;
  NewWindow.FirstGadget=NULL;
  NewWindow.CheckMark=NULL;
  NewWindow.Screen=NULL;
  NewWindow.BitMap=NULL;
  NewWindow.MinWidth=0;
  NewWindow.MinHeight=0;
  NewWindow.MaxWidth=0;
  NewWindow.MaxHeight=0;
  return(OpenWindow(&NewWindow));
}
Programı yazıp çalıştırdığınıza arka arkaya üç adet window açılacak. Daha sonra belirli aralıklarla window'lar teker teker kapanacaktır. Compile ve Link işlemlerini,
Aztec 3.6'da -> CC +1 c.c, LN c.o -lc32 
Aztec 5.0'da -> CC c.c -3 +1, LN c.o -lc1
olarak yapabilirsiniz. Gelecek ay kaldığımız yerden devam edeceğiz.

Şimdilik hepinize iyi çalışmalar...