|
From: Jeff H. <je...@Ac...> - 2005-09-20 17:05:29
|
Joe English wrote:
> Jeff Hobbs wrote:
> > Take a simple validated entry widget:
> >
> > proc isValid {e str} {
> > set ok [file isfile $str]
> > $e configure -bg [expr {$ok ? "white" : "lightyellow"}]
> > return 1
> > }
>
> OK -- so here you're using the validation facility strictly
> to provide visual feedback, not to prevent the user from
> entering an invalid value (which in this case is impossible
> anyway -- you can't type a valid filename without typing
> something that isn't a filename in between).
Correct, I am "overloading" validatecommand to provide visual
feedback for validity instead of the "less friendly" forced
exclusion. This is considered friendlier UI practice in some
cases now, and the classic entry widget allows you to do this
very easily. I prefer to do this with validatecommand
instead of var tracing as the "View" then maintains its own
consistency. Note that likely many use the -validatecommand
as an entry tracing command.
> Part of the problem is that the return value of the
> '-validatecommand' means two different things, depending on
> context: (a) allow/don't allow this change, or (b) the value
> is currently valid/invalid. (The ttk::entry manpage calls case
> (a) "prevalidation" and case (b) "revalidation".)
>
> But in this case, what you want to say is "the new value is
> invalid, but accept the change anyway". There's no good way
> to do this with the current API.
Yes, and I see this as an unfortunate limitation compared to
the classic entry, given that we have disallowed good UI
practice.
> One possibility would be to use the 'alternate' state instead
> of 'invalid' for visual feedback:
OK, that would work fine, then I just have to add comments as
to why I call it "alternate" vs. "invalid", since the latter
is self-documenting.
> How about this: change the [ttk::entry] widget to generate
> an <<EntryChanged>> virtual event whenever the value changes.
Eh? That's what -validate is already supposed to do. The use
of a virtual event here seems excessive.
> The ttk::entry widget doesn't currently perform validation
> when the linked -textvariable is set because this leads to
> anomalies -- if the validation script(s) also set the
> variable, the widget can't detect it since the original write
> trace is still active. I can only think of two ways around
> this; either don't worry about it and say "User beware",
> which is basically what the core [entry] does; or schedule
> revalidation as an idle handler, which leads to even more
> weirdness. However, it *would* be safe to queue an
> <<EntryChanged>> event in this condition.
I tried the idle handler with the core entry, and had to go
with "user beware" in the end. I don't think we should have
to rely on further events in this situation.
> I'm not sure how useful the current 'invalid/!invalid' state
> logic is. The intent was to give visual feedback about the
> current validity of the value, and also to prevent validation
> lockout: if the widget becomes invalid, let the user type
> whatever he wants until it's valid again. But if the
> application is using prevalidation, the widget can't become
> invalid in the first place (barring bugs in the app).
>
> Maybe it should only set/clear the invalid bit after revalidation?
> This would make your first approach work (use '-validate key',
> set/clear the invalid bit in the -validatecommand, always return 1.)
> Or maybe the widget should not set it at all, leaving it entirely
> up to the app to do so?
This makes more sense - I want to have the state-based
visual control without actual lockout occuring, and it would
be nice to somehow make this work through -validatecommand.
Jeff
|