Criar uma biblioteca gráfica a partir do zero - página 9

 
Aliaksandr Hryshyn:

Mais:

Clicar com o botão direito do mouse nas áreas da janela, aparece um menu. Mude o mouse e clique com o botão esquerdo do mouse. Isto faz com que a janela se mova.

Isso é possível. Para sua informação, eu mesmo estou me desenvolvendo e testando, então simplesmente não sei de alguns bugs até encontrá-los acidentalmente no processo. Estou fazendo tudo sozinha...

 

Aqui está meu exemplo, no arquivo anexo, há três janelas que se sobrepõem uma à outra.

Criar uma janela com subjanelas é assim, apenas usando o motor sem código adicional. Exceto para lidar com o evento de clicar nos botões 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);
     }
  }

Lidando com o evento de clicar nos botões 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;
        }
     }
  }

Há vários botões e apenas uma janela pai

Arquivos anexados:
 
Реter Konow:

Havia tal erro. Fixou-o. O evento em si é fixo, mas os bugs ocorrem com várias mudanças que não podem ser evitadas no desenvolvimento do código.

Sim, é complicado.

Uma foto da demonstração:


 
É que em um negócio como este, a primeira coisa que você tem que fazer é trabalhar os eventos e controles de janela, e o resto é mais fácil, embora haja muito mais trabalho a ser feito em outro lugar.
 
Qualquer pessoa interessada em fazer uma biblioteca de elementos visuais a partir do zero :) ?
 
Aliaksandr Hryshyn:
É que neste caso, antes de tudo, temos que elaborar os eventos e controles de janela, o resto é mais fácil, mas há muito mais trabalho a ser feito.

O trabalho de base já está pronto.

1: As janelas devem ter botões de fechamento e de colapso (pelo menos).

2: As janelas devem ser redesenhadas uma sobre a outra quando clicadas.

3: As janelas devem se mover com o mouse.

4: as janelas devem ser "detectadas" (focalizadas) no gráfico quando o cursor se move ( evento pontiagudo).

5. Todos os elementos das janelas devem estar em um "mapa" comum da janela e devem ser detectados quando o mouse estiver pairando (evento apontado).

 

Os elementos mais simples:

1. Uma Janela estática, dimensionalmente imutável e indelével.

2. Botão.

3. caixa de seleção.

4. Botão de rádio.

5. Tab.

6. Linha, moldura, divisor, retângulo.


Elementos de complexidade média:

1. Sliders.

2. Barras de progresso.

3. Campos de entrada.

4. Campos de rolagem.

5. Itens de lista simples.


Itens de alta complexidade.

1. Uma lista suspensa (um elemento muito complexo).

2. Uma janela dinâmica (extensível). Super-complexo.


Existem cerca de 50 tipos de controles. Cada um deve ter um conjunto comum e único de propriedades apoiado pela funcionalidade correspondente do motor. Propriedades pelo menos 100, caso contrário, o trabalho dos elementos será severamente limitado.

Formas e linhas simples não precisam de muitas propriedades, mas quanto mais complexo o elemento, mais existem.
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
  • www.mql5.com
Все объекты, используемые в техническом анализе, имеют привязку на графиках по координатам цены и времени – трендовая линия, каналы, инструменты Фибоначчи и т.д.  Но есть ряд вспомогательных объектов, предназначенных для улучшения интерфейса, которые имеют привязку к видимой всегда части графика (основное окно графика или подокна индикаторов...
 

Merda! esqueci as mesas! É uma selva lá fora... ))))

E uma lista de árvores, e todo tipo de colapsos.

 
Cada controle interativo tem um parâmetro controlado por ele com seu próprio conjunto de propriedades. Por exemplo, um botão tem um parâmetro tipo bool (1 ou 0), um campo de entrada tem um parâmetro tipo string-type, um deslizador tem um parâmetro tipo range-type... Um campo de entrada com botões tem um parâmetro com propriedades valor_corrente, último_valor, mínimo, máximo, passo, tipo_valor e outros. Cada propriedade é suportada pela funcionalidade.

Cada elemento interativo deveria (idealmente) ter 8 estados diferentes que mudam em eventos diferentes.

Por exemplo: neutro, ponto_neutro, ponto_neutro_activado, ponto_neutro_activado, ponto_neutro_activado, ponto_neutro_activado, ponto_neutro_activado, ponto_neutro_activado, ponto_neutro_activado.

Cada estado é projetado com seu próprio conjunto de valores de propriedade de elementos e entra em vigor em seus próprios eventos, que são fixados por uma funcionalidade especial.
 
Реter Konow:

Merda! esqueci as mesas! É uma selva lá fora... ))))

E uma lista em forma de árvore, e todo tipo de colapsos.

No meu caso, a "selva" não é mais complicada do que a média: uma janela de exibição (a área visível da mesa), uma janela em tamanho real na qual todas as células devem caber, ela deslizará dentro da janela principal, janelas para filas e células nelas, mais rolagem (um deslizador delimitado por uma barra). As restrições de posicionamento relativo são determinadas pelas propriedades. Somente para o controle deslizante é necessário interceptar eventos de movimento de objetos e já corrigir a posição da"janela de tamanho completo".Tudo isso é feito por janelas virtuais, precisamos aparafusar parte visual a ela, sem parte visual haverá janelas para linhas e janelas em tamanho real. E para uma célula editável, faça um campo de entrada (este é personalizado), todas as outras coisas serão tratadas pelo motor - ele terá os eventos certos para cada célula (eventos do mouse, redesenho, movimentação)..... Estas são as possibilidades, mas há também algumas idéias para aumentar o desempenho caso haja muitas janelas (grandes listas, mesas, vários milhares de janelas).