Page 1 of 2

DCBROWSE RBSELECT

Posted: Sun Aug 30, 2015 2:57 am
by Tom
I do use DCBROWSE with the RBSELECT clause very often. Unfortunately, RBSELECT (itemRbSelect) fires too late.

I have popup menus connected to the dataareas, or custom handlers which provide a special kind of drag&drop with RbDown. But with RBSELECT, the pointer is not at the right position in this moment, so the WHEN clauses of the popup menus don't react correctly, or the wrong portion of cells is taken with d&d. Any ideas how to set the browse position with RbDown before the event is recognized in the handler?

Re: DCBROWSE RBSELECT

Posted: Sun Aug 30, 2015 6:37 am
by rdonnay
Tom -

Is there a short sample you can give me that I can work with?

Roger

Re: DCBROWSE RBSELECT

Posted: Mon Aug 31, 2015 6:10 am
by Tom
Hi, Roger.

Compile and run this. If you hit the right mouse button in a new (!) line, the debug code inside the handler will show the data from the line where the pointer was before:

Code: Select all

#include "dcdialog.ch"
#include "appevent.ch"
#pragma library ("dclipx.lib")

FUNCTION Main()
LOCAL GetList := {}, GetOptions := {}, oBrowse, aDirectory

aDirectory := Directory()

@ 0,0 DCBROWSE oBrowse DATA aDirectory SIZE 100,20 RBSELECT FIT

DCBROWSECOL ELEMENT 1 Header 'Name' PARENT oBrowse WIDTH 20
DCBROWSECOL ELEMENT 2 Header 'Size' PARENT oBrowse WIDTH 10
DCBROWSECOL ELEMENT 3 Header 'Date' PARENT oBrowse WIDTH 10
DCBROWSECOL ELEMENT 4 Header 'Time' PARENT oBrowse WIDTH 10
DCBROWSECOL ELEMENT 5 Header 'Attrs.' PARENT oBrowse WIDTH 10

DCREAD GUI FIT TITLE 'Test' ;
       HANDLER myHandler REFERENCE @oBrowse

RETURN nil

STATIC FUNCTION myHandler(nEvent, mp1, mp2, oXbp, oDlg, GetList, oBrowse)
IF Valtype(oXbp) = 'O' .and. nEvent == xbeM_RbDown
  DCQDEBUGQUIET oBrowse:ArrayElement, oBrowse:DataSource[DC_BrowseRow(oBrowse),1]
ENDIF
RETURN DCGUI_NONE

PROC AppSys() ; RETURN
To be honest, I don't believe there's a solution for this, since oBrowse:itemRbDown, which is used by your RBSELECT clause, fires to late. But maybe you have an idea for a workaround.

Re: DCBROWSE RBSELECT

Posted: Mon Aug 31, 2015 8:50 am
by rdonnay
To be honest, I don't believe there's a solution for this, since oBrowse:itemRbDown, which is used by your RBSELECT clause, fires to late. But maybe you have an idea for a workaround.
I had a similar problem with one of Bobby Drakos applications and solved the problem using DC_SaveEvents() and DC_RestoreEvents().
I don't know if it will work in this situation but I'll give it a try.

Re: DCBROWSE RBSELECT

Posted: Mon Aug 31, 2015 11:49 am
by rdonnay
I found a workaround that works for me.

Code: Select all

STATIC FUNCTION myHandler(nEvent, mp1, mp2, oXbp, oDlg, GetList, oBrowse)

LOCAL nCell

IF Valtype(oXbp) = 'O' .and. oXbp:isDerivedFrom('XbpCellGroup') .AND. nEvent == xbeM_RbDown
  nCell := oXbp:cellFromPos(mp1)
  oBrowse:itemRbDown( mp1, { oXbp:parent, nCell } )
  oBrowse:forceStable()
  wtf oBrowse:arrayElement
  RETURN DCGUI_IGNORE
ENDIF
RETURN DCGUI_NONE

Re: DCBROWSE RBSELECT

Posted: Tue Sep 01, 2015 12:39 am
by Tom
Thanks, Roger! Works excellent!

If someone uses this: Keep the RBSELECT clause in your DCBROWSE code. This is the adjusted sample:

Code: Select all

#include "dcdialog.ch"
#include "appevent.ch"
#pragma library ("dclipx.lib")

FUNCTION Main()
LOCAL GetList := {}, GetOptions := {}, oBrowse, aDirectory

aDirectory := Directory()

@ 0,0 DCBROWSE oBrowse DATA aDirectory SIZE 100,20 RBSELECT FIT

DCBROWSECOL ELEMENT 1 Header 'Name' PARENT oBrowse WIDTH 20
DCBROWSECOL ELEMENT 2 Header 'Size' PARENT oBrowse WIDTH 10
DCBROWSECOL ELEMENT 3 Header 'Date' PARENT oBrowse WIDTH 10
DCBROWSECOL ELEMENT 4 Header 'Time' PARENT oBrowse WIDTH 10
DCBROWSECOL ELEMENT 5 Header 'Attrs.' PARENT oBrowse WIDTH 10

DCREAD GUI FIT TITLE 'Test' ;
       HANDLER myHandler REFERENCE @oBrowse

RETURN nil

STATIC FUNCTION myHandler(nEvent, mp1, mp2, oXbp, oDlg, GetList, oBrowse)
LOCAL nCell

IF Valtype(oXbp) = 'O' .and. oXbp:isDerivedFrom('XbpCellGroup') .AND. nEvent == xbeM_RbDown
  nCell := oXbp:cellFromPos(mp1)
  oBrowse:itemRbDown( mp1, { oXbp:parent, nCell } )
  oBrowse:forceStable()
ENDIF

IF Valtype(oXbp) = 'O' .and. nEvent == xbeM_RbDown
  DCQDEBUGQUIET oBrowse:ArrayElement, oBrowse:DataSource[DC_BrowseRow(oBrowse),1]
ENDIF
RETURN DCGUI_NONE

PROC AppSys() ; RETURN

Re: DCBROWSE RBSELECT

Posted: Tue Sep 01, 2015 1:26 am
by hz_scotty
@Tom

Your new code works but skip back one line when RB-Down in Browse!
is this ok?

Rogers Version works all correct - i think

Re: DCBROWSE RBSELECT

Posted: Tue Sep 01, 2015 1:35 am
by skiman
Looks as this is the difference between the two:
RETURN DCGUI_IGNORE in Rogers code.

Re: DCBROWSE RBSELECT

Posted: Tue Sep 01, 2015 1:46 am
by Tom
Hi, Chris.

This is because the xbeM_RbDown is recognized two times in the handler - first to set the browse pointer, second to do something with rbdown. This is why I'm doing all this.

By the way: Using the itemRbDown-method manipulates the mp1 array (mouse position). Saving it before and restoring it after that solves this issue. If there would be a menu popup on rbdown after this code, the menu would appear at the wrong position.

Re: DCBROWSE RBSELECT

Posted: Tue Sep 01, 2015 1:58 am
by Tom
Hi, Hans.
Your new code works but skip back one line when RB-Down in Browse!
You're right. Seems that RBSELECT causes itemRbDown to fire again with the wrong position. If RBSELECT is not used, itemRbDown will not fire anyway, since it's only set (it's a slot) if RBSELECT is used.