Click here to Skip to main content
15,883,705 members
Articles / Desktop Programming / Windows Forms
Tip/Trick

[tut 9] hand tool (part 2) navigator panel

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
3 Jul 2016CPOL5 min read 10.2K   205   4  
we will continue the functionality of the hand tool with having a navigator panel which works as a map, we will also have a red rectangle which tells the user where he is actually viewing inside the whole form, also it can be moved to pan the form

Introduction

This is the Ninth tutorial of a series of tutorials of how to build a graphics program using C# in Windows form that exports the artwork in a vector format.

.... also, you would understand how to move, delete, ctrl z your vector art and save it in a special format to be read by your program again.

Also, we will learn how to save XML files... how to export in verilog format... how to use a star algorithm... how to use hand tool... how to manually create the ctrl z technique.

What you will be capable of building:

we will continue the functionality of the hand tool with having a navigator panel which works as a map,

we will also have a red rectangle which tells the user where he is actually viewing inside the whole form,  also it can be moved to pan the form

this navigator panel would be able to : when you pan the form , the navigator panel would be updated

Image 1

also it would enable the user to click at any place in the navigator panel , and the form would be panned

Image 2

also it would enable the user to drag and drop the red rectangle which would pan he form 

Image 3

Background

 


Map of the tut

  1. add a tab control inside the super_form
  2. create a form and name it Navigator_form , edit some of its proprieties , and add it to the  tab control inside the super_form
  3. in the super_form change some variables to be static
  4. in the Navigator_form , create a button to have a click function to refresh the navigator_form , and in Form1 work in the Onpaint to refresh the navigator form
  5. in the Navigator_form work on getting the value for the graphics to be scaled down by , so that the big graphics(shapes and lines ) would view in a smaller area inside the Navigator_form
  6. in the Navigator_form work with the OnPaint function to view the shapes and the lines 
  7. in the Navigator_form create a red rectangle and move it with the value of the scroll value in the form 
  8. in the Navigator_form create a MouseDown function to make the behavior of enabling the user to click at any place in the navigator panel , and the form would be panned
  9. in the Navigator_form create a MouseMove function to make the behavior of enabling the user to drag and drop the red rectangle which would pan he form 

 

1-add a tab control inside the super_form

get the tab_control from the tool box

Image 4

add it in the the super_form[Desgin] to the left of the old tabcontrol

Image 5

 

from the proprieties of the new added tab_contol , click on the tabPages

 Image 6

remove all pages inside the tabPages 

Image 7

 


2-create a form and name it Navigator_form , edit some of its proprieties , and add it to the  tab control inside the super_form

create a form and name it Navigator_form

Image 8

edit some of its proprieties

change its back color to make it white

Image 9

and make a special cursor for this form, so when the mouse enters this form the cursor would be changed, lets make the default hand cursor 

Image 10

change the form border size as we don't need

Image 11

but we need it to be 

Image 12

so we would change Navigator_form proprieties 

Image 13

and we would change its size to be 

Image 14

 

now we need to add this newly created Form , to the tabControl inside the super_form

so work on the constructor of super_form

C#
public super_form()
       {
           InitializeComponent();

          .

          .//old code

          .


           //new code
           Navigator_form nav = new Navigator_form();   //create a new object of Navigator_form 
           AddNewTab_nav(nav); //would be discussed 
           //new code

       }

now we need to create the function itself that adds the form to the tabControl 

C#
private void AddNewTab_nav(Form frm)
{
    TabPage tab = new TabPage(frm.Text);
    frm.TopLevel = false;
    frm.Parent = tab;
    frm.Visible = true;

    tabControl2.TabPages.Add(tab);
    //tabControl2 is the tabControl that we have just created
}

 

 


 

3-in the super_form change some variables to be static

let the integer that tells which form was selected to be static ,so that it would be used in the navigator_form , as we need the navigator form to be the map of the only selected form , as we need the navigator form to be the map for each form

C#
public static int selected_tab=0;

and change form_list to be static

C#
public static List<Form1> form_list=new List<Form1>();

 


 

4-in the Navigator_form , create a button to have a click function to refresh the navigator_form , and in Form1 work in the Onpaint to refresh the navigator form

as we would need the Onpaint function to be called from an another form , we would need the Onpaint function to be static , but this can't be done, so there is a method around this , by making the click function on a static button, and inside this click call the Onpaint

so first lets create an Onpaint

Image 15

then we would create a static button

C#
public static Button invalidate_button=new Button();

then in the constructor of the Navigator_form , assign a click function for this button

C#
public Navigator_form()
      {
          InitializeComponent();
          invalidate_button.Click += Invalidate_button_Click;
       }

this function would simply refresh the form

C#
private void Invalidate_button_Click(object sender, EventArgs e)
{
    Invalidate();
}

then in the Form1 in its OnPaint function we would simply call the click function of that button to refresh the Navigator_form 

C#
protected override void OnPaint(PaintEventArgs e)
      {

          .

          .//old code

          .


          Navigator_form.invalidate_button.PerformClick();
      }

 


 

5-in the Navigator_form work on getting the value for the graphics to be scaled down by , so that the big graphics(shapes and lines ) would view in a smaller area inside the Navigator_form

first in the Navigator_form create two new int

C#
double div_h;
double div_w;

in the constructor of the Navigator_form 

C#
public Navigator_form()
        {
            InitializeComponent();
            invalidate_button.Click += Invalidate_button_Click;
            DoubleBuffered = true;  //to make the drawing more smooth

            Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab); 
            //know which form is selected , use the static selected_tab

            Size siize = selected_form.AutoScrollMinSize;//get size of the selected form 
            div_h = (double)this.Size.Height /(double) siize.Height ;
            div_w = (double)this.Size.Width / (double)siize.Width ;

            //divide the size of the navigator form by the size of the selected form 
            //do it for horizontal and vertical

            div_h = Math.Round(div_h, 1); 
            div_w = Math.Round(div_w, 1); 

            //approximate to the first decimal place 
            //if it was 0.19523---> 0.2

        }

 


 

6-in the Navigator_form work with the OnPaint function to view the shapes and the lines 

C#
private  void Navigator_form_Paint(object sender, PaintEventArgs e)
      {
          Graphics g = e.Graphics;

          Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
          //know which form is selected , use the static selected_tab

          Matrix m = new Matrix();//to scale down the graphics we would use a Matrix

          m.Scale((float)div_h, (float)div_w, MatrixOrder.Append);
          //define the matrix with values previously calculated
          g.Transform = m;
          //actually scale down te graphics

          //draw the lines
          foreach (lines l in selected_form.lines_list)
          {
              g.DrawPath(l.pen, l.path_line);
              g.FillPath(Brushes.Black, l.arrow_path_line);
          }

          //draw the shapes
          foreach (shapes sh in selected_form.shape_list)
          {
              Svg.ISvgRenderer render = null; ;

              g.DrawPath(new Pen(Brushes.Black, 2), sh.draw_svg().Path(render));
              g.FillPath(Brushes.Khaki, sh.draw_svg().Path(render));
          }

      }

7-in the Navigator_form create a red rectangle and move it with the value of the scroll value in the form 

in the Navigator_form , create a rectangle

C#
public  Rectangle border = new Rectangle();

and in the Navigator_form , edit the OnPaint 

C#
       private  void Navigator_form_Paint(object sender, PaintEventArgs e)
        {

            .

            .//old code

            .

            //first calculate the location of the red rectangle which would simply 
            //  be the opposite of the scroll value of the selected form

            Point offset_point = new Point(-selected_form.AutoScrollPosition.X,
                                                              -selected_form.AutoScrollPosition.Y);
            border.Location = offset_point;

 

            //set the size of the red rectangle to be the same size of what the user 
            //can see without panning which is 1000 * 700 
            //don't forget that all graphics would be scaled down

            Size siize = new System.Drawing.Size(1000, 700);
            border.Size = siize;


            //then draw the rectangle in a red color
            e.Graphics.DrawRectangle(new Pen(Brushes.Red, 1), border);
}

now the navigator would be refreshed when working in the Form1 

Image 16

now we need to expand the features of the navigator form to enable clicking and dragging and drapog the red rectangle


8-in the Navigator_form create a MouseDown function to make the behavior of enabling the user to click at any place in the navigator panel , and the form would be panned

in the Navigator_form create a MouseDown function

Image 17

then in the back code in the Navigator_form in the Navigator_form_MouseDown

C#
private void Navigator_form_MouseDown(object sender, MouseEventArgs e)
{
    Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
    //know which form is selected , use the static selected_tab

    Point p = new Point(e.Location.X * 5, e.Location.Y * 5);
    //get the position of the mouse 
    //and scale it up by multiplying it by 5, because we have scaled down the graphics before

    selected_form.AutoScrollPosition = p;
    //move (pan) the selected form 
}

 

so thee result would be 

Image 18

 


9-in the Navigator_form create a MouseMove function to make the behavior of enabling the user to drag and drop the red rectangle which would pan he form 

in the Navigator_form create a MouseMove function

Image 19

then in the back code in the Navigator_form in the Navigator_form_MouseMove

C#
        private void Navigator_form_MouseMove(object sender, MouseEventArgs e)
        {

           //only work when the mouse moves and clicks the left button 
           //would implement the drag & drop functionality

            if (e.Button == MouseButtons.Left)
            {

                //same code as in function of Navigator_form_MouseDown

                Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);

                Point p = new Point(e.Location.X * 5, e.Location.Y * 5);
                selected_form.AutoScrollPosition = p;
            }
        }

so the result would be 

Image 20

 

 

If you liked the tut Vote it up Smile | :)  

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
Egypt Egypt
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --