Crear una biblioteca gráfica desde cero - página 9

 
Aliaksandr Hryshyn:

Más:

Haga clic con el botón derecho del ratón en las áreas de la ventana y aparecerá un menú. Desplazar el ratón y hacer clic con el botón izquierdo del ratón. Esto hace que la ventana se mueva.

Es posible. Para tu información, yo mismo estoy desarrollando y probando, así que simplemente no me entero de algunos errores hasta que los encuentro accidentalmente en el proceso. Estoy haciendo todo por mi cuenta...

 

Este es mi ejemplo, en el archivo adjunto, hay tres ventanas superpuestas.

La creación de una ventana con subventanas es así, simplemente utilizando el motor sin código adicional. Excepto para manejar el evento de hacer clic en los botones superiores.

cStrategy_viewer::cStrategy_viewer()
  {
   int width_type=126;
   int height_type=30;
   int width_object=170;
   int height_object=22;

   my_handler.md=GetPointer(this);
   int obj_types_count=(ER_NODE_TYPE_COUNT-1);
//Основное окно
   _main_window=new cV_object_rectangle();
   _main_window.Set_property_info(vop_position_x,10);
   _main_window.Set_property_info(vop_position_y,50);
   _main_window.Set_property_info(vop_size_x,width_type*obj_types_count);
   _main_window.Set_property_info(vop_size_y,700);
   _main_window.Set_property_info(vop_is_zorder_top_on_click,true);
   _main_window.Create(cV_object_base::global_parent_object);
//Заголовок
   cV_object_rectangle *caption=new cV_object_rectangle();
   caption.Set_property_info(vop_position_x,-1);
   caption.Set_property_info(vop_position_y,-1);
   caption.Set_property_info(vop_size_x,_main_window.Get_property(vop_size_x).data_long);
   caption.Set_property_info(vop_size_y,20);
   caption.Create(_main_window);
//Текст заголовка.Будет отображаться полное имя файла стратегии
   _caption_text=new cV_object_label();
   _caption_text.Set_property_info(vop_position_x,-1);
   _caption_text.Set_property_info(vop_position_y,-1);
   _caption_text.Set_property_info(vop_size_x,caption.Get_property(vop_size_x).data_long);
   _caption_text.Set_property_info(vop_text,"Стратегия ....");
   _caption_text.Set_property_info(vop_text_anchor,TA_CENTER);
   _caption_text.Set_property_info(vop_font_size,20);
   _caption_text.Set_property_info(vop_is_movable,true);
   _caption_text.Set_property_info(vop_moving_parent_index,2);
   _caption_text.Set_property_info(vop_is_position_fixing_parent_x,true);
   _caption_text.Set_property_info(vop_is_position_fixing_parent_y,true);
   _caption_text.Set_property_info(vop_position_fixing_parent_index_x,2);
   _caption_text.Set_property_info(vop_position_fixing_parent_index_y,2);
   _caption_text.Create(caption);
//Контейнер для типов объектов
   _object_types=new cV_object_base();
   _object_types.Set_property_info(vop_position_x,0);
   _object_types.Set_property_info(vop_position_y,20);
   _object_types.Set_property_info(vop_size_x,obj_types_count*width_type);
   _object_types.Set_property_info(vop_size_y,height_type);
   _object_types.Create(_main_window);
//Типы объектов
   cV_object_rectangle *obje_type;
   cV_object_label *obje_type_text;
   for(int i1=0; i1<obj_types_count; i1++)
     {
      obje_type=new cV_object_rectangle();
      obje_type.Set_property_info(vop_position_x,i1*width_type);
      obje_type.Set_property_info(vop_position_y,0);
      obje_type.Set_property_info(vop_size_x,width_type);
      obje_type.Set_property_info(vop_size_y,height_type);
      obje_type.Set_property_info(vop_border_line_width,3);
      obje_type.Set_property_info(vop_color_borders_mouse_moving,clrLightBlue);
      obje_type.Set_property_info(vop_color_borders_selected,clrYellow);
      obje_type.Set_property_info(vop_is_change_color_borders_on_mouse_move,true);
      obje_type.Set_property_info(vop_is_change_color_borders_on_select,true);
      obje_type.Set_property_info(vop_is_selected,false);
      obje_type.Set_property_info(vop_is_my_event_MOUSE_DOWN_UP_CLICK_LEFT,true);
      color clr=0;
      switch(eNode_type(i1+1))
        {
         case nt_function:
           {
            clr=clrDimGray;
            break;
           }
         case nt_indicator_data:
           {
            clr=clrNavy;
            break;
           }
         case nt_indicator:
           {
            clr=clrMaroon;
            break;
           }
         case nt_if:
           {
            clr=clrBlack;
            break;
           }
         case nt_const:
           {
            clr=clrGreen;
            break;
           }
         case nt_buffer:
           {
            clr=clrBlue;
            break;
           }
         case nt_node_top:
           {
            clr=clrIndigo;
            break;
           }
        }
      obje_type.Set_property_info(vop_color_borders,clr);
      obje_type.Set_property_info(vop_color_back,clr);
      obje_type.Create(_object_types);
      obje_type.Add_event_handler(GetPointer(my_handler));
      obje_type_text=new cV_object_label();
      obje_type_text.Set_property_info(vop_text,StringSubstr(EnumToString(eNode_type(i1+1)),3));
      obje_type_text.Set_property_info(vop_color_back,clrWhite);
      obje_type_text.Set_property_info(vop_size_x,width_type-1);
      obje_type_text.Set_property_info(vop_position_x,-3);
      obje_type_text.Set_property_info(vop_position_y,5-3);
      obje_type_text.Set_property_info(vop_text_anchor,TA_CENTER);
      obje_type_text.Set_property_info(vop_font_size,18);
      obje_type_text.Create(obje_type);
     }
   _object_types.Get_child(0).Set_property(vop_is_selected,true);
//Окно отображения объектов
   cV_object_rectangle *objects_viever=new cV_object_rectangle();
   objects_viever.Set_property_info(vop_position_x,0);
   objects_viever.Set_property_info(vop_position_y,height_type+_object_types.Get_property(vop_position_y).data_long);
   objects_viever.Set_property_info(vop_size_x,width_object);
   objects_viever.Set_property_info(vop_size_y,30*height_object);
   objects_viever.Create(_main_window);
//Контейнер объектов
   int functions_count=cRules::Get_object_count(nt_function);
   _objects=new cV_object_base();
   _objects.Set_property_info(vop_position_x,0);
   _objects.Set_property_info(vop_position_y,0);
   _objects.Set_property_info(vop_size_x,width_object);
   _objects.Set_property_info(vop_size_y,functions_count*height_object);
   _objects.Set_property_info(vop_color_back,clrOlive);
//_objects.Set_property_info(vop_is_position_fixing_parent_x,true);
//_objects.Set_property_info(vop_is_position_fixing_parent_y,true);
   _objects.Create(objects_viever);
//Объекты
   for(int i1=0; i1<functions_count; i1++)
     {
      cV_object_label *object=new cV_object_label();
      object.Set_property_info(vop_size_x,width_object-2);
      object.Set_property_info(vop_position_x,1);
      object.Set_property_info(vop_position_y,i1*height_object);
      object.Set_property_info(vop_color_back,clrWhite);
      object.Set_property_info(vop_text,cRules::Get_object_name(nt_function,i1));
      object.Set_property_info(vop_text_anchor,TA_LEFT);
      object.Set_property_info(vop_font_size,height_object-2);
      object.Create(_objects);
     }
  }

Manejar el evento de hacer clic en los botones superiores:

void cStrategy_viewer::cMy_handler::On_event(sEvent &event)
  {
   cV_object_base *obj=GetPointer(event.object);
   switch(event.id)
     {
      case CHARTEVENT_CLICK_:
        {
         if(obj.Get_parent()==GetPointer(md._object_types))
           {
            obj.Set_property(vop_is_selected,true);
           }
         break;
        }
     }
  }

Hay varios botones y sólo una ventana principal

Archivos adjuntos:
 
Реter Konow:

Hubo un error de este tipo. Lo he arreglado. El evento en sí se arregla bien, pero se producen fallos con varios cambios que no se pueden evitar en el desarrollo del código.

Sí, es complicado.

Una imagen de la demostración:


 
Es que en un caso así, lo primero que hay que hacer es resolver los eventos y los controles de las ventanas, el resto es más fácil, aunque el resto es mucho más trabajo.
 
Cualquiera que esté interesado en hacer una biblioteca de elementos visuales desde cero :) ?
 
Aliaksandr Hryshyn:
Es que en este caso, primero hay que elaborar los eventos y los controles de las ventanas, el resto es más fácil, pero hay mucho más trabajo que hacer.

El trabajo de base ya está hecho.

1: las ventanas deberían tener botones de cierre y colapso (al menos).

2: las ventanas deben redibujarse una encima de la otra al hacer clic.

3: Las ventanas deben moverse con el ratón.

4: las ventanas deben ser "detectadas" (enfocadas) en el gráfico cuando el cursor se mueve ( evento señalado).

5. Todos los elementos de las ventanas deben estar en un "mapa" común de la ventana y ser detectados cuando se pasa el ratón por encima (evento señalado).

 

Los elementos más simples:

1. Una ventana estática, dimensionalmente inmutable e indeleble.

2. Botón.

3. Casilla de verificación.

4. Botón de radio.

5. Ficha.

6. Línea, marco, divisor, rectángulo.


Elementos de complejidad media:

1. Deslizadores.

2. Barras de progreso.

3. Campos de entrada.

4. Campos desplazables.

5. Elementos de la lista simple.


Artículos de alta complejidad.

1. Una lista desplegable (un elemento muy complejo).

2. Una ventana dinámica (extensible). Supercomplejo.


Hay unos 50 tipos de controles. Cada uno de ellos debe tener un conjunto común y único de propiedades soportadas por la funcionalidad del motor correspondiente. Propiedades al menos 100, de lo contrario el trabajo de los elementos se verá muy limitado.

Las formas y líneas simples no necesitan muchas propiedades, pero cuanto más complejo sea el elemento, más habrá.
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
  • www.mql5.com
Все объекты, используемые в техническом анализе, имеют привязку на графиках по координатам цены и времени – трендовая линия, каналы, инструменты Фибоначчи и т.д.  Но есть ряд вспомогательных объектов, предназначенных для улучшения интерфейса, которые имеют привязку к видимой всегда части графика (основное окно графика или подокна индикаторов...
 

¡Mierda! ¡Me olvidé de las mesas! Es una jungla ahí fuera... ))))

Y una lista de árboles, y todo tipo de colapsos...

 
Cada control interactivo tiene un parámetro controlado con su propio conjunto de propiedades. Por ejemplo, un botón tiene un parámetro de tipo bool (1 o 0), un campo de entrada tiene un parámetro de tipo cadena, un deslizador tiene un parámetro de tipo rango... Un campo de entrada con botones tiene un parámetro con propiedades valor_actual, valor_último, mínimo, máximo, paso, tipo_valor y otras. Cada propiedad se apoya en la funcionalidad.

Cada elemento interactivo debe tener (idealmente) 8 estados diferentes que cambian en diferentes eventos.

Por ejemplo: neutro, neutro_señalado, neutro_activado, neutro_señalado, neutro_señalado, neutro_bloqueado, activado_bloqueado.

Cada estado está diseñado con su propio conjunto de valores de propiedades de los elementos y entra en vigor en sus propios eventos, que se fijan mediante una funcionalidad especial.
 
Реter Konow:

¡Mierda! ¡Me olvidé de las mesas! Es una jungla ahí fuera... ))))

Y una lista en forma de árbol, y todo tipo de colapsadores...

En mi caso, la "jungla" no es más complicada que la media: una ventana de visualización (el área visible de la tabla), una ventana de tamaño completo en la que deben caber todas las celdas, que se deslizará dentro de la ventana principal, ventanas para las filas y celdas en ellas, además del desplazamiento (un deslizador delimitado por una barra). Las restricciones de posicionamiento relativo vienen determinadas por las propiedades. Sólo para el deslizador es necesario interceptar los eventos de movimiento del objeto y ya corregir la posición dela "ventana de tamaño completo". Todo esto se hace mediante ventanas virtuales, necesitamos atornillar la parte visual a ella, sin la parte visual habrá ventanas para las líneas y la ventana de tamaño completo. Y para una celda editable, hacer un campo de entrada (esto es una costumbre), todas las otras cosas serán manejadas por el motor - que obtendrá los eventos adecuados para cada celda (eventos del ratón, redibujando, moviendo)..... Estas son las posibilidades, pero también hay un par de ideas para aumentar el rendimiento en caso de que haya demasiadas ventanas (listas grandes, tablas, varios miles de ventanas).

Razón de la queja: