Thread: [Gambas-user] A Gambas odissey
Brought to you by:
gambas
|
From: Doriano B. <dor...@fa...> - 2008-08-11 08:13:14
|
Hello all...
I am writing a file manager, hybrid between FileRunner and a more
modern one.
I started with a DirView, and soon discovered that it doesn't raise the
KeyPress event (but the IDE makes you think that). There were other
things missing in DirView, so I wrote my MyDirView the way I wanted. It
was easy at first, but then I discovered that it is difficult, or at
least not clear, how to move the "Current" cursor. I am not sure why,
but it does work by setting the Selected property of an item. I failed,
instead, in removing all the children of an item, one by one (there is a
clear() method, but I need to delete them one by one). The "for each ...
in item.children" does not work; it is not the first time I see similar
anomalies, especially while stepping the source.
Writing MyDirView revealed another problem. If in a custom control I
receive the KeyPress event, I can not re-raise it (stack overflow). So I
have to raise another event with a different name. This breaks the
consistency of naming - in a row of four controls, each derived from the
other, the same event must be called with four different names. I took a
look at the FileView control to see what has been done in there. It
receives Click events, and raises Click events. What inside? It does not
inherit from ListView or similar. Now I understand why it works, but I
don't like it.
Anyway, I went ahead. I put two FileView on the form. They don't raise
KeyPress event. It's getting tiring. I don't want to rewrite MyFileView
just now (I will do, because I need more functionalities). I only need
to catch Backspace and Enter, so I make a menu voice which has the
Backspace key as its shortcut. Now the backspace works, but... how the
hell can I tell which control is focused? The only way I found was to
catch the GotFocus and LostFocus events, and track the focus by hand. I
have only three controls, but what about if I had dozens of them?
Grouping them would group all their events, while I am interested in
grouping only GotFocus/LostFocus events.
To make it short, I succeded in make it work, and passed to the
Enter key. The Enter key should invoke the selected file in one of the
two FileView's. A menu voice has only one shortcut, but the Enter keys
are two (Gambas calls them Enter and Return). Uhm... no way. Then I try
to use the Form_Keypress event, but it does not fire - the controls are
stealing the keys. So, there is no way to do this thing. If a FileView
does not "activate" a file when the user presses Enter, then you can not:
1: inherit a new control which does, because you must rename all its
events
2: use a menu voice to do it, because a menu voice has only one
shortcut; if you want use more keys, no way
3: use the form KeyPress, which does not fire
The only way left is to create a new control, and then instantiate a
FileView inside it. This is not inheritance, because you have to
replicate all the things you need: events, properties, methods.
Coming from Delphi, I must say the following:
Delphi forms have a KeyPreview property. If you set it, then *all* the
keypresses are first passed to the form. The form then decides wether to
ignore the key, or make additional things, to let the key pass, or to
stop it.
Delphi containers have an ActiveControl property which tells which
control has the focus. Moreover, every control has a Focused property
which tells if a specific control has the focus or not. The list of
things Delphi has and Gambas doesn't is long, but I don't want to
criticize. I am really missing keyboard and focus control. It seems that
VisualBasic programmers use the mouse a lot, and neglect keyboards, and
so do many users, so this could be the reason why Gambas seems to do the
same.
I don't know Gambas very well, and I could have missed a lot of things.
But it is easy to miss things - in the documentation a "See also"
section in every topic could really help.
Finally, I must say that I think, and *repeat*, I think, the event
management is wrong or, at least, it is not as flexible as it could be.
Once a control raises event, you can not make it stop. If you group
controls, you group all their events. Once you assign a handler to an
event, you can no more change it. Probably Gambas is too developed to
change things at this point but, for who cares or is courious, I will
explain how events work in Delphi. An event in delphi has an associated
property which contains the address of a routine to launch. For example,
if a control has a Click event, then it has a OnClick property. That
property contains the address of the routine to invoke when the control
wants to "raise" the Click event. The OnClick property is a procedural
type, a thing that does not exist in Gambas. But being a property, the
main program can disable that event by setting that property to NIL
(NULL), or change the handler by setting the property to another value.
It is possible to associate many controls to the same handler, but only
the events we want, not *all* the events of *all* the selected controls.
In fact, events do not exist in delphi, they are simply procedure calls.
Instead of writing:
raise KeyPress ' Gambas code
which, I suppose, unleashes a textual search for a public subroutine
named in some correct way, in Delphi one would write:
if OnKeypress<>NIL then OnKeypress(); // procedural call
This paradigm is faster, more sure, more flexible, more easy to
understand. When deriving controls, the derived one can override the
methods of the ancestor, and still call the inherited one. Gambas has an
interesting feature which does the opposite: instead of calling the
ancestor method on demand, it can stop it on demand. It is quite the
same, I think.
Happy holidays to everyone.
|
|
From: Fabien B. <gam...@gm...> - 2008-08-12 10:15:12
|
hohoooo there is many thing wrong here ! 2008/8/11 Doriano Blengino <dor...@fa...>: > Hello all... > > I am writing a file manager, hybrid between FileRunner and a more > modern one. > > I started with a DirView, and soon discovered that it doesn't raise the > KeyPress event (but the IDE makes you think that). dir view is a top level component you can easily rewrite it > There were other > things missing in DirView, so I wrote my MyDirView the way I wanted. It > was easy at first, but then I discovered that it is difficult, or at > least not clear, how to move the "Current" cursor. I am not sure why, > but it does work by setting the Selected property of an item. I failed, > instead, in removing all the children of an item, one by one (there is a > clear() method, but I need to delete them one by one). The "for each ... > in item.children" does not work; it is not the first time I see similar > anomalies, especially while stepping the source. > > Writing MyDirView revealed another problem. If in a custom control I > receive the KeyPress event, I can not re-raise it (stack overflow). So I > have to raise another event with a different name. This breaks the > consistency of naming - in a row of four controls, each derived from the > other, the same event must be called with four different names. I took a > look at the FileView control to see what has been done in there. It > receives Click events, and raises Click events. What inside? It does not > inherit from ListView or similar. Now I understand why it works, but I > don't like it. it don't have to inherit it's a composed widget..; not an extention. > > Anyway, I went ahead. I put two FileView on the form. They don't raise > KeyPress event. It's getting tiring. I don't want to rewrite MyFileView > just now (I will do, because I need more functionalities). I only need > to catch Backspace and Enter, so I make a menu voice which has the > Backspace key as its shortcut. Now the backspace works, but... how the > hell can I tell which control is focused? The only way I found was to > catch the GotFocus and LostFocus events, and track the focus by hand. I > have only three controls, but what about if I had dozens of them? > Grouping them would group all their events, while I am interested in > grouping only GotFocus/LostFocus events. > > To make it short, I succeded in make it work, and passed to the > Enter key. The Enter key should invoke the selected file in one of the > two FileView's. A menu voice has only one shortcut, but the Enter keys > are two (Gambas calls them Enter and Return). Uhm... no way. Then I try > to use the Form_Keypress event, but it does not fire - the controls are > stealing the keys. So, there is no way to do this thing. If a FileView > does not "activate" a file when the user presses Enter, then you can not: > > 1: inherit a new control which does, because you must rename all its > events what about observer ? > 2: use a menu voice to do it, because a menu voice has only one > shortcut; if you want use more keys, no way ??? > 3: use the form KeyPress, which does not fire > > The only way left is to create a new control, and then instantiate a > FileView inside it. This is not inheritance, because you have to > replicate all the things you need: events, properties, methods. > > Coming from Delphi, I must say the following: > > Delphi forms have a KeyPreview property. If you set it, then *all* the > keypresses are first passed to the form. The form then decides wether to > ignore the key, or make additional things, to let the key pass, or to > stop it. > > Delphi containers have an ActiveControl property which tells which > control has the focus. Moreover, every control has a Focused property > which tells if a specific control has the focus or not. The list of > things Delphi has and Gambas doesn't is long, but I don't want to > criticize. I am really missing keyboard and focus control. It seems that > VisualBasic programmers use the mouse a lot, and neglect keyboards, and > so do many users, so this could be the reason why Gambas seems to do the > same. > > I don't know Gambas very well, and I could have missed a lot of things. many > But it is easy to miss things - in the documentation a "See also" > section in every topic could really help. there is > > Finally, I must say that I think, and *repeat*, I think, the event > management is wrong or, at least, it is not as flexible as it could be. > Once a control raises event, you can not make it stop. not true ... it's STOP EVENT >If you group > controls, you group all their events. yes it's an event handler grouping, not a true group ... to doing a group you need to store objects in an array > Once you assign a handler to an > event, you can no more change it. wrong : Object.attach(Object, parentclass, "handler name") > Probably Gambas is too developed to > change things at this point but, for who cares or is courious, I will > explain how events work in Delphi. An event in delphi has an associated > property which contains the address of a routine to launch. For example, > if a control has a Click event, then it has a OnClick property. That > property contains the address of the routine to invoke when the control > wants to "raise" the Click event. The OnClick property is a procedural > type, a thing that does not exist in Gambas. true ... gambas is a true oriented object language > But being a property, the > main program can disable that event by setting that property to NIL > (NULL), PUBLIC SUB MyList_KeyPress() STOP EVENT END But it's true that we can't turn off an event > or change the handler by setting the property to another value. > It is possible to associate many controls to the same handler, but only > the events we want, not *all* the events of *all* the selected controls. > In fact, events do not exist in delphi, they are simply procedure calls. > Instead of writing: > > raise KeyPress ' Gambas code > > which, I suppose, unleashes a textual search for a public subroutine > named in some correct way, in Delphi one would write: > > if OnKeypress<>NIL then OnKeypress(); // procedural call > > > This paradigm is faster, more sure, more flexible, more easy to > understand. When deriving controls, the derived one can override the > methods of the ancestor, and still call the inherited one. Gambas has an > interesting feature which does the opposite: instead of calling the > ancestor method on demand, it can stop it on demand. It is quite the > same, I think. ok got it in fact > > > Happy holidays to everyone. > to you too Fabien |
|
From: Fabien B. <gam...@gm...> - 2008-08-12 10:53:31
Attachments:
testinherit-0.0.1.tar.gz
|
is this can help you ? This a simple demo off event management via objerver object that catch the event before object. If you have others question tell me Fabien 2008/8/12 Fabien Bodard <gam...@gm...>: > hohoooo there is many thing wrong here ! > > 2008/8/11 Doriano Blengino <dor...@fa...>: >> Hello all... >> >> I am writing a file manager, hybrid between FileRunner and a more >> modern one. >> >> I started with a DirView, and soon discovered that it doesn't raise the >> KeyPress event (but the IDE makes you think that). > > dir view is a top level component you can easily rewrite it > > >> There were other >> things missing in DirView, so I wrote my MyDirView the way I wanted. It >> was easy at first, but then I discovered that it is difficult, or at >> least not clear, how to move the "Current" cursor. I am not sure why, >> but it does work by setting the Selected property of an item. I failed, >> instead, in removing all the children of an item, one by one (there is a >> clear() method, but I need to delete them one by one). The "for each ... >> in item.children" does not work; it is not the first time I see similar >> anomalies, especially while stepping the source. >> >> Writing MyDirView revealed another problem. If in a custom control I >> receive the KeyPress event, I can not re-raise it (stack overflow). So I >> have to raise another event with a different name. This breaks the >> consistency of naming - in a row of four controls, each derived from the >> other, the same event must be called with four different names. I took a >> look at the FileView control to see what has been done in there. It >> receives Click events, and raises Click events. What inside? It does not >> inherit from ListView or similar. Now I understand why it works, but I >> don't like it. > it don't have to inherit it's a composed widget..; not an extention. >> >> Anyway, I went ahead. I put two FileView on the form. They don't raise >> KeyPress event. It's getting tiring. I don't want to rewrite MyFileView >> just now (I will do, because I need more functionalities). I only need >> to catch Backspace and Enter, so I make a menu voice which has the >> Backspace key as its shortcut. Now the backspace works, but... how the >> hell can I tell which control is focused? The only way I found was to >> catch the GotFocus and LostFocus events, and track the focus by hand. I >> have only three controls, but what about if I had dozens of them? >> Grouping them would group all their events, while I am interested in >> grouping only GotFocus/LostFocus events. >> >> To make it short, I succeded in make it work, and passed to the >> Enter key. The Enter key should invoke the selected file in one of the >> two FileView's. A menu voice has only one shortcut, but the Enter keys >> are two (Gambas calls them Enter and Return). Uhm... no way. Then I try >> to use the Form_Keypress event, but it does not fire - the controls are >> stealing the keys. So, there is no way to do this thing. If a FileView >> does not "activate" a file when the user presses Enter, then you can not: >> >> 1: inherit a new control which does, because you must rename all its >> events > what about observer ? >> 2: use a menu voice to do it, because a menu voice has only one >> shortcut; if you want use more keys, no way > ??? >> 3: use the form KeyPress, which does not fire >> > >> The only way left is to create a new control, and then instantiate a >> FileView inside it. This is not inheritance, because you have to >> replicate all the things you need: events, properties, methods. >> >> Coming from Delphi, I must say the following: >> >> Delphi forms have a KeyPreview property. If you set it, then *all* the >> keypresses are first passed to the form. The form then decides wether to >> ignore the key, or make additional things, to let the key pass, or to >> stop it. >> >> Delphi containers have an ActiveControl property which tells which >> control has the focus. Moreover, every control has a Focused property >> which tells if a specific control has the focus or not. The list of >> things Delphi has and Gambas doesn't is long, but I don't want to >> criticize. I am really missing keyboard and focus control. It seems that >> VisualBasic programmers use the mouse a lot, and neglect keyboards, and >> so do many users, so this could be the reason why Gambas seems to do the >> same. >> >> I don't know Gambas very well, and I could have missed a lot of things. > many >> But it is easy to miss things - in the documentation a "See also" >> section in every topic could really help. > there is >> >> Finally, I must say that I think, and *repeat*, I think, the event >> management is wrong or, at least, it is not as flexible as it could be. >> Once a control raises event, you can not make it stop. > not true ... it's STOP EVENT >>If you group >> controls, you group all their events. > > yes it's an event handler grouping, not a true group ... to doing a > group you need to store objects in an array >> Once you assign a handler to an >> event, you can no more change it. > > wrong : Object.attach(Object, parentclass, "handler name") > >> Probably Gambas is too developed to >> change things at this point but, for who cares or is courious, I will >> explain how events work in Delphi. An event in delphi has an associated >> property which contains the address of a routine to launch. For example, >> if a control has a Click event, then it has a OnClick property. That >> property contains the address of the routine to invoke when the control >> wants to "raise" the Click event. The OnClick property is a procedural >> type, a thing that does not exist in Gambas. > > true ... gambas is a true oriented object language > >> But being a property, the >> main program can disable that event by setting that property to NIL >> (NULL), > > PUBLIC SUB MyList_KeyPress() > STOP EVENT > END > > But it's true that we can't turn off an event > >> or change the handler by setting the property to another value. >> It is possible to associate many controls to the same handler, but only >> the events we want, not *all* the events of *all* the selected controls. >> In fact, events do not exist in delphi, they are simply procedure calls. >> Instead of writing: >> >> raise KeyPress ' Gambas code >> >> which, I suppose, unleashes a textual search for a public subroutine >> named in some correct way, in Delphi one would write: >> >> if OnKeypress<>NIL then OnKeypress(); // procedural call >> >> >> This paradigm is faster, more sure, more flexible, more easy to >> understand. When deriving controls, the derived one can override the >> methods of the ancestor, and still call the inherited one. Gambas has an >> interesting feature which does the opposite: instead of calling the >> ancestor method on demand, it can stop it on demand. It is quite the >> same, I think. > ok got it in fact > > > > >> >> >> Happy holidays to everyone. >> > > to you too > > Fabien > |
|
From: Doriano B. <dor...@fa...> - 2008-08-13 09:09:18
Attachments:
tuxfm-0.0.18.tar.gz
|
I send the file manager I am writing, for anybody could be interested in. For now, navigation is almost complete. It misses a mean to delete bookmarks, because I wanted to delete them by right-clicking on the menu voice, but this is not possible (the mouse right button it is not discerned). Now I can not decide about how to do it. File association seems to work, even if the code is awful. Deleting files works - do it at your own risk... Everything else is under construction. Happy coding to everyone. |
|
From: Doriano B. <dor...@fa...> - 2008-08-13 10:40:16
|
Fabien Bodard ha scritto:
> is this can help you ?
>
> This a simple demo off event management via objerver object that catch
> the event before object.
>
Ok, it works. But, as you can see in my previous message and the
attached source, it was not that my problem. In fact, I already did the
same in MyDirView (I suppose this is the only way to enrich events).
I have several problems with gambas but, nevertheless, I like it. As far
as I have seen until now, it is the only functioning true RAD tool in
linux, and it has several nice things in it. For example, the settings[]
class is amusing, and there are many other good things. Unfortunately it
is still in development, so some features are missing or buggy, like the
GTK system; but this is only question of time. Documentation is
hermetic sometimes, but it can grow and improve.
The only real problem comes from the inheritance from visual basic, I
suppose, which, as many other micro$oft products, is tailored to suit a
market, and not to do things the right way. This is very dangerous,
because a similar product invades the market, cutting away other,
perhaps better, competitors. Then it shapes the mind of the users
(programmers), so the general culture is polluted too.
In this respect, it is a point of distinction that Gambas claims to be
"not a clone of visual basic" and, in fact, it is not a clone. But... I
could be wrong, I don't know visual basic enough, perhaps it should be
better I didn't talk... well, I think event management is wrong. I
suppose this is an inheritance from visual basic, like several others.
Many of them could be good and, if you don't like them, simply you can
avoid them. But others cannot be avoided, and event management is one of
them. I am afraid to see gambas collapse because of a inherent flaw. In
this very case, I have simply the problem that DirView does not raise
the KeyPress event. The first thing you replied to me was "you can
rewrite it". Multiply this reply for every control a user wants to use,
but also wants to improve, and see where all we will go.
To be sure, I just made a test with delphi. I derived a TMyListBox from
TListBox, and overrided the KeyPress event:
TMyListbox = class(TListBox)
procedure keypress(var key: char); override;
end;
procedure TMyListBox.keypress(var key: char);
begin
if key=#13 then begin
addItem('A item', NIL);
exit;
end;
inherited keypress(key);
end;
This code snippet creates a widget class, TMyListBox, which is a ListBox
that adds an item to the list if the user presses enter (key #13). All
the rest is untouched, all the events (Click, DoubleClick, Resize, and
so on) function like before. Don't pay too much attention to the
verbosity of pascal: it comes from the fact that pascal does not require
to have a different file for every different class you want to declare,
so every declaration (the keypress procedure, for example) has to be
associated to its class. In gambas this example could be something like:
' gambas class file
inherits ListBox
public sub ME_KeyPress()
if key.code=key.enter then
me.add("A item")
return
endif
inherited KeyPress ' or "Raise KeyPress", or whatever...
end
This is the crucial point. In gambas this is not possible. I wanted to
derive MyDirView from DirView and only add a couple of things, all the
rest was pretty ok. But I was left with two options:
1 - inherit from DirView, and replicate all its events with a
different name
2 - inherit from TreeView, rewrite all the file related stuff, and
replicate all its events with different names
I chose the second option, because I wanted to modify several things,
but the real problem is events. If they were transparently raised,
unless overridden, the circle would be complete. It would be a quick and
trivial job to create personalized controls to suite every need.
I know what happended to DirView. The programmer created it from
TreeView, and thinked nobody was interested in KeyPress, Expand, and
other events from TreeView. On the other hand, implement them would have
required writing them one by one, with a different name; certainly this
was not appealing...
Dear Fabien,
I am sorry to write this kind of flaming: someone could interpret it as
a complaint. But I think this is an important point to make gambas a
much better than it is now. I don't know if Benoit would read this
message thread, and I know, as said before, that perhaps gambas is too
developed to make this kind of modification. But I would pray the gambas
developers to pay attention, and then decide. If I am wrong, I am sorry.
I will never raise this argument again.
Good day to everybody, and long life to Gambas.
|
|
From: Fabien B. <gam...@gm...> - 2008-08-13 16:15:42
|
2008/8/13 Doriano Blengino <dor...@fa...>:
> Fabien Bodard ha scritto:
>> is this can help you ?
>>
>> This a simple demo off event management via objerver object that catch
>> the event before object.
>>
>
> Ok, it works. But, as you can see in my previous message and the
> attached source, it was not that my problem. In fact, I already did the
> same in MyDirView (I suppose this is the only way to enrich events).
>
> I have several problems with gambas but, nevertheless, I like it. As far
> as I have seen until now, it is the only functioning true RAD tool in
> linux, and it has several nice things in it. For example, the settings[]
> class is amusing, and there are many other good things. Unfortunately it
> is still in development, so some features are missing or buggy, like the
> GTK system; but this is only question of time. Documentation is
> hermetic sometimes, but it can grow and improve.
>
> The only real problem comes from the inheritance from visual basic, I
> suppose, which, as many other micro$oft products, is tailored to suit a
> market, and not to do things the right way. This is very dangerous,
> because a similar product invades the market, cutting away other,
> perhaps better, competitors. Then it shapes the mind of the users
> (programmers), so the general culture is polluted too.
>
> In this respect, it is a point of distinction that Gambas claims to be
> "not a clone of visual basic" and, in fact, it is not a clone. But... I
> could be wrong, I don't know visual basic enough, perhaps it should be
> better I didn't talk... well, I think event management is wrong. I
> suppose this is an inheritance from visual basic, like several others.
> Many of them could be good and, if you don't like them, simply you can
> avoid them. But others cannot be avoided, and event management is one of
> them. I am afraid to see gambas collapse because of a inherent flaw. In
> this very case, I have simply the problem that DirView does not raise
> the KeyPress event. The first thing you replied to me was "you can
> rewrite it". Multiply this reply for every control a user wants to use,
> but also wants to improve, and see where all we will go.
>
> To be sure, I just made a test with delphi. I derived a TMyListBox from
> TListBox, and overrided the KeyPress event:
>
> TMyListbox = class(TListBox)
> procedure keypress(var key: char); override;
> end;
>
> procedure TMyListBox.keypress(var key: char);
> begin
> if key=#13 then begin
> addItem('A item', NIL);
> exit;
> end;
> inherited keypress(key);
> end;
>
> This code snippet creates a widget class, TMyListBox, which is a ListBox
> that adds an item to the list if the user presses enter (key #13). All
> the rest is untouched, all the events (Click, DoubleClick, Resize, and
> so on) function like before. Don't pay too much attention to the
> verbosity of pascal: it comes from the fact that pascal does not require
> to have a different file for every different class you want to declare,
> so every declaration (the keypress procedure, for example) has to be
> associated to its class. In gambas this example could be something like:
>
> ' gambas class file
> inherits ListBox
>
> public sub ME_KeyPress()
> if key.code=key.enter then
> me.add("A item")
> return
> endif
> inherited KeyPress ' or "Raise KeyPress", or whatever...
> end
>
... :-) You are not listening me ... too closed in your mind ?
look :
' gambas class file
inherits ListBox
Private lstObserver as New observer(ME) as "ME"
public sub ME_KeyPress()
if key.code=key.enter then
me.add("A item")
return
endif
'not needed >inherited KeyPress ' or "Raise KeyPress", or
whatever... in fact this happen before the handler event so by default
event is raised
'But you steel can stop it by STOP EVENT keyword :)
end
> This is the crucial point. In gambas this is not possible. I wanted to
> derive MyDirView from DirView and only add a couple of things, all the
> rest was pretty ok. But I was left with two options:
>
> 1 - inherit from DirView, and replicate all its events with a
> different name
> 2 - inherit from TreeView, rewrite all the file related stuff, and
> replicate all its events with different names
>
> I chose the second option, because I wanted to modify several things,
> but the real problem is events. If they were transparently raised,
> unless overridden, the circle would be complete. It would be a quick and
> trivial job to create personalized controls to suite every need.
>
> I know what happended to DirView. The programmer created it from
> TreeView, and thinked nobody was interested in KeyPress, Expand, and
> other events from TreeView. On the other hand, implement them would have
> required writing them one by one, with a different name; certainly this
> was not appealing...
>
> Dear Fabien,
> I am sorry to write this kind of flaming: someone could interpret it as
> a complaint. But I think this is an important point to make gambas a
> much better than it is now. I don't know if Benoit would read this
> message thread, and I know, as said before, that perhaps gambas is too
> developed to make this kind of modification. But I would pray the gambas
> developers to pay attention, and then decide. If I am wrong, I am sorry.
> I will never raise this argument again.
>
> Good day to everybody, and long life to Gambas.
>
>
I think you need to learn Object Oriented Language ... delphi like vb
is a pseudo OO language.
Then learn Gambas better...
And for information ... Benoit Minisini know the gambas language
better than all of us ..; because he is the creator of it ! So ...
listen before repeat the same wrong cristisime (sorry for my english
and my not technical language ..; but i'm just a poor french
vinegrower..
Regards,
Fabien Bodard
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> Gambas-user mailing list
> Gam...@li...
> https://lists.sourceforge.net/lists/listinfo/gambas-user
>
|
|
From: Doriano B. <dor...@fa...> - 2008-08-14 08:24:52
Attachments:
newbutton-0.0.2.tar.gz
|
Fabien Bodard ha scritto: > 2008/8/13 Doriano Blengino <dor...@fa...>: > >> Fabien Bodard ha scritto: >> >>> is this can help you ? >>> >>> This a simple demo off event management via objerver object that catch >>> the event before object. > ... :-) You are not listening me ... too closed in your mind ? > > look : > > > ' gambas class file > inherits ListBox > Private lstObserver as New observer(ME) as "ME" > Sorry Fabien, I really made a lot of mistakes. It's ironic that I made something very similar to your code, a few month ago, in order to test this kind of inheritance. Then I sended the source to Benoit, which commented "I should have used an Observer...". But I used an observer... This is the same case. You sended to me a working example, and I did not notice. You can see the source, if you want. Now that I test it again, it does something strange. It should print in the TextArea "\nClass - enter Try me\nForm Enter Try me", showing that an event traverses first its class, then its parent. Running the program, it only shows the "\nForm Enter Try me", but stepping the source it correctly passes through the two cascading event handlers. It seems that there are two different FMain.taMessages. Surely my fault... > I think you need to learn Object Oriented Language ... delphi like vb > is a pseudo OO language. > Then learn Gambas better... > I sure need to learn. But can you explain to me why delphi is "pseudo OO"? > And for information ... Benoit Minisini know the gambas language > better than all of us ..; because he is the creator of it ! So ... > listen before repeat the same wrong cristisime (sorry for my english > I feel the need to ask to be forgiven again, because I wrote a lot of wrong things (and some truth). It was not criticism, anyway - I told you. I tried to explain what, in my opinion, could have been better for gambas. Then I got totally confused about things I already knew... may be I am getting too old... Anyway, it has been a useful discussion, at least for me... kind of concurrent documentation... :-) Cheers to everybody, Doriano Blengino. |
|
From: Doriano B. <dor...@fa...> - 2008-08-13 08:53:34
|
Fabien Bodard ha scritto:
>> things missing in DirView, so I wrote my MyDirView the way I wanted. It
>> was easy at first, but then I discovered that it is difficult, or at
>> least not clear, how to move the "Current" cursor. I am not sure why,
>> but it does work by setting the Selected property of an item.
>>
I derived MyDirView from TreeView, and wrote a ME_KeyPress event to
manage arrow keys and textual search (i.e., you start to write the name
of the directory you want to reach, and MyDirView select that
directory). There is a SELECT statement that catches arrow keys.
The Left key, for example, should move the Current item to its parent
(the parent directory). After using ME.MoveParent, I need a:
ME.item.Selected = TRUE
because otherwise nothing happens. Later in the same routine I develop
the textual search which, after finding the correct item using MoveFirst
and several MoveBelow, simply returns. And it works! Without setting any
Selected property.
While I am writing I realize that in the first case I STOP the event,
while in the second one I do not. If I STOP in the second case, it does
not work. So, the event handler of TreeView is doing something: if I
stop it, I need to set the Selected property, if I do not stop it, it
perhaps does something similar. Anyway the question is: how to move the
Current item? I mean, the item the user sees as current?
>> other, the same event must be called with four different names. I took a
>> look at the FileView control to see what has been done in there. It
>> receives Click events, and raises Click events. What inside? It does not
>> inherit from ListView or similar. Now I understand why it works, but I
>> don't like it.
>>
> it don't have to inherit it's a composed widget..; not an extention.
>
What is an extension? I suppose a composed widget is one built from
several other widgets. And so? If had to write a MyFileView, I would
inherit from ColumnView, which already have many things I need. But,
apparently, the Gambas mind is different from mine...
>> 1: inherit a new control which does, because you must rename all its
>> events
>>
> what about observer ?
>
I tried that; I didn't succed. May be I missed something, because I was
facing an unexpected problem and tried several ways, in a crescendo of
confusion and frustration. I think, indeed, that an Observer can catch
events that are effectively raised. If an event does not rise, no
Observers can catch it...
>> 2: use a menu voice to do it, because a menu voice has only one
>> shortcut; if you want use more keys, no way
>>
> ???
>
Think: if a control does not raise a KeyPress event, how can I catch
keys? A menu catches shortcuts, which are keys. So you put a menu voice
(a menu item) somewhere, and it will catch a single key (I wanted to
catch the Tab, Enter and Return). Problem is a menu only catch one key,
but I can use three different menu voices, perhaps hidden...
>> Finally, I must say that I think, and *repeat*, I think, the event
>> management is wrong or, at least, it is not as flexible as it could be.
>> Once a control raises event, you can not make it stop.
>>
> not true ... it's STOP EVENT
>
Yes, but where should you write your "STOP EVENT" statement? In a event
handler...
By doing so, you don't really keep the control from raising events;
instead you stop them to be processed, which is different. In a message
some time ago Benoit told me that "events are a cost, so they should be
used only in specialized controls and not for other purposes...".
This is the reason why "events are a cost". They keep to fire, even if
nobody (no code) is interested in them. I have seen some gambas
distribution source code; sometimes a boolean flag is used to
temporarily prevent an event to rise:
public sub TreeView_Expand()
if $bDontRaise then return
' process...
end
If TreeView had a OnExpand property, which tells what subroutine to
invoke on expanding, instead of declaring a $bDontRaise and setting it
to true one could write
TreeView.OnExpand=NULL
>> Once you assign a handler to an
>> event, you can no more change it.
>>
>
> wrong : Object.attach(Object, parentclass, "handler name")
>
Right. I was forgetting this.
>> wants to "raise" the Click event. The OnClick property is a procedural
>> type, a thing that does not exist in Gambas.
>> true ... gambas is a true oriented object language
>>
???
Does it mean that a "true object oriented language" should not have
procedural types?
Delphi (or Kylix, or freepascal, or C++) are true object oriented
language, and they have procedural types.
Well. Now I am going to see that code you courtly sent to me, and then I
will reply.
Last question: what about focus management? How can I know what control
has the input focus?
Thank you - have a nice day.
|
|
From: Benoit M. <ga...@us...> - 2008-08-13 10:39:22
|
On mercredi 13 août 2008, Doriano Blengino wrote: > Fabien Bodard ha scritto: > >> things missing in DirView, so I wrote my MyDirView the way I wanted. It > >> was easy at first, but then I discovered that it is difficult, or at > >> least not clear, how to move the "Current" cursor. I am not sure why, > >> but it does work by setting the Selected property of an item. > > I derived MyDirView from TreeView, and wrote a ME_KeyPress event to > manage arrow keys and textual search (i.e., you start to write the name > of the directory you want to reach, and MyDirView select that > directory). Beware that your textual search only works in ASCII. You must use UTF-8 String class to deal with the UTF-8 string returned by Key.Text. -- Benoit Minisini |
|
From: Benoit M. <ga...@us...> - 2008-08-13 10:36:16
|
On lundi 11 août 2008, Doriano Blengino wrote: > Hello all... > > I am writing a file manager, hybrid between FileRunner and a more > modern one. > > I started with a DirView, and soon discovered that it doesn't raise the > KeyPress event (but the IDE makes you think that). There were other > things missing in DirView, so I wrote my MyDirView the way I wanted. It > was easy at first, but then I discovered that it is difficult, or at > least not clear, how to move the "Current" cursor. The Current property is not writable at the moment in TreeView, ListView and ColumnView. I don't remember if there is a specific reason for that. If not, I will make it writable in Gambas 3. > I am not sure why, > but it does work by setting the Selected property of an item. I failed, > instead, in removing all the children of an item, one by one (there is a > clear() method, but I need to delete them one by one). The "for each ... > in item.children" does not work; it is not the first time I see similar > anomalies, especially while stepping the source. Items are not enumerable, because they are not true objects. Instead, you must use the Move* methods that move an internal cursor. Use the TreeView.Item property to get the item pointed by that internal cursor. > > Writing MyDirView revealed another problem. If in a custom control I > receive the KeyPress event, I can not re-raise it (stack overflow). If "you" (I think "you" mean "an object A") receives an event from an object "B", raising it "again" does not mean anything. Only the object "B" can raise the event again. If you mean that the object A is its own event observer, why would it need to send itself an event? > So I > have to raise another event with a different name. This breaks the > consistency of naming - in a row of four controls, each derived from the > other, the same event must be called with four different names. I took a > look at the FileView control to see what has been done in there. It > receives Click events, and raises Click events. What inside? It does not > inherit from ListView or similar. Now I understand why it works, but I > don't like it. I think you are confusing the sender and the receiver. These Click events are not all the same. > > Anyway, I went ahead. I put two FileView on the form. They don't raise > KeyPress event. It's getting tiring. FileView and DirView are compound controls, they do not inherit TreeView or whatever directly. This is mandatory for the FileView control, as it has actually two different views inside: a ListView and an IconView. You don't see KeyPress event sent by the inside views, for the same reason a Container does not see the KeyPress events sent by its children. I admit this seems a bit stupid from the outside. > I don't want to rewrite MyFileView > just now (I will do, because I need more functionalities). I only need > to catch Backspace and Enter, so I make a menu voice A menu "voice"? What's that? > which has the > Backspace key as its shortcut. Now the backspace works, but... how the > hell can I tell which control is focused? Application.ActiveControl will tell you. > The only way I found was to > catch the GotFocus and LostFocus events, and track the focus by hand. I > have only three controls, but what about if I had dozens of them? > Grouping them would group all their events, while I am interested in > grouping only GotFocus/LostFocus events. > > To make it short, I succeded in make it work, and passed to the > Enter key. The Enter key should invoke the selected file in one of the > two FileView's. A menu voice has only one shortcut, but the Enter keys > are two (Gambas calls them Enter and Return). Uhm... no way. Then I try > to use the Form_Keypress event, but it does not fire - the controls are > stealing the keys. So, there is no way to do this thing. If a FileView > does not "activate" a file when the user presses Enter, then you can not: > > 1: inherit a new control which does, because you must rename all its > events > 2: use a menu voice to do it, because a menu voice has only one > shortcut; if you want use more keys, no way > 3: use the form KeyPress, which does not fire > > The only way left is to create a new control, and then instantiate a > FileView inside it. This is not inheritance, because you have to > replicate all the things you need: events, properties, methods. KeyPress (and other) events emitted by a control are for its event observer(s), not for itself. To catch them, you need to create an Observer object on the control. You can catch the event before it is raised, or just after. If you catch the event before it is raised (it is the default), then you can stop it if you want. For the FileView control, it is more complex as you have to observe the view, which is the child control of FileView. And that view can change. > > Coming from Delphi, I must say the following: > > Delphi forms have a KeyPreview property. If you set it, then *all* the > keypresses are first passed to the form. The form then decides wether to > ignore the key, or make additional things, to let the key pass, or to > stop it. I think this is possible to implement. > > Delphi containers have an ActiveControl property which tells which > control has the focus. See below. > Moreover, every control has a Focused property > which tells if a specific control has the focus or not. I can implement that too. Maybe I will call it "HasFocus" instead. > The list of > things Delphi has and Gambas doesn't is long, but I don't want to > criticize. You are welcome, as I don't know Delphi at all. > I am really missing keyboard and focus control. It seems that > VisualBasic programmers use the mouse a lot, and neglect keyboards, and > so do many users, so this could be the reason why Gambas seems to do the > same. I admit I personnaly neglicted the keyboard when implementing the DirView and FileView controls, but I don't think so in Gambas itself. > > I don't know Gambas very well, and I could have missed a lot of things. > But it is easy to miss things - in the documentation a "See also" > section in every topic could really help. > > Finally, I must say that I think, and *repeat*, I think, the event > management is wrong or, at least, it is not as flexible as it could be. > Once a control raises event, you can not make it stop. If you group > controls, you group all their events. Once you assign a handler to an > event, you can no more change it. Mmm. Not really. Maybe you should first understand that it works differently in Gambas than in Delphi. I suggest you read the three following documentation pages: http://gambasdoc.org/help/doc/object-model http://gambasdoc.org/help/cat/event http://gambasdoc.org/help/comp/gb/observer > Probably Gambas is too developed to > change things at this point but, for who cares or is courious, I will > explain how events work in Delphi. An event in delphi has an associated > property which contains the address of a routine to launch. For example, > if a control has a Click event, then it has a OnClick property. That > property contains the address of the routine to invoke when the control > wants to "raise" the Click event. The OnClick property is a procedural > type, a thing that does not exist in Gambas. But being a property, the > main program can disable that event by setting that property to NIL > (NULL), or change the handler by setting the property to another value. > It is possible to associate many controls to the same handler, but only > the events we want, not *all* the events of *all* the selected controls. > In fact, events do not exist in delphi, they are simply procedure calls. > Instead of writing: > > raise KeyPress ' Gambas code > > which, I suppose, unleashes a textual search for a public subroutine > named in some correct way, in Delphi one would write: > > if OnKeypress<>NIL then OnKeypress(); // procedural call > > > This paradigm is faster, more sure, more flexible, more easy to > understand. When deriving controls, the derived one can override the > methods of the ancestor, and still call the inherited one. Gambas internally almost does the same thing, except that all methods must be members of a same object, the event observer. You are mixing again the object that raises the event with the object that receives it. Apparently, this concept does not exist in Delphi, or it is not clearly visible. Not really object-oriented... :-) Note that you can make an event observer whose class inherits another one and that reimplements the event handler, and that calls the event handler of its inherited class with the SUPER keyword. And note that the textual search for public event handlers is done when the object is attached only. > Gambas has an > interesting feature which does the opposite: instead of calling the > ancestor method on demand, it can stop it on demand. It is quite the > same, I think. The event propagation has nothing to do with inheritance tree. It is just sent to the "Before" observer objects, the event observer, and then the "After" observer objects. The STOP EVENT instruction immediately stops this algorithm. Regards, -- Benoit Minisini |
|
From: Doriano B. <dor...@fa...> - 2008-08-13 15:44:28
|
Benoit Minisini ha scritto:
>> I failed,
>> instead, in removing all the children of an item, one by one (there is a
>> clear() method, but I need to delete them one by one). The "for each ...
>> in item.children" does not work; it is not the first time I see similar
>> anomalies, especially while stepping the source.
>>
>
> Items are not enumerable, because they are not true objects.
>
> Instead, you must use the Move* methods that move an internal cursor. Use the
> TreeView.Item property to get the item pointed by that internal cursor.
>
Sorry - it was my mistake. Actually I didn't use "for each", but this:
ME.MoveTo(path)
DO
IF ME.movechild() THEN BREAK
ME.Item.Delete
ME.MoveTo(path)
LOOP
The idea is to delete children of Path, one by one. It is this example
that does not work, it even dirties the string variable Path. I noticed
that stepping the source sometimes has unwanted side effects, which
disappear when the program is run normally. And, I see now that it can
be written as:
DO
ME.MoveTo(path)
IF ME.movechild() THEN BREAK
ME.Item.Delete
LOOP
>> Writing MyDirView revealed another problem. If in a custom control I
>> receive the KeyPress event, I can not re-raise it (stack overflow).
>>
> If "you" (I think "you" mean "an object A") receives an event from an
> object "B", raising it "again" does not mean anything. Only the object "B"
> can raise the event again.
>
> If you mean that the object A is its own event observer, why would it need to
> send itself an event?
>
When writing code, I project myself into the code and think as I was the
CPU... :-))
So, "I raise an event" should mean "the object we are talking of raises
an event"...
And about sending events to itself... why not? Often I set up a timer
only to posticipate an action (note: *not* to delay it, only to get out
the event handler). For example, I had a problem with deleting a
TabStrip from a Button inside it. The TabStrip refused to Delete()
because it was not empty; so in the event handler of the Button I set up
a timer which, in the next event loop, deletes the TabStrip.
The purpose of the timer is not to delay things, but to posticipate
them. It is a mean to send an event to itself.
> FileView and DirView are compound controls, they do not inherit TreeView or
> whatever directly. This is mandatory for the FileView control, as it has
> actually two different views inside: a ListView and an IconView.
>
> You don't see KeyPress event sent by the inside views, for the same reason a
> Container does not see the KeyPress events sent by its children.
>
> I admit this seems a bit stupid from the outside.
>
I don't understand why DirView does not inherit from TreeView. I looked
at the source, and there is nothing that prevents that.
A DirView is no less than a TreeView; simply, its items are directory
names. A routine to read directory names from file system and put them
in the tree could be the only different thing.
Look at my file manager application, in the MyDirView class. The only
routine which has to do with files is populate(). All the rest is there
because of missing things in TreeView, or because I am not a good
programmer, or because I am not a good documentation reader.
>> I don't want to rewrite MyFileView
>> just now (I will do, because I need more functionalities). I only need
>> to catch Backspace and Enter, so I make a menu voice
>>
>
> A menu "voice"? What's that?
>
A menu item, an object of type Menu, which has a Name, a Caption, a
Shortcut.
Sorry for my naming confusion.
> Application.ActiveControl will tell you.
>
Aaahhhh! Look at http://gambasdoc.org/help/comp/gb/application
Just speaking of Delphi, the Oracle of Delphi would help in such
cases... if you can not find something in the docs, ask the Oracle...
Just joking...
>> Delphi forms have a KeyPreview property. If you set it, then *all* the
>> keypresses are first passed to the form. The form then decides wether to
>> ignore the key, or make additional things, to let the key pass, or to
>> stop it.
>>
> I think this is possible to implement.
>
There are situations where it can help.
>> Moreover, every control has a Focused property
>> which tells if a specific control has the focus or not.
>>
> I can implement that too. Maybe I will call it "HasFocus" instead.
>
To avoid to write duplicates, could be better think twice. Having
Application.ActiveControl already covers this case, perhaps:
if Application.ActiveControl = ControlToTestForFocus then ...
>> Finally, I must say that I think, and *repeat*, I think, the event
>> management is wrong or, at least, it is not as flexible as it could be.
>> Once a control raises event, you can not make it stop. If you group
>> controls, you group all their events. Once you assign a handler to an
>> event, you can no more change it.
>>
> Mmm. Not really. Maybe you should first understand that it works differently
> in Gambas than in Delphi.
>
> http://gambasdoc.org/help/doc/object-model
> http://gambasdoc.org/help/cat/event
> http://gambasdoc.org/help/comp/gb/observer
>
Ok, I read them. The docs do not go deep enough for the speaking we are
making now.
I learned that, with Object.lock(), you can stop a control to send
events. I did not know. Problem is, you disable *all* its events.
With Object.Attach() you can change the event names of a control (all
the events), not a single event handler.
A group of controls can share events - yes: all the events or none of them.
You see, and please take this with friendship, this is not what I call
"flexible".
Looking at DirView source, I see:
$bNoEvent = TRUE
$hTreeView.Clear
...
TreeView_Expand
$bNoEvent = FALSE
This is a clear symptom of lack of flexibility. You have to circumvent
the normal event processing, because it is not flexible enough.
To solve this problem, you had:
- to declare a variable ($bNoEvent) somewhere in the outer scope
- to set/reset that variable (and this is required, because in some
point you want to stop the events)
- to modify the relevant event handler and make it test $bNoEvent
In delphi, the same thing would have reduced to set/reset the
TreeView.OnSelect property, i.e., exactly the only thing we wanted.
Anyway, this particular case is not important - I solved already similar
cases as you did in DirView.
But, please, don't tell me I say this because I am used to delphi and
not to Gambas. This is true only in part...
> You are mixing again the object that raises the event with the object that
> receives it. Apparently, this concept does not exist in Delphi, or it is not
> clearly visible. Not really object-oriented... :-)
>
Ah ah ah...
Please, please, please... give delphi a try, so you will speak knowing
what you are saying.
In this discussion, I win 1,5 to 1, because I know delphi and a little
gambas, you keep saying you don't know delphi. It is true that you know
gambas better than me (and better than everyone else, right?), so may be
I win only 1,5 to 1,4...
Objects and events are two concepts totally unrelated. Tcl/Tk has event
management, and it is not an object language. Turbo pascal was a true
object language, and had no events.
You say half the truth in saying that the event concept is not clearly
visible in delphi. This comes from the fact that delphi is strictly
bound to the windows world, where events are called "messages". Delphi
manages them perfectly, but they are not the best. The power of delphi
is such it can hide this awful thing behind "standard", strong-type
checked, parametrized function calls. Excuse me if this is not enough.
Messages in windows are records (structs in C), having 4 integers in
them. The first integer says what kind of message is, all the rest
depends on what type of message you look at. Those integers can contain
coordinates, key codes, or be pointers to some string in memory, or even
point to some complicated structure (which possibly you have to free,
once used...). These integers sometime are break in words, just for fun.
These messages are sent to the main procedure of a program, directed to
a window handle (in windows, everything is a window). This "WindowProc"
parses that record, and dispatches them to the appropriate window. So,
for a MouseDown event you receive a wonderful:
procedure TForm1.ListBox1MouseDown(Sender: TObject; Button:
TMouseButton; Shift: TShiftState; X, Y: Integer);
which has in the header all the information you need, without going to
see key.xxx, mouse.xxx (external, unrelated variables).
You can not get the "no event data error", in delphi.
The LAST variable used in gambas, here is named Sender (the name is more
appropriate).
Beside the fact that this method is cleaner than in gambas, there is
another advantage: you can call/invoke event handlers as they were
normal subroutines (and they are in fact). You can not do it in gambas,
because the global variables LAST, Key, Mouse are undefined.
This also means that you don't need to raise events - you can invoke
directly the event handler, if you want. But, for the sake of
completeness, I must say that, if you want, you can send messages, and
you can send them in two different ways - normal way, or "post" them,
which means they are queued and processed in the next event loop. There
is also an Idle event, which is missing in gambas (apropos: how about to
implement it?). This event is raised when the application is idle -
useful for background processing.
Delphi is a true object/class language. Gambas is not. How about method
overriding, virtual methods, protected methods, default properties,
published properties, and the list could continue... but probably this
things are unknown for a visual basic programmer (fortunately you know
also C++. How events work in C++?).
Back on your half truth. Events, as known in gambas, do not exist in
delphi. They are simply not needed but, if you want to interface
directly with that monster called windows, then you can use messages
(which are events).
Want to know? Gambas events could be better if they had an associated
property to set. Grouping, disabling, intercepting, all this things
could be done. Gambas events could be better if they carried event
informations along: the pressed key for a keypress, the coordinates,
button and shift state for mousedown, and so on. Why gambas does it not?
Please tell me.
Ok, I am making all the people waste time.
I love gambas, and could love it more. This is all I have to say.
Nice day to everybody.
|
|
From: Benoit M. <ga...@us...> - 2008-08-13 16:11:09
|
On mercredi 13 août 2008, Doriano Blengino wrote: > Benoit Minisini ha scritto: > >> I failed, > >> instead, in removing all the children of an item, one by one (there is a > >> clear() method, but I need to delete them one by one). The "for each ... > >> in item.children" does not work; it is not the first time I see similar > >> anomalies, especially while stepping the source. > > > > Items are not enumerable, because they are not true objects. > > > > Instead, you must use the Move* methods that move an internal cursor. Use > > the TreeView.Item property to get the item pointed by that internal > > cursor. > > Sorry - it was my mistake. Actually I didn't use "for each", but this: > > ME.MoveTo(path) > DO > IF ME.movechild() THEN BREAK > ME.Item.Delete > ME.MoveTo(path) > LOOP > > The idea is to delete children of Path, one by one. It is this example > that does not work, it even dirties the string variable Path. I noticed > that stepping the source sometimes has unwanted side effects, which > disappear when the program is run normally. You should elaborate, as these are clearly bugs: stepping the source should always have no side effects (effect for things that depends on time or window activation/deactivation). > And, I see now that it can > be written as: > > DO > ME.MoveTo(path) > IF ME.movechild() THEN BREAK > ME.Item.Delete > LOOP > > >> Writing MyDirView revealed another problem. If in a custom control I > >> receive the KeyPress event, I can not re-raise it (stack overflow). > > > > If "you" (I think "you" mean "an object A") receives an event from an > > object "B", raising it "again" does not mean anything. Only the object > > "B" can raise the event again. > > > > If you mean that the object A is its own event observer, why would it > > need to send itself an event? > > When writing code, I project myself into the code and think as I was the > CPU... :-)) > So, "I raise an event" should mean "the object we are talking of raises > an event"... > > And about sending events to itself... why not? Often I set up a timer > only to posticipate an action (note: *not* to delay it, only to get out > the event handler). For example, I had a problem with deleting a > TabStrip from a Button inside it. The TabStrip refused to Delete() > because it was not empty; so in the event handler of the Button I set up > a timer which, in the next event loop, deletes the TabStrip. > The purpose of the timer is not to delay things, but to posticipate > them. It is a mean to send an event to itself. OK, but "you" are not sending event to "yourself". The event is sent by the timer. > > > FileView and DirView are compound controls, they do not inherit TreeView > > or whatever directly. This is mandatory for the FileView control, as it > > has actually two different views inside: a ListView and an IconView. > > > > You don't see KeyPress event sent by the inside views, for the same > > reason a Container does not see the KeyPress events sent by its children. > > > > I admit this seems a bit stupid from the outside. > > I don't understand why DirView does not inherit from TreeView. I looked > at the source, and there is nothing that prevents that. No. But when DirView was created, (a few years ago!), Observer didn't exist, and it was one of the first control written in Gambas, and was used for debugging the UserControl control. > A DirView is no less than a TreeView; simply, its items are directory > names. A routine to read directory names from file system and put them > in the tree could be the only different thing. > Look at my file manager application, in the MyDirView class. The only > routine which has to do with files is populate(). All the rest is there > because of missing things in TreeView, or because I am not a good > programmer, or because I am not a good documentation reader. > > >> I don't want to rewrite MyFileView > >> just now (I will do, because I need more functionalities). I only need > >> to catch Backspace and Enter, so I make a menu voice > > > > A menu "voice"? What's that? > > A menu item, an object of type Menu, which has a Name, a Caption, a > Shortcut. > Sorry for my naming confusion. > > > Application.ActiveControl will tell you. > > Aaahhhh! Look at http://gambasdoc.org/help/comp/gb/application Application.ActiveControl is implemented in gb.qt, so you are not looking at the right page. A component can reimplement an already existing class by adding methods, properties... This is like inheritance, but by keeping the same name. > > Just speaking of Delphi, the Oracle of Delphi would help in such > cases... if you can not find something in the docs, ask the Oracle... > Just joking... > > >> Delphi forms have a KeyPreview property. If you set it, then *all* the > >> keypresses are first passed to the form. The form then decides wether to > >> ignore the key, or make additional things, to let the key pass, or to > >> stop it. > > > > I think this is possible to implement. > > There are situations where it can help. > > >> Moreover, every control has a Focused property > >> which tells if a specific control has the focus or not. > > > > I can implement that too. Maybe I will call it "HasFocus" instead. > > To avoid to write duplicates, could be better think twice. Having > Application.ActiveControl already covers this case, perhaps: > > if Application.ActiveControl = ControlToTestForFocus then ... > > >> Finally, I must say that I think, and *repeat*, I think, the event > >> management is wrong or, at least, it is not as flexible as it could be. > >> Once a control raises event, you can not make it stop. If you group > >> controls, you group all their events. Once you assign a handler to an > >> event, you can no more change it. > > > > Mmm. Not really. Maybe you should first understand that it works > > differently in Gambas than in Delphi. > > > > http://gambasdoc.org/help/doc/object-model > > http://gambasdoc.org/help/cat/event > > http://gambasdoc.org/help/comp/gb/observer > > Ok, I read them. The docs do not go deep enough for the speaking we are > making now. > I learned that, with Object.lock(), you can stop a control to send > events. I did not know. Problem is, you disable *all* its events. > With Object.Attach() you can change the event names of a control (all > the events), not a single event handler. > A group of controls can share events - yes: all the events or none of them. > You see, and please take this with friendship, this is not what I call > "flexible". It is less flexible than the Delphi way, but I yet think it is enough. > Looking at DirView source, I see: > > $bNoEvent = TRUE > $hTreeView.Clear > ... > TreeView_Expand > $bNoEvent = FALSE > > This is a clear symptom of lack of flexibility. You have to circumvent > the normal event processing, because it is not flexible enough. > To solve this problem, you had: > > - to declare a variable ($bNoEvent) somewhere in the outer scope > - to set/reset that variable (and this is required, because in some > point you want to stop the events) > - to modify the relevant event handler and make it test $bNoEvent > > In delphi, the same thing would have reduced to set/reset the > TreeView.OnSelect property, i.e., exactly the only thing we wanted. OK. But implementing events the same way as Delphi has a cost that is higher than the management of these specific case that are not very common. > Anyway, this particular case is not important - I solved already similar > cases as you did in DirView. > But, please, don't tell me I say this because I am used to delphi and > not to Gambas. This is true only in part... > > > You are mixing again the object that raises the event with the object > > that receives it. Apparently, this concept does not exist in Delphi, or > > it is not clearly visible. Not really object-oriented... :-) > > Ah ah ah... > Please, please, please... give delphi a try, so you will speak knowing > what you are saying. I didn't say that Delphi is not object-oriented. I just said that the concept of event observer is more object-oriented. :-) > In this discussion, I win 1,5 to 1, because I know delphi and a little > gambas, you keep saying you don't know delphi. It is true that you know > gambas better than me (and better than everyone else, right?), so may be > I win only 1,5 to 1,4... > Objects and events are two concepts totally unrelated. Tcl/Tk has event > management, and it is not an object language. Turbo pascal was a true > object language, and had no events. > You say half the truth in saying that the event concept is not clearly > visible in delphi. This comes from the fact that delphi is strictly > bound to the windows world, where events are called "messages". Delphi > manages them perfectly, but they are not the best. The power of delphi > is such it can hide this awful thing behind "standard", strong-type > checked, parametrized function calls. Excuse me if this is not enough. > Messages in windows are records (structs in C), having 4 integers in > them. The first integer says what kind of message is, all the rest > depends on what type of message you look at. Those integers can contain > coordinates, key codes, or be pointers to some string in memory, or even > point to some complicated structure (which possibly you have to free, > once used...). These integers sometime are break in words, just for fun. > These messages are sent to the main procedure of a program, directed to > a window handle (in windows, everything is a window). This "WindowProc" > parses that record, and dispatches them to the appropriate window. So, > for a MouseDown event you receive a wonderful: > > procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: > TMouseButton; Shift: TShiftState; X, Y: Integer); > > which has in the header all the information you need, without going to > see key.xxx, mouse.xxx (external, unrelated variables). > You can not get the "no event data error", in delphi. > The LAST variable used in gambas, here is named Sender (the name is more > appropriate). > Beside the fact that this method is cleaner than in gambas, there is > another advantage: you can call/invoke event handlers as they were > normal subroutines (and they are in fact). You can not do it in gambas, > because the global variables LAST, Key, Mouse are undefined. > This also means that you don't need to raise events - you can invoke > directly the event handler, if you want. This is true for these special events that use static values only. Otherwise event handlers are public methods like any other public methods, and you can call them from anywhere. > But, for the sake of > completeness, I must say that, if you want, you can send messages, and > you can send them in two different ways - normal way, or "post" them, > which means they are queued and processed in the next event loop. There > is also an Idle event, which is missing in gambas (apropos: how about to > implement it?). This event is raised when the application is idle - > useful for background processing. GTK+ has that, but not QT, so I don't think I can do that. > Delphi is a true object/class language. Gambas is not. How about method > overriding, virtual methods, protected methods, default properties, > published properties, and the list could continue... but probably this > things are unknown for a visual basic programmer (fortunately you know > also C++. How events work in C++?). Maybe you should *really* read the documentation pages I told you. Especially this one: http://gambasdoc.org/help/doc/object-model Gambas has method / property overriding, virtual methods. There is no protected method (what for?), and no default property. But there is a default method, enumerators, array accessors... And class overriding: a Gambas component can reimplement and/or extend an already existing class declared in another component. You can even do that in your own project, by using the EXPORT keyword. For example, if you add a class named TextBox in your project, adds the EXPORT keyword to it, this TextBox class will extend and replace the TextBox control. > Back on your half truth. Events, as known in gambas, do not exist in > delphi. They are simply not needed but, if you want to interface > directly with that monster called windows, then you can use messages > (which are events). Gambas events have nothing to do with X11 events, QT events, GTK+ events or Windows events. There are Gambas events. Some of the Gambas events are raised from a internal GUI event (keyboard, mouse, focus), but not all. > Want to know? Gambas events could be better if they had an associated > property to set. Grouping, disabling, intercepting, all this things > could be done. Gambas events could be better if they carried event > informations along: the pressed key for a keypress, the coordinates, > button and shift state for mousedown, and so on. Why gambas does it not? > Please tell me. I admit that Keyboard and Mouse events accessing global structures is not very beautiful. I did that because it was simpler for the programmer, and because I never meet the need for explicitely calling a mouse or keyboard event handler, unless for doing bad things. :-) > > Ok, I am making all the people waste time. > > I love gambas, and could love it more. This is all I have to say. > > Nice day to everybody. > Regards, -- Benoit Minisini |
|
From: Doriano B. <dor...@fa...> - 2008-08-13 18:06:51
|
Benoit Minisini ha scritto: >> ME.MoveTo(path) >> DO >> IF ME.movechild() THEN BREAK >> ME.Item.Delete >> ME.MoveTo(path) >> LOOP >> >> You should elaborate, as these are clearly bugs: stepping the source should >> always have no side effects (effect for things that depends on time or window >> activation/deactivation). >> I tried again the code and it works, even when stepping the source. Sorry for that - may be it was a GTK bug, or may be I did not recreate the same situation. If it happens again, I will elaborate. >> The TabStrip refused to Delete() >> because it was not empty; so in the event handler of the Button I set up >> a timer which, in the next event loop, deletes the TabStrip. >> The purpose of the timer is not to delay things, but to posticipate >> them. It is a mean to send an event to itself. >> > OK, but "you" are not sending event to "yourself". The event is sent by the > timer. > I did not say that by using a timer I send an event to myself, I said this is a workaround for sending an event to myself. And I talked about this situation in response to your statement "it is useless for an object to send events to itself". >> Aaahhhh! Look at http://gambasdoc.org/help/comp/gb/application >> > Application.ActiveControl is implemented in gb.qt, so you are not looking at > the right page. > Toucheé. Sorry. > A component can reimplement an already existing class by adding methods, > properties... This is like inheritance, but by keeping the same name. > Again, sorry. May be, then, that gambas lacks classic inheritance? :-) >> I learned that, with Object.lock(), you can stop a control to send >> events. I did not know. Problem is, you disable *all* its events. >> With Object.Attach() you can change the event names of a control (all >> the events), not a single event handler. >> A group of controls can share events - yes: all the events or none of them. >> You see, and please take this with friendship, this is not what I call >> "flexible". >> > It is less flexible than the Delphi way, but I yet think it is enough. > May be, may be. Clearly, if I am used to do certain things, soon or later I find they are missing, if they lack. I take this occasion to say that I messed up things when talking about events, and the impossibility to derive a control from another and simply add what it is missing. These things in gambas work - I just made them in my MyDirView... >> $bNoEvent = TRUE >> $hTreeView.Clear >> ... >> TreeView_Expand >> $bNoEvent = FALSE >> >> In delphi, the same thing would have reduced to set/reset the >> TreeView.OnSelect property, i.e., exactly the only thing we wanted. >> > OK. But implementing events the same way as Delphi has a cost that is higher > than the management of these specific case that are not very common. > Perhaps this is specular to what said before. You find that this situation is not very common, because you don't "search" for it, while I do. About the cost... who can say? I don't see why Delphi should have a higher cost, and you don't see why Gambas should have the higher one. A final trial is impossible, I think; but I also think this is of scarce importance. > I didn't say that Delphi is not object-oriented. I just said that the concept > of event observer is more object-oriented. :-) > I cannot catch the point. Because you use C++, and I do not, you know C++ better than me. Can you briefly explain to me how are events managed in C++? Very briefly? >> because the global variables LAST, Key, Mouse are undefined. >> This also means that you don't need to raise events - you can invoke >> directly the event handler, if you want. >> > This is true for these special events that use static values only. Otherwise > event handlers are public methods like any other public methods, and you can > call them from anywhere. > I will try now to explain how a true event management could be implemented. As far as I know, no "normal" language implements them in this way, but someone could citate Erlang, or Python, or other less procedural languages. I could be wrong, may be there exists a true imperative language that does. I don't know. Let's start with an event handler. If the event handler receives all the parameters it needs, it is perfect, because it does not depend on anything outside its scope. Now, how to pass parameters to an event handler? It is easy to call it directly, like Delphi does. It is simply matter of PUSHing all the values to the stack, and then CALL a subroutine. But also, it is not a true event, because true events have to be queueable. So, if we want to "post" an event, we must construct a record (a struct), containing all the parameters the handler expects, and append that stuff somewhere. At some time later, these data are pushed onto the stack and the handler is called. This is what windows does with its messages, but those messages have all the same image - it is up to the handler to decode them and access correctly the single values. This is awful - a true high level language should not permit this. And, in fact, Delphi does not permit this. It hides this awful thing behind pascal syntax. But, with this syntax, you can not enqueue an event. And, as far as I know, nor gambas can. >> There >> is also an Idle event, which is missing in gambas (apropos: how about to >> implement it?). This event is raised when the application is idle - >> useful for background processing. >> > GTK+ has that, but not QT, so I don't think I can do that. > Perhaps this event could be generated by gambas itself, at the end of the event loop, if it was an "empty" loop (i.e., there were no events, no timers to fire, no repaints...). Note that this Idle event is in some respect in contrast to an event-driven application... especially if the application uses threads. I mean - you need background processing? Then use a thread... but threads are complicated (and, yes, Delphi has true threads, just in case you wonder. And, yes, they are object - again, just in case... :-)). >> Delphi is a true object/class language. Gambas is not. How about method >> overriding, virtual methods, protected methods, default properties, >> published properties, and the list could continue... but probably this >> things are unknown for a visual basic programmer (fortunately you know >> also C++. How events work in C++?). >> > Maybe you should *really* read the documentation pages I told you. Especially > this one: http://gambasdoc.org/help/doc/object-model > Well, I went there again. My compliments for the great simplicity used to implement such a complicated matter. This is one of the things for which gambas can be appreciated. But the documentation is simplified too: no mention of the SUPER keyword (I did a textual search). I found its description using the google search function inside the page. > I admit that Keyboard and Mouse events accessing global structures is not very > beautiful. I did that because it was simpler for the programmer, and because > I never meet the need for explicitely calling a mouse or keyboard event > handler, unless for doing bad things. :-) > Uhm... bad things... may be... In regard to "simpler for the programmer"... again... may be... Best salutations to everybody. |