Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: How to assign gesturestandard mouvment dynamicaly in c++ XE6



Permlink Replies: 6 - Last Post: Mar 3, 2016 2:07 PM Last Post By: bernard tran
bernard tran

Posts: 31
Registered: 2/24/06
How to assign gesturestandard mouvment dynamicaly in c++ XE6
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 2, 2016 2:30 PM
__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, ClassCore *core) : TTreeView(owner){
Parent = ((TForm3*)owner)->PanelList;
Gm = new TGestureManager(this);
Touch->GestureManager = Gm;
**Gm->StandardGestures += sgRight; ??? // Here, how to assign movment??? [sgRight, sgLeft] ??? <sgRight, sgLeft>**
i've foud no sample, no documentation about this point...
... some code...
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: How to assign gesturestandard mouvment dynamicaly in c++ XE6
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 2, 2016 3:13 PM   in response to: bernard tran in response to: bernard tran
El 02/03/2016 a las 23:30, bernard tran escribió:
__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, ClassCore *core) : TTreeView(owner){
Parent = ((TForm3*)owner)->PanelList;
Gm = new TGestureManager(this);
Touch->GestureManager = Gm;
**Gm->StandardGestures += sgRight; ??? // Here, how to assign movment??? [sgRight, sgLeft] ??? <sgRight, sgLeft>**
i've foud no sample, no documentation about this point...
... some code...

First you must register the controls you want to assign gestures:

	Gm->RegisterControl(Button1);

Then you can assign the gestures to the control:

	Gm->StandardGestures[Button1] = TStandardGestures() << sgRight << sgLeft;

Or add gestures

	Gm->StandardGestures[Button1] = Gm->StandardGestures[Button1] << sgUp << sgDown;


or remove gestures
	Gm->StandardGestures[Button1] = Gm->StandardGestures[Button1] >> sgUp >> sgLeft;
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to assign gesturestandard mouvment dynamicaly in c++ XE6
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 2, 2016 3:36 PM   in response to: Antonio Estevez in response to: Antonio Estevez
Antonio wrote:

First you must register the controls you want to assign gestures:

Gm->RegisterControl(Button1);


Then you can assign the gestures to the control:

Gm->StandardGestures[Button1] = TStandardGestures() << sgRight << sgLeft;

Good catch about having to pass the control pointer to the StandardGestures
property of TGestureManager. I missed that.

However, looking at things closer, I see that TTouchManager has its own StandardGestures
property, which does not require a control pointer (it has an internal FControl
member that is set in the TTouchManager constructor), and which delegates
to TGestureManager if one has been assigned. TTouchManager calls RegisterControl()
when a GestureManager is assigned to it, so the code can be simplified a
little by using the TTouchManager property instead of the TGestureManager
property directly:

__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, ClassCore 
*core)
    : TTreeView(owner)
{
    Parent = ((TForm3*)owner)->PanelList;
    Gm = new TGestureManager(this);
    Touch->GestureManager = Gm;
    //Gm->StandardGestures[this] = TStandardGestures() << sgRight;
    Touch->StandardGestures = TStandardGestures() << sgRight;
}


--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to assign gesturestandard mouvment dynamicaly in c++ XE6
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 2, 2016 3:21 PM   in response to: bernard tran in response to: bernard tran
bernard wrote:

Parent = ((TForm3*)owner)->PanelList;

It is dangerous to assume the Owner is any specific class type. Since you
are already specifying custom constructor parameters anyway, you should add
a new parameter for the desired Parent. Or better, just let the caller assign
whatever Parent it wants after the constructor has exited.

Gm->StandardGestures += sgRight; ??? // Here, how to assign movment???
[sgRight, sgLeft] ??? <sgRight, sgLeft>**

The StandardGestures property is a Set of TStandardGesture enum values.
To add specific values to an existing Set, use the '<<' operator, eg:

Gm->StandardGestures = Gm->StandardGestures << sgRight;


To replace the entire Set, construct a blank Set and then add the desired
values to it, eg:

Gm->StandardGestures = TStandardGestures() << sgRight << sgLeft;


--
Remy Lebeau (TeamB)
bernard tran

Posts: 31
Registered: 2/24/06
Re: How to assign gesturestandard mouvment dynamicaly in c++ XE6
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 3, 2016 11:12 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hello, and thank's for your solutions...

i understand than TGesture can be a global common control for all component who need to be gesture controled, and can register one or many TObject by:
Gm->RegisterControl(a_TObject);

1) Can i use more than one TGestureManager (one by TObject, in order to dynamicaly créate TGestureManager inside a component), or is it better to créate one global TGestureManager and use RegisterControl for each component where control gesture needed?
2) Why this code return always EventInfo.GestureID == 0 ??
... (code inside my treeview component)
Gm = new TGestureManager(this);
Gm->RegisterControl(this);
Gm->StandardGestures[this] = TStandardGestures() << sgRight << sgLeft;
Touch->GestureManager = Gm;
OnGesture = Gesture;
...

void __fastcall ClassTreeViewList::Gesture(TObject *Sender, const TGestureEventInfo &EventInfo, bool &Handled) {
switch (EventInfo.GestureID ) { // At this point, when gesture catched, execute this part of code, but always 0 in EventInfo.GestureID
case sgRight : { if (Selected != NULL) Selected->Expand(false); return; }
case sgLeft : { if (Selected != NULL) Selected->Collapse(true); return; }
}
}

all work fine if i use an existing TGesturemanager comming from the main Form (not dynamic created), linked and register with mytreeview.
... (code inside my treeview component)
Touch->GestureManager = Form3->Gesture;
Touch->GestureManager->RegisterControl(this);
Touch->GestureManager->StandardGestures[this] = TStandardGestures() << sgRight << sgLeft;
OnGesture = Gesture;
...

void __fastcall ClassTreeViewList::Gesture(TObject *Sender, const TGestureEventInfo &EventInfo, bool &Handled) {
switch (EventInfo.GestureID ) {
case sgRight : { if (Selected != NULL) Selected->Expand(false); return; }
case sgLeft : { if (Selected != NULL) Selected->Collapse(true); return; }
}
}
here, EventInfo.GestureID return sgRight ou sgLeft correctly...

3) is this too part of code similar???
a) Gm->RegisterControl(mytreeview); // somewhere in Maincode
b) Touch->GestureManager = Gm; // Inside component eq to this->Touch->GestureManager =Gm;
or may i code both?

4) To symplify...i've try to understand... Can i code Touch = Form3->GestureManager instaed of Touch->GestureManager = Form3->GestureManager ?? (i'm suspicious about that!)

5) for the dangerous code portion:
My code:
__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, ClassCore *core) : TTreeView(owner){
Parent = ((TForm3*)owner)->PanelList;

Your recomendation ??
__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, TPanel *panellist, ClassCore *core) : TTreeView(owner){
Parent = panellist;

This class is spécific for one project, and not for share... i only call this class one time in my code, and i'm sure before calling than TPanel *PanelList exist inside TForm3... it's just because i am too lazzy to pass 2 parameter instead of 1. (but not enough to explain why i'm not so lazzy!!)

just for fun, i've try to code this project in FMX code, but Treeview is realy too slow with 100000 Treeviewitem.... 1 second to populate in vcl.... and i can take 2 or 3 café in FMX before populate end...

Best regards...

b.tran

Edited by: bernard tran on Mar 3, 2016 11:18 AM

Edited by: bernard tran on Mar 3, 2016 11:20 AM

Edited by: bernard tran on Mar 3, 2016 11:23 AM

Edited by: bernard tran on Mar 3, 2016 11:34 AM

Edited by: bernard tran on Mar 3, 2016 12:09 PM

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to assign gesturestandard mouvment dynamicaly in c++ XE6 [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 3, 2016 12:20 PM   in response to: bernard tran in response to: bernard tran
bernard wrote:

i understand than TGesture can be a global common control for all
component who need to be gesture controled, and can register one or
many TObject by:

Gm->RegisterControl(a_TObject);

As I said earlier, each control's individual TTouchManager already registers
its owning control with whatever TGestureManager is assigned to it. You
do not need to register controls manually.

1) Can i use more than one TGestureManager (one by TObject, in order
to dynamicaly créate TGestureManager inside a component)

Technically yes, but I would not advise doing it.

is it better to créate one global TGestureManager and use
RegisterControl for each component where control gesture needed?

It would be best to let the user of your component assign whatever TGestureManager
they want to use, so they can decide whether to share a common TGestureManager
with multiple controls, or not. Your component should not be creating its
own TGestureManager internally at all. Stick with using the properties of
your control's TTouchManager, don't access TGestureManager properties directly.
Let TTouchManager delegate to TGestureManager for you if one has been assigned.

2) Why this code return always EventInfo.GestureID == 0 ??

GestureID 0 is sgiNoGesture. That means there was no actual gesture.

... (code inside my treeview component)
Gm = new TGestureManager(this);
Gm->RegisterControl(this);
Gm->StandardGestures[this] = TStandardGestures() << sgRight <<
sgLeft;
Touch->GestureManager = Gm;

You really need to get rid of all that code, and just use the Touch->StandardGestures
property by itself:

__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, ClassCore 
*core)
    : TTreeView(owner)
{
    Touch->StandardGestures = TStandardGestures() << sgRight << sgLeft;
}


OnGesture = Gesture;

DO NOT make your component assign an event handler to its own OnGesture event.
That prevents users of your component from assigning their own event handlers.
You should instead be overidding the virtual DoGesture() method, which is
called if a user's OnGesture event handler does not handle a given gesture:

protected:
    virtual void __fastcall DoGesture(const TGestureEventInfo &EventInfo, 
bool &Handled);
...
 
void __fastcall ClassTreeViewList::DoGesture(const TGestureEventInfo &EventInfo, 
bool &Handled)
{
    // sgRight and sgLeft are not gesture IDs!  You need to use sgiLeft and 
sgiRight instead...
    switch (EventInfo.GestureID)
    {
        case sgiRight:
        {
            if (Selected != NULL)
                Selected->Expand(false);
            Handled = true;
            return;
        }
        case sgiLeft:
        {
            if (Selected != NULL)
                Selected->Collapse(true);
            Handled = true;
            return;
        }
    }
}


4) To symplify...i've try to understand... Can i code Touch =
Form3->GestureManager instaed of Touch->GestureManager =
Form3->GestureManager ?? (i'm suspicious about that!)

No, you cannot assign a TGestureManager directly to a Touch property, you
must assign it to the Touch->GestureManager property instead.

5) for the dangerous code portion:
My code:
__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner,
ClassCore *core) : TTreeView(owner){
Parent = ((TForm3*)owner)->PanelList;
Your recomendation ??

I already gave you my recommendations for that.

__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner,
TPanel *panellist, ClassCore *core) : TTreeView(owner){
Parent = panellist;

That is one way to do it. The very presence of the core parameter means
ClassTreeViewList must be constructed in code at runtime, so the caller should
be allowed to set whatever Parent it wants, whether that be:

TreeView = new ClassTreeViewList(this, PanelList, core);


Or:

TreeView = new ClassTreeViewList(this, core);
TreeView->Parent = PanelList;


I would suggest the latter.

--
Remy Lebeau (TeamB)
bernard tran

Posts: 31
Registered: 2/24/06
Re: How to assign gesturestandard mouvment dynamicaly in c++ XE6 [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 3, 2016 2:07 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi again...

All work fine now...

following your step:

create class:
TreeView = new ClassTreeViewList(this, core);
TreeView->Parent = PanelList;
TreeView->Touch->GestureManager = Gm;   // Gm is a global component not dynamic in the main form;


ClassTreeView
__fastcall ClassTreeViewList::ClassTreeViewList(TComponent *owner, ClassCore *core) : TTreeView(owner){
	Touch->StandardGestures = TStandardGestures() << sgRight << sgLeft;
        ... some code ...
}


Override DoGesture
void __fastcall ClassTreeViewList::DoGesture(const TGestureEventInfo &EventInfo, bool &Handled) {
	switch (EventInfo.GestureID ) {
		case Controls::sgiRight : {
			... do something ...
			Handled = true;
			return;
		}
		case Controls::sgiLeft  : {
			... do something ...
			Handled = true;
			return;
		}
	}
}


Really thank's for your help.

Best regards:

b.tran
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02