Selam..
- İstanbul'dan biraz önce döndüm sorunuzu yani gördüm...
- Burada
@heavy'nin verdiği örnek çerçevesinde bir çözüm sunumu yapılmıştır. Alternatif çözümler her zaman sonsuzdur..

Ben olsam basit bir
TPanel array ile hallederdim ve her tıklanan panelin kendisinin ben tıklandım diye bağırmasını kullanırdım...
- Bir koltuğa / hangi koltuğa ve / veya koltuk dizisine tıklandı veya tıklanmadıyı Sihirle (beynimizle) çözücez, ilüzyonla (göz yanıltmaca ile) koltuk seçimini yaptırıcaz...
- Şöyle ki, yine mouse ile selection yaptığımızda iki tane noktaya ihtiyacımız olacak.
X_Bas, Y_Bas, X_Son, Y_Son şeklinde... Bu bize koltuk bloğunu bulmamız için başlangıç noktası olacaktır. Bunları önce iki tane
TPoint içinde, sonra da kolayca bir tane
TRect içinde topluycaz..
- Koltuk bloğunu hesaplayarak bulmayı avantaja dönüştürüp kullanıcaz. Sihir bu...
- Peki seçimi nasıl kullanıcıya göstericez ? Bu da ilüzyon. Canvas büyüklüğü kadar bir TPaintbox koyucaz ve seçimi bunun üzerinde yaptırıp koltuklarımız üzerinde herhangi bir boyama yapılmasının önüne geçicez.. Sonucu yine arkadaki asıl Canvas'a seçenekler sonucu olarak aktarıcaz...
- Biliyorsunuz veya bilmeyenler için
TPaintBox,
TCanvas içeren bir bileşendir. Canvas özelliği olmayan nesnelere bu özelliği kazandırmakta sıkça kullanılır (TPanel gibi). Ayrıca saydam bir yapı teşkil eder,
Layer stili projeler geliştirmeye olanak sağlar.. Bu kadar
TPaintBox girizgahı yeter.
- Şimdi uygulayalım.. İlk olarak bileşen paletindeki
System sayfasındaki
TPaintBox nesnesini formumuza koyalım.
Align özelliği
alClient yapalım ki boyutlandırma ile uğraşmayalım. ( hani boya fırçası iconu olan

)
- Koordinatlarımızı saklayacağımız
global değişkenlerimiz ve bir de geçici olarak arka fonu saklayacağımız bir
TBitmap tanımı yapıyoruz. Bu da
global.
-
OffTopic : Benim özel tercihim belki diğer mesajlarımdan görenler olmuştur; Global değişkenlerin başına küçük
x harfi koyuyorum ki bu değişkeni nerede tanımladığımı bileyim. Küçük bir örnekte yersiz gelebilir ama elimizi tembel alıştırmamak lazım. Tüm arkadaşlara şahsım tarafından bu tip bir uygulama şiddetle önerilir.
Kod: Tümünü seç
var
Form1: TForm1;
xBaslaNokta : TPoint;
xBitisNokta : TPoint;
xBaslaBool : Boolean;
xBitmap : TBitmap;
- Önce
OnFormCreate olayında ne yapıyoruz,
xBitmap'imizi tanımlayıp boyutlandırıyoruz.

Bu boyutlandırmayı dinamik hale getirmek için Canvas'ın büyüklüğünün değiştiği yerde yapmanın faydası var onu da ekleyelim...
Kod: Tümünü seç
procedure TForm1.FormCreate(Sender: TObject);
begin
xBitmap := TBitmap.Create;
xBitmap.Width := Form1.ClientWidth;
xBitmap.Height := Form1.ClientHeight;
end;
- Tabii OnCLose olayında da bunu free edicez... Örneğimizde xBitmap ana formda olduğundan bu işlem program kapanırken kendiliğinden yapılır ama bunun bir alt formda olacağını da varsayarak tedbiri elden bırakmıyoruz...
Kod: Tümünü seç
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
xBitmap.Free;
xBitmap := Nil;
end;
- Şimdi de mousedown, mousemove ve mouseup eventlerimiz.. Unutmayınız Mouse işlemleri görünmeyen saydam tabaka olan TPaint üzerinde yapıldığından Mouse işlemleri için tetiklenecek Layer yine bu TPaint olacağından bunun OnMousexxxxx olaylarına yazıyoruz.
- Dilerseniz tüm bu işlemleri
TPaintbox kullanmaksızın asıl
Canvas'da da yapabilirdiniz ama ben bu şekilde olmasını uygun görüyorum. Gelecekte başka işlemler için de lazım olabilir.
Kod: Tümünü seç
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
xBaslaNokta := Point(X, Y);
// ilk tıklamada xBitmap'a sceenshot alıyoruz.
If NOT xBaslaBool then begin
xBitmap.Canvas.CopyRect (Form1.Canvas.ClipRect, Form1.Canvas, Form1.Canvas.ClipRect );
end;
xBaslaBool := True;
end;
Kod: Tümünü seç
procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
//Sol butoon basılı iken neler olacak...
if ssLeft in Shift then
begin
PaintBox1.Canvas.Draw( 0, 0, xBitmap );
PaintBox1.Canvas.DrawFocusRect( Rect(xBaslaNokta.X, xBaslaNokta.Y, X, Y) );
xBitisNokta := Point(X, Y);
xBaslaBool := False;
end;
end;
Kod: Tümünü seç
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
If NOT xBaslaBool then begin
ShowMessageFmt('%d,%d /%d,%d', [xBaslaNokta.X, xBaslaNokta.Y, xBitisNokta.X, xBitisNokta.Y]);
PaintBox1.Canvas.Draw( 0, 0, xBitmap );
end;
end;
- Gerisi bu koordinatlar arasının hangi koltuklara tekamül ettiğini bulmaya kalıyor. Basit bir fonksiyon kurup bunu yapmak mümkün.
- Metodoloji basit. İlk verdiğim fonksiyonda tüm veriler değişken olarak sakladım ki dinamizm oluşsun. Bu dinamizm içindeki değişken ölçüleri size refarns olacak. Şöyle ki...
Kod: Tümünü seç
Const
SiraSayisi = 13; // 13 sıra A .. M için
TekSiraKoltuk = 21; // Tek numaralı sıralar 21 koltuk ayarlayalım...
CiftSiraKoltuk = 21; // Çift numaralı sıralar 21 koltuk ayarlayalım...
KoltukGenislik = 30;
KoltukYukseklik = 30;
KoltukAralik = 02;
SolBas = 20; // 20,10 ilk koltuk adresi
UstBas = 10;
... demişiz.
- Mesela blok aralığı,
195,124 - 329,125 olsun... Bu bize yukardan aşağı (124 - UstBas) div (KoltukYukseklik + KoltukAralik) kadar tepe değeri, (125 - UstBas) div (KoltukYukseklik + KoltukAralik) kadar alt değeri demektir. Sol sağ aralığı da aynı şekilde. Bu seçilenler başka bir fonksiyonda dögü ile renklendirilip yazılır hale getirilir.
- Bu formül sizin tarafınızdan biraz elden geçirilecektir tabi. Ben sadece yol gösteriyorum. Geri kalanını da size bırakayım yoruldum..
