Add dfl.chart module with TableRenderer class and its example

This commit is contained in:
haru-s 2024-03-31 21:44:56 +09:00
parent b5cb580f2d
commit 4a5e8052fc
14 changed files with 504 additions and 15 deletions

View file

@ -3,6 +3,23 @@
This unofficial project is a migration of [D Forms Library (DFL)](http://wiki.dprogramming.com/Dfl/HomePage "D Forms Library (DFL)") that is managed on SVN.
DFL is a Win32 windowing library for the D language.
## Recent major features
- **Module "dfl.chart" is now comming.**
- **TableRenderer (with example)**
- ~LineGraphRenderer~
- ~TimeChartRenderer~
- **Add simple clock "Dclock" as an example of DFL application.**
- Module "dfl.printing" is now comming.
- PrintDialog
- PrintSetupDialog
- PrintPreviewDialog
- DUB is available for DFL.
- Remove dflexe.
- Remove GTK-based DFL.
- Remove some bundled libraries such as user32_dfl.lib etc... (From now on, use dmd-bundled libraries such as the MinGW platform library and so on.)
## Screen shots
![screen shot](./examples/buttons/image/screenshot.png "screen shot")
![screen shot](./examples/tabcontrol/image/screenshot.png "screen shot")
![screen shot](./examples/listview/image/screenshot.png "screen shot")
@ -22,16 +39,7 @@ DFL is a Win32 windowing library for the D language.
![screen shot](./examples/toolbar/image/screenshot.png "screen shot")
![screen shot](./examples/richtextbox/image/screenshot.png "screen shot")
![screen shot](./examples/dclock/image/screenshot.png "screen shot")
## Recent major features
- **Module "dfl.printing" is now comming.**
- **PrintDialog**
- **PrintSetupDialog**
- **PrintPreviewDialog**
- DUB is available for DFL.
- Remove dflexe.
- Remove GTK-based DFL.
- Remove some bundled libraries such as user32_dfl.lib etc... (From now on, use dmd-bundled libraries such as the MinGW platform library and so on.)
![screen shot](./examples/tablerenderer/image/screenshot.png "screen shot")
## Build and Install (dfl.lib and dfl_debug.lib)
### 1. Set environment variables

16
examples/tablerenderer/.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
.dub
docs.json
__dummy.html
docs/
/hello_dfl
hello_dfl.so
hello_dfl.dylib
hello_dfl.dll
hello_dfl.a
hello_dfl.lib
hello_dfl-test-*
*.exe
*.pdb
*.o
*.obj
*.lst

View file

@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C++ Launch (Windows) tablerenderer",
"type": "cppvsdbg",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "./bin/tablerenderer.exe",
"console": "internalConsole"
}
]
}

View file

@ -0,0 +1,20 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "dub",
"run": false,
"cwd": ".",
"compiler": "$current",
"archType": "$current",
"buildType": "$current",
"configuration": "$current",
"problemMatcher": [
"$dmd"
],
"group": "build",
"label": "dub: Build tablerenderer_sample",
"detail": "dub build --compiler=dmd.EXE -a=x86_64 -b=debug -c=application"
}
]
}

View file

@ -0,0 +1,2 @@
# Screen Shot
![screen shot](./image/screenshot.png "screen shot")

View file

@ -0,0 +1,16 @@
{
"authors": ["haru-s"],
"copyright": "Copyright (C) 2024 haru-s",
"description": "DFL sample code.",
"name": "tablerenderer",
"targetType": "executable",
"targetPath": "bin",
"dependencies": {
"dfl": {
"path": "../../../dfl"
}
},
"lflags-windows-x86_omf-dmd": ["/exet:nt/su:windows:6.0"],
"lflags-windows-x86_mscoff-dmd": ["/SUBSYSTEM:WINDOWS", "/ENTRY:mainCRTStartup"],
"lflags-windows-x86_64-dmd": ["/SUBSYSTEM:WINDOWS", "/ENTRY:mainCRTStartup"]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,3 @@
set dmd_path=c:\d\dmd2\windows
set dmc_path=c:\dmc\dm
cmd

View file

@ -0,0 +1,67 @@
import dfl;
version(Have_dfl) // For DUB.
{
}
else
{
pragma(lib, "dfl.lib");
}
class MainForm : Form
{
alias CustomTableRenderer = TableRenderer!(string, string, string);
CustomTableRenderer _table;
public this()
{
this.text = "TableRenderer example";
this.size = Size(450, 450);
string csv =
"ID,Name,Value\n" ~
"1,Kyoto,100\n" ~
"2,Osaka,50\n" ~
"3,Tokyo,20\n" ~
"4,Aomori,10\n";
_table = new CustomTableRenderer(csv);
_table.height = 40;
_table.width[0] = 50;
_table.width[1] = 80;
_table.width[2] = 150;
_table.paddingX = 10;
_table.paddingY = 12;
_table.margin = Point(20, 20);
_table.hasHeader = true; // true : 1st line is header.
_table.showHeader = true;
_table.firstRecord = 0;
_table.lastRecord = 3;
_table.textColor = Color.black;
_table.backColor = Color.white;
_table.lineColor = Color.lightGray;
_table.headerLine = true;
_table.topSideLine = true;
_table.leftSideLine = true;
_table.bottomSideLine = true;
_table.rightSideLine = true;
_table.verticalLine = true;
_table.horizontalLine = true;
_table.headerFont = new Font("MS Gothic", 16f, FontStyle.BOLD);
_table.recordFont = new Font("MS Gothic", 12f, FontStyle.REGULAR);
}
protected override void onPaint(PaintEventArgs e)
{
if (_table)
_table.draw(e.graphics);
}
}
static this()
{
Application.enableVisualStyles();
}
void main()
{
Application.run(new MainForm());
}

View file

@ -0,0 +1,12 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"d.projectImportPaths": [
"..\\..\\..\\dfl\\source"
]
}
}

View file

@ -67,9 +67,9 @@ set VCCOMMON="%VCINSTALLDIR%\bin"
@set PATH=%VCCOMMON%;%PATH%
set dfl_files=package.d all.d base.d application.d internal/dlib.d internal/clib.d internal/utf.d internal/com.d control.d clippingform.d form.d registry.d drawing.d menu.d notifyicon.d commondialog.d filedialog.d folderdialog.d panel.d textboxbase.d textbox.d richtextbox.d picturebox.d listbox.d groupbox.d splitter.d usercontrol.d button.d label.d collections.d internal/winapi.d internal/wincom.d event.d socket.d timer.d environment.d messagebox.d tooltip.d combobox.d treeview.d tabcontrol.d colordialog.d listview.d data.d clipboard.d fontdialog.d progressbar.d resources.d statusbar.d imagelist.d toolbar.d trackbar.d sharedcontrol.d printing.d %_stdcwindowsd%
set dfl_files=package.d all.d base.d application.d internal/dlib.d internal/clib.d internal/utf.d internal/com.d control.d clippingform.d form.d registry.d drawing.d menu.d notifyicon.d commondialog.d filedialog.d folderdialog.d panel.d textboxbase.d textbox.d richtextbox.d picturebox.d listbox.d groupbox.d splitter.d usercontrol.d button.d label.d collections.d internal/winapi.d internal/wincom.d event.d socket.d timer.d environment.d messagebox.d tooltip.d combobox.d treeview.d tabcontrol.d colordialog.d listview.d data.d clipboard.d fontdialog.d progressbar.d resources.d statusbar.d imagelist.d toolbar.d trackbar.d sharedcontrol.d printing.d chart.d %_stdcwindowsd%
set dfl_objs=package.obj all.obj base.obj application.obj dlib.obj clib.obj utf.obj com.obj control.obj clippingform.obj form.obj registry.obj drawing.obj menu.obj notifyicon.obj commondialog.obj filedialog.obj folderdialog.obj panel.obj textboxbase.obj textbox.obj richtextbox.obj picturebox.obj listbox.obj groupbox.obj splitter.obj usercontrol.obj button.obj label.obj collections.obj winapi.obj wincom.obj event.obj socket.obj timer.obj environment.obj messagebox.obj tooltip.obj combobox.obj treeview.obj tabcontrol.obj colordialog.obj listview.obj data.obj clipboard.obj fontdialog.obj progressbar.obj resources.obj statusbar.obj imagelist.obj toolbar.obj trackbar.obj sharedcontrol.obj printing.obj %_stdcwindowsobj%
set dfl_objs=package.obj all.obj base.obj application.obj dlib.obj clib.obj utf.obj com.obj control.obj clippingform.obj form.obj registry.obj drawing.obj menu.obj notifyicon.obj commondialog.obj filedialog.obj folderdialog.obj panel.obj textboxbase.obj textbox.obj richtextbox.obj picturebox.obj listbox.obj groupbox.obj splitter.obj usercontrol.obj button.obj label.obj collections.obj winapi.obj wincom.obj event.obj socket.obj timer.obj environment.obj messagebox.obj tooltip.obj combobox.obj treeview.obj tabcontrol.obj colordialog.obj listview.obj data.obj clipboard.obj fontdialog.obj progressbar.obj resources.obj statusbar.obj imagelist.obj toolbar.obj trackbar.obj sharedcontrol.obj printing.obj chart.obj %_stdcwindowsobj%
@rem Also update link pragmas for build.
if "%MODEL%" == "64" (

View file

@ -59,9 +59,9 @@ set _stdcwindowsd=internal/_stdcwindows.d
set _stdcwindowsobj=_stdcwindows.obj
:dfl_not_tango_files
set dfl_files=package.d all.d base.d application.d internal/dlib.d internal/clib.d internal/utf.d internal/com.d control.d clippingform.d form.d registry.d drawing.d menu.d notifyicon.d commondialog.d filedialog.d folderdialog.d panel.d textboxbase.d textbox.d richtextbox.d picturebox.d listbox.d groupbox.d splitter.d usercontrol.d button.d label.d collections.d internal/winapi.d internal/wincom.d event.d socket.d timer.d environment.d messagebox.d tooltip.d combobox.d treeview.d tabcontrol.d colordialog.d listview.d data.d clipboard.d fontdialog.d progressbar.d resources.d statusbar.d imagelist.d toolbar.d trackbar.d sharedcontrol.d printing.d %_stdcwindowsd%
set dfl_files=package.d all.d base.d application.d internal/dlib.d internal/clib.d internal/utf.d internal/com.d control.d clippingform.d form.d registry.d drawing.d menu.d notifyicon.d commondialog.d filedialog.d folderdialog.d panel.d textboxbase.d textbox.d richtextbox.d picturebox.d listbox.d groupbox.d splitter.d usercontrol.d button.d label.d collections.d internal/winapi.d internal/wincom.d event.d socket.d timer.d environment.d messagebox.d tooltip.d combobox.d treeview.d tabcontrol.d colordialog.d listview.d data.d clipboard.d fontdialog.d progressbar.d resources.d statusbar.d imagelist.d toolbar.d trackbar.d sharedcontrol.d printing.d chart.d %_stdcwindowsd%
set dfl_objs=package.obj all.obj base.obj application.obj dlib.obj clib.obj utf.obj com.obj control.obj clippingform.obj form.obj registry.obj drawing.obj menu.obj notifyicon.obj commondialog.obj filedialog.obj folderdialog.obj panel.obj textboxbase.obj textbox.obj richtextbox.obj picturebox.obj listbox.obj groupbox.obj splitter.obj usercontrol.obj button.obj label.obj collections.obj winapi.obj wincom.obj event.obj socket.obj timer.obj environment.obj messagebox.obj tooltip.obj combobox.obj treeview.obj tabcontrol.obj colordialog.obj listview.obj data.obj clipboard.obj fontdialog.obj progressbar.obj resources.obj statusbar.obj imagelist.obj toolbar.obj trackbar.obj sharedcontrol.obj printing.obj %_stdcwindowsobj%
set dfl_objs=package.obj all.obj base.obj application.obj dlib.obj clib.obj utf.obj com.obj control.obj clippingform.obj form.obj registry.obj drawing.obj menu.obj notifyicon.obj commondialog.obj filedialog.obj folderdialog.obj panel.obj textboxbase.obj textbox.obj richtextbox.obj picturebox.obj listbox.obj groupbox.obj splitter.obj usercontrol.obj button.obj label.obj collections.obj winapi.obj wincom.obj event.obj socket.obj timer.obj environment.obj messagebox.obj tooltip.obj combobox.obj treeview.obj tabcontrol.obj colordialog.obj listview.obj data.obj clipboard.obj fontdialog.obj progressbar.obj resources.obj statusbar.obj imagelist.obj toolbar.obj trackbar.obj sharedcontrol.obj printing.obj chart.obj %_stdcwindowsobj%
@rem Also update link pragmas for build.
set dfl_libs_dfl=%dmd_path%\lib\user32.lib %dmd_path%\lib\shell32.lib %dmd_path%\lib\oleaut32.lib %dmd_path%\lib\undead.lib

332
source/dfl/chart.d Normal file
View file

@ -0,0 +1,332 @@
// chart.d
//
// Written by haru-s/Rayerd in 2024.
///
module dfl.chart;
private import dfl.base;
private import dfl.drawing;
private import std.csv;
private import std.typecons;
private import std.conv;
private import std.algorithm;
///
class TableRenderer(T...)
{
enum DEFAULT_HEIGHT = 25; ///
enum DEFAULT_WIDTH = 100; ///
enum DEFAULT_PADDING_X = 5; ///
enum DEFAULT_PADDING_Y = 5; ///
///
this(string csv)
{
_csv = csv;
_columns = T.length;
height = DEFAULT_HEIGHT;
for (int i; i < columns; i++)
_width ~= DEFAULT_WIDTH;
_headerFont = new Font("MS Gothic", 12f, FontStyle.BOLD);
_recordFont = new Font("MS Gothic", 12f, FontStyle.REGULAR);
_paddingX = DEFAULT_PADDING_X;
_paddingY = DEFAULT_PADDING_Y;
_textColor = Color.black;
_backColor = Color.white;
_lineColor = Color.black;
}
/// Draw records from first record to last record.
void draw(Graphics g)
{
// Draw background.
g.fillRectangle(new SolidBrush(_backColor), bounds);
// Draw top side line.
if (_topSideLine)
g.drawLine(new Pen(_lineColor), Point(margin.x, margin.y), Point(bounds.right, margin.y));
// Draw header line.
if (_showHeader && _hasHeader && _headerLine)
g.drawLine(new Pen(_lineColor), Point(margin.x, margin.y + height), Point(bounds.right, margin.y + height));
// Draw header and records.
int row; // -row- is line number in CSV.
int viewLine; // -viewLine- is line number on display.
foreach (record; csvReader!(Tuple!T)(_csv))
{
// Draw header.
if (row == 0)
{
if (_showHeader)
{
int y = margin.y + viewLine * height + _paddingY;
foreach (int col, value; record)
{
int x = margin.x + sum(_width[0..col]) + _paddingX;
g.drawText(to!string(value), _headerFont, _textColor, Rect(x, y, bounds.right, bounds.bottom));
}
row++;
viewLine++;
continue;
}
else
{
row++;
// Do not increment -viewLine- here.
continue;
}
}
// Draw record.
if (firstRecord + (_hasHeader?1:0) <= row && row <= lastRecord + (_hasHeader?1:0))
{
int y = margin.y + viewLine * height + _paddingY;
foreach (int col, value; record)
{
int x = margin.x + sum(_width[0..col]) + _paddingX;
g.drawText(to!string(value), _recordFont, _textColor, Rect(x, y, bounds.right, bounds.bottom));
}
// Draw horizontal line.
if (_horizontalLine && viewLine < lastRecord - firstRecord + (_showHeader?1:0))
{
int y2 = margin.y + height * (viewLine + 1);
g.drawLine(new Pen(_lineColor), Point(margin.x, y2), Point(bounds.right, y2));
}
row++;
viewLine++;
}
else
{
row++;
// Do not increment -viewLine- here.
}
}
// Draw left side line.
if (_leftSideLine)
g.drawLine(new Pen(_lineColor), Point(margin.x, margin.y), Point(margin.x, margin.y + height * viewLine));
// Draw right side line.
if (_rightSideLine)
g.drawLine(new Pen(_lineColor), Point(bounds.right, margin.y), Point(bounds.right, margin.y + height * viewLine));
// Draw vertical line.
if (_verticalLine)
{
for (int i; i < _columns - 1; i++)
{
int w = sum(_width[0..i+1]);
g.drawLine(new Pen(_lineColor), Point(margin.x + w, margin.y), Point(margin.x + w, margin.y + height * viewLine));
}
}
// Draw bottom side line.
if (_bottomSideLine)
g.drawLine(new Pen(_lineColor), Point(margin.x, margin.y + height * viewLine), Point(bounds.right, margin.y + height * viewLine));
}
///
void hasHeader(bool byes)
{
_hasHeader = byes;
}
///
void showHeader(bool byes)
{
if (!_hasHeader)
throw new DflException("DFL: showHeader is failure because do not have header.");
_showHeader = byes;
}
///
void headerLine(bool byes)
{
_headerLine = byes;
}
///
void topSideLine(bool byes)
{
_topSideLine = byes;
}
///
void leftSideLine(bool byes)
{
_leftSideLine = byes;
}
///
void bottomSideLine(bool byes)
{
_bottomSideLine = byes;
}
///
void rightSideLine(bool byes)
{
_rightSideLine = byes;
}
///
void verticalLine(bool byes)
{
_verticalLine = byes;
}
///
void horizontalLine(bool byes)
{
_horizontalLine = byes;
}
///
Rect bounds() const
{
int rows = (_showHeader?1:0) + lastRecord - firstRecord + 1;
return Rect(_margin.x, _margin.y, sum(_width), height * rows);
}
/// Left and Top margins.
void margin(Point pt)
{
_margin.x = pt.x;
_margin.y = pt.y;
}
/// ditto
Point margin() const
{
return _margin;
}
///
void paddingX(int px)
{
_paddingX = px;
}
///
void paddingY(int py)
{
_paddingY = py;
}
///
void firstRecord(int r)
{
_firstRecord = r;
}
///
int firstRecord() const
{
return _firstRecord;
}
///
void lastRecord(int r)
{
_lastRecord = r;
}
///
int lastRecord() const
{
return _lastRecord;
}
///
int columns() const
{
return _columns;
}
///
void height(int h)
{
_height = h;
}
/// ditto
int height() const
{
return _height;
}
///
struct WidthObject // Internal struct.
{
///
this(ref int[] w)
{
_arr = w;
}
///
void opIndexAssign(int value, size_t i)
{
_arr[i] = value;
}
///
int opIndex(size_t i)
{
return _arr[i];
}
private:
int[] _arr;
}
///
WidthObject width()
{
return WidthObject(_width);
}
///
void textColor(Color c)
{
_textColor = c;
}
///
void backColor(Color c)
{
_backColor = c;
}
///
void lineColor(Color c)
{
_lineColor = c;
}
void headerFont(Font f)
{
_headerFont = f;
}
void recordFont(Font f)
{
_recordFont = f;
}
private:
string _csv;
Point _margin;
int _paddingX;
int _paddingY;
int _columns;
int _height;
int[] _width;
int _firstRecord;
int _lastRecord;
Color _textColor;
Color _backColor;
Color _lineColor;
bool _hasHeader;
bool _showHeader;
bool _headerLine;
bool _topSideLine;
bool _leftSideLine;
bool _bottomSideLine;
bool _rightSideLine;
bool _verticalLine;
bool _horizontalLine;
Font _headerFont;
Font _recordFont;
}

View file

@ -15,4 +15,4 @@ public import dfl.base, dfl.menu, dfl.control, dfl.usercontrol,
dfl.combobox, dfl.treeview, dfl.picturebox, dfl.tabcontrol,
dfl.listview, dfl.statusbar, dfl.progressbar, dfl.resources,
dfl.imagelist, dfl.toolbar, dfl.trackbar, dfl.sharedcontrol,
dfl.printing;
dfl.printing, dfl.chart;