More work on selection handling in iOS
Got the selection start and end handle dragging working... The trick was not to call SwWrtShell::SetCursor(), but SwCrsrShell::SetCrsr(). Sounds easy but took a lot of guessing and experimentation to figure out. Anyway, now it does what I had expected it to do a few das ago already. There are glitches, especially in corner cases like if you move the start handle past the end handle or vice versa. more Change-Id: Id6c1d99a4052531789bccf0d48165cfb41b89cfe 9b94c0dd55b04a7b6b3c40654562a9c51fa9b450
This commit is contained in:
@@ -20,6 +20,10 @@ extern "C" {
|
|||||||
// "Implementation" of touch_lo_* functions, called on the LO thread through
|
// "Implementation" of touch_lo_* functions, called on the LO thread through
|
||||||
// the PostUserEvent mechanism. Not called by UI thread code.
|
// the PostUserEvent mechanism. Not called by UI thread code.
|
||||||
|
|
||||||
|
void touch_lo_selection_start_move_impl(const void *documentHandle,
|
||||||
|
int x,
|
||||||
|
int y);
|
||||||
|
|
||||||
void touch_lo_selection_end_move_impl(const void *documentHandle,
|
void touch_lo_selection_end_move_impl(const void *documentHandle,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
|
@@ -113,9 +113,12 @@ void touch_lo_draw_tile(void *context, int contextWidth, int contextHeight, int
|
|||||||
|
|
||||||
void touch_lo_mouse_drag(int x, int y, MLOMouseButtonState state);
|
void touch_lo_mouse_drag(int x, int y, MLOMouseButtonState state);
|
||||||
|
|
||||||
|
// Move the start of the selection to (x,y)
|
||||||
|
void touch_lo_selection_start_move(const void *documentHandle,
|
||||||
|
int x,
|
||||||
|
int y);
|
||||||
|
|
||||||
// Move the end of the selection to (x,y)
|
// Move the end of the selection to (x,y)
|
||||||
// (work in progress, of course there should be a corresponding function
|
|
||||||
// to move the start of the selection, too.)
|
|
||||||
void touch_lo_selection_end_move(const void *documentHandle,
|
void touch_lo_selection_end_move(const void *documentHandle,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
|
@@ -154,71 +154,59 @@
|
|||||||
|
|
||||||
- (void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer
|
- (void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer
|
||||||
{
|
{
|
||||||
|
const int N = self.selectionRectangleCount;
|
||||||
|
|
||||||
static enum { NONE, TOPLEFT, BOTTOMRIGHT } draggedHandle = NONE;
|
static enum { NONE, TOPLEFT, BOTTOMRIGHT } draggedHandle = NONE;
|
||||||
static CGFloat previousX, previousY;
|
static CGPoint previous;
|
||||||
|
static CGPoint dragOffset;
|
||||||
|
|
||||||
CGPoint location = [gestureRecognizer locationInView:self];
|
CGPoint location = [gestureRecognizer locationInView:self];
|
||||||
CGPoint translation = [gestureRecognizer translationInView:self];
|
CGPoint translation = [gestureRecognizer translationInView:self];
|
||||||
|
|
||||||
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
|
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
|
||||||
previousX = previousY = 0;
|
previous = CGPointMake(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPoint delta;
|
CGPoint delta;
|
||||||
delta.x = translation.x - previousX;
|
delta.x = translation.x - previous.x;
|
||||||
delta.y = translation.y - previousY;
|
delta.y = translation.y - previous.y;
|
||||||
|
|
||||||
// NSLog(@"location: (%f,%f) , drag: (%f,%f)", location.x, location.y, delta.x, delta.y);
|
// NSLog(@"location: (%f,%f) , drag: (%f,%f)", location.x, location.y, delta.x, delta.y);
|
||||||
|
|
||||||
previousX = translation.x;
|
previous = translation;
|
||||||
previousY = translation.y;
|
|
||||||
|
|
||||||
if (gestureRecognizer.state == UIGestureRecognizerStateBegan &&
|
if (gestureRecognizer.state == UIGestureRecognizerStateBegan &&
|
||||||
gestureRecognizer.numberOfTouches == 1) {
|
gestureRecognizer.numberOfTouches == 1) {
|
||||||
if (CGRectContainsPoint([self topLeftResizeHandle], location)) {
|
if (CGRectContainsPoint([self topLeftResizeHandle], location)) {
|
||||||
NSLog(@"===> dragging TOPLEFT handle");
|
NSLog(@"===> dragging TOPLEFT handle");
|
||||||
draggedHandle = TOPLEFT;
|
draggedHandle = TOPLEFT;
|
||||||
|
dragOffset.x = location.x - self.selectionRectangles[0].origin.x;
|
||||||
|
dragOffset.y = location.y - self.selectionRectangles[0].origin.y;
|
||||||
} else if (CGRectContainsPoint([self bottomRightResizeHandle], location)) {
|
} else if (CGRectContainsPoint([self bottomRightResizeHandle], location)) {
|
||||||
NSLog(@"===> dragging BOTTOMRIGHT handle");
|
NSLog(@"===> dragging BOTTOMRIGHT handle");
|
||||||
draggedHandle = BOTTOMRIGHT;
|
draggedHandle = BOTTOMRIGHT;
|
||||||
|
dragOffset.x = location.x - self.selectionRectangles[N-1].origin.x;
|
||||||
|
dragOffset.y = location.y - self.selectionRectangles[N-1].origin.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draggedHandle == TOPLEFT) {
|
if (draggedHandle == TOPLEFT) {
|
||||||
const int N = self.selectionRectangleCount;
|
|
||||||
|
|
||||||
CGPoint old = self.selectionRectangles[0].origin;
|
touch_lo_selection_start_move(self.documentHandle,
|
||||||
|
location.x - dragOffset.x, location.y - dragOffset.y);
|
||||||
|
|
||||||
self.selectionRectangles[0].origin = location;
|
|
||||||
self.selectionRectangles[0].size.width -= (location.x - old.x);
|
|
||||||
self.selectionRectangles[0].size.height -= (location.y - old.y);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
touch_lo_selection_attempt_resize(self.documentHandle,
|
|
||||||
self.selectionRectangles,
|
|
||||||
self.selectionRectangleCount);
|
|
||||||
#else
|
|
||||||
touch_lo_tap((self.selectionRectangles[0].origin.x + self.selectionRectangles[N-1].origin.x) / 2,
|
|
||||||
(self.selectionRectangles[0].origin.y + self.selectionRectangles[N-1].origin.y) / 2);
|
|
||||||
|
|
||||||
touch_lo_mouse(self.selectionRectangles[0].origin.x,
|
|
||||||
self.selectionRectangles[0].origin.y,
|
|
||||||
DOWN, NONE);
|
|
||||||
touch_lo_mouse(self.selectionRectangles[N-1].origin.x +
|
|
||||||
self.selectionRectangles[N-1].size.width,
|
|
||||||
self.selectionRectangles[N-1].origin.y +
|
|
||||||
self.selectionRectangles[N-1].size.height,
|
|
||||||
UP, NONE);
|
|
||||||
#endif
|
|
||||||
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
|
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
|
||||||
draggedHandle = NONE;
|
draggedHandle = NONE;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (draggedHandle == BOTTOMRIGHT) {
|
} else if (draggedHandle == BOTTOMRIGHT) {
|
||||||
|
|
||||||
touch_lo_selection_end_move(self.documentHandle, location.x, location.y);
|
touch_lo_selection_end_move(self.documentHandle,
|
||||||
|
location.x - dragOffset.x, location.y - dragOffset.y);
|
||||||
|
|
||||||
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
|
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
|
||||||
draggedHandle = NONE;
|
draggedHandle = NONE;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -262,36 +262,8 @@ void SwSelPaintRects::Show()
|
|||||||
mpCursorOverlay = 0;
|
mpCursorOverlay = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (false)
|
|
||||||
;
|
|
||||||
#endif
|
|
||||||
else if(!empty())
|
else if(!empty())
|
||||||
{
|
{
|
||||||
#if !HAVE_FEATURE_DESKTOP
|
|
||||||
#ifdef IOS
|
|
||||||
const OutputDevice* pOut = GetShell()->GetWin();
|
|
||||||
if ( ! pOut )
|
|
||||||
pOut = GetShell()->GetOut();
|
|
||||||
SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(const_cast<SwCrsrShell*>(GetShell()));
|
|
||||||
if ( pWrtShell )
|
|
||||||
{
|
|
||||||
// Buffer will be deallocated in the UI layer
|
|
||||||
CGRect *rects = (CGRect *) malloc((sizeof(CGRect))*size());
|
|
||||||
for (size_t i = 0; i < size(); ++i)
|
|
||||||
{
|
|
||||||
Point origin = pOut->LogicToPixel((*this)[i].Pos());
|
|
||||||
Size size = pOut->LogicToPixel((*this)[i].SSize());
|
|
||||||
rects[i] = CGRectMake(origin.X(), origin.Y(),
|
|
||||||
size.Width(), size.Height());
|
|
||||||
}
|
|
||||||
// GetShell returns a SwCrsrShell which actually is a SwWrtShell
|
|
||||||
touch_ui_selection_start(MLOSelectionText, pWrtShell, rects, size(), NULL);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Not yet implemented
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
|
SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
|
||||||
rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
|
rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
|
||||||
|
|
||||||
@@ -310,8 +282,38 @@ void SwSelPaintRects::Show()
|
|||||||
|
|
||||||
xTargetOverlay->add(*mpCursorOverlay);
|
xTargetOverlay->add(*mpCursorOverlay);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
const OutputDevice* pOut = GetShell()->GetWin();
|
||||||
|
if ( ! pOut )
|
||||||
|
pOut = GetShell()->GetOut();
|
||||||
|
SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(const_cast<SwCrsrShell*>(GetShell()));
|
||||||
|
if (!empty())
|
||||||
|
{
|
||||||
|
if (pWrtShell)
|
||||||
|
{
|
||||||
|
// Buffer will be deallocated in the UI layer
|
||||||
|
MLORect *rects = (MLORect *) malloc((sizeof(MLORect))*size());
|
||||||
|
for (size_t i = 0; i < size(); ++i)
|
||||||
|
{
|
||||||
|
Point origin = pOut->LogicToPixel((*this)[i].Pos());
|
||||||
|
Size size = pOut->LogicToPixel((*this)[i].SSize());
|
||||||
|
#ifdef IOS
|
||||||
|
rects[i] = CGRectMake(origin.X(), origin.Y(),
|
||||||
|
size.Width(), size.Height());
|
||||||
|
#else
|
||||||
|
// Not yet implemented
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// GetShell returns a SwCrsrShell which actually is a SwWrtShell
|
||||||
|
touch_ui_selection_start(MLOSelectionText, pWrtShell, rects, size(), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
touch_ui_selection_none();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2688,6 +2688,33 @@ static bool lcl_urlOverBackground(SwWrtShell& rSh, const Point& rDocPos)
|
|||||||
|
|
||||||
#if !HAVE_FEATURE_DESKTOP
|
#if !HAVE_FEATURE_DESKTOP
|
||||||
|
|
||||||
|
void touch_lo_selection_start_move_impl(const void *documentHandle,
|
||||||
|
int x,
|
||||||
|
int y)
|
||||||
|
{
|
||||||
|
SwWrtShell *pWrtShell = reinterpret_cast<SwWrtShell*>(const_cast<void*>(documentHandle));
|
||||||
|
|
||||||
|
if (!pWrtShell)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const OutputDevice *pOut = pWrtShell->GetWin();
|
||||||
|
if (!pOut)
|
||||||
|
pOut = pWrtShell->GetOut();
|
||||||
|
|
||||||
|
const Point aDocPos( pOut->PixelToLogic( Point(x, y) ) );
|
||||||
|
|
||||||
|
pWrtShell->ChgCurrPam( aDocPos );
|
||||||
|
|
||||||
|
// Keep mark normally at the start and point at the end,
|
||||||
|
// just exchange for the duration of moving the start.
|
||||||
|
pWrtShell->GetCrsr()->Exchange();
|
||||||
|
{
|
||||||
|
SwMvContext aMvContext( pWrtShell );
|
||||||
|
pWrtShell->SwCrsrShell::SetCrsr( aDocPos );
|
||||||
|
}
|
||||||
|
pWrtShell->GetCrsr()->Exchange();
|
||||||
|
}
|
||||||
|
|
||||||
void touch_lo_selection_end_move_impl(const void *documentHandle,
|
void touch_lo_selection_end_move_impl(const void *documentHandle,
|
||||||
int x,
|
int x,
|
||||||
int y)
|
int y)
|
||||||
@@ -2703,13 +2730,11 @@ void touch_lo_selection_end_move_impl(const void *documentHandle,
|
|||||||
|
|
||||||
const Point aDocPos( pOut->PixelToLogic( Point(x, y) ) );
|
const Point aDocPos( pOut->PixelToLogic( Point(x, y) ) );
|
||||||
|
|
||||||
// SAL _ DEBUG("touch_lo_selection_end_move_impl: " << Point(x, y) << " => " << aDocPos);
|
|
||||||
|
|
||||||
pWrtShell->ChgCurrPam( aDocPos );
|
pWrtShell->ChgCurrPam( aDocPos );
|
||||||
|
|
||||||
{
|
{
|
||||||
SwMvContext aMvContext( pWrtShell );
|
SwMvContext aMvContext( pWrtShell );
|
||||||
pWrtShell->SetCursor( &aDocPos, sal_False );
|
pWrtShell->SwCrsrShell::SetCrsr( aDocPos );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -62,6 +62,12 @@ public:
|
|||||||
|
|
||||||
DECL_LINK( DisplayConfigurationChanged, void* );
|
DECL_LINK( DisplayConfigurationChanged, void* );
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const void *documentHandle;
|
||||||
|
int x, y;
|
||||||
|
} SelectionStartMoveArg;
|
||||||
|
DECL_LINK( SelectionStartMove, SelectionStartMoveArg* );
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const void *documentHandle;
|
const void *documentHandle;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@@ -508,6 +508,32 @@ void touch_lo_keyboard_did_hide()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPL_LINK( IosSalInstance, SelectionStartMove, SelectionStartMoveArg*, pArg )
|
||||||
|
{
|
||||||
|
touch_lo_selection_start_move_impl(pArg->documentHandle, pArg->x, pArg->y);
|
||||||
|
|
||||||
|
delete pArg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void touch_lo_selection_start_move(const void *documentHandle,
|
||||||
|
int x,
|
||||||
|
int y)
|
||||||
|
{
|
||||||
|
IosSalInstance *pInstance = IosSalInstance::getInstance();
|
||||||
|
|
||||||
|
if ( pInstance == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
IosSalInstance::SelectionStartMoveArg *pArg = new IosSalInstance::SelectionStartMoveArg;
|
||||||
|
pArg->documentHandle = documentHandle;
|
||||||
|
pArg->x = x;
|
||||||
|
pArg->y = y;
|
||||||
|
Application::PostUserEvent( LINK( pInstance, IosSalInstance, SelectionStartMove), pArg );
|
||||||
|
}
|
||||||
|
|
||||||
IMPL_LINK( IosSalInstance, SelectionEndMove, SelectionEndMoveArg*, pArg )
|
IMPL_LINK( IosSalInstance, SelectionEndMove, SelectionEndMoveArg*, pArg )
|
||||||
{
|
{
|
||||||
touch_lo_selection_end_move_impl(pArg->documentHandle, pArg->x, pArg->y);
|
touch_lo_selection_end_move_impl(pArg->documentHandle, pArg->x, pArg->y);
|
||||||
|
Reference in New Issue
Block a user