Discussão do artigo "Interfaces Gráficas X: Os Controles Horário, Lista de Caixas de Seleção e Tabela Ordenada (build 6)" - página 2
Você está perdendo oportunidades de negociação:
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Registro
Login
Você concorda com a política do site e com os termos de uso
Se você não tem uma conta, por favor registre-se
No entanto, parece-me que as alterações recentes relacionadas à especificação de coordenadas por deslocamento a partir da borda do formulário não são muito amigáveis para o usuário final. Se antes o usuário podia usar com segurança duas opções para especificar o local de um objeto na janela, agora uma delas se tornou mais complicada. As coisas desmoronaram assim em toda a tela.
Exemplo:
Botão1 - sua coordenada x está a 4 pixels de distância da borda esquerda da janela do formulário. Ela é definida da seguinte forma: x=m_window.X()+4; O tamanho do botão1 é de 43 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt1.X2();
Botão2 - sua coordenada está a 2 pixels de distância da borda direita do botão1. Ele é definido da seguinte forma: x=m_butt1.X2()+2; O tamanho do botão2 é de 24 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt2.X2();
Botão3 - sua coordenada está a 4 pixels de distância da borda direita do botão2. Ele é definido da seguinte forma: x=m_butt2.X2()+4; O tamanho do botão3 é de 18 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt3.X2();
A barra de separação vertical está a 4 pixels da borda direita do botão3: x=m_butt3.X2()+4;
Portanto, podemos alterar facilmente o tamanho de qualquer um dos três botões, e todos eles estarão localizados no deslocamento que definimos, e a barra de separação estará perfeitamente posicionada no deslocamento que precisamos do botão3.
Button1: x_gap1=4;
Button2: x_gap2=4+m_butt1.XSize()+2;
Button3: x_gap3=4+m_butt1.XSize()+2+m_butt2.XSize()+4;
R-Strip: x_gap4=4+m_butt1.XSize()+2+m_butt2.XSize()+4+m_butt3.XSize()+4;
Aqui é sugerido especificar a coordenada X2() em vez de especificar os tamanhos dos objetos, mas esse não é o caso - tudo desmorona de uma só vez (eu, por exemplo, quebrei a cabeça ao adivinhar que Y2() não aponta para o local correto da coordenada Y).
Vejamos: eu defini as coordenadas do menu com um recuo de 1 pixel na horizontal e com um recuo do tamanho do "cabeçalho" da janela principal. A altura do menu é de 18 pixels.
x=m_window_main.X()+1;
y=m_window_main.Y()+m_window_main.CaptionHeight();
h=18;
O menu está em seu lugar:
Agora preciso colocar a tabela deslocada da borda inferior do menu. Se o CaptionHeight() da janela do formulário for de 18 pixels e a altura do menu também for de 18 pixels, o deslocamento vertical da tabela deverá ser de 36 pixels. Há duas opções: ou nos sentamos com uma calculadora e calculamos todos os deslocamentos necessários (e os recalculamos novamente no caso de ajustes subsequentes com alterações de tamanho) ou tentamos obtê-los. Escolhemos a segunda opção, é claro, e tentamos: para a tabela, o y_gap deve ser igual à altura do título da janela principal mais a altura do menu: m_window_main.CaptionHeight()+m_menu_main.YSize();
x=2;
y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
w=140;
Compilar, obter:
A guia está no lugar. Mas. O valor Y2() do menu, nesse caso, não deveria coincidir com o valor que calculamos? Afinal, é mais conveniente não coletar os tamanhos de todos os objetos que se seguem uns aos outros, mas apenas obter suas coordenadas, certo? Vamos tentar: altere o cálculo da coordenada para sua obtenção:
x=2;
//y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
y=m_menu_main.Y2()+1;
w=140;
Compile, get:
Y2() não deveria retornar o mesmo Y2 que calculamos anteriormente? m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
Agora não especificamos coordenadas com deslocamento a partir de qualquer borda da janela, mas apenas deslocamento, e apenas a partir do topo ou da esquerda. Bom. Remova da coordenada Y2() obtida a coordenada Y() da parte superior da janela do formulário para obter o valor do deslocamento a partir da parte superior da janela do formulário:
x=2;
//y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
y=m_menu_main.Y2()-m_window_main.Y()+1;
w=140;
Compile e obtenha o que deseja:
Então, para vinte objetos que estão a dois pixels de distância um do outro, devemos sempre adicionar seus tamanhos mais o deslocamento um do outro para obter o deslocamento correto para o último objeto? Afinal, Y2() do décimo nono objeto (a partir do qual era possível construir o vigésimo objeto apenas adicionando um deslocamento de dois pontos) agora não nos dá um ponto de partida e não retorna o que é esperado.... e temos que somar os tamanhos de todos os objetos para obter o deslocamento necessário ou, para cada objeto antes de sua criação, temos que calcular seu deslocamento com base em sua coordenada Y2() e na coordenada Y() inicial da janela do formulário.
Não estou entendendo. Anatoly, por favor, me dê uma solução. O que estou fazendo de errado? Por que é assim? Por que você acha que agora está mais amigável? Se antes você podia simplesmente especificar o deslocamento de qualquer borda da janela do formulário, de qualquer objeto nessa janela ou até mesmo da borda do gráfico em geral para criar o objeto necessário, agora você tem que fazer uma dança de pandeiro para calcular suas coordenadas antes de criá-lo? É melhor e mais conveniente escrever mais código e cálculos diferentes?
Entendo que você é o autor e sabe o que é melhor. Mesmo assim, você permite que outras pessoas o utilizem. Eu (apenas minha opinião) acho que essa inovação acabou sendo a única decisão ruim de apresentá-la como uma atualização - ela se tornou pior. Ele não tinha mais os recursos fáceis de criação de interface que tinha antes.
Peço desculpas se o ofendi (antigamente, os mensageiros com más notícias tinham suas cabeças cortadas).
...
Desculpe-me se o ofendi.
Responderei um pouco mais tarde, mas, antes disso, gostaria de esclarecer o que você quer dizer com essa frase em relação a mim. O que são "más notícias" e quem é um "mensageiro" nesse contexto? :)
Responderei um pouco mais tarde, mas, antes disso, gostaria de esclarecer o que você quis dizer com essa frase sobre mim. O que são "más notícias" e quem é um "mensageiro" nesse contexto? :)
:)
Chamei de "más notícias" minha atitude em relação à inovação de que não é mais possível usar qualquer coordenada arbitrária como ponto de referência da coordenada do objeto, mas apenas as bordas esquerda e superior do formulário (adicionei um recálculo das coordenadas no local - cálculos desnecessários).... E o mensageiro sou eu, é claro, já que não gostei e disse isso :)
:)
A má notícia é que chamei minha atitude para a inovação de que agora não é possível tomar qualquer coordenada arbitrária como ponto de referência de coordenadas do objeto, mas apenas as bordas esquerda e superior do formulário (adicionei um recálculo de coordenadas em cálculos locais - desnecessários).... Bem, o mensageiro sou eu, é claro, já que não gostei e disse isso :)
Então, aí está. Muito bom. Porque eu achei que tinha entendido errado. )
Aqui está minha resposta:
No entanto, acho que as alterações recentes relacionadas à especificação de coordenadas por deslocamento da borda do formulário não são muito amigáveis para o usuário final. Se antes o usuário podia usar com segurança duas opções para especificar o local do objeto na janela, agora uma delas se tornou mais complicada. Já aconteceu de as coisas desmoronarem e se dividirem por toda a tela dessa forma.
...
Agora vamos ver o que temos de fazer ao criar a interface de acordo com as novas regras:
Button1: x_gap1=4;
Button2: x_gap2=4+m_butt1.XSize()+2;
Button3: x_gap3=4+m_butt1.XSize()+2+m_butt2.XSize()+4;
R Strip: x_gap4=4+m_butt1.XSize()+2+m_butt2.XSize()+4+m_butt3.XSize()+4;
...
Em vez de especificar os tamanhos dos objetos, você ficaria tentado a especificar a coordenada X2() deles, mas esse não é o caso - tudo desmorona de uma vez (eu, por exemplo, quebrei a cabeça até perceber que Y2() não aponta para o local correto da coordenada Y).
É muito simples. Anteriormente, você tinha que passar coordenadas absolutas para os métodos de criação de elementos. Elas tinham de ser calculadas em relação ao ponto mais à esquerda do formulário ao qual o elemento está anexado.
Aqui está um exemplo do que tivemos de fazer anteriormente:
//|| Cria um botão|
//+------------------------------------------------------------------+
bool CProgram::CreateSimpleButton(const int x_gap,const int y_gap,const string button_text)
{
//--- Salvar o ponteiro no formulário
m_simple_button.WindowPointer(m_window);
//--- Coordenadas
int x=m_window.X()+x_gap;
int y=m_window.Y()+y_gap;
//--- Definir propriedades antes da criação
m_simple_button.ButtonXSize(100);
//--- Criando um botão
if(!m_simple_button.CreateSimpleButton(m_chart_id,m_subwin,button_text,x,y))
return(false);
//--- Adicione um ponteiro ao elemento na base
CWndContainer::AddToElementsArray(0,m_simple_button);
return(true);
}
//---
Agora você não precisa calcular nada, pois basta passar as coordenadas relativas.
Um exemplo do que precisa ser feito agora:
//|| Cria um botão|
//+------------------------------------------------------------------+
bool CProgram::CreateSimpleButton(const int x_gap,const int y_gap,const string button_text)
{
//--- Passar o objeto do painel
m_simple_button.WindowPointer(m_window);
//--- Definir propriedades antes da criação
m_simple_button.ButtonXSize(100);
//--- Criando um botão
if(!m_simple_button.CreateSimpleButton(m_chart_id,m_subwin,button_text,x_gap,y_gap))
return(false);
//--- Adicione um ponteiro ao elemento na base
CWndContainer::AddToElementsArray(0,m_simple_button);
return(true);
}
//---
Nos seus exemplos acima, você está calculando coordenadas absolutas. Decisão estúpida seguida de conclusões erradas colocadas apressadamente em público.
Os métodos CElement ::X(), CElement ::X2(), CElement ::Y() e CElement::Y2() retornam coordenadas absolutas das bordas do elemento. E foi fácil entender isso apenas com a saída desses valores para o registro do terminal, se houver alguma dúvida.
Abaixo está um exemplo de cálculo da indentação( coordenadarelativa ) em relação a algum elemento. Há dois botões. A coordenada X (relativa) do segundo botão é calculada em relação à borda direita do primeiro botão.
//|| Cria a GUI do programa
//+------------------------------------------------------------------+
bool CProgram::CreateGUI(void)
{
//--- Criando um painel
if(!CreateWindow("EXPERT PANEL"))
return(false);
if(!CreateSimpleButton1(7,25,"BUTTON 1"))
return(false);
if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2"))
return(false);
//---
return(true);
}
//---
Como resultado, o segundo botão será definido com um recuo de 5 pixels da borda direita do primeiro botão:
//---
Ao alterar a largura ou a coordenada X do primeiro botão, a posição do segundo botão será ajustada automaticamente.
Portanto, os cálculos desnecessários estão apenas em seu exemplo citado acima.
//|| Cria a GUI do programa
//+------------------------------------------------------------------+
bool CProgram::CreateGUI(void)
{
//--- Criando um painel
if(!CreateWindow("EXPERT PANEL"))
return(false);
if(!CreateSimpleButton1(7,25,"BUTTON 1"))
return(false);
if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2"))
return(false);
//---
return(true);
}
//---
Como resultado, o segundo botão será definido com um recuo de 5 pixels a partir da borda direita do primeiro botão:
//---
Ao alterar a largura ou a coordenada X do primeiro botão, a posição do segundo botão será ajustada automaticamente.
Portanto, os cálculos extras estão apenas em seu exemplo citado acima.
Aqui... Isso não ficou muito claro:
if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2"))
Tenho que colocar esse recálculo em minhas funções para não escrever esse recálculo em todos os lugares ao especificar as coordenadas de um objeto recém-criado, mas para continuar escrevendo como era antes - é mais claro ver a relação de um objeto com outro. É uma questão de gosto e preferências de cada um, é claro...
A propósito, o navegador de arquivos não funciona mesmo quando se especificam as coordenadas, como você disse. Mas talvez seja apenas eu. Vou procurar o motivo.
Capturas de tela da plataforma de negociação MetaTrader
EURUSD, D1, 2016.12.12
MetaQuotes Software Corp., MetaTrader 5, Demonstração
Anatoly, parece que você esqueceu de editar o FileNavigator.mqh no arquivo
//| Cria uma lista em árvore|
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\folder_w10.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\text_file_w10.bmp"
//---
bool CFileNavigator::CreateTreeView(void)
{
//--- Salvar o ponteiro da janela
m_treeview.WindowPointer(m_wnd);
//--- Definir propriedades
m_treeview.Id(CElement::Id());
m_treeview.ResizeListAreaMode(true);
m_treeview.TreeViewAreaWidth(m_treeview_area_width);
m_treeview.ContentAreaWidth(m_content_area_width);
m_treeview.AutoXResizeMode(CElement::AutoXResizeMode());
m_treeview.AutoXResizeRightOffset(CElement::AutoXResizeRightOffset());
m_treeview.AnchorRightWindowSide(m_anchor_right_window_side);
m_treeview.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Formam matrizes da lista de árvores
int items_total=::ArraySize(m_g_item_text);
for(int i=0; i<items_total; i++)
{
//--- Definir a imagem para o item (pasta/arquivo)
string icon_path=(m_g_is_folder[i])? m_folder_icon : m_file_icon;
//--- Se for uma pasta, exclua o último caractere ('\') da string
if(m_g_is_folder[i])
m_g_item_text[i]=::StringSubstr(m_g_item_text[i],0,::StringLen(m_g_item_text[i])-1);
//--- Adicionar um item à lista da árvore
m_treeview.AddItem(i,m_g_prev_node_list_index[i],m_g_item_text[i],icon_path,m_g_item_index[i],
m_g_node_level[i],m_g_prev_node_item_index[i],m_g_items_total[i],m_g_folders_total[i],false,m_g_is_folder[i]);
}
//--- Criar uma lista em árvore
if(!m_treeview.CreateTreeView(m_chart_id,m_subwin,m_x-1,m_y+m_address_bar_y_size-1))
return(false);
//--- Salvar as dimensões do navegador
CElement::XSize(m_treeview.XSize());
CElement::YSize(m_treeview.YSize()+m_address_bar_y_size);
return(true);
}
//+------------------------------------------------------------------+
É aqui que você precisa adicioná-lo:
if(!m_treeview.CreateTreeView(m_chart_id,m_subwin,m_x-m_wnd.X()-1,m_y-m_wnd.Y()+m_address_bar_y_size-1))
return(false);
...
A propósito, o navegador de arquivos trava mesmo ao especificar as coordenadas, como você disse. Mas talvez seja só eu. Fui procurar o motivo.
Não consegui reproduzi-lo:
Eu mesmo não o reproduzi:
Verifique o FileNavigator.mqh na atualização mais recente.
Esse é o mais recente.
Quero dizer, no site, no artigo - talvez haja um antigo pregado nas atualizações. Peguei o arquivo da atualização mais recente, baixado do site na parte inferior do artigo a partir do zip.
Aqui, fiz as correções conforme escrevi acima:
Capturas de tela da plataforma de negociação MetaTrader
EURUSD, W1, 2016.12.12
MetaQuotes Software Corp., MetaTrader 5, Demo