Creating a graphic library from scratch - page 5

 
How is the library progressing?
 
Реter Konow:
How is the library progressing?

everything is more than fine.

 

I've also got the hang of making a graphics library, just with the elements I need.

The main trick of the library is its windowing engine:

  • it does not depend on graphics, you can say virtual windows without a single function to work with graphics, even absolutely windows will work correctly(events,properties)
  • sets of properties for a window that affect its behaviour, dependent properties of that window and others

   cV_object_base::Init(my_handler);
   cV_object_rectangle *app_00=new cV_object_rectangle();
   cV_object_rectangle *app_0=new cV_object_rectangle();
   cV_object_rectangle *app_1=new cV_object_rectangle();

   cV_object_label *lb1=new cV_object_label();
   app_00.Create(cV_object_base::global_parent_object);
   app_00.Set_property(vop_size_x,800);
   app_00.Set_property(vop_size_y,500);
   app_00.Set_property(vop_color_back,clrDarkGreen);

   app_0.Create(app_00,"AAA");

   app_00.Set_property(vop_is_position_fixing_parent_x,true);
   app_00.Set_property(vop_is_position_fixing_parent_y,true);

   app_1.Create(app_00);
   app_0.Set_property(vop_is_zorder_top_on_click,true);
   app_0.Set_property(vop_is_position_fixing_parent_x,true);
   app_0.Set_property(vop_is_position_fixing_parent_y,true);
   app_1.Set_property(vop_is_zorder_top_on_click,true);

   app_0.Set_property(vop_size_x,1000);
   app_0.Set_property(vop_size_y,300);
   app_0.Set_property(vop_position_x,100);
   app_0.Set_property(vop_position_y,100);
   app_0.Set_property(vop_color_back,clrDarkBlue);
   app_0.Set_property(vop_is_movable,true);
   app_0.Set_property(vop_is_selected_multi,false);

   lb1.Create(app_0,"E_hallo_world_E");
   lb1.Set_property(vop_is_movable,true);
   lb1.Set_property(vop_color_back_selected,clrDarkTurquoise);
   lb1.Set_property(vop_is_change_color_back_on_select,true);
   lb1.Set_property(vop_is_zorder_top_on_click,true);

   app_1.Set_property(vop_size_x,300);
   app_1.Set_property(vop_size_y,500);
   app_1.Set_property(vop_position_x,200);
   app_1.Set_property(vop_position_y,200);
   app_1.Set_property(vop_is_movable,true);

   cV_object_rectangle *app_2;
   cV_object_rectangle *app_3;
   for(int i1=0; i1<4; i1++)
     {
      app_2=new cV_object_rectangle();
      app_3=new cV_object_rectangle();
      app_2.Create(app_0,ShortToString(ushort('A'+i1)));
      app_3.Create(app_1);

      app_2.Set_property(vop_size_x,100);
      app_2.Set_property(vop_size_y,75);
      app_3.Set_property(vop_size_x,75);
      app_3.Set_property(vop_size_y,100);

      app_2.Set_property(vop_position_x,i1*20);
      app_2.Set_property(vop_position_y,i1*40);
      app_3.Set_property(vop_position_x,i1*20);
      app_3.Set_property(vop_position_y,i1*40);

      app_2.Set_property(vop_color_back,clrDarkGray);
      app_3.Set_property(vop_color_back,clrLightGoldenrod);

      app_2.Set_property(vop_is_movable,true);
      app_2.Set_property(vop_is_zorder_top_on_click,true);
      app_3.Set_property(vop_is_movable,true);

      app_3.Set_property(vop_is_change_color_back_on_select,true);
      app_3.Set_property(vop_color_back_selected,clrRed);

      app_2.Set_property(vop_color_back_selected,clrDarkTurquoise);
      app_2.Set_property(vop_is_change_color_back_on_select,true);
     }
   app_3.Set_property(vop_moving_parent_index,1);
   app_3.Set_property(vop_position_x,150);
   app_3.Set_property(vop_size_y,150);

   app_2.Set_property(vop_moving_parent_index,2);
   app_2.Set_property(vop_position_x,150);
   app_2.Set_property(vop_size_y,150);

   app_2.Set_property(vop_color_borders,clrDarkTurquoise);
   app_3.Set_property(vop_color_borders,clrDarkTurquoise);

   app_2.Set_property(vop_is_change_color_back_on_mouse_move,true);
   app_3.Set_property(vop_is_change_color_back_on_mouse_move,true);
   app_2.Set_property(vop_is_change_color_borders_on_mouse_move,true);
   app_3.Set_property(vop_is_change_color_borders_on_mouse_move,true);
   app_3.Set_property(vop_is_selected,true);


  • as graphics you can use both standard objects and canvas, and DirectX, whatever you like
  • engine windows are the building blocks for building graphical elements
  • use of different optimizations for performance (exclusion of unnecessary calls of graphic system functions, as well as exclusion from drawing of invisible boxes)
  • Simplicity in creation of a new graphic item, both implementation of graphic design and creation of child graphic items/windows structure. All events and calculation of dependent properties will be performed at engine level, it does not distinguish custom graphic items, it works only at basic windows level

Creating and deleting the standard OBJ_RECTANGLE_LABEL object

bool cV_object_rectangle::_Create_resource()
  {
   if(!ObjectCreate(0,visual_object_name,OBJ_RECTANGLE_LABEL,0,0,0))
     {
      cLng_add_user(lng_id,8,EnumToString(OBJ_RECTANGLE_LABEL),"");
      return false;
     }
   return true;
  }

bool cV_object_rectangle::_Delete_resource()
  {
   ObjectDelete(0,visual_object_name);
   return true;
  }

This implements a method for changing the properties of the standard OBJ_RECTANGLE_LABEL object, rustling through the help and using the properties of interest

bool cV_object_rectangle::_Set_property(eV_object_property property,sV_property_value &property_value)
  {
   _is_redraw_object=true;
   switch(property)
     {
      case vop_s_is_hidden:
        {
         if(property_value.data_long)
           {
            ObjectSetInteger(0,visual_object_name,OBJPROP_XSIZE,0);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YSIZE,0);
            ObjectSetInteger(0,visual_object_name,OBJPROP_XDISTANCE,-20);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YDISTANCE,-20);
           }
         else
           {
            ObjectSetInteger(0,visual_object_name,OBJPROP_XSIZE,_property_values[vop_s_size_real_x].data_long);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YSIZE,_property_values[vop_s_size_real_y].data_long);
            ObjectSetInteger(0,visual_object_name,OBJPROP_XDISTANCE,_property_values[vop_s_position_real_x].data_long);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YDISTANCE,_property_values[vop_s_position_real_y].data_long);
           }
         break;
        }
      case vop_s_color_back:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_BGCOLOR,property_value.data_long);
         break;
        }
      case vop_border_type:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_BORDER_TYPE,property_value.data_long);
         break;
        }
      case vop_s_color_borders:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_COLOR,property_value.data_long);
         break;
        }
      case vop_s_position_real_x:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_XDISTANCE,property_value.data_long);
         break;
        }
      case vop_s_position_real_y:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_YDISTANCE,property_value.data_long);
         break;
        }
      case vop_s_size_real_x:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_XSIZE,property_value.data_long);
         break;
        }
      case vop_s_size_real_y:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_YSIZE,property_value.data_long);
         break;
        }
      case vop_font_size:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_FONTSIZE,property_value.data_long);
         break;
        }
      case vop_line_width:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_WIDTH,property_value.data_long);
         break;
        }
      default:
        {
         _is_redraw_object=false;
        }
     }
   return true;
  }

  • easy event handling
This is an external event handler, the name of the object of interest (window/graphical item) can be specified when creating it
class My_handler:public iE_event_handler
  {
   void              On_event(sEvent &event)
     {
      if(event.id==CHARTEVENT_CLICK_)
        {
         if(
            (event.sparam=="A")||
            (event.sparam=="B")||
            (event.sparam=="C")||
            (event.sparam=="D")||
            (event.sparam=="E_hallo_world_E")
         )
           {
            sV_property_value v;
            cV_object_base *obj;
            obj=cV_object_base::Get_object_from_name(event.sparam);
            obj.Get_property(vop_is_selected,v);
            v.data_long=!v.data_long;
            obj.Set_property(vop_is_selected,v.data_long);
           }
         else
            if(event.sparam=="AAA")
              {
               sV_property_value v;
               cV_object_base *obj;
               obj=cV_object_base::Get_object_from_name("AAA");
               obj.Get_property(vop_is_selected_multi,v);
               v.data_long=!v.data_long;
               obj.Set_property(vop_is_selected_multi,v.data_long);
              }
            else
               if(event.sparam=="vt_rectangle_4")
                 {
                  sV_property_value v;
                  cV_object_base *obj;
                  obj=cV_object_base::Get_object_from_name("AAA");
                  obj.Get_property(vop_position_x,v);
                  v.data_long=v.data_long+5;
                  obj.Set_property(vop_position_x,v.data_long);
                  ulong ms=cV_object_base::Get_timer_msc();
                  if(ms!=ULONG_MAX)
                    {
                     Print(ms/1000.0," мс");
                    }
                 }
        }
     }
  };

The text label is implemented via kanvas because the width and height cannot be changed in OBJ_LABEL object, and for this reason rendering is performed when a CHARTEVENT_ON_PAINT event occurs (requiring redrawing)

bool cV_object_label::_On_event(const sEvent &event)
  {
   if(event.id==CHARTEVENT_ON_PAINT)
     {
      color color_back=clrBlack;
      if(CheckPointer(_object_parent))
        {
         color_back=color(_object_parent._property_values[vop_color_back].data_long);
        }
      int width=int(_property_values[vop_s_size_real_x].data_long);
      int height=int(_property_values[vop_s_size_real_y].data_long);
      int x=int(_property_values[vop_s_position_global_x].data_long-_property_values[vop_s_position_real_x].data_long);
      int y=int(_property_values[vop_s_position_global_y].data_long-_property_values[vop_s_position_real_y].data_long);
      _canvas.Resize(width,height);
      width=int(_property_values[vop_size_x].data_long);
      height=int(_property_values[vop_size_y].data_long);
      _canvas.Erase(ColorToARGB(color_back));
      switch(int(_property_values[vop_text_anchor].data_long))
        {
         case TA_CENTER:
           {
            x=x+(width-_canvas.TextWidth(_property_values[vop_text].data_string))/2;
            break;
           }
         case TA_RIGHT:
           {
            x=x+(width-_canvas.TextWidth(_property_values[vop_text].data_string));
            break;
           }
        }
      _canvas.TextOut(x,y,_property_values[vop_text].data_string,ColorToARGB(color(_property_values[vop_s_color_back].data_long)));//);
      _canvas.Update(false);
     }
   return true;
  }

What to render and update is determined automatically. The properties are logged before calling ChartRedraw() . Events that have not caused the chart to be redrawn are skipped.

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   cV_object_base::On_chart_event(id,lparam,long(dparam),sparam);
   ulong ms=cV_object_base::Get_timer_msc();
   if(ms!=ULONG_MAX)
     {
      Print(ms/1000.0," мс");
     }
  }

The demo is in attached file, above sources are used in it.

Files:
Test_forms.ex5  221 kb
 

The demo doesn't display all possible properties, only some of them:

It's still a work in progress, so far.

 
Aliaksandr Hryshyn:

The demo doesn't display all possible properties, only some of them:

It's still a work in progress, for now.

Good luck with the development! :)

 
Реter Konow:

Good luck with the development! :)

Thanks :)

 

Tested the functionality and potential of 3D graphics in MT5 on a weak computer with 4 GB of RAM and 2 processor cores.



It works fine even after a long pause in programming. But the thing is heavy and it takes a lot of hard work to create something serious.

 
Does it help to make money?
 
Реter Konow:

Tested the functionality and potential of 3D graphics in MT5 on a weak computer with 4 GB of RAM and 2 processor cores.

It works fine even after a long pause in programming. But, the thing is heavy and it takes a lot of hard work to develop something serious.

For HFT, I think 3D will be useful for graphical analysis of the cup's volume and order flow.
But I don't know how to interpret such information.

dom

stream

 

My God! What is all this for?