Help understanding BView and drawing

Hi everyone, can someone help me to understand more about how drawing works in BView? I have read the BeBook and Haiku book sections and feel like I am missing something. or I am just doing it wrong.

what i am doing is use SetViewBitmap to draw a background then I want to draw a square where the mouse is, so of course i have to erase the square whenever the mouse moves. but I have tried everything i can think of to erase the square and nothing works.

FillRect with a color of B_TRANSPARENT_COLOR or rbg_color(255, 255, 255, 0) using B_OP_ALPHA or B_OP_ERASE draws a transparent square but it doesn’t really “erase”.

do the drawing commands like StrokeRect or FillRect draw on a magic layer on top of the ViewBitmap or does it draw directly on the ViewBitmap?
it seems like the only way to “erase” is using Invalidate() with the rectangle i want to erase but then it seems to have other side effects and i saw a thread in this forum about using SetViewBitmap for animation maybe isn’t correct anyway How exactly do I draw to a BDirectWindow? - #11 by X512

I hope this makes sense, i just want to draw something on top of a setViewBitmap and then erase it and redraw when I move the mouse

any help is appreciated

You usually should do all your drawing in BView::Draw method implementation and tell OS changed areas that need to be updated with BView::Invalidate call. Drawing outside of BView::Draw is usually a bad practice and it is significantly slower if multiple draw commands are used.

2 Likes

Welcome to the Haiku community. In addition to what @X512 already said, it’s always a good idea in these situations to post the relevant parts of your code so we can see what you are actually doing. You can post code here on the forum, or even better on some website like GitHub where we can quickly fetch your code and look at it.

Hello, indeed I think you have the wrong mental model of what’s happening. There is no “erasing” and there are no layers that you can draw on top of. The implementation is much simpler.

Your application calls functions that draw directly into the framebuffer. Normally this is done from within your Draw() functione as that allows app_server to decide when your app should redraw, and which area needs to be repainted. The expectation is that when Draw() is called, the application should be able to redraw things from the ground up, as whatever was drawn before is considered discardable (maybe the window was minimized or offscreen, maybe another window was moved above it and erased some things, …).

Still, app_server will do some groundwork for you, typically painting either the view color or the view bitmap, just before it calls your Draw() function.

So, the general flow is:

  • When anything happens that needs your view to update, store the needed information (mouse position, for example) and call Invalidate()
  • app_server will restore the view bitmap or view color, and then call your Draw() function
  • From there you can draw your rectangle (or anything you want) basically starting from a blank canvas
4 Likes

Thank you @X512 and @PulkoMandy this is definitely helpful and makes sense. I will see if I can get this to work

and Bluesky thank you but this is part of artpaint that I am trying to fix so its a lot of code but i guess i couldve tried to post a smaller bit

1 Like

Thanks again this really was super helpful and I think I have it mostly working but I did have to hack up the code a bit to get it to match this philosphy. and now I need to clean it up but it seems like it might work

2 Likes