I want to change the Horizsize/VertSize of my Series Points in a TChart.
I can change it on a manual way, but not in the c++-code itself.
The series Pointer sub-component property is only available in certain series-type classes, such as the TLineSeries class.
Hence you need to cast your series-pointers to the appropriate derived-type first.
For a standard line chart:
// TChart * pChart - pointer to your chart component.
// Cast to appropriate derived series-type.
TLineSeries* pLineSeries = dynamic_cast<TLineSeries*>( pChart->Series[index_of_series]);
// Now you can reach the Pointer sub-component property: pLineSeries->Pointer
// Seems like each individual point(TSeriesPointer) on the series can be accessed.
// Set Vertical size and Horizontal size:
pLineSeries->Pointer->operator [](index_of_point)->VertSize = 5;
pLineSeries->Pointer->operator [](index_of_point)->HorizSize = 5;
Related
I obtained a value of -65536 from the RTTI inspector for Red.
How do I convert it into a constant description of Red without duplicating all the members of the TAlphaColorRec record into an array?
How do I set ColorCombobox1.Color := ... somefunction(-65536) that TColorCombobox knows it is Red?
From Delphi source:
TAlphaColorRec = record
const
Alpha = TAlphaColor($FF000000);
Aliceblue = Alpha or TAlphaColor($F0F8FF);
Antiquewhite = Alpha or TAlphaColor($FAEBD7);
Aqua = Alpha or TAlphaColor($00FFFF);
I read How to set a custom TAlphaColor programmatically? but it does not have what I need.
I think what you're looking for in question #1 is AlphaColorToString() in the System.UIConsts unit.
I am writing an MQL4 Custom Indicator that would tell how many bars ago a particular set of moving averages crossed.
To be specific, I want the output to show me that
"The 20 period MA( .. PRICE_OPEN ) is below MA( .. PRICE_CLOSE ) for the past 10 bars".
in a form of an int number.
double ma1 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_OPEN, 0 );
double ma2 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_CLOSE, 0 );
I want to find out that ma1 has been above or below ma2 for how many bars since the current bar.
TLDR;
MQL4 Custom Indicator design is a bit schizophrenic task with 2 parts
Once decided to design a Custom Indicator, one has to pay attention to both sides of the coin.
MQL4 code has a non-trivial signature for a caller-side( normally an
Expert Advisor or a Script type of MQL4 code )and
Custom Indicator, on it's own, operates in a special mode, where it calculates & store it's values into one or more arrays called IndexBuffer-s.
Phase I.: design Caller-side interface ( what all do we need to set / receive ? )
Phase II.: design Custom Indicator implementation side
This way, the given indicator shall
set just one parameter: a period ... 20
receive just one int a value of days { +:above | 0: xoss | -: under }
Phase I. : Design Caller-side interface
Given the above parametrisation and the MQL4 concept of Custom Indicator construction, the following universal template ( recommended to be routinely maintained as a commented section right in CustomIndicator-file ) reflects details needed for the Caller-side interface ( which one benefits from by just a copy-paste mechanics, while the implementation-integrity responsibility is born by the CustomIndicator maintainer ):
// CALL-er SIDE INTERFACE |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//
// #define sIndicatorPathNAME "#AliceInTheWonderlands_msMOD_0.00"
//
// //_____________________________________INPUT(s)
// // iMA_PERIOD:
// extern int iMA_PERIOD = 20;
//
// //_____________________________________OUTPUT(s):
// #define iOutputDoubleUpOrDnBUFFER 0
//
// //_____________________________________CALL-SIGNATURE:
//
// double iCustom( _Symbol, // string symbol, // symbol: Symbol name on the data of which the indicator will be calculated. NULL means the current symbol.
// PERIOD_W1, // int timeframe, // timeframe
// sIndicatorPathNAME, // string name, // path/name of the custom indicator compiled program: Custom indicator compiled program name, relative to the root indicators directory (MQL4/Indicators/). If the indicator is located in subdirectory, for example, in MQL4/Indicators/Examples, its name must be specified as "Examples\\indicator_name" (double backslash "\\"must be specified as separator instead of a single one).
// iMA_PERIOD, // ...[1] ..., // custom indicator [1]-st input parameter
// <<N/A>>, // ...[2+] // custom indicator further input parameters (if necessary)
// iOutputDoubleUpOrDnBUFFER, // int mode, // line index: Line index. Can be from 0 to 7 and must correspond with the index, specified in call of the SetIndexBuffer() function.
// i // int bar_shift // shift
// );
// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Typical Expert Advisor call looks like this:
int anIndicatorVALUE = iCustom( _Symbol,
PERIOD_W1,
sIndicatorPathNAME,
iMA_PERIOD,
iOutputDoubleUpOrDnBUFFER,
aCurrentBarPTR
);
if ( 0 > anIndicatorVALUE ) // on "line" under for <anIndicatorVALUE> [PERIOD]-s
{ ...
}
Phase II. : Design Custom Indicator implementation side
Preset an overall capacity
#property indicator_buffers 1 // compile time directive
Allocate memory for IndexBuffer(s) needed
IndicatorBuffers( 1 ); // upper limit of 512 is "far" enough
Declare IndexBuffer
double UpOrDnBUFFER[]; // mandatory to be a double
Associate IndexBuffer with an index
SetIndexBuffer( 0, UpOrDnBUFFER ); // index 0: UpOrDnBUFFER[]
ArraySetAsSeries( UpOrDnBUFFER, True ); // reverse AFTER association
The core logic of any Custom Indicator is inside an OnCalculate() function, where you
- implement desired calculusand- store resulting values into respective cells of the UpOrDnBUFFER[];
Writing a fully fledged code upon request is not the key objective of StackOverflow, but let me sketch a few notes on this, as Custom Indicator implementation side requires a bit practice:
because Custom Indicator OnCalculate() operates "progressively", so do design your calculation strategy & keep in mind the state-less-ness between "blocks" of forward-progressive blocks of calculations.
as given, crosses are tri-state system, so watch issues on cases, where decisions are made on a "live" bar, where the state { above | cross | under } may change many times during the bar-evolution.
I have a ColumnSeries chart that I want to represent the majorTickLabel as if hovering above the majorGridLine but I don't see a straight forward way of controlling where the label draws beyond what I currently have which achieves insetting the label so that it 'hovers' above the graph.
Is this functionality missing from the API? If so, any suggestions on where to look at to achieve this?
Below is my current y-axis implementation
let yAxis = SChartNumberAxis()
yAxis.style.majorGridLineStyle.showMajorGridLines = true
yAxis.rangePaddingHigh = 500
yAxis.discontinuousTickLabelClipping = SChartDiscontinuousTickLabelClippingHigh
yAxis.axisPosition = SChartAxisPositionReverse
yAxis.style.majorTickStyle.tickGap = -45
goalChart.yAxis = yAxis
UPDATE- ANSWER BELOW
Thanks Sammy, simply offsetting the tickLabel resolved my issue. Below is a copy of the solution used.
#objc func sChart(chart: ShinobiChart!, alterTickMark tickMark: SChartTickMark!, beforeAddingToAxis axis: SChartAxis!) {
if !axis.isXAxis() {
if let label = tickMark.tickLabel {
label.frame.offset(dx: 0, dy: -8)
}
}
}
The tickGap property on SChartTickStyle gives you some control over the position of the tick mark label relative to the tick mark itself. It seems that you have discovered this, and that it doesn't offer the power that you require.
For more fine-grained control, you should look at implementing the SChartDelegate protocol, specifically the following method:
- (void)sChart:(ShinobiChart *)chart alterTickMark:(SChartTickMark *)tickMark
beforeAddingToAxis:(SChartAxis *)axis
This gives you an opportunity to change the tick mark before it gets added to the axis. You can get hold of the label via the tickLabel property. For further details on the other properties available to you during this method call, check out the documentation for SChartTickMark.
sam
Specific question
How to create an array of buttons on Borland C++ Builder and work with it?
I'm using Borland C++ Builder 6 and Borland Developer Studio 2006 (Turbo C++ 2006).
Purpose
To work with a lot of buttons on a form just using a for loop with an index, for example, changing their caption, size and position.
I know if I have a button called Button1 and inside a click event of this button if I create another button (through TButton *Button2 = new TButton(Form1)), I can assign Button1 to Button2 (Button2 = Button1) and them I can simply modify caption of Button1 with Button2->Caption. So I would like to extend it assigning pointers of real components to elements of an array to them work with all of them with a for loop.
Well, if someone found an way to add all buttons as an array on a form, it's better :)
Tries
Following tests were made putting respective code on TForm1::Button1Click(), an event of a button on a form:
Test 1
Description: Creating an array directly
Code:
TButton Buttons[3];
Result: Compile error:
> [C++ Error] Unit1.cpp(23): E2248 Cannot find default constructor
> to initialize array element of type 'TButton'
Comments:
I tested some variants of this test (e.g. TButton Buttons = new TButton[3], working with calloc function and others), but all of them points to the issue that TButton does not have a constructor without arguments, i.e., TButton(), but only TButton (TComponent *AOwner), TButton(void *ParentWindow) and TButton(const TButton &);
Any way to use operator new with arguments for TButton constructor prototypes, for an array?
Test 2
Description: Creating a vector
Code: Also add #include "vector.h" on unit header...
vector<TButton> Buttons;
Buttons[0].Caption="it is ok";
Buttons[1].Caption="mayday, mayday";
Result: Debugger exception on 3rd line:
> Project Project1.exe raised exception class EAccessViolation
> with message 'Acceess violation at address 401075B9 in module
> 'vcl60.bpl'. Read of address 00000254'. Proccess stopped. Use
> Step or Run to continue.
Comments:
Yeah, I expected that it would be raised, but I put it here to someone say how to allocate memory for more elements on that vector after created, since vector<TButton> Buttons(3); does not work for the same reason test1 failed :(
General question
How to do it for any visual component?
All of your attempts failed for the same reason - you are trying to create an array/vector of actual TButton object instances instead of an array/vector of pointers to TButton instances.
To create a fixed-length array of button pointers:
TButton* Buttons[3];
...
Buttons[0] = Button1;
Buttons[1] = Button2;
Buttons[2] = Button3;
...
for(index = 0; index < 3; ++index)
{
TButton *Btn = Buttons[index];
// use Btn as needed...
}
To create a dynamic-length array of button pointers:
TButton** Buttons;
...
Buttons = new TButton*[3];
Buttons[0] = Button1;
Buttons[1] = Button2;
Buttons[2] = Button3;
...
for(index = 0; index < 3; ++index)
{
TButton *Btn = Buttons[index];
// use Btn as needed...
}
...
delete[] Buttons;
To create a vector of button pointers:
std::vector<TButton*> Buttons;
...
Buttons.push_back(Button1);
Buttons.push_back(Button2);
Buttons.push_back(Button3);
...
for(index = 0; index < 3; ++index)
{
TButton *Btn = Buttons[index];
// use Btn as needed...
}
/*
Or:
for(std::vector<TButton*>::iterator iter = Buttons.begin(); iter != Buttons.end(); ++iter)
{
TButton *Btn = *iter;
// use Btn as needed...
}
*/
All this is very nice and correctly true. But I mean the user’s question was some other intention. If for all the buttons we get each of them index does no special benefit - this is only a true method: the aim is to control all components with a click (button, panels, shapes and so on…) and don’t write for each index a new code,
That why I changed a few program’s code:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
typedef TPanel* TPanels;
TPanels Panels[3] = {Panel1, Panel2, Panel3};
int count;
for(count=0;count<3;count++)
Panels[count]->Left=random(100);
}
As one can see instead of index here is count. Certainly don’t forget insert randomize() to TForm1
Miraculous Typedef + Pseudo Array = Solution
Miraculous Typedef:
After hours searching a way, I saw a typedef on that Stack Overflow and Google search journey and thought why not to:
typedef TButton* TButtons;
Well, it changes all the things, because I could perform:
TButtons Buttons[3];
Pseudo Array:
The issue remained on how to allocate memory for data stored on that Buttons[3] array, but with knowledge of 2nd paragraph of Purpose section of my question, I thought: forget new data, data is there, point to there (so I call that to build a pseudo array, because I create only an array of pointers to existing data):
TButtons Buttons[3] = {Button1, Button2, Button3};
Where Button1, Button2 and Button3 were already created when I put them on the form normally (through my mouse).
Working example
Create a new vcl/forms application project;
Put 3 buttons as those on the left on figure bellow (Button1, Button2, Button3) to demonstrate that solution, and 1 great button (Button4) also as figure bellow to do the actions;
Insert following code on click event of the fourth button, the great one (Button4);
typedef TButton* TButtons;
TButtons Buttons[3] = {Button1, Button2, Button3};
int index;
for(index=0;index<3;index++)
{
Buttons[index]->Caption=(AnsiString)"teste "+index+" - "+(1+random(100));
Buttons[index]->Left=25+4*random(100);
Buttons[index]->Top=25+4*random(100);
}
Perform a "shazam!" run and play with that...
I created a skin called customSliderTrack in the graphical editor of Adobe Flash CS5.5. This Slider is now in the "library" of the FLA file.
I can apply this skin with the following code:
var cls:Class = getDefinitionByName("CustomSliderTrack") as Class;
var tmpTrack:Sprite = new cls();
slider.setStyle("sliderTrackSkin",tmpTrack);
However due to the binary nature of the FLA file and lack of compatibility of different Versions of Adobe Flash I need to implement it all in Actionscript.
I understand that cls is a MovieClip object but I cant get the same results with new MovieClip(). I think this might be related to the dashed Lines in the graphical editor(I modified the default SliderTrack_skin). I havn't found out yet what they mean and how to replace them with Actionscript code.
setStyle automatically sets the track.height and track.width. In case of the track.height the slider.height attribute does not seem to have any effect. To work around this problem simply set the track.height to the best value.
To access the track extend the Slider class and override the configUI Function:
public class CustomSlider extends Slider
{
override protected function configUI():void
{
// Call configUI of Slider
super.configUI();
// The sprite that will contain the track
var t:Sprite = new Sprite();
// Draw the content into the sprite
t.graphics.beginFill(0x000000, 0.1);
t.graphics.drawRect(0, -15, width, 30);
t.graphics.endFill();
// Set the Sprite to be the one used by the Slider
this.setStyle("sliderTrackSkin",t);
// Reset the height to the value that it should be
track.height = 30;
}
}
Depending on the complexity of your track asset, you could accomplish this with the drawing API: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html
A very simple example would be:
var track:Sprite = new Sprite();
track.graphics.lineStyle(2, 0xcccccc);
track.graphics.beginFill(0x000000, 1);
track.graphics.drawRect(0, 0, 400, 20);
track.graphics.endFill();
track.scale9Grid = new Rectangle(2, 2, 396, 16);
slider.setStyle("sliderTrackSkin",track);
This creates a track that is just a black rectangle, 400x20 pixels in size. You can set the scale9grid in code to control how the skin scales. In the example above the rectangle's border wont scale, but the black rectangle inside will. Experimenting with the methods in the drawing API could be all you need.
If you need a more complex asset, I'd recommend loading an image and then passing that in to slider.setStyle.