MarketAlert – Real-Time Market & Crypto News, Analysis & AlertsMarketAlert – Real-Time Market & Crypto News, Analysis & Alerts
Font ResizerAa
  • Crypto News
    • Altcoins
    • Bitcoin
    • Blockchain
    • DeFi
    • Ethereum
    • NFTs
    • Press Releases
    • Latest News
  • Blockchain Technology
    • Blockchain Developments
    • Blockchain Security
    • Layer 2 Solutions
    • Smart Contracts
  • Interviews
    • Crypto Investor Interviews
    • Developer Interviews
    • Founder Interviews
    • Industry Leader Insights
  • Regulations & Policies
    • Country-Specific Regulations
    • Crypto Taxation
    • Global Regulations
    • Government Policies
  • Learn
    • Crypto for Beginners
    • DeFi Guides
    • NFT Guides
    • Staking Guides
    • Trading Strategies
  • Research & Analysis
    • Blockchain Research
    • Coin Research
    • DeFi Research
    • Market Analysis
    • Regulation Reports
Reading: MQL5 Trading Tools (Part 19): Building an Interactive Tools Palette for Chart Drawing
Share
Font ResizerAa
MarketAlert – Real-Time Market & Crypto News, Analysis & AlertsMarketAlert – Real-Time Market & Crypto News, Analysis & Alerts
Search
  • Crypto News
    • Altcoins
    • Bitcoin
    • Blockchain
    • DeFi
    • Ethereum
    • NFTs
    • Press Releases
    • Latest News
  • Blockchain Technology
    • Blockchain Developments
    • Blockchain Security
    • Layer 2 Solutions
    • Smart Contracts
  • Interviews
    • Crypto Investor Interviews
    • Developer Interviews
    • Founder Interviews
    • Industry Leader Insights
  • Regulations & Policies
    • Country-Specific Regulations
    • Crypto Taxation
    • Global Regulations
    • Government Policies
  • Learn
    • Crypto for Beginners
    • DeFi Guides
    • NFT Guides
    • Staking Guides
    • Trading Strategies
  • Research & Analysis
    • Blockchain Research
    • Coin Research
    • DeFi Research
    • Market Analysis
    • Regulation Reports
Have an existing account? Sign In
Follow US
© Market Alert News. All Rights Reserved.
  • bitcoinBitcoin(BTC)$67,695.000.90%
  • ethereumEthereum(ETH)$1,968.761.01%
  • tetherTether(USDT)$1.000.00%
  • rippleXRP(XRP)$1.420.57%
  • binancecoinBNB(BNB)$628.073.43%
  • usd-coinUSDC(USDC)$1.000.01%
  • solanaSolana(SOL)$84.613.09%
  • tronTRON(TRX)$0.2854030.28%
  • dogecoinDogecoin(DOGE)$0.1006022.81%
  • Figure HelocFigure Heloc(FIGR_HELOC)$1.030.77%
Trading Strategies

MQL5 Trading Tools (Part 19): Building an Interactive Tools Palette for Chart Drawing

Last updated: February 19, 2026 7:40 pm
Published: 1 day ago
Share

In our previous article (Part 18), we combined vector-based rectangles and triangles to create rounded speech bubbles/balloons with orientation control in MetaQuotes Language 5 (MQL5), enabling dynamic UI elements for trading interfaces. In Part 19, we develop an interactive tools palette for chart drawing, featuring draggable panels, resizing, theme switching, and buttons for tools like crosshairs, lines, and shapes. This customizable system enhances analysis with real-time interactions and instructions. We will cover the following topics:

By the end, you’ll have a functional palette ready for expanding trading workflows — let’s dive in!

The interactive tools palette for chart drawing centralizes buttons for essential functions like crosshairs, trendlines, lines, rectangles, Fibonacci, text, and arrows, enabling quick selection and application on trading charts with real-time feedback. It supports dragging, resizing, theme switching between dark and light modes, and minimizing to optimize the workspace, while providing instructions and status updates for intuitive use. This design streamlines analysis by offering a customizable, responsive UI that adapts to user interactions without cluttering the chart. We plan to use canvas objects for the header and panel, manage mouse events for interactivity, define enumerations for resize modes and tools, and handle drawing logic with object creation on charts. In brief, here is a visual representation of our objectives.

To create the program in MQL5, open the MetaEditor, go to the Navigator, locate the Experts folder, click on the “New” tab, and follow the prompts to create the file. Once it is made, in the coding environment, we will need to declare some input parameters and global variables that we will use throughout the program.

We begin the implementation by including the Canvas library with “#include ” to access core graphical functionalities for building the palette. Next, we declare global canvas objects “canvasHeader” and “canvasTools” for the panel’s header and main area, assigning names like “HeaderCanvas” and “ToolsCanvas” for reference, along with user inputs for position, size, and background opacity to allow customization. To support themes, we initialize “is_dark_theme” to true and define color constants for dark and light modes, covering headers, borders, icons, instructions, status, and buttons, enabling visual consistency across switches.

We track panel state with variables for current position and dimensions, dragging flags, resize modes via the “ENUM_RESIZE_MODE” enumeration (NONE, BOTTOM, RIGHT, BOTTOM_RIGHT), hover states, and constants like minimum sizes and thicknesses for usability limits. For tools, we define the “TOOL_TYPE” enumeration listing options from NONE to ARROW, initialize “active_tool” to NONE, and manage drawing flags like “drawing_first_click”, along with a “ToolButton” structure holding symbol, font, type, and tooltip, creating an array “buttons[8]” for the palette items. Finally, we set up variables for measuring mode, fixed points, click timing, hovered indices, and a y-offset for tools alignment, preparing for interactive features. We will then need some helper functions to make the code modular.

We continue by defining a series of getter functions like “GetHeaderColor” to retrieve theme-aware colors, each returning the dark or light variant based on the “is_dark_theme” flag, ensuring consistent styling for headers, hovers, drags, texts, borders, icons, instructions, status, active buttons, and hovers without redundant checks. Next, the “GetToolName” function extracts the name of a tool from its type by looping through the “buttons” array, matching the type, and substringing the tooltip up to ” Tool” for clean output, defaulting to “None” if no match. To classify tools, we implement “IsSingleClickTool” using a switch statement on the tool type, returning true for horizontal/vertical lines, text, and arrows that require only one click, and false otherwise for precise event handling. With that done, we can initialize the creation of the header and the palette body.

To create the initial rendering, we implement the “DrawHeader” function to render the palette’s header on the canvas, starting by erasing it with Erase set to 0, then filling a rectangle with dynamic background color from getters like “GetHeaderDragColor” if dragging, “GetHeaderHoverColor” if hovered, or standard otherwise, converted to ARGB. Next, we draw the border using Rectangle with ARGB from “GetBorderColor”, set bold “Arial” font for the title “Tools Palette” with FontSet and TextOut in the theme text color. To add controls, we compute button Y centering, then for theme, set Wingdings font, position and color the ‘[‘ symbol based on hover, and draw with “TextOut”; similarly for minimize (toggle ‘o’ or ‘r’ symbol) and close (‘X’ in Webdings), adjusting colors for hover states like yellow or red. Finally, we update the canvas with Update to display changes. You can customize the icons using your own characters if needed. See a set of the font characters you can use.

In the “DrawToolsPanel” function, we erase the tools canvas, fill it with the top color ARGB adjusted for “BackgroundOpacity”, and draw the border rectangle. We lay out buttons in 4 columns with padding, loop to fill backgrounds if active or hovered using “GetActiveBtnColor” or “GetHoverBtnColor”, set custom fonts for icons like ‘v’ in “Wingdings”, center and draw them with TextOut in icon color, then add bold tool names below. If there’s an instruction in “current_instruction”, we draw it centered near the bottom with “GetInstructionColor”; add active tool status similarly. To indicate resizing, if “resize_hovered” or “resizing”, we set “Wingdings 3” font, determine arrow code and angle per “hover_mode” (e.g., ‘2’ at 450 for bottom-right), position dynamically, draw in red or icon color, and reset angle. We conclude by updating the canvas with “Update”. We can now initialize this by drawing it using the following logic.

We proceed in the OnInit event handler by initializing current panel positions and dimensions from user inputs, ensuring alignment with configured values. Next, we create the header canvas using CreateBitmapLabel with ARGB normalize for transparency, logging failures, and returning INIT_FAILED if unsuccessful, and similarly for the tools canvas positioned below the header with a y-offset. To populate the palette, we initialize the “buttons” array entries with specific symbols (e.g., ‘v’ for crosshair), fonts like Wingdings, tool types from the enumeration, and tooltips for hover info. We then draw the header and tools panel via their respective functions, enable mouse move events with ChartSetInteger to capture interactions, redraw the chart, store the local chart ID for object management, and return INIT_SUCCEEDED. Upon compilation, we get the following outcome.

We can see the panel is initialised correctly. What we now need to do is breathe life into the panel to handle interactivity and theme changes. We will define some more helper functions to get that done easily.

Here, we implement the “ToggleTheme” function to switch between dark and light modes by inverting the “is_dark_theme” flag, then redrawing the header and tools panel to apply new colors, and refreshing the chart for immediate visibility. Next, we create “ToggleMinimize” to alternate the panel state with “panel_minimized”, destroying the tools canvas when minimizing to save space or recreating it when restoring, followed by header redraw and chart update. To detect interactions, we define “IsMouseOverHeader,” which checks if the mouse is within the header bounds but excludes the button area starting from the theme offset, returning true only for draggable regions.

Similarly, “IsMouseOverButton” verifies mouse position over a specific button by calculating its left edge from offset and comparing it to the button size and header height. For resizing, “IsMouseOverResize” evaluates if the mouse is near the bottom, right, or corner edges of the tools panel (ignoring if minimized), updating the reference mode like “BOTTOM_RIGHT” and returning true if detected. We add “GetHoveredTool” to identify the button under the mouse by converting to local coordinates, iterating a 4-column grid with padding, and returning the index if within a button’s bounds, or -1 otherwise.

To manage tools, “ToggleTool” activates or deactivates based on type, handling crosshair cleanup if switching, resetting drawing flags, and setting appropriate instructions like “Click on chart to draw” before redrawing the panel. “DeactivateTool” fully resets the active tool, particularly clearing crosshair elements and enabling scroll, then updates instructions and redraws. Finally, we provide cleanup with “DeleteMeasureObjects” removing fixed crosshair and measure line/label, and “DeleteCrosshair” deleting moving crosshair plus calling the measure delete function, followed by chart redraw. We will now handle the objects’ functions and their creation.

To handle chart drawing, we implement the “HandleDrawing” function to manage the creation of chart objects based on the active tool and mouse position, beginning by converting coordinates to time and price with ChartXYToTimePrice, returning early if unsuccessful. Next, we generate a unique object name using current time, set default blue color and vertical line type, then branch for single-click tools via “IsSingleClickTool”, switching to configure types like OBJ_HLINE for horizontal (resetting times), OBJ_VLINE for vertical (resetting prices), OBJ_TEXT or OBJ_ARROW, marking valid and setting create flag.

For two-click tools, we capture the first point if “drawing_first_click” is false, updating globals and instruction without creation; on the second click, retrieve the end point, reset the flag, and configure types such as OBJ_TREND for trendline, OBJ_RECTANGLE, or OBJ_FIBO, validating the object. If creation is flagged and valid, we use ObjectCreate with parameters, set properties like color, style, width, text, or arrow code if applicable, dash for lines, selectable and selected states, then redraw the chart with ChartRedraw and deactivate the tool, clearing instructions. Finally, we refresh the tools panel with “DrawToolsPanel” to reflect changes. Let us now handle the crosshair; the others are straightforward.

We implement the “UpdateMovingCrosshair” function to manage a dynamic crosshair on the chart, defining names for horizontal “Cross_H” and vertical “Cross_V” lines, checking if each exists with ObjectFind (negative return if not), creating them via “ObjectCreate” as OBJ_HLINE or “OBJ_VLINE” with red solid style if absent, or moving them with ObjectMove to the current time and price if present, providing real-time cursor tracking. Next, we create the “UpdateFixedCrosshair” function for a static reference crosshair, using names “Cross_HF” and “Cross_VF”, similarly checking existence, creating with green solid style at fixed_time and fixed_price, or updating positions, enabling persistent markers during measuring mode for comparisons. Now, we will handle its click.

We implement the “HandleCrosshairClick” function to process clicks during crosshair mode, retrieving current microseconds with GetMicrosecondCount to detect double-clicks within 500 ms of “last_click_time”. If double-click, we toggle measuring: if not active, set fixed point to current time and price, enable measuring, disable chart scroll with ChartSetInteger, update instruction; if active, reset measuring, delete objects via “DeleteMeasureObjects”, re-enable scroll, and restore default instruction, then redraw the tools panel and reset click time. For single clicks, we update “last_click_time” to now, allowing detection of subsequent clicks as doubles. Let us now define a logic to update the measuring line between the crosshairs.

For the measuring line, we implement the “UpdateMeasureLine” function to display a connecting line during measuring mode, defining a name “Measure_Line”, checking existence with ObjectFind, creating it as OBJ_TREND from fixed to current time/price with blue dash-dot style, width 1, and no ray if absent, or moving its points with ObjectMove if present, providing visual linkage between points. We create the “UpdateMeasureLabel” function to show dynamic metrics near the mouse, calculating bars difference by dividing times by period seconds from PeriodSeconds to get virtual bars and taking absolute with MathAbs, then pips using symbol point from SymbolInfoDouble adjusted for 3 or 5 digits (multiplying by 10), absolute price diff formatted to digits from the SymbolInfoInteger function.

To format the text with StringFormat including bars, pips, rounded to 1 decimal, and price diff, we check label existence, create as OBJ_LABEL at the upper-left corner with mouse-offset position, “Arial” font size 9, blue color if new, or update position and text if existing, enhancing user feedback on measurements. This label computation is crucial as it accurately quantifies time and price spans across varying symbol precisions and periods, aiding precise analysis without manual calculations. To bring the palette to life, we will handle chart events in the event handler for intuitive interactions.

We use the OnChartEvent event handler to manage all user interactions with the palette and tools, starting by checking for CHARTEVENT_KEYDOWN to detect the escape key (lparam 27) and deactivate the current tool with “DeactivateTool”, then returning early. In case you are wondering, the escape character is code 27 in the ASCII table. See below.

Next, if not a CHARTEVENT_MOUSE_MOVE, we exit; otherwise, extract mouse X, Y, and state from parameters, store previous hover flags, and update them using functions like “IsMouseOverHeader”, “IsMouseOverButton” for theme/minimize/close, and “IsMouseOverResize”, which sets “hover_mode”. Next, we set tooltips on the tools canvas with ObjectSetString for resize modes or hovered tool buttons, clearing if none; if any hover changed, redraw header and tools (if not minimized), followed by the ChartRedraw function. If not minimized, we detect hovered tool index with “GetHoveredTool” and redraw if changed; for resize states, update local hover coordinates and redraw tools.

On mouse down (ms 1, prev 0), we initiate dragging if header hovered by setting flags, disabling scroll, and redrawing header; toggle theme or minimize if respective buttons hovered; call deinit if close; or if a tool button hovered, toggle its type; handle non-crosshair drawing with “HandleDrawing”; start resizing if over resize area by setting flags, starts, and disabling scroll before redrawing tools. During drag (ms 1), we calculate deltas, clamp new positions to chart bounds with the MathMax and MathMin functions, update globals, and set object distances for header and tools (if visible), then redraw the chart. For resizing (ms 1), compute and clamp new dimensions based on mode, update globals, resize canvases with Resize and set sizes via ObjectSetInteger, then redraw header, tools, and chart.

On mouse up (ms 0, prev 1), reset dragging and resizing flags, re-enable scroll, redraw header and tools, and refresh chart. We convert mouse to time/price with ChartXYToTimePrice, and if crosshair is active, update moving crosshair; if measuring, also update fixed, measure line, and label; on qualifying down click outside palette, handle with “HandleCrosshairClick” and redraw. Finally, update “prev_mouse_state” to the current for next events, ensuring responsive, stateful interactivity. Finally, we need to delete our objects when not needed.

In the OnDeinit event handler, we perform cleanup by destroying the header and tools canvases with the Destroy method, removing any active crosshair through “DeleteCrosshair”, resetting the measuring flag to false, and re-enabling mouse scroll via the ChartSetInteger function. To ensure no leftover objects, we retrieve the total count with ObjectsTotal on the local chart, loop backward for safe deletion, fetch names using ObjectName, and remove those prefixed “Tool_” with the ObjectDelete function. Finally, we invoke ChartRedraw to update the chart, completing resource release upon program exit. Upon compilation, we get the following outcome.

From the visualization, we can see that we have created an interactive tools palette, hence achieving our objectives. What now remains is testing the workability of the system, and that is handled in the preceding section.

We did the testing, and below is the compiled visualization in a single Graphics Interchange Format (GIF) bitmap image format.

In conclusion, we’ve built an interactive tools palette in MQL5 for chart drawing, featuring draggable and resizable panels with theme switching between dark and light modes. We incorporated buttons for various tools like crosshairs, trendlines, lines, rectangles, Fibonacci retracements, text, and arrows, managing mouse events for seamless activation and on-chart interactions. This customizable system enhances trading analysis with real-time feedback and instructions, providing a versatile UI for efficient workflows. With this interactive tools palette, you’re equipped to streamline chart annotations and measurements, ready for integration into advanced trading strategies. In the preceding parts, we will upscale to a more detailed palette with more organized tools. Keep tuned!

Read more on mql5.com

This news is powered by mql5.com mql5.com

Share this:

  • Share on X (Opens in new window) X
  • Share on Facebook (Opens in new window) Facebook

Like this:

Like Loading...

Related

The Humorous Ironic Path of Barry Honig
Riven Trust Review 2025: Is It Legit Or A Scam?
HOT 100 Startups: Dublin
$TINT | ($TINT) Investment Report (TINT)
DeFi Technologies Announces Closing of US$100 Million Registered Direct Offering

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Email Copy Link Print
Previous Article Top 10 Futures Funding Firms for Experienced Traders: A Structural Stress Test
Next Article Digital Ownership in Virtual Economies
© Market Alert News. All Rights Reserved.
Welcome Back!

Sign in to your account

Username or Email Address
Password

Prove your humanity


Lost your password?

%d