File Dialog - continue development; StringGridWidget - support custom drawn cells adapter

This commit is contained in:
Vadim Lopatin 2014-12-17 16:24:01 +03:00
parent 35104b170a
commit a51c058696
5 changed files with 168 additions and 10 deletions

BIN
res/mdpi/folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

BIN
res/mdpi/text-plain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

View File

@ -143,11 +143,70 @@ struct RootEntry {
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 */
bool isPathDelimiter(char 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() */
@property string exePath() {
string path = thisExePath();

View File

@ -35,6 +35,12 @@ import dlangui.widgets.grid;
import dlangui.widgets.editors;
import dlangui.platforms.common.platform;
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
enum FileDialogFlag : uint {
@ -49,7 +55,7 @@ enum FileDialogFlag : uint {
}
/// File open / save dialog
class FileDialog : Dialog {
class FileDialog : Dialog, CustomGridCellAdapter {
protected EditLine path;
protected EditLine filename;
protected StringGridWidget list;
@ -58,15 +64,80 @@ class FileDialog : Dialog {
protected VerticalLayout rightPanel;
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) {
super(caption, parent, fileDialogFlags);
}
protected void rootEntrySelected(RootEntry entry) {
// TODO
protected bool openDirectory(string dir) {
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() {
ListWidget list = new ListWidget("ROOTS_LIST");
WidgetListAdapter adapter = new WidgetListAdapter();
@ -76,7 +147,7 @@ class FileDialog : Dialog {
btn.styleId = "TRANSPARENT_BUTTON_BACKGROUND";
btn.focusable = false;
btn.onClickListener = delegate(Widget source) {
rootEntrySelected(root);
openDirectory(root.path);
return true;
};
adapter.widgets.add(btn);
@ -110,10 +181,11 @@ class FileDialog : Dialog {
rightPanel.addChild(path);
list = new StringGridWidget("files");
list.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
list.resize(3, 3);
list.setColTitle(0, "Name"d);
list.setColTitle(1, "Size"d);
list.setColTitle(2, "Modified"d);
list.resize(4, 3);
list.setColTitle(0, " "d);
list.setColTitle(1, "Name"d);
list.setColTitle(2, "Size"d);
list.setColTitle(3, "Modified"d);
list.showRowHeaders = false;
list.rowSelect = true;
rightPanel.addChild(list);
@ -128,7 +200,11 @@ class FileDialog : Dialog {
addChild(content);
addChild(createButtonsPanel([ACTION_OPEN, ACTION_CANCEL], 0, 0));
string[] path = splitPath("/home/lve/src");
Log.d("path: ", path);
//string[] path = splitPath("/home/lve/src");
//Log.d("path: ", path);
list.customCellAdapter = this;
openDirectory(currentDir);
}
}

View File

@ -202,8 +202,25 @@ enum GridActions : int {
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
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)
protected int _cols;
/// row count (including header rows and fixed rows)
@ -1140,6 +1157,9 @@ class StringGridWidget : StringGridWidgetBase {
}
protected override Point measureCell(int x, int y) {
if (_customCellAdapter && _customCellAdapter.isCustomCell(x, y)) {
return _customCellAdapter.measureCell(x, y);
}
//Log.d("measureCell ", x, ", ", y);
FontRef fnt = font;
dstring txt;
@ -1158,6 +1178,9 @@ class StringGridWidget : StringGridWidgetBase {
/// draw cell content
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);
FontRef fnt = font;
dstring txt = cellText(col, row);