Hi Sam.
1. First of all EditBox is a very old class that never got a proper clean up. Don't look for consistency, it's not there. We plan to have a cleaner design with user reviews for a new version of the GUI engine, but at the moment we are trying to focus on making everything stable and functional.
This is a topic for discussing future improvements to the GUI toolkit, and
Mantis can be used to keep track of these improvements and their progress.
So AddS is like a 'low level' method meant to be fast, e.g. if you have a lot of text to output. After calling AddS (e.g. multiple times), you're expected to call
EditBox::SetViewToCursor, which will ensure the cursor is kept visible and update the control. At the minimum a call to Update(null) is necessary for the control to redraw itself.
The higher level version of AddS, '
PutS', calls AddS, SetViewToCursor, and mark the control as modified. That is the method expected to be called most often by the user (AddS is more for internal use), unless you need the performance gain that you get from calling AddS multiple times.
There is also a Printf (printf like formatting) and PutCh (single character) output function. There is not yet a Print/PrintLn-like method in the EditBox because it predates those (but should come in the future).
2. I see that behavior. That is because
EditBox::SetViewToCursor is expected to be called after calling AddS. Calling it or using PutS instead of AddS will fix this as well.
3. Calling
txtDir.Activate(); in OnPostCreate() will do this for you. It seems to work in OnCreate() as well. The difference between OnCreate() and OnPostCreate() is that OnPostCreate happens at the very end of the window creation process, all the display have been set up, graphics have been loaded, and any child or slave windows have been created as well.
In the next generation GUI we hope to come up with an easier way to define: The tab ordering of the controls, and the control active by default.
4. You have a good point about EditBox::AddS vs ListBox::AddString, although I never thought to compare these two, the ListBox and EditBox being used for very different purposes. AddString came as a convenience function for ListBoxes working with String data types that combines AddRow/SetData in a single function call. The GUI toolkit has a very long history (about 14 years) and the last GUI review / cleanup has been a long time ago, we need a new usability review
Bonus suggestions:
- In eC 'this.' is not required and I generally suggest to omit it, unless it is to distinguish between a member variable an overshadowing local variable or argument with the same name.
- Buttons can have be the 'default' buttons for the dialog, they get a black border and 'Enter' anywhere in the dialog presses them (This is amazingly a cancellable process in Ecere! The button doesn't click until you release the Enter key, and you can cancel by using the Tab key or Escape key while the button is held down
). Set
isDefault = true;
- Set
tabCycle = true on dialogs, so that you can use the Tab key to cycle between controls
- Ecere has very powerful
anchors to make dialogs rescale to different sizes. You can define the distance between any edge of the control and the parent window's corresponding edge either relatively (a percentage) or to a fixed number of pixels. Checkout the 'anchor' property under the 'Layout' properties category of any Window.
- Set
minClientSize instead of size to guarantee that a window cannot be resized smaller than an area in which the dialog will look good. Or you can set clientSize to guarantee a number of pixels in the client area, regardless of how much space the window decorations (title bars/borders) will take.
- I'm not a fan of the carriage return/new line combination, so internally \r characters are never used. They are ignored when you do AddS("\r\n") so you might as well just say
AddS("\n"). If you want "\r\n" to be saved to a file for each new line you can pass true to the EditBox::Save method for the 'lf' parameter.
-
!txtDir.contents[0] is a simpler, equivalent check to !strcmp(txtDir.contents,""), and 'ok' is the default type for a MessageBox so you can omit it
- The return value of NotifyClicked is for chaining mouse events and it's a rather advanced topic. You can simply
return true regardless of error or not.
- You can set
nativeDecorations = true; to use native system decorations. I've recently completed the support on Windows and there is partial support on X already.
- I changed the EditBox and Labels using a connected label, as I discussed in the
other thread.
Here is my tweaked version of your sample code:
Code: Select all
import "ecere"
class Form1 : Window
{
text = "Form1";
background = activeBorder;
borderStyle = sizable;
hasMaximize = true;
hasMinimize = true;
hasClose = true;
tabCycle = true;
nativeDecorations = true;
minClientSize = { 576, 432 };
EditBox txtDir { this, text = "请输入文夹件路径:", size = { 214, 19 }, position = { 144, 24 } };
Label lblTxtDir { this, labeledWindow = txtDir, size = { 116, 13 }, position = { 24, 24 } };
Button btnView
{
this, text = "(V)iew", altV, position = { 488, 24 };
isDefault = true;
bool NotifyClicked(Button button, int x, int y, Modifiers mods)
{
if(!txtDir.contents[0])
MessageBox {text="Error",contents="Text can not be blank.",master=this}.Modal();
else
{
txtFiles.Clear();
listDir(txtDir.contents);
}
return true;
}
};
EditBox txtFiles { this, anchor = { left = 16, top = 64, right = 18, bottom = 17 }, hasHorzScroll = true, hasVertScroll = true, readOnly = true, multiLine = true };
bool OnPostCreate()
{
txtDir.Activate();
return true;
}
void listDir(char* path)
{
FileListing listing {path};
while(listing.Find())
{
if(listing.stats.attribs.isDirectory)
{
listDir(listing.path) ;
}
else
{
txtFiles.AddS(listing.path);
txtFiles.AddS("\n");
}
}
txtFiles.SetViewToCursor(true);
}
}
Form1 form1 {};