Založte projekt ve VS na WinForms aplikaci v .NET Framework (C#).
Projekt bude mít pouze jeden formulář, na kterém bude nějaký panel, a na něm nakreslíme celé umělecké dílo - dům se zahradou (s plotem) :-)
Na kreslení použijeme grafickou knihovnu GDI (GDI+), přičemž žádná část nebude "z obrázku" (bitmapa).
Vše hezky vektorově, tj. pomocí metod DrawLine
, DrawRectangle
, DrawEllipse
,
případně FillRectangle
a FillEllipse
.
Abychom si připomněli práci s objekty, bude každá část domu reprezentována nějakou třídou, která bude držet jisté grafické vlastnosti té části (rozměry, barvu apod.), bude mít v sobě zapouzdřené "podčásti", ze kterých se skládá, a hlavně: Bude umět se vykreslit. Vykreslí se tak, že napřed vykreslí sama sebe (je-li co pro danou část vykreslovat) a pak zavolá vykreslení svých "podčástí".
Celý obrázek bude zapouzdřen do komponenty (části), která reprezentuje celý dům včetně zahrady. Říkejme jí statek nebo nemovitost (anglicky Property).
Nemovitost se skládá ze dvou částí - domu (House) a zahrady, či spíše plotu (Fence).
Dům má opět dvě části: přízemní obytnou část (GroundFloor) a střechu (Roof>). V přízemí jsou dveře (Door) a dvě čtvercová okna (SquareWindow). Střecha má kulaté okno (RoundWindow).
Plot na zahradě se skládá ze svislých kůlů (Pole) a vodorovných latí (Batten).
Kdo by si chtěl věci dobrovolně zesložitit, může dát ještě plot do zahrady (Garden), a teprve tu dát do celé nemovitosti. A na zahradě může být třeba strom (Tree) nebo květiny (Flower). Na střeše může být komín (Chimney), okna mohou mít okenní tabulky (WindowPane). Nechávám na vaší fantazii a času, který do uměleckého díla hodláte investovat.
Nyní ještě schematicky, jak vypadá struktura "zanoření" povinných tříd, které se umějí kreslit jako části domu:
A úplně nakonec: Jelikož čtvercové a kulaté okno mají leccos společného (oboje je "okno"), uděláme ještě jednu třídu (Window) jako jejich společného předka. Takže kromě mnoha asociací typu celek-část si vyzkoušíme i dědičnost.
Příklad zdrojového kódu pro přízemí domu:
public class GroundFloor { public Door Door { get; set; } public Point DoorPosition { get; set; } public SquareWindow LeftWindow { get; set; } public Point LeftWindowPosition { get; set; } public SquareWindow RightWindow { get; set; } public Point RightWindowPosition { get; set; } public int Width { get; set; } public int Height { get; set; } public Color Color { get; set; } public GroundFloor(int width, int height) { this.Width = width; this.Height = height; this.Color = Color.Black; this.Door = new Door { Height = this.Height / 2, Width = this.Width / 5, Color = Color.Pink }; this.DoorPosition = new Point(this.Width / 2 - this.Door.Width / 2, this.Height - this.Door.Height); this.LeftWindow = new SquareWindow { Size = this.Width / 6, Color = Color.Blue }; this.LeftWindowPosition = new Point(this.Width / 12, this.Height / 3); this.RightWindow = new SquareWindow { Size = this.Width / 6, Color = Color.Blue }; this.RightWindowPosition = new Point(11 * this.Width / 12 - this.RightWindow.Size, this.Height / 3); } public void Draw(Graphics g, int left, int top) { Pen pen = new Pen(this.Color, 2); g.DrawRectangle(pen, left, top, this.Width, this.Height); pen.Dispose(); this.Door.Draw(g, left + this.DoorPosition.X, top + this.DoorPosition.Y); this.LeftWindow.Draw(g, left + this.LeftWindowPosition.X, top + this.LeftWindowPosition.Y); this.RightWindow.Draw(g, left + this.RightWindowPosition.X, top + this.RightWindowPosition.Y); } }
Výsledek by měl vypadat nějak takto (barvičky si vyberte dle libosti a vkusu):
Pokud chce mít někdo "méně schematický" obrázek, pak třeba:
A pro ty, kdo to mají rádi opravdu "fancy":