[haiku-development] Re: Implement Begin- and EndRectTracking() in the app_server

  • From: Vivek Roy <vivekroyandroid@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Tue, 28 Mar 2017 00:47:06 +0530


AFAIR, the drawing engine always works on screen coordinates. I don't
remember if the rectangle is supposed to leave the view, though.


From what I could make sense of, the BPoint 'where' is also based on screen
coordinates. So I just added checks so that for B_TRACK_RECT_CORNER, the
rectangle does not go out of the window. But I could make sure it remains
inside the window frame inside which it originated, not for some view. (I
suppose, windows can have multiple views).


I believe it's okay, but best look for how already existing code does it,
like moving windows around.


I tried, but could not figure out how to implement the ClearTrackingRect()
function. If you could just point me to some code.

Please have a closer look at our coding style guide, and always try not to
let your changes stick out.
Just a couple of things I noticed:
- We usually keep a blank line after the constructor in class definitions.
- if*space*(
- We use camel case variable names: rect_width -> rectWidth, new_left ->
newLeft, etc.
- The opening { from a function always goes to the next line.


I always manage to have some of them. Sorry, about that. I hope I fixed
them now.

Thanks,
Vivek
From 1e143bc6bdd6f430785e90f6cd6f3f4db016ab0c Mon Sep 17 00:00:00 2001
From: Vivek Roy <vivekroyandroid@xxxxxxxxx>
Date: Sun, 26 Mar 2017 21:58:50 +0530
Subject: [PATCH] Implementing BeginRectTracking() and EndRectTracking()

---
 src/servers/app/Desktop.cpp | 100 +++++++++++++++++++++++++++++++++++++++++++-
 src/servers/app/Desktop.h   |   6 +++
 2 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp
index 340df6d..39c1db4 100644
--- a/src/servers/app/Desktop.cpp
+++ b/src/servers/app/Desktop.cpp
@@ -106,6 +106,7 @@ class MouseFilter : public EventFilter {
 public:
        MouseFilter(Desktop* desktop);
 
+       void UpdateTrackingRect(BPoint where, BRect frame);
        virtual filter_result Filter(BMessage* message, EventTarget** _target,
                int32* _viewToken, BMessage* latestMouseMoved);
 
@@ -116,6 +117,9 @@ private:
        int32           fResetClickCount;
        BPoint          fLastClickPoint;
        ClickTarget     fLastClickTarget;
+       bool            fIsTrackingRect;
+       BRect           fTrackedRect;
+       uint32          fTrackedRectHow;
 };
 
 
@@ -248,11 +252,68 @@ MouseFilter::MouseFilter(Desktop* desktop)
        fLastClickModifiers(0),
        fResetClickCount(0),
        fLastClickPoint(),
-       fLastClickTarget()
+       fLastClickTarget(),
+       fIsTrackingRect(false)
 {
 }
 
 
+void
+MouseFilter::UpdateTrackingRect(BPoint where, BRect frame)
+{
+       if (fTrackedRectHow == B_TRACK_WHOLE_RECT) {
+
+               float rectWidth = fTrackedRect.Width(),
+                       rectHeight = fTrackedRect.Height();
+               float newLeft = where.x - (rectWidth / 2),
+                       newTop = where.y - (rectHeight / 2);
+
+               if (newLeft < 0)
+                       newLeft = 0;
+               if (newTop < 0)
+                       newTop = 0;
+
+               fTrackedRect.Set(newLeft, newTop,
+                       newLeft + rectWidth, newTop + rectHeight);
+
+       } else if (fTrackedRectHow == B_TRACK_RECT_CORNER) {
+
+               float newLeft, newTop, newRight, newBottom;
+               BPoint oldLeftTop = fTrackedRect.LeftTop();
+
+               if (where.x < oldLeftTop.x) {
+                       newLeft = where.x;
+                       newRight = oldLeftTop.x;
+               } else {
+                       newLeft = oldLeftTop.x;
+                       newRight = where.x;
+               }
+
+               if (where.y < oldLeftTop.y) {
+                       newTop = where.y;
+                       newBottom = oldLeftTop.y;
+               } else {
+                       newTop = oldLeftTop.y;
+                       newBottom = where.y;
+               }
+
+               BPoint frameLeftTop = frame.LeftTop(),
+                       frameRightBottom = frame.RightBottom();
+
+               if (newLeft < frameLeftTop.x)
+                       newLeft = frameLeftTop.x;
+               if (newTop < frameLeftTop.y)
+                       newTop = frameLeftTop.y;
+               if (newRight > frameRightBottom.x)
+                       newRight = frameRightBottom.x;
+               if (newBottom > frameRightBottom.y)
+                       newBottom = frameRightBottom.y;
+
+               fTrackedRect.Set(newLeft, newTop, newRight, newBottom);
+       }
+}
+
+
 filter_result
 MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* 
_viewToken,
        BMessage* latestMouseMoved)
@@ -315,6 +376,9 @@ MouseFilter::Filter(BMessage* message, EventTarget** 
_target, int32* _viewToken,
                                if (clickCount != 1 && clickTarget != 
fLastClickTarget)
                                        clickCount = 1;
 
+                               UpdateTrackingRect(where, window->Frame());
+                               fDesktop->DrawTrackingRect(window, 
fTrackedRect);
+
                                // update our click count management attributes
                                fResetClickCount = originalClickCount - 
clickCount;
                                fLastClickTarget = clickTarget;
@@ -350,8 +414,25 @@ MouseFilter::Filter(BMessage* message, EventTarget** 
_target, int32* _viewToken,
                                window->MouseMoved(message, where, &viewToken,
                                        latestMouseMoved == NULL || 
latestMouseMoved == message,
                                        false);
+
+                               fDesktop->ClearTrackingRect(window, 
fTrackedRect);
+                               UpdateTrackingRect(where, window->Frame());
+                               fDesktop->DrawTrackingRect(window, 
fTrackedRect);
+
                                fDesktop->NotifyMouseMoved(window, message, 
where);
                                break;
+
+                       case B_BEGIN_TRACK_RECT:
+                               if (message->FindInt64("how", &fTrackedRectHow) 
!= B_OK)
+                                       fTrackedRectHow = B_TRACK_WHOLE_RECT;
+                               if (message->FindRect("rect", &fTrackedRect) != 
B_OK)
+                                       return B_DISPATCH_MESSAGE;
+                               fIsTrackingRect = true;
+                               break;
+
+                       case B_END_TRACK_RECT:
+                               fIsTrackingRect = false;
+                               break;
                }
 
                if (viewToken != B_NULL_TOKEN) {
@@ -914,6 +995,23 @@ Desktop::UnlockDirectScreen(team_id team)
 }
 
 
+void
+Desktop::ClearTrackingRect(Window* window, BRect trackedRect)
+{
+       // erase the old rectangle (trackedRect)
+}
+
+
+void
+Desktop::DrawTrackingRect(Window* window, BRect trackedRect)
+{
+       if (GetDrawingEngine()->LockParallelAccess()) {
+               GetDrawingEngine()->StrokeRect(trackedRect);
+               GetDrawingEngine()->UnlockParallelAccess();
+       }
+}
+
+
 // #pragma mark - Workspaces methods
 
 
diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h
index f46b4c8..43cabe2 100644
--- a/src/servers/app/Desktop.h
+++ b/src/servers/app/Desktop.h
@@ -147,6 +147,12 @@ public:
        virtual void                            ScreenAdded(Screen* screen) {}
        virtual bool                            ReleaseScreen(Screen* screen) { 
return false; }
 
+       // Tracking Rectangle
+                       void                            
ClearTrackingRect(Window* window,
+                                                                       BRect 
trackedRect);
+                       void                            
DrawTrackingRect(Window* window,
+                                                                       BRect 
trackedRect);
+
        // Workspace methods
 
                        void                            SetWorkspaceAsync(int32 
index,
-- 
2.1.4

Other related posts: