Canvas is cool! - page 100

 
Maxim Kuznetsov #:

and no external DLL, just the cairographics.org API.

draws :-) WORKS !!!


and the final test is of course SVG :-)

//+------------------------------------------------------------------+
//|                                                        Test2.mq5 |
//|                                         Maxim Kuznetsov (c) 2024 |
//|                                       https://luxtrade.unaux.com |
//+------------------------------------------------------------------+
#property copyright "Maxim Kuznetsov (c) 2024"
#property link      "https://luxtrade.unaux.com"
#property version   "1.00"

#include <WinApi/LibLoaderApi.mqh>

// api cairographics.org
// как наполнится можно в отдельный mqh :-)
#define  cairo_surface_ptr ulong
#define  cairo_ptr ulong
#define  cairo_format_t int
#define  CAIRO_FORMAT_ARGB32 0

#import "libcairo-2.dll"
// surface
cairo_surface_ptr cairo_image_surface_create_for_data(uint &data[], cairo_format_t format,int width,int height,int stride);
void cairo_surface_flush(cairo_surface_ptr);
void cairo_surface_destroy(cairo_surface_ptr);
// cairo
cairo_ptr cairo_create(cairo_surface_ptr);
void cairo_destroy(cairo_ptr);
void cairo_stroke(cairo_ptr);
//paths
void cairo_new_path(cairo_ptr);
void cairo_move_to(cairo_ptr,double x,double y);
void cairo_rel_move_to(cairo_ptr,double dx,double dy);
void cairo_line_to(cairo_ptr,double x,double y);
void cairo_rel_line_to(cairo_ptr,double dx,double dy);
void cairo_rectangle(cairo_ptr,double x,double y,double width,double height);
void cairo_set_source_rgba(cairo_ptr,double red,double green,double blue,double alpha);
void cairo_fill(cairo_ptr);
#import

struct RsvgRectangle {
  double x;
  double y;
  double width;
  double height;
};
#define  RsvgHandle_ptr ulong

#import "librsvg-2-2.dll"
RsvgHandle_ptr rsvg_handle_new_from_data(uchar &utf8[],ulong bytes,ulong shouldBeZero);
RsvgHandle_ptr rsvg_handle_new_from_file(uchar &nameUtf[],ulong shouldBeZero);
int rsvg_handle_render_document(RsvgHandle_ptr,cairo_ptr,RsvgRectangle &viewport,ulong shouldBeZero);
void rsvg_handle_set_dpi_x_y (RsvgHandle_ptr,double dpi_x,double dpi_y);
void rsvg_handle_set_dpi(RsvgHandle_ptr,double dpi);
#import

#import "libgobject-2.0-0.dll"
int g_object_unref(ulong);
#import

#import "libgthread-2.0-0.dll"
void g_thread_init(ulong shouldBeZero=0);
#import

string prefix="test2";

void Test2 (int width=800,int height=600) 
{
   string fileName=TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\Ghostscript_Tiger.svg";
   PrintFormat("svg from %s",fileName);
   uint data[];
   string obj=prefix+".test1";
   string rc_name=prefix+".test1";
   // create image   
   ArrayResize(data,width*height);
   ArrayInitialize(data,0x10101010);
   // call cairo
   cairo_surface_ptr surface=cairo_image_surface_create_for_data(data,CAIRO_FORMAT_ARGB32,width,height,width*sizeof(uint));
   if (surface==0) {
      Print("cairo_image_surface_create_for_data() failed");
      return;
   }
   cairo_ptr cr=cairo_create(surface);
   if (cr==0) {
      Print("cairo_create() failed");
      cairo_surface_destroy(surface);
      return;
   }
   uchar fileNameUtf[];
   int bytes=StringToCharArray(fileName,fileNameUtf,0,WHOLE_ARRAY,CP_UTF8);
   RsvgHandle_ptr rsvg=rsvg_handle_new_from_file(fileNameUtf,0);
   if (rsvg!=0) {
      RsvgRectangle viewport={0.0, 0.0, width, height};
      rsvg_handle_render_document(rsvg,cr,viewport,0);
      g_object_unref(rsvg);
   } else {
      cairo_set_source_rgba(cr,0.8,0.8,0,0.1);
      cairo_move_to(cr,0,0);
      cairo_rectangle(cr,0,0,width-1,height-1);
      cairo_fill(cr);
      
      cairo_set_source_rgba(cr,0,0,0.9,0.5);
      cairo_rectangle(cr,0,0,width-1,height-1);
      cairo_stroke(cr);
   }
   cairo_surface_flush(surface);      
   // create(update) resource from data
   if (!ResourceCreate(rc_name,data,(uint)width,(uint)height,0,0,(uint)width,COLOR_FORMAT_ARGB_RAW)) {
      Print("ResourceCreate failed");
      return;
   }
   cairo_destroy(cr);
   cairo_surface_destroy(surface);
   // create object with resource
   if (!ObjectCreate(0,obj,OBJ_BITMAP_LABEL,0,0,0)) {
      Print("ObjectCreate failed (exists?)");
   }
   ObjectSetInteger(0,obj,OBJPROP_HIDDEN,false);
   ObjectSetInteger(0,obj,OBJPROP_XSIZE,width);
   ObjectSetInteger(0,obj,OBJPROP_YSIZE,height);
   ObjectSetInteger(0,obj,OBJPROP_XDISTANCE,100);
   ObjectSetInteger(0,obj,OBJPROP_YDISTANCE,100);
   ObjectSetString(0,obj,OBJPROP_BMPFILE,"::"+rc_name);
   ChartRedraw();
}   
bool Module(string dllname) 
{
   if (!GlobalVariableCheck(dllname)) {
      GlobalVariableSet(dllname,1.0);
      GlobalVariableTemp(dllname);
      if (LoadLibraryW(dllname)==0) {
         GlobalVariableDel(dllname);
         Alert(StringFormat("Module %s not loaded - pls. restart terminal for omit bugs",dllname));
         return false;
      }
   }
   return true;
}
int OnInit()
{
   EventSetTimer(60);
   // load and fixate cairo in app
   if (!Module("libcairo-2.dll")) return INIT_FAILED;
   if (!Module("librsvg-2-2.dll")) return INIT_FAILED;
   if (!Module("libgobject-2.0-0.dll")) return INIT_FAILED;
   if (!Module("libgthread-2.0-0.dll")) return INIT_FAILED;
   g_thread_init(0);
   // invoke test
   Test2();
   ChartRedraw();
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   ObjectsDeleteAll(0,prefix+".");
   EventKillTimer();
}
void OnTick()
{
}
void OnTimer()
{
}
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
}

 
Реter Konow #:
Well, I don't know). I have been approached many times by people asking how to use my panels in the tester. This question is relevant for many people. And if I had not left MT4, I could easily help them. As for MT5, I assume that such a scheme will not work. But I have not checked it.

In general, there is a demand for panels trading in the tester. And it is strange that with such a level of programming power of forum members, no one has occupied an empty niche)).
There are such panels and for free nobody needs them. If they were bought I would have done it long ago. Any function works in the tester, and if you introduce Dll even coordinates can be made to read.In the market 3 top already 10 years hanging, overpower them I think it is impossible, no matter what features in your panel were not . Guys in Chile make 20k a month while poor scammers rewrite all their Neurons every month.
 
Maxim Kuznetsov #:

and the final test of course SVG :-)

Cool!
Thanks Maxim!
 
Nikolai Semko #:
Great!
Thanks Maxim!

You're welcome ;-)

If anyone wants to replicate (first tests, not sure if they are easily reproducible):

I have msys2 https://www.msys2.org/ installed and the dlls were taken from it, from its packages.

so that the libraries can be found by the system, the paths are added to %PATH%.

Deployment without msys2, as a standalone-autonomous EA/indicator application, is a separate song and pain :-) Where, how and what DLLs to put to make MT find everything correctly and in any case - you can write a novel.

MSYS2
MSYS2
  • www.msys2.org
MSYS2 is a collection of tools and libraries providing you with an easy-to-use environment for building, installing and running native Windows software. It consists of a command line terminal called mintty, bash, version control systems like git and subversion, tools like tar and awk and even build systems like autotools, all based on a...
 
Maxim Kuznetsov #:

and the final test of course SVG :-)

funny. I used this SVG too when I was dabbling in writing SVG libraries in JS a few years ago

https://nikolaisemko.github.io/DWLibDemo/

 
Nikolai Semko #:

Fun fact. I used this SVG too when I was dabbling in writing SVG libraries in JS
https://nikolaisemko.github.io/DWLibDemo/

this is a classic test vector image...originally postscript as far as I know.

 
Реter Konow #:
Well, I don't know). I have been approached many times by people asking how to use my panels in the tester. This question is relevant for many people. And if I had not left MT4, I could easily help them. As for MT5, I assume that such a scheme will not work. But I have not tested it.

In general, there is a demand for panels trading in the tester. And it is strange that with such a level of programming power of forum members, no one has occupied an empty niche)).

I looked at the panels in the market, it is 99% variants of buy-sell + SL+TP. I want to insert my DSP methods from scalper.

 
Alexey Volchanskiy #:

I know how to write DLLs since kindergarten, I don't understand how they can help. I put the question differently: how to make a GUI with buttons and input fields without using ChartEvent, so that it works in the tester?

I'm going to make a panel for Market, so need a standard tester. Or will have to make a demo to test the panel on a demo account.
I made a dial with buttons for entering values in the tester.We write values into a string and send it to fields and variables.But how to make it read coordinates is already a problem.I hate standard graphical objects I am a supporter of kanvas and coordinate maths but for the tester we will have to use the first one
Files:
 
Dz Mak #:
I made a dial with buttons for entering values in the tester.We write values into a string and send it to fields and variables.But how to make it read coordinates is already a problem.I hate standard graphical objects I am a supporter of kanvas and coordinate maths but for the tester we will have to use the first one
Canvas works for the tester too. I have written about it many times. Just the frequency of its output should be controlled by real time. Only in the tester, events do not work in Expert Advisors, so control in control panels is impossible. But it is possible with a bit of luck in indicators
 
Nikolai Semko #:
Canvas works for the tester as well. I have written about it many times. Just the frequency of its output should be controlled by real time. Only in the tester, events do not work in Expert Advisors, so control in control panels is impossible. But it is possible with a bit of luck in indicators
I know, that's not what I meant. Everything works there except reading coordinates, events just need to be written by yourself. My panels are fully functional in the tester, (type - Expert Advisor), only that you can't move them with the mouse, because I couldn't make it read coordinates by any castile, the tester just doesn't see the cursor, yes I would have found a solution, but alas the desire to do nonsense is gone