mirror of https://github.com/buggins/dlangui.git
File Dialog - continue development; StringGridWidget - support custom drawn cells adapter
This commit is contained in:
parent
35104b170a
commit
a51c058696
Binary file not shown.
|
After Width: | Height: | Size: 652 B |
Binary file not shown.
|
After Width: | Height: | Size: 540 B |
|
|
@ -143,11 +143,70 @@ struct RootEntry {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// returns true if directory is root directory (e.g. / or C:\)
|
||||||
|
bool isRoot(string path) {
|
||||||
|
string root = rootName(path);
|
||||||
|
if (path.equal(root))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Filters file name by pattern list
|
||||||
|
bool filterFilename(string filename, string[] filters) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** List directory content
|
||||||
|
|
||||||
|
Optionally filters file names by filter.
|
||||||
|
|
||||||
|
Result will be placed into entries array.
|
||||||
|
|
||||||
|
Returns true if directory exists and listed successfully, false otherwise.
|
||||||
|
*/
|
||||||
|
bool listDirectory(string dir, bool includeDirs, bool includeFiles, string[] filters, ref DirEntry[] entries) {
|
||||||
|
entries.length = 0;
|
||||||
|
if (!isDir(dir)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isRoot(dir) && includeDirs) {
|
||||||
|
entries ~= DirEntry(appendPath(dir, ".."));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DirEntry[] dirs;
|
||||||
|
DirEntry[] files;
|
||||||
|
foreach (DirEntry e; dirEntries(dir, SpanMode.shallow)) {
|
||||||
|
if (e.isDir) {
|
||||||
|
dirs ~= e;
|
||||||
|
} else if (e.isFile) {
|
||||||
|
files ~= e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (includeDirs)
|
||||||
|
foreach(DirEntry e; dirs)
|
||||||
|
entries ~= e;
|
||||||
|
if (includeFiles)
|
||||||
|
foreach(DirEntry e; files)
|
||||||
|
if (filterFilename(e.name, filters))
|
||||||
|
entries ~= e;
|
||||||
|
return true;
|
||||||
|
} catch (FileException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns true if char ch is / or \ slash */
|
/** Returns true if char ch is / or \ slash */
|
||||||
bool isPathDelimiter(char ch) {
|
bool isPathDelimiter(char ch) {
|
||||||
return ch == '/' || ch == '\\';
|
return ch == '/' || ch == '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns current directory
|
||||||
|
@property string currentDir() {
|
||||||
|
return getcwd();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns current executable path only, including last path delimiter - removes executable name from result of std.file.thisExePath() */
|
/** Returns current executable path only, including last path delimiter - removes executable name from result of std.file.thisExePath() */
|
||||||
@property string exePath() {
|
@property string exePath() {
|
||||||
string path = thisExePath();
|
string path = thisExePath();
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ import dlangui.widgets.editors;
|
||||||
import dlangui.platforms.common.platform;
|
import dlangui.platforms.common.platform;
|
||||||
import dlangui.dialogs.dialog;
|
import dlangui.dialogs.dialog;
|
||||||
|
|
||||||
|
private import std.file;
|
||||||
|
private import std.path;
|
||||||
|
private import std.utf;
|
||||||
|
private import std.conv : to;
|
||||||
|
|
||||||
|
|
||||||
/// flags for file dialog options
|
/// flags for file dialog options
|
||||||
enum FileDialogFlag : uint {
|
enum FileDialogFlag : uint {
|
||||||
/// file must exist (use this for open dialog)
|
/// file must exist (use this for open dialog)
|
||||||
|
|
@ -49,7 +55,7 @@ enum FileDialogFlag : uint {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// File open / save dialog
|
/// File open / save dialog
|
||||||
class FileDialog : Dialog {
|
class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
protected EditLine path;
|
protected EditLine path;
|
||||||
protected EditLine filename;
|
protected EditLine filename;
|
||||||
protected StringGridWidget list;
|
protected StringGridWidget list;
|
||||||
|
|
@ -58,13 +64,78 @@ class FileDialog : Dialog {
|
||||||
protected VerticalLayout rightPanel;
|
protected VerticalLayout rightPanel;
|
||||||
|
|
||||||
protected RootEntry[] _roots;
|
protected RootEntry[] _roots;
|
||||||
|
protected string _path;
|
||||||
|
protected string _filename;
|
||||||
|
protected DirEntry[] _entries;
|
||||||
|
protected bool _isRoot;
|
||||||
|
|
||||||
this(UIString caption, Window parent, uint fileDialogFlags = DialogFlag.Modal | FileDialogFlag.FileMustExist) {
|
this(UIString caption, Window parent, uint fileDialogFlags = DialogFlag.Modal | FileDialogFlag.FileMustExist) {
|
||||||
super(caption, parent, fileDialogFlags);
|
super(caption, parent, fileDialogFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void rootEntrySelected(RootEntry entry) {
|
protected bool openDirectory(string dir) {
|
||||||
// TODO
|
list.rows = 0;
|
||||||
|
string[] filters;
|
||||||
|
if (!listDirectory(dir, true, true, filters, _entries))
|
||||||
|
return false;
|
||||||
|
_path = dir;
|
||||||
|
_isRoot = isRoot(dir);
|
||||||
|
path.text = toUTF32(_path);
|
||||||
|
list.rows = _entries.length;
|
||||||
|
for (int i = 0; i < _entries.length; i++) {
|
||||||
|
string fname = baseName(_entries[i].name);
|
||||||
|
string sz;
|
||||||
|
string date;
|
||||||
|
bool d = _entries[i].isDir;
|
||||||
|
list.setCellText(1, i, toUTF32(fname));
|
||||||
|
if (d) {
|
||||||
|
list.setCellText(0, i, "folder");
|
||||||
|
} else {
|
||||||
|
list.setCellText(0, i, "text-plain"d);
|
||||||
|
sz = to!string(_entries[i].size);
|
||||||
|
date = "2014-01-01 00:00:00";
|
||||||
|
}
|
||||||
|
list.setCellText(2, i, toUTF32(sz));
|
||||||
|
list.setCellText(3, i, toUTF32(date));
|
||||||
|
}
|
||||||
|
list.autoFitColumnWidths();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return true for custom drawn cell
|
||||||
|
override bool isCustomCell(int col, int row) {
|
||||||
|
if (col == 0 && row >= 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DrawableRef rowIcon(int row) {
|
||||||
|
string iconId = toUTF8(list.cellText(0, row));
|
||||||
|
DrawableRef res;
|
||||||
|
if (iconId.length)
|
||||||
|
res = drawableCache.get(iconId);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return cell size
|
||||||
|
override Point measureCell(int col, int row) {
|
||||||
|
DrawableRef icon = rowIcon(row);
|
||||||
|
if (icon.isNull)
|
||||||
|
return Point(0, 0);
|
||||||
|
return Point(icon.width + 2, icon.height + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// draw data cell content
|
||||||
|
override void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
||||||
|
DrawableRef img = rowIcon(row);
|
||||||
|
if (!img.isNull) {
|
||||||
|
Point sz;
|
||||||
|
sz.x = img.width;
|
||||||
|
sz.y = img.height;
|
||||||
|
applyAlign(rc, sz, Align.HCenter, Align.VCenter);
|
||||||
|
uint st = state;
|
||||||
|
img.drawTo(buf, rc, st);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Widget createRootsList() {
|
protected Widget createRootsList() {
|
||||||
|
|
@ -76,7 +147,7 @@ class FileDialog : Dialog {
|
||||||
btn.styleId = "TRANSPARENT_BUTTON_BACKGROUND";
|
btn.styleId = "TRANSPARENT_BUTTON_BACKGROUND";
|
||||||
btn.focusable = false;
|
btn.focusable = false;
|
||||||
btn.onClickListener = delegate(Widget source) {
|
btn.onClickListener = delegate(Widget source) {
|
||||||
rootEntrySelected(root);
|
openDirectory(root.path);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
adapter.widgets.add(btn);
|
adapter.widgets.add(btn);
|
||||||
|
|
@ -110,10 +181,11 @@ class FileDialog : Dialog {
|
||||||
rightPanel.addChild(path);
|
rightPanel.addChild(path);
|
||||||
list = new StringGridWidget("files");
|
list = new StringGridWidget("files");
|
||||||
list.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
list.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
list.resize(3, 3);
|
list.resize(4, 3);
|
||||||
list.setColTitle(0, "Name"d);
|
list.setColTitle(0, " "d);
|
||||||
list.setColTitle(1, "Size"d);
|
list.setColTitle(1, "Name"d);
|
||||||
list.setColTitle(2, "Modified"d);
|
list.setColTitle(2, "Size"d);
|
||||||
|
list.setColTitle(3, "Modified"d);
|
||||||
list.showRowHeaders = false;
|
list.showRowHeaders = false;
|
||||||
list.rowSelect = true;
|
list.rowSelect = true;
|
||||||
rightPanel.addChild(list);
|
rightPanel.addChild(list);
|
||||||
|
|
@ -128,7 +200,11 @@ class FileDialog : Dialog {
|
||||||
addChild(content);
|
addChild(content);
|
||||||
addChild(createButtonsPanel([ACTION_OPEN, ACTION_CANCEL], 0, 0));
|
addChild(createButtonsPanel([ACTION_OPEN, ACTION_CANCEL], 0, 0));
|
||||||
|
|
||||||
string[] path = splitPath("/home/lve/src");
|
//string[] path = splitPath("/home/lve/src");
|
||||||
Log.d("path: ", path);
|
//Log.d("path: ", path);
|
||||||
|
|
||||||
|
list.customCellAdapter = this;
|
||||||
|
|
||||||
|
openDirectory(currentDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -202,8 +202,25 @@ enum GridActions : int {
|
||||||
SelectDocumentEnd,
|
SelectDocumentEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CustomGridCellAdapter {
|
||||||
|
/// return true for custom drawn cell
|
||||||
|
bool isCustomCell(int col, int row);
|
||||||
|
/// return cell size
|
||||||
|
Point measureCell(int col, int row);
|
||||||
|
/// draw data cell content
|
||||||
|
void drawCell(DrawBuf buf, Rect rc, int col, int row);
|
||||||
|
}
|
||||||
|
|
||||||
/// Abstract grid widget
|
/// Abstract grid widget
|
||||||
class GridWidgetBase : ScrollWidgetBase {
|
class GridWidgetBase : ScrollWidgetBase {
|
||||||
|
protected CustomGridCellAdapter _customCellAdapter;
|
||||||
|
|
||||||
|
/// Get adapter to override drawing of some particular cells
|
||||||
|
@property CustomGridCellAdapter customCellAdapter() { return _customCellAdapter; }
|
||||||
|
/// Set adapter to override drawing of some particular cells
|
||||||
|
@property GridWidgetBase customCellAdapter(CustomGridCellAdapter adapter) { _customCellAdapter = adapter; return this; }
|
||||||
|
|
||||||
|
|
||||||
/// column count (including header columns and fixed columns)
|
/// column count (including header columns and fixed columns)
|
||||||
protected int _cols;
|
protected int _cols;
|
||||||
/// row count (including header rows and fixed rows)
|
/// row count (including header rows and fixed rows)
|
||||||
|
|
@ -1140,6 +1157,9 @@ class StringGridWidget : StringGridWidgetBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Point measureCell(int x, int y) {
|
protected override Point measureCell(int x, int y) {
|
||||||
|
if (_customCellAdapter && _customCellAdapter.isCustomCell(x, y)) {
|
||||||
|
return _customCellAdapter.measureCell(x, y);
|
||||||
|
}
|
||||||
//Log.d("measureCell ", x, ", ", y);
|
//Log.d("measureCell ", x, ", ", y);
|
||||||
FontRef fnt = font;
|
FontRef fnt = font;
|
||||||
dstring txt;
|
dstring txt;
|
||||||
|
|
@ -1158,6 +1178,9 @@ class StringGridWidget : StringGridWidgetBase {
|
||||||
|
|
||||||
/// draw cell content
|
/// draw cell content
|
||||||
protected override void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
protected override void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
||||||
|
if (_customCellAdapter && _customCellAdapter.isCustomCell(col, row)) {
|
||||||
|
return _customCellAdapter.drawCell(buf, rc, col, row);
|
||||||
|
}
|
||||||
rc.shrink(2, 1);
|
rc.shrink(2, 1);
|
||||||
FontRef fnt = font;
|
FontRef fnt = font;
|
||||||
dstring txt = cellText(col, row);
|
dstring txt = cellText(col, row);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue