About form.Create()

General help with the Ecere Cross Platform GUI toolkit: Window, common controls, events, etc.
Help with the 2D Graphics library: Surface, Display, Bitmap, Font and others.
Post Reply
samsam598
Posts: 212
Joined: Thu Apr 14, 2011 9:44 pm

About form.Create()

Post by samsam598 »

Given below code,with or without form.Create(),the form(window) shows anyhow.So what's the Window::Create() for?Could you please explain?thanks.

Btw,I found WindlowList in the ecere/gui/dialogs/ directory,but have no clue how to use it.Could you please explain as well.Thanks.

form2.ec:

Code: Select all

 
 
 
import "ecere"
 
class Form2 : Window
{
   text = "Form2";
   background = activeBorder;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   size = { 576, 432 };
}
 
 
form1.ec:

Code: Select all

 
import "ecere"
import "form2"
class Form1 : Window
{
   text = "Form1";
   background = activeBorder;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   menu = {  };
   size = { 448, 136 };
   anchor = { horz = -64, vert = -148 };
   nativeDecorations = true;
 
   bool OnCreate(void)
   {
 
      return true;
   }
 
   Button button1
   {
      this, text = "button1", size = { 90, 29 }, position = { 208, 40 };
 
      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
      {
         if(MessageBox{type=yesNo}.Modal()==yes)
            MessageBox{contents="Yes is clicked."}.Modal();
         else
            MessageBox{contents="No is clicked"}.Modal();
         WindowList{}.Modal();
         return true;
      }
   };
}
 
Form1 form1;
Form2 form2Arry[5]; 
 
class App:GuiApplication
{
   bool Init()
   {
      int i;
      form1=Form1{};
      //form1.Create();
 
      for(i=0;i<5;i++)
      {
         form2Arry[i]=Form2{};
         //form2Arry[i].Create();
         form2Arry[i].master=form1;
      }
      return true;
   }
}                   
 
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: About form.Create()

Post by jerome »

Hi Sam,

Excellent questions, as always!

When a parent window is created, any child window inside it automatically gets created as well, unless their 'autoCreate' property is set to false. This applies to top level windows as well when the 'desktop' is 'created'. The desktop is the default parent if you don't specify a parent or specify null for a window, and is the virtual space representing the user's desktop in windowed mode. In full-screen mode, the desktop actually behaves more like a regular window, it gets a default blue background color. The desktop 'creation' occurs from GuiApplication()::Main, right after calling Init(). This is why it doesn't change anything if you call Create() from within Init() or not, it gets done automatically because autoCreate is true.

Therefore, Create() usually only needs to be called when you create a window at runtime, e.g. a pop-up window. Note that calling Modal() (e.g. for MessageBox) includes an implicit call to Create(), in addition to setting isModal to true, and running a modal loop that will return when the window is destroyed.

As for WindowList, this is the list of Windows you see in the IDE when you select the Window/Windows... menu item. The way to use it is normally to assign the built-in Window::MenuWindowWindows method to a menu item in the MDI frame window's menu, which will automatically create it for you. You can seen an example in sdk/samples/guiAndGfx/mdiSample. Note that you are calling it properly, WindowList lists the window of its 'master', in your case the desktop because you didn't specify any master. However, WindowList only lists windows that have the isActiveClient property set to true: try setting it on your Form2 class.

Also I see you used arrays there, you might want to play with the eC containers dynamic arrays:

Array<Form2> forms { };

then you can do:

forms.Add(Form2 { master = form1 });

or you can even do:

Array<Form2> forms { [
{ master = form1 },
{ master = form1 },
{ master = form1 },
{ master = form1 },
{ master = form1 }
] };

Regards,

Jerome
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: About form.Create()

Post by D.Bane »

Hi Sam.

Jerome will be able to answer you better, but I want to take a try at it as well :)

You should use the .Create() when you want some class window to be created inside of a function/button press or where you need it.

Code: Select all

bool NotifyClicked(Button button, int x, int y, Modifiers mods)
{
     Form2 
      {
            parent = this.parent,
            text="we have a new window of class Form2",
            nativeDecoration=true
      }.Create();
}
And you can add anything you want in it...for example, lets add the button to close the window with this next newly added Form2

Code: Select all

 
bool NotifyClicked(Button button, int x, int y, Modifiers mods)
{
   Form2 form2
   {
     parent = this.parent,
     text="we have a new window of class Form2",
     nativeDecoration=true
 
    // you can also add the methods inside it...using only Form2 as a back end and making different uses of it 'on fly'
     bool OnCreate()
      {
         //Do Something
          parent.text = "Form2 hacked its parent"; //:)
      }
   }
 
      Button btnClose
      {
         parent = form2;
         text = "closeMe";
         anchor = {left = 10,top = 10,right = 10};
         font = {"Tahoma", 10};
 
         bool NotifyClicked(Button button, int x, int y, Modifiers mods)
         {
            Destroy(0);
            return(true);
         }
      };
 
   form2.Create();
 
}
 
So if you want to have it somewhere but do not want it to be show from the start this is how you use it.

hehe Jerome answered me before I even stated the question :)

Best Regards,
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
samsam598
Posts: 212
Joined: Thu Apr 14, 2011 9:44 pm

Re: About form.Create()

Post by samsam598 »

Thanks both!I would like to repeat,hey,I love this place :D

@D.Bane:sorry I can't make my app run after adding the code you listed.Could you please provide the full source?Thank you again.

Regards,
Sam
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: About form.Create()

Post by D.Bane »

Hi Sam.
I would like to repeat,hey,I love this place :D
I know exactly what you mean :D

I will post both forms here, as it seems that it will upload only one file..


form1.ec

Code: Select all

import "ecere"
import "form2"
 
class Form1 : Window
{
 text = "Form1";
 background = activeBorder;
 borderStyle = sizable;
 hasMaximize = true;
 hasMinimize = true;
 hasClose = true;
 menu = {  };
 size = { 448, 136 };
 anchor = { horz = -64, vert = -148 };
 nativeDecorations = true;
 
 Button button1
 {
    this, text = "button1", size = { 90, 29 }, position = { 208, 40 };
 
    bool NotifyClicked(Button button, int x, int y, Modifiers mods)
    {
       if(MessageBox{type=yesNo, text="form choice", contents="selecting yes will show you the time, while selecting no will show you the date./nPlease make your selection now."}.Modal()==yes)
       {
          //MessageBox{contents="Yes is clicked."}.Modal();
          //For some reason if you have this line shown you get an error when trying to compile...
          // If you have the other lines down behind it..otherwise it compiles
 
          // now we want to add to this version of form2 a button that will close it and remove
          //  the x button from the window top right corner even though it is placed as show in the
          //  original Form2 class
          Form2 frmForm2Yes
          {
             parent = this.parent;
             text = "form2 - Yes was clicked";
             size = {h = 500, w = 500};
             hasClose = false;
             showDate = true;
 
            //if you for some reason also wanted to change something in the OnRedraw method for this
            //  specific case, but you want it to still do what it was doing, you then do next..
 
               void OnRedraw(Surface surface)
               {
                  surface.Rectangle(size.w/2 - 102,size.h/2 - 22,size.w/2 + 102, size.h/2 + 22);
 
                  Form2::OnRedraw(surface);
               }
 
          };
             Button btnClose
             {
                parent = frmForm2Yes , text = "Close", position = {x = 50, y = 50};
 
               bool NotifyClicked(Button button, int x, int y, Modifiers mods)
               {
                  Destroy(0);
                  return true;
               }
             };
 
         //Now we make the frmForm2Yes visible, or better to say created.
         // We can do this in two ways.
         // If we use .Create() it will create a window but if we use .Modal() it will create a window
         //  and make it on top of the other windows - Just like MessageBox class is used.
 
         frmForm2Yes.Create();
 
       }
       else
       {
          //MessageBox{contents="No is clicked"}.Modal();
          // the same as above regarding error
          Form2
          {
             this.parent;
             text = "form2 - No was clicked";
             showDate = false;
          }.Create();
      }
       return true;
    }
 };
}
 
Form1 form1 {}; //this will create the form1
form2.ec

Code: Select all

import "ecere"
 
class Form2 : Window
{
 text = "Form2";
 background = activeBorder;
 borderStyle = sizable;
 hasMaximize = true;
 hasMinimize = true;
 hasClose = true;
 size = { 576, 432 };
 
   bool showDate;
   Box bxShown;//using for updating the form, but only one part, not to redraw everything
 
   bool OnCreate()
   {
      //bxShown = {left = , top = ...}; // we can update the box in one row, or one at a time...
      bxShown.left = (size.w / 2) - 100;
      bxShown.top = size.h / 2 - 20;
      bxShown.height = 40;
      bxShown.width = 200;
 
      return true;
   }
 
   Timer tmrTime
   {
      userData = this, started = true, delay = 1;
 
         bool DelayExpired()
         {
            Update(bxShown);
            return true;
         }
   }
 
   void OnRedraw(Surface surface)
   {
      DateTime dt;
      char txt[100];
 
      dt.GetLocalTime(); //Get time
 
      //if(showDate == true)
      if(showDate)   PrintBuf(txt, sizeof(txt), dt.year, "/", dt.month, "/", dt.day);
      else           PrintBuf(txt, sizeof(txt), dt.hour, ":", dt.minute, ":", dt.second);
 
      surface.CenterTextf(size.w/2,size.h/2, CopyString(txt));
   }
}
 

I hope it will help you :)

Best Regards,
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
samsam598
Posts: 212
Joined: Thu Apr 14, 2011 9:44 pm

Re: About form.Create()

Post by samsam598 »

Hi D.Bane,

Excellent example!

Regards,
Sam
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: About form.Create()

Post by jerome »

D.Bane, you should be able to upload 2 attachments on the forums.
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: About form.Create()

Post by jerome »

D.Bane,

I noticed a couple of problems in your sample.

1. Surface::CenterTextf doesn't center vertically, only horizontally. So the 'y' position is the top of the text box, the 'top' of the Update box should be the same as the y coordinate in the call to CenterTextf

2. You should update the box in OnResize rather than in OnCreate, especially since you are using a resizable border.

3. You should use clientSize as opposed to size, clientSize is the size of the client area, excluding the title bar and resizing borders.

4. In your call to CenterTextf, you're using 'CopyString' which allocates a new string copy, there's no need and it is a memory leak. surface.CenterTextf(clentSize.w/2,clentSize.h/2, txt); is fine

Here is the updated sample code:

Code: Select all

import "ecere"
 
class Form2 : Window
{
   text = "Form2";
   background = activeBorder;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   size = { 576, 432 };
 
   bool showDate;
   Box bxShown;//using for updating the form, but only one part, not to redraw everything
 
   void OnResize(int width, int height)
   {
      bxShown.left = (clientSize.w / 2) - 100;
      bxShown.top = clientSize.h / 2;
      bxShown.height = 20;
      bxShown.width = 200;
  }
 
   Timer tmrTime
   {
      userData = this, started = true, delay = 1;
 
      bool DelayExpired()
      {
         Update(bxShown);
         return true;
      }
   }
 
   void OnRedraw(Surface surface)
   {
      DateTime dt;
      char txt[100];
 
      dt.GetLocalTime(); //Get time
 
      //if(showDate == true)
      if(showDate)   PrintBuf(txt, sizeof(txt), dt.year, "/", dt.month, "/", dt.day);
      else           PrintBuf(txt, sizeof(txt), dt.hour, ":", dt.minute, ":", dt.second);
 
      surface.CenterTextf(clientSize.w/2, clientSize.h/2, txt);
   }
}
Regards,

Jerome
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: About form.Create()

Post by D.Bane »

Hi,

Nice to hear that you liked it Sam. It is also nice to hear about the memory leak.. I don't know exactly why, but I remember having some kind of trouble with strings, and CopyString() made it all work nicely so I may have been over using it since (think in 0.43 version)... Thanks for pointing this out to me Jerome.

Yes, thank you for pointing that out as well (point 2 and 3), about OnResize(). I was going for a working example, but have not made it properly :/ But, now I know more :)

Will try to make the next one a perfect sample :)

Best Regards,
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
Post Reply