https://gitlab.fjfi.cvut.cz/culikzde/pw
Menu je popsáno v minulé kapitole
“Naklikáme” reakce na open a save a doplníme část programu
Pokud si uživatel vybere jméno souboru, zvolené jméno nalezneme v openDialog.FileName.
Třída Bitmap má konstruktor s jedním textovým parametrem - jménem souboru, který bude načten.
Pokud je nový obrázek menší než okno, použijeme pro zvětšení funkci pictureBox_SizeChanged, kterou popíšme “za chvilku”.
private void openMenuItem_Click (object sender, EventArgs e) { if (openDialog.ShowDialog () == DialogResult.OK) { pictureBox.Image = new Bitmap (openDialog.FileName); pictureBox_SizeChanged (null, null); // zvetsime bitmapu, pokud je obrazek mensi nez okno } }
Pro nahrávání do souboru použijeme metodu pictureBox.Image.Save.
První parametr je jméno souboru.
Druhý (nepovinný) parametr určuje formát souboru.
Na začátek programu musíme doplnit using System.Drawing.Imaging; obsahující ImageFormat.Jpeg
(Using direktivy někdy uvedu také v komentáři na příslušném místě programu jako upozornění, že direktivu musíme přidat na začátek souboru.)
private void saveMenuItem_Click (object sender, EventArgs e) { // using System.Drawing.Imaging; if (saveDialog.ShowDialog () == DialogResult.OK) pictureBox.Image.Save (saveDialog.FileName, ImageFormat.Jpeg); }
Odkazy na barevné panely budu ukládat do proměnné colorTools typu List <Panel> (obdoba typu vector v C++).
Ihned při deklaraci vytvtoříme prazdný seznam new List <Panel> ()
Do seznamu přidáme první (modrý) panel colorTools.Add (colorPanel);
Funkce addColorPanel nově vzniklé panely přidají na konec seznamu.
Barvu panelu s indexem 0 použijeme pro počáteční barvu tužky, barvu panelu s indexem 1 pro štětec.
private List <Panel> colorTools = new List <Panel> (); public DrawForm () { InitializeComponent (); colorTools.Add (colorPanel); // modry panel addColorPanel (Color.Yellow); addColorPanel (Color.Red); addColorPanel (Color.Green); pen = new Pen (colorTools[0].BackColor); // modra barva podle prvniho panelu brushColor = colorTools[1].BackColor; // zluta podle druheho panelu brush = new SolidBrush (brushColor); comboBox.SelectedIndex = (int) Shape.line; pictureBox_SizeChanged (null, null); // vytvorime praznou bitmapu }
Funkce addColorPanel již nepotřebuje proměnnou panelCnt, ale použije současnou délku seznamu.
void addColorPanel (Color c) { Panel p = new Panel (); // vytvorime novy panel p.BackColor = c; // novy panel umistime vpravo od soucasnych panelu int cnt = colorTools.Count; /* --> */ p.Left = colorPanel.Left + cnt * (colorPanel.Width + colorPanel.Left); p.Top = colorPanel.Top; // ze vzoroveho panelu zkopirujeme souradnici y a velikost p.Width = colorPanel.Width; p.Height = colorPanel.Height; p.MouseDown += colorPanel_MouseDown; // pridame reakci na stisknuti mysi p.Parent = toolPanel; // pridame do toolPanelu /* --> */ colorTools.Add (p); }
V “design” režimu vybereme pictureBox a přidáme reakci událost SizeChanged.
private void pictureBox_SizeChanged (object sender, EventArgs e) { Bitmap old = null; if (pictureBox.Image != null) old = new Bitmap (pictureBox.Image); // kopie obrazku (pokud existuje) int w = pictureBox.Width; int h = pictureBox.Height; if (old != null) { // pripadne zvetsime sirku a vysku, at neprijdeme o cast puvodniho obrazku if (old.Width > w) w = old.Width; if (old.Height > h) h = old.Height; } Bitmap b = new Bitmap (w, h); Graphics g = Graphics.FromImage (b); Brush br = new SolidBrush (Color.White); g.FillRectangle (br, 0, 0, w, h); // vyplnime bilou barvou if (old != null) g.DrawImage (old, 0, 0); // obtiskneme puvodni obrazek pictureBox.Image = b; }
Funkci pictureBox_SizeChanged použijeme i v konstruktoru a při načtení nového obrázku ze souboru.
(Funkce nevyužívá své parametry, tak dosadíme dvakrát null.)
Místo SolidBrush použijeme LinearGradientBrush (a doplníme using System.Drawing.Drawing2D;)
brush = new LinearGradientBrush (new PointF (0, 0), new PointF (100, 100), brushColor, secondBrushColor);
using System.Drawing.Drawing2D; ... public DrawForm () { InitializeComponent (); colorTools.Add (colorPanel); // modry panel addColorPanel (Color.Yellow); addColorPanel (Color.Red); addColorPanel (Color.Green); pen = new Pen (colorTools[0].BackColor); // modra barva podle prvniho panelu brushColor = colorTools[1].BackColor; // zluta podle druheho panelu Color secondBrushColor = colorTools[2].BackColor; brush = new LinearGradientBrush (new PointF (0, 0), new PointF (100, 100), brushColor, secondBrushColor); ...
V Solution Exploreru pravou myší klikneme na projekt Draw
Z kontextového menu vybereme Add, Form (Windows Forms)
Soubor pojmenujeme PenDialog.cs
Vrátíme se do “designu” hlavního okna DrawForm
Do “Edit” menu přidáme položku “&Pen Properties”, pojmenujeme ji penMenuItem
( Pokud chceme přidat do menu oddělovací čáru, přidáme položku se textem obsahujícím jeden znak minus “-“ )
Dvakrát kliknenme na novou položku menu
Vytvoříme nový dialog, předáme mu odkaz na právě používanou tužku, dialogové okno zobrazíme
private void penMenuItem_Click (object sender, EventArgs e) { PenDialog dlg = new PenDialog (); dlg.setPen (pen); dlg.Show (); }
Do souboru PenDialog.cs ještě musíme doplnit funkci setPen, tu napíšeme včetně hlavičky (“nenaklikáme”)
public void setPen (Pen p) { propertyGrid.SelectedObject = p; }
Odkaz na právě používanou tužku uložíme do propertyGrid.SelectedObject a o zbytek práce se postará třída PropertyGrid