Render - ahatornn/clforms GitHub Wiki
To form the final pseudographic interface, the library uses several stages. First, preparing the final image in the context of drawing the component. The OnRender method is used for these purposes.
/// Filling a pseudographics drawing context
protected virtual void OnRender(IDrawingContext context)
The essence of this method is to use the IDrawingContext object to describe drawing instructions. All graphic elements can override this method as they wish. Let's take a closer look at the operation of this method using the example of the ProgressBar component
/// <inheritdoc cref="Control.OnRender"/>
1. protected override void OnRender(IDrawingContext context)
2. {
3. base.OnRender(context);
4. var reducedArea = context.ContextBounds.Reduce(Padding);
5. if (reducedArea.HasEmptyDimension())
6. {
7. return;
8. }
9. var leftPart = ((value - minimum) * reducedArea.Width) / (maximum - minimum);
10. for (var row = 0; row < reducedArea.Height; row++)
11. {
12. context.SetCursorPos(Padding.Left, Padding.Top + row);
13. context.DrawText(new string(' ', leftPart), selectedBackground, selectedForeground);
14. }
15. if (showValue)
16. {
17. var text = valueAsPerCent
18. ? $"{(value - minimum) * 100 / (maximum - minimum)}%"
19. : value.ToString();
20.
21. var leftIndent = (reducedArea.Width - text.Length) / 2;
22. var topIndent = (reducedArea.Height - 1) / 2;
23. context.SetCursorPos(Padding.Left + leftIndent, Padding.Top + topIndent);
24. if (leftIndent < leftPart)
25. {
26. context.DrawText(text.Substring(0, Math.Min(leftPart - leftIndent, text.Length)),
selectedBackground,
selectedForeground);
27. if (leftPart - leftIndent < text.Length)
28. {
29. context.DrawText(text.Substring(leftPart - leftIndent), Background, Foreground);
30. }
31. }
32. else
33. {
34. context.DrawText(text, Background, Foreground);
35. }
36. }
37. }
3: Calling the OnRender method of the base class, which fills the entire rectangular area of the drawing context with the current background color and component font. You can do it yourself using the code shown below
context.Release(Background, Foreground, '\0');
4: Calculation of a rectangular drawing area, taking into account the specified padding.
5: If the resulting area is too small, then the preparation is completed and the method ends, because nothing will be displayed on the screen.
9: The size of the left side of the component is calculated, which displays the current value of the ProgressBar.
10: A cycle that draws each line that represents the height of the client part of the component.
12: Set the cursor to the beginning draw lines.
13: A string is formed of spaces, the color selectedForeground and the background selectedBackground with the length calculated in line 9.
15: The necessity of drawing the text of the current value of the ProgressBar is checked.
17: The displayed text is calculated as a value or percentage.
21: The indent on the left is calculated to print the text of the ProgressBar value so that the text is centered horizontally.
22: The indentation from the top is calculated to print the text of the ProgressBar value so that the text is centered vertically.
23: The cursor is positioned at the beginning of printing the text of the ProgressBar value.
24: The necessity of printing the text in 2 stages is calculated if the text crosses the background border of the current ProgressBar value.
26: The first part of the line is formed.
27: Checks whether the second part of the text is printed if it falls on the border of the background transition.
29: The second part of the line is formed.
34. If all the text fit without the border of the background transition, the text of the current ProgressBar value is formed in its entirety.
It is important to remember that all the instructions that you specify in the
OnRendermethod do not immediately display the console window on the screen.
At what point in time is the OnRender method called? If you look at the description of the life cycle, you can see that this happens when the DetectVisualInvalidate() method is called by the clforms core.
After OnRender is called for all form components, the final image will be transferred from the memory to the console window using the TransferToScreen() method by the clforms core.