did you ever wanted to have GUI like in for example lineage2? where allmost all panels
can be draged and evan more, those panels sticks to each other and to screen border.
So I tryed to create sistem like this and make it quite simple to use.

///REQUIREMENTS///
-mouse_mode>0
-mouse_pos.x and mouse_pos.y should be changed with pointer.x and pointer.y values
you can do it by calling function like mouseMove() in main() function
Code:

function mouseMove()
{
mouse_mode = 2;
while (mouse_mode > 0) // move it over the screen
{
mouse_pos.x = pointer.x;
mouse_pos.y = pointer.y;
wait(1);
}
}



-3dgs version. I gues newer than 6.22 should be fine but I am not sure for 100%


///DESCRIPTION///

There are only three function in the code:

function panelRegist(panel_name);
function panelDragBtn(button_num,panel_name);
function panelDragBgr(panel_name);

panelRegist(panel_name)
-----------------------------
This function regists panel which will work as a catcher.
It mean when you will drag some panel over the screen panel will snap not only to screen borders, but also to
panels registred through this function.

Parameter(panel_name) name of existing panel

Note: no quotes needed
panelRegist("my_panel"); //Wrong
panelRegist(my_panel); //Correct
-----------------------------


panelDragBtn(button_num,panel_name)
-----------------------------
This function will drag your panel and perform snaping.

Parameter(button_num) you don't need to set this parmeter it's handlet by the 3dgs engine
Parameter(panel_name) you don't need to set this parmeter it's handlet by the 3dgs engine

Info: Function does not return anything it self but it changes global varible last_stick values:
last_stick.x gets your dragble panels position x if it was sticked to vertical border
last_stick.y gets your dragble panels position y if it was sticked to horizontal border
last_stick.z gets pointer to panel which catched your dragble panel, -1 if "catcher" was screen or 0 if panel was not sticked at all.
So as you can see after you finish drag action you will able to get some useful info
f.e you can use last_stick.z to get information about "catcher" panel like this
Code:
//afcourse you can use any other pointer to panel but dump_pointer was created exactly for situations like this
if(last_stick.z>0)
{
dump_pointer = ptr_for_handle(last_stick.z);
//...
}



Note: this function should be assigned for panel's button "click" event
Also you can call it inside your own btn_click_func(), but in this case
btn_click_func() function must have 2 parameters and passed for panelDragBtn()
function btn_click_func(btn,pan)
{
panelDragBtn; //wrong
panelDragBtn(btn,pan); //correct
}

Example:Code:

panel my_panel
{
button = x, y, bmapOn, bmapOff, bmapOver, panelDragBtn, NULL, NULL;
}


-----------------------------


panelDragBgr(panel_name)
-----------------------------
This function does the same thing as panelDragBtn() does.
Difference is that this function must be assigned for panel's "on_click" event
If you don't know what on_click is you shoul'd read about it in Manual->C-Script->Panel->Panel attributes

Note:You can call this function inside your own pan_click_func(), but in this case pan_click_func() function must have 1 parameters and passed for panelDragBgr()
function pan_click_func(pan)
{
panelDragBgr; //wrong
panelDragBgr(pan); //correct
}

Parameter(panel_name) you don't need to set this parmeter it's handlet by the 3dgs engine

Example:Code:

panel my_panel
{
on_click = panelDragBgr;
}


-----------------------------

///USAGE///
Firs add this line somewhere at the top of your main code
include <dragGUI.wdl>

To use this sistem it's not hard.
Let's say you want let player drag your "main menu" panel and stick to screen border. And let's say you want let
to start to drag "main menu" panel when player clicks left mouse button anywhere on panel background
Only change you must to do in this case is add this line in "main menu" panel object description
Code:

panel main_menu
{
//buttons such as Start game, Save, Load, Options etc.
on_click = panelDragBgr;
}



///CODE///
Code:

//////////////////////////////////////////////////////////////////////////
// dragGUI.wdl //
//////////////////////////////////////////////////////////////////////////

function panelRegist(panel_name);
function panelDragBtn(button_num,panel_name);
function panelDragBgr(panel_name);

panel* dragible; // is uset in panelDragBtn() function
panel* dump_pointer; // is uset in panelDragBtn() function

var num_of_panels = 0; //number of registred panels
var panels_list[64]; //let's say you will have only about 64 stickible panels "catchers"
var last_stick[3]; //[0]-pos_x [1]-pos_y [2]-handle number or -1 if was stiked to something

function panelRegist(panel_name)
{
panels_list[num_of_panels] = handle(panel_name);
num_of_panels += 1;
}

function panelDragBtn(button_num,panel_name)
{
// change this value to increase/decrease maximum distance beetween panels till they can be not sticked
// less means you mast drag panel very close to stck it. try 5 then 50 you will see difference :)
var accuracy = 10;

var diff_x = 0;
var diff_y = 0;
var hot_x[2];
var hot_y[2];

var i = 0;
var j = 0;

dragible = panel_name;
dump_pointer = NULL;
vec_set(last_stick.x,nullvector); //reset last_stick value

diff_x = pointer.x - dragible.pos_x;
diff_y = pointer.y - dragible.pos_y;

while(mouse_left==1) //while mouse left is not released
{
dragible.pos_x = pointer.x - diff_x;
dragible.pos_y = pointer.y - diff_y;

i = 0;
while(i<num_of_panels)
{
dump_pointer = ptr_for_handle(panels_list[i]);

if(dump_pointer.visible==1)
{
hot_x[0] = dump_pointer.pos_x;
hot_x[1] = dump_pointer.pos_x + bmap_width(dump_pointer.bmap);

hot_y[0] = dump_pointer.pos_y;
hot_y[1] = dump_pointer.pos_y + bmap_height(dump_pointer.bmap);
}

j = 0;
while(j<2)
{
if(abs(hot_x[j] - dragible.pos_x)<accuracy)
{
dragible.pos_x = hot_x[j];
last_stick.x = dragible.pos_x;
last_stick.z = panels_list[i]; //save handle
}

if(abs(hot_x[j] - (dragible.pos_x + bmap_width(dragible.bmap)))<accuracy)
{
dragible.pos_x = hot_x[j] - bmap_width(dragible.bmap);
last_stick.x = dragible.pos_x;
last_stick.z = panels_list[i]; //save handle
}

if(abs(hot_y[j] - dragible.pos_y)<accuracy)
{
dragible.pos_y = hot_y[j];
last_stick.y = dragible.pos_y;
last_stick.z = panels_list[i]; //save handle
}

if(abs(hot_y[j] - (dragible.pos_y + bmap_height(dragible.bmap)))<accuracy)
{
dragible.pos_y = hot_y[j] - bmap_height(dragible.bmap);
last_stick.y = dragible.pos_y;
last_stick.z = panels_list[i]; //save handle
}

j += 1;
}


i += 1;
}

//snap to screen border
hot_x[0] = 0;
hot_x[1] = screen_size.x;

hot_y[0] = 0;
hot_y[1] = screen_size.y;

i = 0;
while(i<2)
{
if(abs(hot_x[i] - dragible.pos_x)<accuracy)
{
dragible.pos_x = hot_x[i];
last_stick.x = dragible.pos_x;
last_stick.z = -1; //save handle
}

if(abs(hot_x[i] - (dragible.pos_x + bmap_width(dragible.bmap)))<accuracy)
{
dragible.pos_x = hot_x[i] - bmap_width(dragible.bmap);
last_stick.x = dragible.pos_x;
last_stick.z = -1; //save handle
}

if(abs(hot_y[i] - dragible.pos_y)<accuracy)
{
dragible.pos_y = hot_y[i];
last_stick.y = dragible.pos_y;
last_stick.z = -1; //save handle
}

if(abs(hot_y[i] - (dragible.pos_y + bmap_height(dragible.bmap)))<accuracy)
{
dragible.pos_y = hot_y[i] - bmap_height(dragible.bmap);
last_stick.y = dragible.pos_y;
last_stick.z = -1; //save handle
}

i += 1;
}

wait(1);
}

}

function panelDragBgr(panel_name)
{
panelDragBtn(0,panel_name);
}


///DOWNLOADS///
Source Mirror

Simply unzip files and execute demo.wdl via Scritp editor
Demo Mirror





If you have any troubles, questions or suggestions you are welcome to comment it. Thats why I put it in the forum

Last edited by Sader; 01/07/07 17:43.