SİTE
İÇİ ARAMA |
|
Blogroll |
|
|
|
El Yazısıyla Şekil Çizme, Undo ve Redo İşlemleri |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bir önceki makalemde sizlere InkPicture ve InkEdit
bileşenleriyle bir tablet uygulamasının nasıl
geliştirilebileceğini anlatmıştım. Örneğin
InkPicture bileşenini formumuzun üzerine eklediğimizde, bu
bileşen üzerinde hiçbir kod gerekmeksizin yazı yazabiliyorduk. Peki
biz sadece InkPicture ve InkEdit değil de diğer bileşenlerinde
üzerine el yazımızla yazı yazabilir miyiz? Evet yazabiliriz. Örneğin Formumuza veya forma
eklediğimiz bir panel üzerine yazı yazabiliriz. Tablet PC
uygulamalarında sıkça karşılaşacağımız
birkaç kavramı açıklamak istiyorum. Bunlar Ink, Strokes, Stroke,
Packet, Gesture.
Yukarıdaki şekilden de
anlaşılacağı üzere, Ink nesnesi bir veya birden çok Strokes
nesnesi, Strokes nesnesi ise bir veya birden fazla Stroke nesnesi
içermektedir.Packet ise Stroke üzerindeki noktalardır. Packet Tablet
PC’nin gönderdiği noktaları tutar. Koordinat bilgileri, kalemin
açı ve basınç bilgilerini barındır. Kalemimizle yazmaya
başladıktan kalemimizi kaldırana kadar
yazdıklarımız Stroke olarak adlandırılır ve
birden fazla stroke ise Strokes olarak anılır.
Gesture ise hareketlerimizi tanımlar. Strokes ve Ink
kavramları yazıya ilişkin isimlerdir, Gesture ise bizim ekran
üzerindeki hareketimize işaret eder. Örneğin kalemimizi yazı
yazmadan ekran üzerinde gezdirirken bir Gesture olayıyla(event) bu
hareketlerimizi yakalayabiliriz.
Temel kavramlardan bahsettikten sonra, şimdi de
InkCollector sınıfından
bahsetmek istiyorum. Yukarıda bahsettiğim gibi eğer bir form
veya panel üzerine el yazısıyla bir şey yazmak istiyorsak bu
durumda InkCollector sınıfını kullanmalıyız. Bu
sınıfın kullanımı son derece kolaydır.
InkCollector ic = new InkCollector(Panel1); |
Yukarıdaki komut ile birlikte Panel1 üzerine
yazı yazabilmekteyiz. Aynı şekilde örneğin Formun üzerinde
yazı yazmak istiyorsak ;
InkCollector ic = new
InkCollector(this); |
veya
InkCollector ic = new
InkCollector(Handle); |
Komutlarını kullanabiliriz. Sadece Panel üzerine yazı yazmakla kalmayıp,
yazdığımızı yazıları yönetebilir, üzerinde
değişiklik yapabiliriz. Zira hepsi yukarıda bahsettiğim bir
biçimde tutulmaktadır. InkCollector
sınıfının CollectionMode özelliği vardır. Bu
özellik 3 değer alabilmektedir. Bunlar ;
CollectionMode.GestureOnly
CollectionMode.InkAndGesture
CollectionMode.InkOnly |
Değerleridir.Eğer CollectionMode özelliğimiz
GestureOnly olarak ayarlanmış ise programımız sadece
Gesture yani hareketlerimizi algılayacaktır. Ink üzerinde
herhangi bir algı
gerçekleşmeyecektir. Eğer CollectionMode özelliğimiz
InkAndGesture olarak ayarlanmış hem Gesture hemde Ink üzerinde
işlem yapılabilecek eğer sadece InkOnly olarak
ayarlanmış ise Gesture eventleri üzerinde işlem
yapılamayacaktır.
Programda InkCollector
bir Paneli işaret etmektedir ve Panel üzerinde yazı yazmamıza
olanak vermektedir, CollectionMode özelliği ise GestureOnly olarak
ayarlanmıştır.
InkCollector ic = new InkCollector(Panel1);
ic.CollectionMode = CollectionMode.GestureOnly; |
Bu durumda kullanıcı panel
üzerinde şeklini çizdikten -örneğin dikdörtgen çizilmiş olsun-
belli süre sonra el yazısıyla çizilen şekil silinecek yerine
düzgün bir dikdörtgen şekli program tarafından çizilecektir. Tablet SDK’da
tanımlı Gesture’lar bulunmaktadır. Bunların büyük bir
çoğunlu program içerisinde gerçekleştirilmiştir. Örneğin
tanımlanmış bir Üçgen şekli vardır. Yani
kullanıcı el yazsıyla bir üçgen şekli çizdiğinde, bunu
kod sayesinde algılayabiliyoruz, hatta kullanıcın hangi
doğrulukta yani çizdiği şeklin üçgene ne kadar benzediği
konusunda da bilgi edinebiliyoruz. Sadece üçgen şekli için
uygulamamızı gerçekleştirelim.(tamamı ekte verilen dosyada
bulunmaktadır)
private InkCollector ic;
private Stack
UndoRedo;private void
init()
{
1. ic
= new InkCollector(panel1);
2. ic.CollectionMode
= CollectionMode.GestureOnly;
3. ic.SetGestureStatus(ApplicationGesture.Triangle,true);
4. ic.Gesture
+=new
InkCollectorGestureEventHandler(inkCollectorGesture_Event);
5. ic.Enabled
= true;
6. UndoRedo
= new Stack(10);
} |
Burada 3. satırda yazılan
kod ile InkCollector tarafından üçgen şeklinin
algılanacağını belirliyoruz eğer değerimizi false
yaparsak program çizilen üçgen şeklini algılamayacaktır.
Programımızda
inkCollectorGesture_Event adında bir Event tanımlıdır, bu
event ile InkCollector nesnesini ilişkilendirmek için 4. satırdaki
kodu kullanıyoruz.Bu event biz şeklimizi çizip hareketimizi durduktan
sonra çalışacaktır. InkCollector nesnesinin Enable
özelliğini true olarak ayarlıyoruz, bunu yaparak yazı yazmaya
olanak sağlıyoruz. Son olarak, undo ve redo işlemlerini
gerçekleştirmek üzere kullanacağımız stack yapısı
için başlangıç kapasitesi 10 olacak biçimde yer alıyoruz. Şimdi inkCollectorGesture_Event
olayımızı inceleyelim.
private void
inkCollectorGesture_Event(object sender,
InkCollectorGestureEventArgs e)
{
1. Rectangle
rc = e.Strokes.GetBoundingBox();
2. Point
ust_sol = new Point(rc.Left, rc.Top);
3. Point
ust_orta = new Point((rc.Left + rc.Right) /2,
rc.Top);
4. Point
ust_sag = new Point(rc.Right, rc.Top);
5. Point
orta_sol = new Point(rc.Left, (rc.Top +
rc.Bottom) /2);
6. Point
orta_sag = new Point(rc.Right, (rc.Top +
rc.Bottom)/2);
7. Point
alt_sol = new Point(rc.Left, rc.Bottom);
8. Point
alt_orta = new Point((rc.Left + rc.Right) /2,
rc.Bottom);
9. Point
alt_sag = new Point(rc.Right, rc.Bottom);
for (int i=0; i<
e.Gestures.Length;i++)
{
10. Point[]
point = new Point[0];
11. Gesture
gest = e.Gestures[i];
switch(gest.Id)
{ case ApplicationGesture.Triangle:
13. point
= new Point[4];
14. point[0]
= alt_sol;
15. point[1]
= ust_orta;
16. point[2]
= alt_sag;
17. point[3]
= alt_sol;
break;
}
if(point.Length > 0)
{
18. Stroke
str = ic.Ink.CreateStroke(point);
19. ic.Ink.Strokes.Add(str);
}
}
} |
Ekrana çizdiğimiz üçgen
şeklin etrafını çevirirsek yani sınırlarını
belirlersek elimize bir dikdörtgen geçecektir. Bu dikdörtgeni elde etmek için
1. satırı kullanıyoruz. Aşağıda çizilen bir üçgen
için elde ettiğimiz dikdörtgen gösterilmiştir;
Daha sonraki 2. ve 9. satırlar
arası bu dikdörtgenin koordinat bilgileri alınmaktadır.
Çizilecek şekiller bu verilere göre çizilecektir. Daha sonra ise sırasıyla
Gesture’lar alınmakta ve
Gesture’ın Id özelliğine bakılarak tanımlanması
yapılmaktadır. Bu örnekte sadece üçgen olup olmadığı
kontrol edilmektedir. Eğer Gesture’ın Id’si, ApplicationGesture.Triangle olarak
belirlenmiş ise ekrana düzgün bir üçgen çizilebilmesi için noktalar belirlenmektedir.
Bunlar 13. ve 17. satırlar arasında yapılmaktadır. Yukarıda
görülen dikdörtgenin sol altı, üstün ortası ve sağ alt
köşeler bir nokta olarak belirlenmektedir.
Sonrasında CreateStroke metodu
kullanılarak bir Stroke çizilmektedir. CreateStroke methodu belirlenen
noktaları parametre olarak almaktadır. Çizilen stroke ise son olarak
InkCollector ile Panele eklenmektedir.
Bu durumda kullanıcının çizdiği bir şekil üçgen
olarak algılandığında düzgün üçgen şekli çizilmiş
olacaktır. Örnek uygulamanın ekran görüntüleri şöyledir ;
El yazısıyla
inkCollectorGesture_Event
olayı işletildikten sonra
Şimdide Undo ve Redo İşlemlerinin nasıl
gerçekleştiğine bakalım. Daha önce bahsettiğim gibi Panel
üzerine bir çok şekil çizdiğimizi düşünelim ve bu
şekillerin her biri bir stroke olarak panele çizilmektedir.
Dolayısıyla silme ve geri ekleme işlemleri de stroke olarak
yapılacaktır. Son eklenen stroke nesnesine
ulaşabileceğimizden dolayı, bunu panelden kaldırıp,
Stack veri yapımızı atarsak ve kullanıcı işlemi
tekrar uygulatmak istediğinde Stack’ten geri alırsak undo ve redo
işlemlerini bir kaç satır kod ile gerçekleştirmiş oluruz.
Şimdi kodları inceleyelim.
Undo İşlemi ;
1.Stroke s =
ic.Ink.Strokes[ic.Ink.Strokes.Count - 1];
2.Int32 id =
ic.Ink.Strokes[ic.Ink.Strokes.Count - 1].Id;
3.Int32[] ids = {id};
4.Strokes sTemp =
ic.Ink.CreateStrokes(ids);
5.Ink i = ic.Ink.ExtractStrokes(sTemp,
ExtractFlags.RemoveFromOriginal);
6.UndoRedo.Push((Ink)i);
7.ic.Ink.DeleteStroke(s);
8.panel1.Invalidate(); |
Son stroke nesnesini bir Ink olarak Stack yapımıza
atacağız, son stroke nesnesini Ink olarak elde etmek için 2. ve 5.
satırlar arasındaki kodu kullanıyoruz. 2. satırda son
eklenen stroke nesnesinin Id değerini alıyoruz ve sadece bu Id
değerinden oluşan bir Int32 dizisi oluşturuyoruz. Zira
CreateStrokes methodu Integer dizisi almaktadır. Silinecek stroke
nesnesinin bir kopyasını oluşturmak için CreateStrokes methodunu
kullanıyoruz ve sTemp adında bir Strokes nesnesine atıyoruz.
5. satırda ise aldığımızı strokes
nesnesini ink biçiminde almak için ExcractStrokes methodunu kullanıyoruz.
Bu method Ink içerisinden belirlediğimiz strokes nesnesini
çıkarıp yenisini bize döndürmektedir. Görüleceği üzere Burada
methoda iki parametre gönderilmektedir.Birincisi almak istediğimiz strokes
nesnesi ikincisi ise çıkarma işleminin nasıl
yapılacağı bilgisidir. Bu parametre için 3 değer
girilebilir. Bunlar ;
ExtractFlags.RemoveFromOriginal
ExtractFlags.CopyFromOriginal
ExtractFlags.DefaultRemoveFromOriginal : Ink içerisinden strokes nesnesini keser ve
geri döndürür
CopyFromOriginal : Ink içerisindeki strokes nesnesini kopyalayarak döndürür
Default : Ink içerisinden strokes nesnesini keser ve geri
döndürür |
Biz programımızda silinmesini istediğimizden
RemoveFromOriginal enum değerini kullanıyoruz. Sonra ise alınan strokes, Stack’e atılıyor, ve
strokes nesnesi Panel üzerinden siliniyor. Bu şekilde Undo işlemini
gerçekleştirmiş oluyoruz.
Redo İşlemi ;
1.Ink iUndo = (Ink)UndoRedo.Pop();
2.ic.Ink.AddStrokesAtRectangle(iUndo.Strokes,
iUndo.GetBoundingBox());
3.panel1.Invalidate(); |
Redo işlemi, Undo işlemine göre daha kolaydır.
Yapmamız gereken tek şey Stack’ten Ink nesnesini alıp panele
aktarmaktır.1. satırda stack’ten Ink nesnesi alınmakta ve panele
AddStrokesAtRectangle methodu kullanılarak aktarılmaktadır. Bu
methodun ikinci parametresi yukarıda bahsettiğim biçimde ink
nesnesini çevreleyen dikdörtgeni almaktadır. Bu şekilde de Redo
işlemi gerçekleştirilmektedir.
Örnek olarak sadece üçgen şeklinin nasıl
çizildiğini inceledik. Ekte verilen programın son halinde
aşağı,yukarı,sağa ve sola çizgiler,
dikdörtgen,yarım çember,V, ^, < ve > şekilleri,
Aşağı,yukarı,sağa ve sola oklar, Üçgen,nokta ve
Yukarı-Sağa(Ters L) şekilleri çizilebilmektedir. Program
görüntüsü aşağıdaki gibidir.
Örnek uygulama için
tıklayın.
Nurettin Şimşek
[email protected]
Makale:
El Yazısıyla Şekil Çizme, Undo ve Redo İşlemleri Mobil Programlama Nurettin Şimşek
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|
|