SlickEdit Community

SlickEdit Product Discussion => SlickEditĀ® => Slick-CĀ® Macro Programming => Topic started by: warnerrs on November 11, 2014, 05:43:47 AM

Title: Please help me improve this form's event handler code
Post by: warnerrs on November 11, 2014, 05:43:47 AM
Trying my hand at building a form to do some code generation. I've stripped my form down to the essentials for this post.

I am triggering this form using alias auto expansion which calls a macro. It calls this macro: uvm_class_wizard()

In uvm_class_wizard(), I am able to save the handle to the editor window, and then use that handle in the event handlers. Rather than saving the handle before opening the form, is it possible to get the handle/id to the last used editor window in the event handler? Is my approach the best way to do this kind of thing?

Code: [Select]
#include "slick.sh"

// scroll down to see the event handler code

_form frm_uvm_class_wizard {
   p_backcolor=0x80000005;
   p_border_style=BDS_DIALOG_BOX;
   p_caption='UVM Class Wizard';
   p_forecolor=0x80000008;
   p_height=5020;
   p_width=4257;
   p_x=16159;
   p_y=2840;
   _command_button cOk {
      p_auto_size=false;
      p_cancel=false;
      p_caption='Ok';
      p_default=false;
      p_height=420;
      p_tab_index=12;
      p_tab_stop=true;
      p_width=1210;
      p_x=1375;
      p_y=4500;
   }
   _command_button cCancel {
      p_auto_size=false;
      p_cancel=false;
      p_caption='Cancel';
      p_default=false;
      p_height=420;
      p_tab_index=13;
      p_tab_stop=true;
      p_width=1210;
      p_x=2761;
      p_y=4500;
   }
}

int ewindow;

void uvm_class_wizard() {
    ewindow = p_window_id;
    show("frm_uvm_class_wizard");
}

defeventtab frm_uvm_class_wizard;
void cCancel.lbutton_up()
{
    ewindow._insert_text( "class cancel\nline two\n" );
    p_active_form._delete_window();
}
void cOk.lbutton_up()
{
    ewindow._insert_text( "class ok\nline two\n" );
    p_active_form._delete_window();
}

Thanks,
Ryan
Title: Re: Please help me improve this form's event handler code
Post by: Graeme on November 11, 2014, 10:53:52 AM
You can use _mdi.p_child to get the last active editor window.

To check for no active editor windows at all you can use
   if (_mdi.p_child._no_child_windows()==0) {
      // there's at least one editor window
   }

There are 701 instances of _mdi.p_child in slick sources.
Title: Re: Please help me improve this form's event handler code
Post by: warnerrs on November 11, 2014, 04:24:38 PM
Thanks. That's exactly what I was looking for.
Title: Re: Please help me improve this form's event handler code
Post by: warnerrs on November 13, 2014, 05:44:07 AM
So I added a check box to my form. I am setting it's default state based on whether or not the buffer is empty. I don't want to do this in the form's on_create() event handler, primarily because an additional function seemed unnecessary. This works exactly as I want it too. However, I don't really understand it. The type system has me confused. Can anyone help me unpack this?

Code: [Select]
_form frm_uvm_class_wizard {
   // ...
   _check_box cInsertHeader {
      // ...
   }
}

void uvm_class_wizard() {
    _control cInsertHeader;
    int ed = _mdi.p_child;
    int line = ed.p_line; // save location, because I don't really want the cursor to move
    int col = ed.p_col;
    frm = show("frm_uvm_class_wizard");
    frm.cInsertHeader.p_value = _mdi.p_child.find('\S','LIHP@') ? 1 : 0;
    ed.p_line = line; // restore location
    ed.p_col = col;
}

Let's ignore (for now) the whole wishy-washy is it an int or an object thing going on with "ed" and "_mdi". That leaves us to analyse.

Code: [Select]
void uvm_class_wizard() {
    _control cInsertHeader;
    frm = show("frm_uvm_class_wizard");
    frm.cInsertHeader.p_value = _mdi.p_child.find('\S','LIHP@') ? 1 : 0;
}

It would probably help if I show you my first attempt at this code:

Code: [Select]
void uvm_class_wizard() {
    frm = show("frm_uvm_class_wizard");
    frm.cInsertHeader.p_value = _mdi.p_child.find('\S','LIHP@') ? 1 : 0;
}

That doesn't work. You get a "Control 'cInsertHeader' must be declared or cannot be a member of a non-struct/union/class type". Ok. Fair enough. It doesn't know what frm is. So I found the section about declaring controls. This seemed like the first logical attempt:

Code: [Select]
void uvm_class_wizard() {
    _control cInsertHeader; // I assumed this affected the local variable cInsertHeader, not the nested variable cInsertHeader
    frm = show("frm_uvm_class_wizard");
    cInsertHeader = frm.cInsertHeader;
    cInsertHeader.p_value = _mdi.p_child.find('\S','LIHP@') ? 1 : 0;
}

Nope. You get "left operand must be lvalue" on the assignment to cInsertHeader. Ok. I reread the example in the doc and try the following:

Code: [Select]
void uvm_class_wizard() {
    _control cInsertHeader; // some how this reaches inside frm, and affects that variable
    frm = show("frm_uvm_class_wizard");
    frm.cInsertHeader.p_value = _mdi.p_child.find('\S','LIHP@') ? 1 : 0;
}

Yeah, it works! But this is mystical magical. I don't get what is going on here.

My best interpretation is, "_control cInsertHeader" is like a pragma that says, "next time you encounter 'cInsertHeader', treat whatever is in front of it as an id to a form.

Somebody went to a lot of trouble to make this language look superficially like C. This reminds me of what I've come to think of AppleScript, it's read only code. Already working code is quite readable, even if you don't know the language, but writing new code feels like searching for a magic incantation.

So if someone can explain to my simple C/Java style brain the proper way to interpret how that works, I'd greatly appreciate it. After that, may you can also explain how I can set and get the value of a "property" from a variable that is declared as an int.

Thanks,
Ryan