|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Castellano ChineseGB Deutsch Francais Italiano Nederlands Portugues Russian Turkce |
taraf�ndan Reha K. Ger�eker <gerceker(at)itu.edu.tr> Yazar hakk�nda: Reha �stanbul T�rkiye'de bir bilgisayar m�hendisli�i ��rencisi. Yaz�l�m geli�tirme ortam� olarak Linux'un sa�lad��� �zg�rl��� �ok seviyor. Zaman�n�n �o�unu programc�l�kla u�ra�arak ge�irir. G�n�n birinde iyi bir bilgisayar programc�s� olmay� istiyor. ��erik:
|
�zet:
Ncurses metin tabanl� terminaller i�in pencereler olu�turma ve kullanmaya, ekran� farkl� renklerde boyamaya ve fonksiyon tu�lar�n� kullanmaya imkan veren bir k�t�phanedir.
Yazd���n�z bir program�n renkli ve pencere temelli bir aray�ze sahip olmas�n� m� istiyorsunuz? Ncurses metin tabanl� terminaller i�in pencereler olu�turma ve kullanmaya, ekran� farkl� renklerde boyamaya ve fonksiyon tu�lar�n� kullanmaya imkan veren bir k�t�phanedir. Ncurses ile yapabilecekleriniz:
Ncurses k�t�phanesini ANSI/POSIX uyumlu UNIX sistemlerde kullanmak m�mk�nd�r. Bunun yan�nda, hangisi kullan�l�yor olursa olsun terminal �zelliklerini sistemden ��renerek terminalden ba��ms�z bir aray�z sunmaktad�r. Bu a��lardan programc�n�n farkl� platformlar ve terminaller i�in bile g�venerek kullanabilece�i bir k�t�phanedir.
Midnight Commander, ncurses kullan�larak yaz�lm�� programlara verilecek �rneklerden bir tanesidir. Ayr�ca konsolda �ekirdek konfig�rasyonu yapmakta kullan�lan aray�z ncurses ile haz�rlanm��t�r. Bu iki programa ili�kin ekran g�r�nt�lerini a�a��da g�r�yorsunuz.
Ncurses GNU/Linux alt�nda geli�tirilmektedir. www.gnu.org/software/ncurses/ adresinden g�ncel s�r�m�n�, ayr�nt�l� bilgileri ve di�er gerekli adresleri ��renebilirsiniz.
Ncurses k�t�phanesini kullanmak i�in curses.h ba�l�k dosyas�n� kodunuza eklemeli ve kodunuzu gcc ile derlerken -lcurses parametresini kullanmay� unutmamal�s�n�z.
Ncurses konusuna girerken k�t�phane i�in temel bir veri yap�s�ndan bahsetmek gerekir. WINDOW adl� bu yap�, ad�ndan da anla��ld��� gibi, ncurses ile olu�turaca��n�z pencereleri temsil etmek i�in kullan�l�r. Hemen hemen t�m ncurses fonksiyonlar� WINDOW tipinden bir i�aret�iyi parametre olarak al�rlar.
Pencereler, ncurses'da en �ok kullan�lan bile�enlerdir. Siz hi�bir pencere yaratmasan�z bile ekran tek ba��na bir pencere olarak kabul edilir. Standart giri�/��k�� k�t�phanesinde (y�nlendirmeler olmad��� s�rece) ekran� stdout adl� FILE i�aret�isinin temsil etmesi gibi ncurses'da da ekran WINDOW tipinde stdscr adl� bir i�aret�i ile temsil edilir. stdscr i�aret�isine ek olarak, k�t�phane taraf�ndan curscr adl� bir ba�ka WINDOW i�aret�isi daha tan�mlan�r. stdscr'nin ekran� temsil etmesi gibi, curscr de o anki ekran g�r�nt�s�n� temsil eder. "�kisinin aras�nda ne fark var ki?" diye d���n�yor olabilirsiniz, okumaya devam edin.
Program�n�zda ncurses fonksiyonlar�n� ve de�i�kenlerini kullanabilmek i�in her�eyden �nce initscr fonksiyonunu �a��rman�z gerekir. Bu fonksiyon stdscr, curscr gibi de�i�kenler i�in bellek al�r ve k�t�phaneyi haz�r hale getirir. Dolay�s�yla her ncurses fonksiyonu initscr'yi takip etmek zorundad�r. Benzer �ekilde ncurses ile i�inizi bitirdi�inizde endwin fonksiyonunu kullanarak k�t�phanenin yaratt��� de�i�kenlerin yokedilmesini sa�layabilirsiniz. Bunu yapt�ktan sonra yeniden initscr �a�r�s� yapmad���n�z s�rece ncurses fonksiyonlar�n� kullanamazs�n�z.
Program�n�zda initscr ve endwin �a�r�lar� aras�nda standart giri�/��k�� k�t�phanesinin fonksiyonlar�n� kullanarak ekrana ��kt� g�ndermemelisiniz. Bu durumda bekledi�iniz g�r�nt�y� elde edemeyebilirsiniz. Ncurses aktif oldu�u s�rece ekran ��kt�s� i�in sadece onun fonksiyonlar�n� kullanmaya dikkat edin. initscr �a��rmadan �nce ya da endwin �a��rd�ktan sonra istedi�inizi yapabilirsiniz.
WINDOW yap�s� i�inde pencerenin eni, boyu, konumu gibi bilgiler tutuldu�u gibi i�eri�i de saklan�r. Ncurses fonksiyonlar� ile bir pencereye yaz� yaz�ld��� zaman bu o yaz�n�n hemen ekranda g�r�nmesi anlam�na gelmez. Yaz�lan yaz� �ncelikle ilgili pencerenin i�eri�inde g�ncellenir. Ekran g�r�nt�s�n�n g�ncellenmesi i�in refresh ya da wrefresh fonksiyonlar�n�n �a�r�lmas� gerekir.
stdscr ile curscr aras�nda yukar�da kafan�za tak�lm�� olabilecek fark buradad�r. curscr ekran�n o anki g�r�nt�s�n� i�erirken, stdscr'nin i�eri�i yap�lm�� yeni fonksiyon �a�r�lar� sonucu farkl� olabilir. stdscr ile curscr'nin �rt��mesi i�in refresh fonksiyonunun �a�r�lmas� gerekir. Di�er bir deyi�le, curscr'nin i�eri�ini de�i�tiren tek fonksiyon refresh fonksiyonudur. Sizin curscr'yi kurcalamaman�z ve onunla ilgili i�leri refresh fonksiyonuna havale etmeniz tavsiye edilir.
refresh fonksiyonu ekran� g�ncelleme i�ini m�mk�n oldu�unca h�zl� yapabilmek i�in de�i�ik bir mekanizmaya sahiptir. Fonksiyon �a�r�ld���nda g�r�nt�s� g�ncellenecek olan pencerenin yaln�zca de�i�en sat�rlar�n� g�nceller. B�ylece de�i�meyen sat�rlar� yeniden ekrana yazmak i�in i�lemci zaman� t�ketmez. Ncurses ile standart giri�/��k�� k�t�phanesi fonksiyonlar�n�n birlikte kullan�lmas�n�n istenmeyen sonu�lar do�urmas�n�n sebebi bu mekanizmad�r; ncurses fonksiyonlar� bir pencereye yazd��� zaman o sat�r�n de�i�ti�ini belirten bayra�� do�rularlar, standart giri�/��k�� fonksiyonlar� ise bu i�i yapmaz.
refresh ile wrefresh fonksiyonlar� temelde ayn� i�i yaparlar. wrefresh fonksiyonu parametre olarak bir WINDOW i�aret�isi al�r ve bu pencerenin g�r�nt�s�n� g�nceller. refresh() ise wrefresh(stdscr) �a�r�s� yapmaya denktir. Daha sonra da bahsedece�im gibi bir�ok ncurses fonksiyonunun (wrefresh gibi) stdscr i�in yaz�lm�� makrolar� vard�r.
�imdi kendi pencerelerinizi yaratman�z� sa�layan subwin ve newwin fonksiyonlar�ndan bahsedelim. Bu iki fonksiyon da parametre olarak olu�turmak istedi�iniz pencerenin enini, boyunu, sol �st k��esinin koordinatlar�n� al�rlar. D�n�� de�erleri ise yeni pencereyi temsil eden bir WINDOW i�aret�isidir. Bu yeni i�aret�iyi yukar�da bahsetti�im wrefresh ve daha sonra bahsedece�im di�er fonksiyonlarla birlikte kullanabilirsiniz.
"Madem ayn� i�i yap�yorlar, neden iki tane fonksiyon var?" diye d���nebilirsiniz. Hakl�s�n�z, tam olarak ayn� i�i yapm�yorlar. subwin fonksiyonu yeni yaratt��� pencereyi bir ba�ka pencerenin alt penceresi olarak yarat�r. Bu �ekilde yarat�lan pencere ana pencerenin o anki t�m �zelliklerini miras al�r. Bu �zellikler daha sonra ana pencereden ba��ms�z olarak de�i�tirilebilir. Bu durum ana pencere ile alt pencereyi birbirine ba�layan bir durum de�ildir.
Bunun d���nda ana ve alt pencereyi birbirine ba�layan bir �zellik vard�r: Pencere i�eri�inin tutuldu�u karakter dizisi ana ve alt pencereler i�in ortakt�r. Di�er bir deyi�le, ana pencere ile alt pencerenin kesi�ti�i bir noktadaki karakter her iki pencere taraf�ndan da de�i�tirilebilir. B�yle bir kareye alt pencere yazarsa ana pencerenin, ana pencere yazarsa alt pencerenin o noktadaki karakterinin �zerine yaz�l�r.
newwin ise tamamiyle yeni bir pencere olu�turur. B�yle bir pencere, kendi alt pencereleri olmad��� s�rece karakter dizisini ba�ka pencerelerle payla�maz. subwin fonksiyonunu kullanman�n avantaj�, ortak karakter dizisi kullan�m� sebebiyle daha az bellek t�ketilmesidir. Ancak pencerelerin birbirlerinin bilgilerinin �zerine yazmas�n�n dezavantaj getirdi�i durumlarda newwin kullanmak do�ru harekettir.
Alt pencerelerinizi ko�ullar elverdi�i s�rece istedi�iniz derinlikte yaratabilirsiniz. Her alt pencerenin de kendi alt pencereleri olabilir fakat bu durumda ayn� karakter dizisini ikiden de fazla pencerenin payla�t���n� unutmay�n.
Yaratt���n�z pencerelerle i�iniz bitti�inde delwin fonksiyonuyla onlar� yokedebilirsiniz. Fonksiyonlar�n parametrelerini ��renmek i�in man sayfalar�na bakman�z� tavsiye ederim.
stdscr'den, curscr'den, ekran g�r�nt�s�n� g�ncellemekten ve yeni pencereler yaratmaktan bahsettik. Peki pencerelerin i�eri�ini nas�l de�i�tirece�iz? Pencerelere nas�l yazaca��z ve pencerelerden nas�l bilgi okuyaca��z?
Bunlar i�in standart giri�/��k�� k�t�phanesinin fonksiyonlar�na �ok benzeyen fonksiyonlar kullan�lmaktad�r. printf yerine printw, scanf yerine scanw, putc ya da putchar yerine addch, getc ya da getchar yerine getch kullan�l�r. Kullan�mlar� al���ld��� gibidir, kullan�m olarak sadece isimleri de�i�iktir. Benzer �ekilde pencereye bir katar (string) yazmak i�in addstr, pencereden bir katar okumak i�in getstr kullan�labilir. T�m bu fonksiyonlar ba�lar�na bir 'w' harfi eklenerek ve birinci parametre olarak bir WINDOW i�aret�isi alarak belirtilen bir ba�ka pencereye de yazabilirler. �rne�in, printw(...) ile wprintw(stdscr, ...) ayn� i�i yapan iki �a�r�d�r, ayn� refresh() ve wrefresh(stdscr) durumunda oldu�u gibi.
Bu fonksiyonlara �ok ayr�nt�l� olarak de�inmek fazla yer kaplayacakt�r. Yapt�klar� i�leri, prototiplerini, d�n�� de�erlerini ve uyar�lar� ��renmek i�in en iyi kaynak her zaman oldu�u gibi man sayfalar�d�r. S�z�n� etti�im her fonksiyon i�in kullanmadan �nce man sayfas�na bir bakman�z� tavsiye ederim. �ok detayl� bilgiler edinebilirsiniz. Ayr�ca yaz�n�n son b�l�m�n� ��retici bir �rne�e ay�rd�m. �u ana kadar anlatt���m ve anlataca��m hemen hemen t�m fonksiyon ve kavramlar� bu �rnek programda takip etme imkan� bulacaks�n�z.
Ncurses ile pencerelere yazmak ve pencerelerden okumak s�zkonusu oldu�u zaman mant�ksal ve fiziksel imle� kavramlar�na da de�inmek gerekir. Fiziksel imle�ten kas�t yan�p s�nerek s�rekli ekranda g�r�nen bildi�imiz imle�tir ve bir tanedir. Mant�ksal imle�ler ise ncurses pencerelerine ait olan ve her pencerenin mutlaka sahip oldu�u ba�ka imle�lerdir. Birden �ok pencere olabilece�ine g�re mant�ksal imle� de birden fazla olabilir.
Mant�ksal imlecin g�revi pencereye bir yaz� yaz�laca�� zaman yazma i�leminin ba�layaca�� ya da pencereden bir bilgi okunaca�� zaman bu bilginin okunaca�� kareyi g�stermektir. Mant�ksal imleci iste�inize g�re hareket ettirebilmeniz demek ekran�n ya da yaratt���n�z pencerenin istedi�iniz karesine istedi�iniz zaman yaz� yazabilmeniz anlam�na gelir. Bu, standart giri�/��k�� k�t�phanesinin sa�lamad��� bir avantajd�r.
Mant�ksal imlecin hareket ettirilmesi i�ini yapan fonksiyon move ya da hemen tahmin edece�iniz �zere wmove fonksiyonlar�d�r. move fonksiyonu wmove fonksiyonunun stdscr i�in yaz�lm�� bir makrosudur.
Bir de mant�ksal imle� ile fiziksel imlecin koordinasyonunun sa�lanmas� durumu s�zkonusudur. Herhangi bir yazma i�leminin ard�ndan fiziksel imlecin bulunaca�� konum, her pencerenin sahip oldu�u _leave bayra��n�n de�erine bak�larak kararla�t�r�l�r. E�er _leave do�ruysa, mant�ksal imle� yazma i�leminden sonra fiziksel imlecin �zerine (son harfin yaz�ld��� kareye) getirilir. E�er _leave yanl��sa, fiziksel imle� mant�ksal imlecin bulundu�u kareye (ilk harfin yaz�ld��� kareye) geri getirilir. _leave bayra��n� y�neten fonksiyon leaveok fonksiyonudur.
Fiziksel imlecin hareket ettirilmesini sa�layan fonksiyon mvcur fonksiyonudur. Di�er fonksiyonlardan farkl� olarak mvcur fonksiyonu bir sonraki refresh'te de�il, hemen etkin olur. Fiziksel imlecin ekranda g�r�nmesini istemiyorsan�z, curs_set fonksiyonunu ilgili parametreleri ile kullanabilirsiniz. Detaylar i�in man sayfalar�na bak�n�z.
Yukar�da bahsetti�im imleci hareket ettirme ve yaz� yazma i�lemlerini tek bir �a�r� ile de yapabilirsiniz. Bu, fonksiyon �a�r�lar�n� birle�tiren makrolar�n varl��� sayesinde m�mk�nd�r. Bu �a�r�lar da addch, addstr, printw, getch, getstr, scanw gibi fonksiyonlar�n man sayfalar�nda detayl� olarak a��klanm��t�r.
Pencelere yazmak tamam. Peki pencereleri nas�l temizleyece�iz, istedi�imiz sat�rlar� ve karakterleri nas�l silece�iz?
Ncurses'da silme, silinecek karenin, sat�r�n ya da pencerenin i�eri�inin bo�luklarla doldurulmas� demektir. A�a��da de�indi�im silme fonksiyonlar�n�n yapt��� da silinecek yerleri bo�lukla doldurmakt�r.
�nce tek tek karakterler ya da sat�rlarla u�ra�an fonksiyonlara de�inelim. delch ve wdelch pencerede o an mant�ksal imlecin alt�nda olan karakteri siler ve ayn� sat�rda mant�ksal imlecin sa��nda bulunan karakterleri birer sola kayd�r�r. deleteln ve wdeleteln ise mant�ksal imlecin bulundu�u sat�r� sildikten sonra alttaki sat�rlar� birer yukar� kayd�r�r.
clrtoeol ve wclrtoeol fonksiyonlar� mant�ksal imlecin bulundu�u sat�rda imlecin sa��nda kalan t�m karakterleri silerler. clrtobot ve wclrtobot fonksiyonlar� ise �nce bir wclrtoeol �a��r�p sat�rda mant�ksal imlecin solunda kalan karakterleri, daha sonra da mant�ksal imlecin bulundu�u sat�r�n alt�nda kalan t�m sat�rlar� silerler.
Bunlar�n d���nda bir de t�m ekran� ya da pencereyi temizlemeye yarayan fonksiyonlar vard�r. T�m ekran� silecek fonksiyonlar�n kullanabilece�i iki y�ntem vard�r. Birincisi t�m ekran� bo�luklarla doldurup refresh fonksiyonunu �a��rmak, di�eri de terminale ekran� temizlemesini belirten kontrol kodunu g�ndermektir. Birinci y�ntem ikinciden daha yava�t�r ��nk� tek tek her karakterin ekrana yeniden yaz�lmas�n� gerektirir. �kincisi ise t�m ekran� hemen temizler.
erase ve werase fonksiyonlar� bir pencerenin karakter dizisini bo�luklarla dolduran fonksiyonlard�r. Bir sonraki refresh �a�r�s�nda pencere temizlenmi� olacakt�r. Bu fonksiyonlar� kullanmak temizlenmek istenen pencere tam ekran boyutunda ise �ok mant�kl� de�ildir. ��nk� bu fonksiyonlar yukar�da bahsedilen y�ntemlerden ilkini kullanmaktad�r. Temizlenecek pencere tam ekran boyutunda oldu�u zaman a�a��da anlataca��m fonksiyonlar� kullanmak daha avantajl�d�r.
Di�er fonksiyonlara ge�meden �nce _clear bayra��ndan s�zetmek gerekir. Her pencerede olan _clear bayra��, e�er do�ruysa bir sonraki refresh'te terminale kontrol kodunun g�nderilmesini ister. Ancak refresh bunu yapmadan �nce bunu isteyen pencerenin tam ekran boyutunda olup olmad���n� (_FULLWIN bayra�� ile) kontrol eder. E�er pencere tam ekran boyutundaysa, refresh terminalin ekran� temizlemesini sa�lar ve sadece bo�luktan farkl� olan karakterleri ekrana yazar. Bu, t�m ekran boyutunda temizlemenin h�zl� olmas�n� sa�lar. Terminal y�nteminin sadece tam ekran boyutundaki pencerelerin temizlenmesi i�in kullan�lmas�n�n sebebi, terminale kontrol kodu g�nderildi�i zaman t�m ekran�n temizlenmesidir. Pencere tam ekran boyutunda de�ilse, t�m ekran�n temizlenmesi istenmez. _clear bayra��n� clearok fonksiyonu kontrol eder.
clear ve wclear fonksiyonlar� tam ekran boyutundaki pencerelerin temizlenmesi i�in tercih edilir. Asl�nda bu fonksiyonlar bir werase ve bir clearok �a�r�s� yapmaya denktir. �ncelikle pencerenin karakter dizisini bo�luklarla doldururlar. Daha sonra da _clear bayra��n� do�rulayarak pencere tam ekran boyutunda ise terminal yoluyla, de�ilse de tek tek t�m karelerin �zerine bo�luk karakteri yazmak yoluyla pencereyi temizlerler.
Sonu� olarak, temizlenecek pencerenin tam ekran boyutunda oldu�unu biliyorsan�z, clear ya da wclear kullan�n. Daha h�zl� bir sonu� elde edersiniz. Fakat silinecek pencere tam ekran boyutunda de�ilse, wclear ya da werase kullanman�z aras�nda bir performans fark� yoktur.
Ekran �zerinde g�r�len renkleri renk �iftleri olarak adland�rmak gerekir. ��nk� her karenin bir arkaplan rengi, bir de yaz� rengi vard�r. Ncurses ile renkli yazabilmenin yolu da kendinize ait renk �iftleri yaratmak ve yaz�lar�n�z�n bu �iftler kullan�larak yaz�lmas�n� sa�lamakt�r.
Ncurses fonksiyonlar�n� kullanabilmek i�in initscr �a�r�s� yapman�z�n gerekmesi gibi, renk fonksiyonlar�n� kullanmadan �nce de start_color fonksiyonunu �a��rman�z gerekir. Bundan sonra renk �iftleri olu�turmak i�in kullanman�z gereken fonksiyon init_pair fonksiyonudur. init_pair ile bir renk �ifti olu�turdu�unuzda, fonksiyona aktarm�� oldu�unuz ilk parametre olan say� ile bu renk �iftini ili�kilendirmi� olursunuz. Daha sonra program�n�zda bu �ifti kullanmak istedi�inizde COLOR_PAIR makrosunu bu say� ile �a��rman�z yeterli olacakt�r.
Renk �iftleri olu�turman�n d���nda yaz�lar�n�z�n bu �iftlerle yaz�lmas�n� sa�laman�z gerekir. Bunu yapan fonksiyonlar attron ve wattron fonksiyonlar�d�r. Bu fonksiyonlar, attroff veya wattroff �a�r�lar� yap�lana kadar ilgili pencereye yaz�lacak her yaz�n�n belirtilen renk �ifti ile yap�lmas�n� sa�larlar.
Bir de pencerelerin genel arkaplan ve yaz� renklerini de�i�tiren bkgd ile wbkgd fonksiyonlar� vard�r. Bu fonksiyonlar �a�r�ld�klar� zaman ilgili pencerenin renk �iftini istenen renk �ifti olarak de�i�tirirler ve bundan sonra pencerenin t�m karelerinin arkaplan rengi ile t�m yaz�lar�n rengi otomatik olarak de�i�ir.
Kullanabilece�iniz renkler ve ad� ge�en fonksiyonlar�n kullan�m detaylar� i�in man sayfalar�na bak�n�z.
G�zel bir g�r�nt� olu�turmak i�in pencerelerinizi kutu i�ine alabilirsiniz. K�t�phane i�erisinde bunu sizin i�in yapacak box adl� bir makro vard�r. Ancak di�er fonksiyonlardan farkl� olarak wbox mevcut de�ildir; box makrosu zaten bir pencere i�aret�isini parametre olarak al�r.
Makronun kolay kullan�m detaylar�n� man sayfas�ndan ��renebilirsiniz. Burada ba�ka bir noktaya dikkat etmeniz gerekmektedir. Bu makroyla pencerelerinizi kutu i�ine alman�z�n tek anlam�, o pencerenin karakter dizisinde pencereyi s�n�rlayan karelere kutuyu olu�turacak karakterlerin yaz�lmas�d�r. E�er siz bu karakterlerin �zerine yazars�n�z kutunun g�r�nt�s�n� bozabilirsiniz. Bunun i�in, as�l pencerenin i�inde subwin ile yeni bir pencere olu�turup d��taki pencereyi kutu i�ine alman�z ve yaz� yazmak i�in i�teki pencereyi kullanman�z g�venilir bir y�ntem olabilir.
Klavyedeki fonksiyon tu�lar�n� kullanabilmeniz i�in �ncelikle klavyeden bilgi okuyaca��n�z pencerede _use_keypad bayra��n�n de�erinin do�rulanmas� gerekir. Bunu yapan fonksiyon keypad fonksiyonudur. Bu fonksiyona �a�r� yaparak fonksiyon tu�lar�n� kullan�l�r hale getirdikten sonra normal girdi fonksiyonlar� ile klavyeden giri� alabilirsiniz.
Ancak bu durumda, �rne�in getch ile ald���n�z bir bilgiyi, char tipinden de�il de int tipinden bir de�i�kenin i�erisinde tutmaya dikkat edin. ��nk� fonksiyon tu�lar�n�n say�sal de�erleri bir char tipi de�i�ken i�inde saklayabilece�iniz de�erlerden b�y�kt�r. Fonksiyon tu�lar�n�n say�sal de�erlerini bilmenize gerek yoktur, bu say�sal de�erler yerine kullanabilece�iniz isimleri getch fonksiyonunun man sayfas�nda bulabilirsiniz.
Burada inceleyece�imiz �rnek program basit ama ��retici bir programd�r. Bu programda ncurses kullan�larak men�ler olu�turulmu� ve men�deki se�eneklerden bir tanesinin se�ilmesi basit bir bi�imde uygulanm��t�r. Bu programda �nemli olan ncurses'in pencere bile�enlerini men� etkisi yaratabilecek �ekilde kullanmakt�r. Program�n ekran g�r�nt�s�n� a�a��da g�r�yorsunuz:
Programda her zaman oldu�u gibi �nce kullan�lan k�t�phanelerin ba�l�k dosyalar� yaz�l�r. Bir de program i�erisinde kullanaca��m�z enter ve escape tu�lar�n�n ASCII kar��l�klar� yerine kullan�lacak sabitler tan�mlan�r.
#include <curses.h> #include <stdlib.h> #define ENTER 10 #define ESCAPE 27
A�a��daki init_curses fonksiyonu program�n ilk �al��t��� zaman �a��rd��� fonksiyondur. �nce initscr �a�r�s� yaparak ncurses �al��t�r�l�r, daha sonra start_color ile renkler kullan�l�r hale getirilir ve ard�ndan da program boyunca kullan�lacak renk �iftleri tan�mlan�r. curs_set(0) �a�r�s� fiziksel imlecin ekran �zerinde g�r�nmemesini sa�larken, noecho �a�r�s� da kullan�c�n�n klavyeden girdi�i karakterlerin ekrana yaz�lmas�n� engeller. noecho fonksiyonunu girdileri kontrol ederek almak ve sadece kabul edilen karakterleri ekrana aktarmak gibi bir ama� i�in de kullanabilirsiniz. noecho fonksiyonunun etkisini kald�rmak i�in gerekti�i zaman echo �a�r�s� yap�l�r. A�a��daki fonksiyon son olarak keypad �a�r�s� yaparak stdscr'den al�nacak girdilerde fonksiyon tu�lar�n�n da kullan�labilmesini sa�lar. F1 ve F2 ile ok tu�lar�n� kullabilmek i�in bu �a�r� gereklidir.
void init_curses() { initscr(); start_color(); init_pair(1,COLOR_WHITE,COLOR_BLUE); init_pair(2,COLOR_BLUE,COLOR_WHITE); init_pair(3,COLOR_RED,COLOR_WHITE); curs_set(0); noecho(); keypad(stdscr,TRUE); }
Bundan sonraki fonksiyon �zerinde men� isimlerini bulunan sat�r� yazan fonksiyondur. Biraz a�a��lara inerek programda yaln�zca bir sat�r olarak g�r�len men� �ubu�unun, main fonksiyon i�erisinde stdscr'nin alt penceresi olarak tan�mlanm�� tek sat�rl�k bir pencere oldu�unu g�rebilirsiniz. ��te a�a��daki fonksiyon o pencereyi parametre olarak al�p �nce arkaplan rengini de�i�tirir, sonra da men� isimlerini yazar. Men� isimlerini burada waddstr ile yaz�yoruz. Bu tercihin belirli bir sebebi yok, istenilen fonksiyon kullan�labilirdi. �lk sat�rdaki wbkgd �a�r�s� ile pencerenin renk �ifti olarak tan�mlanan 2 numaral� �iftin d���nda bir renk �ifti (3) ile yazmak istedi�imizde wattron fonksiyonunu kulland���m�za dikkat edin. Yeniden 2 numaral� �ift ile yazmak i�in ise wattroff kullan�yoruz.
void draw_menubar(WINDOW *menubar) { wbkgd(menubar,COLOR_PAIR(2)); waddstr(menubar,"Menu1"); wattron(menubar,COLOR_PAIR(3)); waddstr(menubar,"(F1)"); wattroff(menubar,COLOR_PAIR(3)); wmove(menubar,0,20); waddstr(menubar,"Menu2"); wattron(menubar,COLOR_PAIR(3)); waddstr(menubar,"(F2)"); wattroff(menubar,COLOR_PAIR(3)); }
S�radaki fonksiyon F1 ya da F2 tu�lar�na bas�ld��� zaman men�lerin a��lmas�n� sa�layan fonksiyondur. Men� a��lma etkisini yaratmak i�in arkaplan� olu�turan pencere (mavi renkli) �zerine men� �ubu�u ile ayn� renkte (beyaz) yeni bir pencere a��lmaktad�r. Ancak bu yeni pencere a��ld��� zaman altta kalan pencerede yaz�lm�� olan yaz�lar�n silinmesini istemiyoruz. Men� kapand��� zaman bu yaz�lar�n yeniden g�r�nmesini istiyoruz. Bu sebeple yeni yarat�lan pencerenin stdscr'nin bir alt penceresi olarak yarat�lmas� do�ru de�ildir. A�a��da da g�r�ld��� gibi items[0] adl� pencere newwin fonksiyonuyla olu�turulmu�tur. Di�er 8 tane items penceresi ise items[0]'�n alt pencereleri olarak yarat�lm��t�r. Burada items[0] men�y� s�n�rlayan �er�eveyi �izmek i�in kullan�l�rken di�er pencereler ise hem �er�eveyi olu�turan karakterlerin �zerine yazmamak hem de men�de se�ili olan eleman� g�stermek i�in kullan�lacakt�r. Se�ili olan eleman� g�stermek i�in kar��l�k gelen items penceresinin arkaplan rengini di�erlerinden farkl� yapmak yeterlidir. Sondan iki �nceki sat�rda da bu yap�lmaktad�r ve men� ilk a��ld���nda birinci s�radaki eleman se�ili olarak g�r�nmektedir.
WINDOW **draw_menu(int start_col) { int i; WINDOW **items; items=(WINDOW **)malloc(9*sizeof(WINDOW *)); items[0]=newwin(10,19,1,start_col); wbkgd(items[0],COLOR_PAIR(2)); box(items[0],ACS_VLINE,ACS_HLINE); items[1]=subwin(items[0],1,17,2,start_col+1); items[2]=subwin(items[0],1,17,3,start_col+1); items[3]=subwin(items[0],1,17,4,start_col+1); items[4]=subwin(items[0],1,17,5,start_col+1); items[5]=subwin(items[0],1,17,6,start_col+1); items[6]=subwin(items[0],1,17,7,start_col+1); items[7]=subwin(items[0],1,17,8,start_col+1); items[8]=subwin(items[0],1,17,9,start_col+1); for (i=1;i<9;i++) wprintw(items[i],"Item%d",i); wbkgd(items[1],COLOR_PAIR(1)); wrefresh(items[0]); return items; }
S�radaki fonksiyon yukar�daki fonksiyon taraf�ndan olu�turulan men� pencerelerini yokeden fonksiyondur. Bunun i�in �nce pencereler tek tek delwin ile yokedilip daha sonra da items i�aret�isi i�in al�nan bellek geri verilmektedir.
void delete_menu(WINDOW **items,int count) { int i; for (i=0;i<count;i++) delwin(items[i]); free(items); }
scroll_menu fonksiyonu men�ler aras�nda ve men� i�inde gezmeyi sa�layan fonksiyondur. Sonsuz bir d�ng� i�inde getch fonksiyonu ile klavyeden girilen tu�lar� okumaktad�r. Kullan�c� a�a�� yukar� ok tu�lar�na basarsa men�de a�a��daki ya da yukar�daki eleman se�ili olarak g�sterilmektedir. Bu, yukar�da da bahsetti�im gibi, se�ili olan eleman�n bulundu�u pencerenin arkaplan rengini di�erlerinden farkl� yaparak sa�lanmaktad�r. Kullan�c� e�er sa� ve sol ok tu�lar�na basarsa i�inde bulunulan men� kapat�lmakta ve di�er men� a��lmaktad�r. Kullan�c� enter tu�una basarsa se�ilmi� olan eleman�n de�eri geri d�nd�r�l�r. Escape tu�u ise herhangi bir eleman� se�meden men�leri kapatmaya yarar. Fonksiyon di�er tu�lar� dikkate almamaktad�r. Bu fonksiyonda getch ile klavyeden ok tu�lar�n�n okunabilmesi i�in iki hat�rlatma yapmakta fayda var. �ncelikle en ba�taki init_curses fonksiyonunda keypad(stdscr,TRUE) �a�r�s� yap�larak stdscr'den fonksiyon tu�lar�n�n okunabilmesi sa�lanm��t�. Buna ek olarak bir de getch ile okunan de�er bir int tipi de�i�kende saklanmaktad�r, ��nk� ok tu�lar� ve di�er fonksiyon tu�lar�n�n say�sal de�erleri char tipi de�i�kenin tutabilece�inden b�y�kt�r.
int scroll_menu(WINDOW **items,int count,int menu_start_col) { int key; int selected=0; while (1) { key=getch(); if (key==KEY_DOWN || key==KEY_UP) { wbkgd(items[selected+1],COLOR_PAIR(2)); wnoutrefresh(items[selected+1]); if (key==KEY_DOWN) { selected=(selected+1) % count; } else { selected=(selected+count-1) % count; } wbkgd(items[selected+1],COLOR_PAIR(1)); wnoutrefresh(items[selected+1]); doupdate(); } else if (key==KEY_LEFT || key==KEY_RIGHT) { delete_menu(items,count+1); touchwin(stdscr); refresh(); items=draw_menu(20-menu_start_col); return scroll_menu(items,8,20-menu_start_col); } else if (key==ESCAPE) { return -1; } else if (key==ENTER) { return selected; } } }
Son olarak s�rada main fonksiyonu var. main fonksiyonu yukar�da anlat�lan fonksiyonlar� kullanarak program�n �al��mas�n� sa�lamaktad�r. Bu fonksiyon da getch ile bas�lan tu� de�erleri okumakta ve e�er F1 ya da F2 tu�lar�na bas�lm��sa draw_menu ile kar��l�k gelen men�y� �izdirmektedir. Men� �izildikten sonra scroll_menu fonksiyonu ile men�lerden bir eleman se�ilmesi sa�lanmaktad�r. scroll_menu fonksiyonu geri d�nd�kten sonra da �nce men� pencereleri silinmekte ve ard�ndan se�ilen eleman messagebar penceresine yazd�r�lmaktad�r.
Burada touchwin fonksiyonuna de�inmekte fayda var. Men�ler kapand�ktan sonra touchwin �a�r�lmadan refresh yap�lsayd� en son a��lan men� ekranda durmaya devam ederdi. Bunun sebebi men�ler yarat�ld��� zaman stdscr �zerinde hi�bir de�i�iklik yap�lmamas� ve refresh �a�r�ld��� zaman stdscr hi� de�i�memi� olarak g�r�ld��� i�in yeniden yaz�lmamas�d�r. touchwin fonksiyonu parametre olarak ald��� pencerenin t�m sat�rlar�ndaki sat�r�n de�i�ti�ini belirten bayraklar� do�rulayarak bir sonraki refresh'te pencerenin, hi� de�i�memi� olsa bile, en ba�tan �izilmesini sa�lar. Men�ler yarat�ld��� zaman stdscr'ye hi� dokunulmam�� olmas� sayesinde, men�ler kapand��� zaman stdscr'de yazan bilgi kaybolmam��t�r.
int main() { int key; WINDOW *menubar,*messagebar; init_curses(); bkgd(COLOR_PAIR(1)); menubar=subwin(stdscr,1,80,0,0); messagebar=subwin(stdscr,1,79,23,1); draw_menubar(menubar); move(2,1); printw("Press F1 or F2 to open the menus. "); printw("ESC quits."); refresh(); do { int selected_item; WINDOW **menu_items; key=getch(); werase(messagebar); wrefresh(messagebar); if (key==KEY_F(1)) { menu_items=draw_menu(0); selected_item=scroll_menu(menu_items,8,0); delete_menu(menu_items,9); if (selected_item<0) wprintw(messagebar,"You haven't selected any item."); else wprintw(messagebar,"You have selected menu item %d.",selected_item+1); touchwin(stdscr); refresh(); } else if (key==KEY_F(2)) { menu_items=draw_menu(20); selected_item=scroll_menu(menu_items,8,20); delete_menu(menu_items,9); wprintw(messagebar,"You have selected menu item %d.",selected_item+1); if (selected_item<0) wprintw(messagebar,"You haven't selected any item."); else wprintw(messagebar,"You have selected menu item %d.",selected_item+1); touchwin(stdscr); refresh(); } } while (key!=ESCAPE); delwin(menubar); delwin(messagebar); endwin(); return 0; }
Aralara yazd���m a��klamalar� ��kar�p kaynak kodunu example.c adl� dosyaya kaydetti�inizi varsayarak
gcc example.c -o example -lcurses
komutu ile kodu derleyebilir ve program� test edebilirsiniz.
Ncurses kullanarak program�n�z i�in g�zel bir aray�z olu�turabilmeniz i�in gereken temel konulara de�indim. Ancak bu k�t�phaneyle yapabilecekleriniz burada anlat�lanlarla s�n�rl� de�ildir. S�k s�k bakman�z� tavsiye etti�im man sayfalar�nda k�t�phane ile ilgili ba�ka y�nler de ke�fedecek ve bu anlatt�klar�m�n yaln�zca giri� d�zeyinde bilgiler oldu�unu g�receksiniz.
|
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Reha K. Ger�eker, FDL LinuxFocus.org Buray� klikleyerek hatalar� rapor edebilir ya da yorumlar�n�z� LinuxFocus'a g�nderebilirsiniz |
�eviri bilgisi:
|
2002-01-28, generated by lfparser version 2.22