How to make bitmap object to behave like button - page 3

 
Anyone can help to make custom chart event to handle mouse clicks
 

I found this code for checking mouse position on Mouse Left DOWN and Mouse Left UP

bool   MouseDown = false, MouseClicked = false;
string ObjectDown = "", ObjectClick = "";

int OnInit() {
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
}

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam
                 ) {
   if(id==CHARTEVENT_MOUSE_MOVE) {
      if( MouseLeftButtonState((uint)sparam) == "DN" && !MouseDown ) {
         MouseDown = true;
         MouseClicked = false;
         ObjectDown = ButtonZone(lparam,dparam);
      }
      if( MouseLeftButtonState((uint)sparam) == "UP" && MouseDown ) {
         MouseClicked = true;
         MouseDown = false;
         ObjectClick = ButtonZone(lparam,dparam);
         //Print("Mouse click completed! Mouse DN: "+ObjectDown+" Mouse UP: "+ObjectClick);
      }
   }
   if(MouseClicked && ObjectClick==ObjectDown) {
      if(ObjectClick=="Button.Name") {
         // BUTTON ACTIONS
      }
      MouseClicked = false;
      ObjectDown   = "";
      ObjectClick  = "";
   }
}

string MouseLeftButtonState(uint state) {
   string res;
   res+=(((state& 1)== 1)?"DN":"UP");   // mouse left
   return(res);
}

string ButtonZone(long lparam, double dparam) {
   long ChartX = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   long ChartY = ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   for( int i=ObjectsTotal(); i>=0; i-- ) {
      string name = ObjectName(i);
      long X_Start=0, X_Size=0, X_End=0, Y_Start=0, Y_Size=0, Y_End=0;
      if( ObjectType(name)!=OBJ_BUTTON ) continue;
      X_Size = (int)ObjectGetInteger(0,name,OBJPROP_XSIZE);
      Y_Size = (int)ObjectGetInteger(0,name,OBJPROP_YSIZE);
      switch((int)ObjectGetInteger(0,name,OBJPROP_CORNER)) {
         case CORNER_LEFT_UPPER : { 
            X_Start = (long)ObjectGetInteger(0,name,OBJPROP_XDISTANCE);
            Y_Start = (long)ObjectGetInteger(0,name,OBJPROP_YDISTANCE);
            break;
         }
         case CORNER_RIGHT_UPPER : { 
            X_Start = ChartX-(long)ObjectGetInteger(0,name,OBJPROP_XDISTANCE);
            Y_Start = (long)ObjectGetInteger(0,name,OBJPROP_YDISTANCE);
            break;
         }
         case CORNER_LEFT_LOWER : { 
            X_Start = (long)ObjectGetInteger(0,name,OBJPROP_XDISTANCE);
            Y_Start = ChartY-(long)ObjectGetInteger(0,name,OBJPROP_YDISTANCE);
            break;
         }
         case CORNER_RIGHT_LOWER : { 
            X_Start = ChartX-(long)ObjectGetInteger(0,name,OBJPROP_XDISTANCE);
            Y_Start = ChartY-(long)ObjectGetInteger(0,name,OBJPROP_YDISTANCE);
            break;
         }
      }
      X_End   = X_Start + X_Size;
      Y_End   = Y_Start + Y_Size;
      if( lparam >= X_Start && lparam <= X_End && dparam >= Y_Start && dparam <= Y_End ) return(name);
   }
   return("");
}

Lets say I have a button named "My Button"

How I can set action to this button using the code above. 

 

Consult this code maybe it will give you an idea of how your structure should be.

#property version   "1.00"

string system_tag="test_";
//variables , names are elongated on purpose
//draft control variables , can be placed inside structures ...you know ,normally
int button_from_x=0,button_to_x=0,button_from_y=0,button_to_y=0;
bool is_button_on_a_click=false,is_button_hovered=false,button_mouse_scroll_memory=false;
//mouse control ,also could be in a structure ... normally
int mouse_x=0,mouse_y=0,previous_mouse_x=0,previous_mouse_y=0;
string mouse_click_string=NULL,previous_mouse_click_string=NULL;
int OnInit()
  {
  //reset
  ObjectsDeleteAll(ChartID(),system_tag);
  is_button_hovered=false;is_button_on_a_click=false;button_mouse_scroll_memory=false;
  mouse_x=0;mouse_y=0;mouse_click_string=NULL;
  previous_mouse_x=0;previous_mouse_y=0;previous_mouse_click_string=NULL;
  //create a button ,ill use rectangle,what it is is irrelevant
    ObjectCreate(ChartID(),system_tag+"_btn",OBJ_RECTANGLE_LABEL,0,0,0);
    ObjectSetInteger(ChartID(),system_tag+"_btn",OBJPROP_XSIZE,200);
    ObjectSetInteger(ChartID(),system_tag+"_btn",OBJPROP_YSIZE,40);
    ObjectSetInteger(ChartID(),system_tag+"_btn",OBJPROP_XDISTANCE,20);
    ObjectSetInteger(ChartID(),system_tag+"_btn",OBJPROP_YDISTANCE,20);
    button_from_x=20;button_to_x=button_from_x+200;
    button_from_y=20;button_to_y=button_from_y+40;
    ChartRedraw();
  //first ,activate mousemove 
  ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,true);
  return(INIT_SUCCEEDED);
  }
//EVENTS 
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
  //mousemove
    if(id==CHARTEVENT_MOUSE_MOVE)
    {
    //get mouse coordinates
      mouse_x=(int)lparam;
      mouse_y=(int)dparam;
      mouse_click_string=sparam;
    //hover check
      bool was_button_hovered=is_button_hovered;
      is_button_hovered=false;
      if(mouse_x>=button_from_x&&mouse_x<=button_to_x&&mouse_y>=button_from_y&&mouse_y<=button_to_y){is_button_hovered=true;}
    //if button is not clicking
      if(is_button_on_a_click==false)
      {
      //if a left click arrives 
        if(mouse_click_string=="1"&&previous_mouse_click_string=="0")
          {
          //and we was hovering the button - so you know , the click starts on the button
            if(was_button_hovered==true)
            {
            //and the mouse is still over the button
              if(is_button_hovered==true)
              {
              //get the mouse scroll memory 
                if(ChartGetInteger(ChartID(),CHART_MOUSE_SCROLL)){button_mouse_scroll_memory=true;}
              //disable the mouse scroll if need be (and if you want to)
                if(button_mouse_scroll_memory){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false);}
              //enable clicking 
                is_button_on_a_click=true;
              }
            //and the mouse is still over the button ends here 
            }
          //and we was hovering the button - so you know , the click starts on the button ends here 
          }
      //if a left click arrives ends here 
      }
      else if(is_button_on_a_click==true)//if button is on a click but dont access the first time 
      {
      //and user lifts their finger from the mouse button
        if(mouse_click_string=="0")
        {
        //restore mouse scroll
          if(button_mouse_scroll_memory==true){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,true);button_mouse_scroll_memory=false;}
        //cancel clicking event 
          is_button_on_a_click=false;
        //dont cancel hover 
        //alert the end of the event
          Alert("THE CLICK IS NOW COMPLETED");
        }
      }
    //if button is not clicking ends here 
    previous_mouse_x=mouse_x;
    previous_mouse_y=mouse_y;
    previous_mouse_click_string=mouse_click_string;
    }
  //mousemove ends here 
  }
//EVENTS
void OnTick(){}

void OnDeinit(const int reason)
  {
  //reset
  ObjectsDeleteAll(ChartID(),system_tag);
  is_button_hovered=false;is_button_on_a_click=false;button_mouse_scroll_memory=false;
  mouse_x=0;mouse_y=0;mouse_click_string=NULL;
  previous_mouse_x=0;previous_mouse_y=0;previous_mouse_click_string=NULL;
  }  
 
@Lorentzos Roussos Thank you. It does what I need. How I can modify the code to use with multiple objects. 
 
Narek Kamalyan:
@Lorentzos Roussos Thank you. It does what I need. How I can modify the code to use with multiple objects. 

You will need to keep a log of all your objects (mostly buttons) with an is_hovered switch , is_clicking switch ,from_x,from_y,to_x,to_y coordinates
and run through them on each mousemove event execution.

The difference is that if any one of the buttons "is clicking" the rest are not interactable.

Pair that with the ability to change the bitmap label and you have a system where the buttons "light up" and stay "lit" ( xD ) when being clicked.

Beware though as in huge deployments you will need to enforce delays and cancel outs of the mouse click to avoid misfires or double execution.

 
Lorentzos Roussos:

You will need to keep a log of all your objects (mostly buttons) with an is_hovered switch , is_clicking switch ,from_x,from_y,to_x,to_y coordinates
and run through them on each mousemove event execution.

The difference is that if any one of the buttons "is clicking" the rest are not interactable.

Pair that with the ability to change the bitmap label and you have a system where the buttons "light up" and stay "lit" ( xD ) when being clicked.

Beware though as in huge deployments you will need to enforce delays and cancel outs of the mouse click to avoid misfires or double execution.

@Lorentzos Roussos I played arround and was able to get what I want, i.e. 

Changed button state by mouse click 

         
	if(is_button_hovered==true) 
                {
                 ObjectSetInteger(0,"Button",OBJPROP_STATE,1);
                 ChartRedraw();
                }

And reset on mouse  release

            if(mouse_click_string=="0")
                {
                  ObjectSetInteger(0,"Button",OBJPROP_STATE,0);
                  ChartRedraw();
                }

So what I am trying to figure out is to cancel the action if the  mouse release was outside of the button. So, where should put the execution code to make it work only if the mouse button was released on the button. 

You will need to keep a log of all your objects (mostly buttons) with an is_hovered switch , is_clicking switch ,from_x,from_y,to_x,to_y coordinates
and run through them on each mousemove event execution.

Can you please show a code sample for two different objects. 

 

Can you please show a code sample for two different objects. 

No

So what I am trying to figure out is to cancel the action if the  mouse release was outside of the button. So, where should put the execution code to make it work only if the mouse button was released on the button. 

Then you will go to the section that controls execution here :

      else if(is_button_on_a_click==true)//if button is on a click but dont access the first time 
      {
      //and user lifts their finger from the mouse button
        if(mouse_click_string=="0")
        {
        //restore mouse scroll
          if(button_mouse_scroll_memory==true){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,true);button_mouse_scroll_memory=false;}
        //cancel clicking event 
          is_button_on_a_click=false;
        //dont cancel hover 
        //alert the end of the event
          Alert("THE CLICK IS NOW COMPLETED");
        }
      }

and specify if the button is no longer hovered on release then dont do whats supposed to be done

      else if(is_button_on_a_click==true)//if button is on a click but dont access the first time 
      {
      //and user lifts their finger from the mouse button
        if(mouse_click_string=="0")
        {
        //restore mouse scroll
          if(button_mouse_scroll_memory==true){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,true);button_mouse_scroll_memory=false;}
        //cancel clicking event 
          is_button_on_a_click=false;
        //dont cancel hover 
        //alert the end of the event
          if(is_button_hovered){Alert("THE CLICK IS NOW COMPLETED");}
          if(!is_button_hovered){Alert("THE USER CHANGED THEIR MIND");}
        }
      }
 

@Lorentzos Roussos you are genious.

Is it possible to put execution code on hovering (without click)?

 
Narek Kamalyan:

@Lorentzos Roussos you are genious.

Is it possible to put execution code on hovering (without click)?

For effects ? yes 

 
Where should I insert the code to be executed on hovering
Reason: