SWT Canvas fails to redraw on Windows but works on Linux - linux

this.canvas = new Canvas(shell, SWT.NO_BACKGROUND);
I'm using a PaintListener:
this.canvas.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
// Draw images
synchronized (imageMarks) {
for (ImageMark mark : Whiteboard.this.imageMarks)
{
Image image = Whiteboard.this.getImage(mark.id);
Point position = ScaledPoint.toSWTPoint(Whiteboard.this.getCanvasSize(), mark.getPosition());
Point bounds = mark.getUnscaledBoundaries(Whiteboard.this.getCanvasSize());
e.gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, position.x, position.y,
bounds.x, bounds.y);
}
}
// Draw pencil marks
synchronized (pencilMarks) {
e.gc.setLineWidth(LINE_WIDTH);
for (double[] line : Whiteboard.this.pencilMarks)
{
Point lastPosPoint = ScaledPoint.toSWTPoint(Whiteboard.this.getCanvasSize(), new ScaledPoint(line[0], line[2]));
Point newPosPoint = ScaledPoint.toSWTPoint(Whiteboard.this.getCanvasSize(), new ScaledPoint(line[1], line[3]));
e.gc.drawLine(lastPosPoint.x, lastPosPoint.y, newPosPoint.x, newPosPoint.y);
}
}
// Draw pointer, assuming it's there
if (pointerMark != null)
{
synchronized (pointerMark) {
Point pos = ScaledPoint.toSWTPoint(Whiteboard.this.getCanvasSize(), pointerMark.getPosition());
if (pointerMark.isFlipped())
e.gc.drawImage(Whiteboard.pointerImageFlipped, pos.x, pos.y);
else
e.gc.drawImage(Whiteboard.pointerImage, pos.x, pos.y);
}
}
}
});
and redrawing the canvas via a canvas.redraw() call. On 64-bit Linux, this seems to be working without any issues, but strangely enough, on 64-bit Windows, nothing ever ends up being erased or redrawn. For example, if the screen is resized, the pencil markings do not resize as well, they just end up being cut out of the screen. When new marks are added (in other words, when the paint listener is called again), the repositioned markings are redrawn on top of the old ones which didn't scale with the window. In other words, I believe the canvas is not being cleared upon canvas.redraw(). Is there a workaround for this?

You are specifying SWT.NO_BACKGROUND which stops the Canvas being cleared before each paint.
If you use SWT.NO_BACKGROUND it is your paint method's responsibility to draw every pixel of the Canvas.
SWT.NO_BACKGROUND JavaDoc:
By default, before a widget paints, the client area is filled with the
current background. When this style is specified, the background is
not filled, and the application is responsible for filling every pixel
of the client area. This style might be used as an alternative to
"double-buffering" in order to reduce flicker. This style does not
mean "transparent" - widgets that are obscured will not draw through.

Related

Background of the control is becoming dark on minimising and maximizing the window

Control background is getting changed after minimizing and maximizing the window.
I want the background to be same and transparent.
This is an ActiveX control. which can be used in multiple projects.
CEdit is the base class for this control on which I have added some extra feature.
I tried setting Bkmode in OnCtlColor and OnCtlColor but it is not working out.
I resolved this by fetching the background color and filling the rec of the control
BOOL CComboBoxCtrl::OnEraseBkgnd(CDC* pDC)
{
COleControl::OnEraseBkgnd(pDC);
RECT rc,rc1;
GetClientRect(&rc);
// Get the color from the parent window
COLORREF crBkgnd = COleControl::AmbientBackColor();
//Fill the rect to overcome the black background issue
pDC->FillSolidRect(&rc,crBkgnd);
if(inputbox != NULL)
inputbox->Invalidate(TRUE);
return S_OK;
}

UI is not fixed on painting the background in VerticalFieldManager in BlackBerry?

I have prepared a screen in which I am allowing user to create an account. as shown in the first image I have used an image(bg_BB.png image) as MainScreen Background, after that i have taken another VFM and painting that white Background (white_bg2.png)on that vertical field manager and ADDING ALL MY FIELD ON THAT VFM.
But the problem arises when the keyboard is pops-up. All the fields apears to be floating over the background as shown in the second pic.
Below is the code which I am using:
Bitmap backGroundImage = Bitmap.getBitmapResource("bg_BB.png");
((VerticalFieldManager) getMainManager()).setBackground(BackgroundFactory.createBitmapBackground(backGroundImage));
final Bitmap tabBackGroundImage = Bitmap.getBitmapResource("white_bg2.png");
_mainVfm = new VerticalFieldManager(Field.USE_ALL_WIDTH) {
protected void paint(Graphics graphics) {
int y = CreateUserAccountScreen.this.getMainManager().getVerticalScroll();
graphics.drawBitmap(0, y,
tabBackGroundImage.getWidth(),
tabBackGroundImage.getHeight(),
tabBackGroundImage,
0, 0 );
super.paint( graphics );
}
};
replace your code with:
Bitmap tabBackGroundImage = Bitmap.getBitmapResource("white_bg2.png");
VerticalFieldManager _mainVfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL |
Manager.VERTICAL_SCROLLBAR|
Manager.USE_ALL_WIDTH);
_mainVfm.setBorder( BorderFactory.createBitmapBorder(
new XYEdges(12,12,12,12), tabBackGroundImage
)
);
make sure that your border image have white background.
i use this method and it works perfectly.

How to clear all the previously drawn graphics in vc++ paint?

I have drawn rectangles in picture box using paint event. When i click clear button. i want the graphics to vanish. i call paint event everytime the mouse moves. What should i do?
Code in paint event:
Graphics^ g = e->Graphics;
float PenWidth = 2;
if(msdwnflag!=-1 && count%2==1)
{
if(selecflag==0)
{
g->DrawRectangle( gcnew Pen( Color::Blue,PenWidth ), RcDraw);
}
else
{
RcDraw.Width = finalMousePos.X- RcDraw.X;
RcDraw.Height = finalMousePos.Y- RcDraw.Y;
g->DrawRectangle( gcnew Pen( Color::Red,PenWidth ), RcDraw);
}
}
If pb is your PictureBox then clear its image to clear all the graphics. Also, You can use a variable (buttonpressed) to check whether it is true (button clear pressed) or false (otherwise)
buttonpressed=1;
pb->Image = nullptr;
pb->Refresh();
In your paint method include all the graphics if Not buttonpressed:
if (buttonpressed != 1){
// all your graphics code
}
When you want the graphics to appear back when you press a button change the buttonpressed value:
buttonpressed=0;
pb->Refresh();
Draw a graphics of the transparent colour. thats wat i finally did. not a gud design but works :)

GTK3 GtkLayout with cairo, cannot get update region

I am trying to draw a GtkLayout using cairo. The layout is huge and I need to get the part that is visible in the container window and update that part only. With GTK2 the expose event data was sufficient to do this. I am not successful with GTK3.
In the function to handle "draw" events, I did the following:
GdkWindow *gdkwin; // window to draw
cairo_region_t *cregion; // update regions
cairo_rectangle_int_t crect; // enclosing rectangle
gdkwin = gtk_layout_get_bin_window(GTK_LAYOUT(layout));
cregion = gdk_window_get_update_area(gdkwin);
cairo_region_get_extents(cregion,&crect);
expy1 = crect.y; // top of update area
expy2 = expy1 + crect.height; // bottom of update area
The problem is that cregion has garbage. Either gdk_window_get_update_area() is buggy or I am not using the right drawing window.
Passing the GtkLayout as follows also does not work (this is the function arg for g_signal_connect):
void draw_function(GtkWidget *layout, cairo_t *cr, void *userdata)
Whatever gets passed is not the GtkLayout from g_signal_connect, but something else.
================= UPDATE ====================
I found a way to do what I want without using GtkLayout.
I am using a GtkDrawingArea inside a viewport.
I can scroll to any window within the large graphic layout
and update that window only. Works well once I figured out
the cryptic docs.
scrwing = gtk_scrolled_window_new(0,0);
gtk_container_add(GTK_CONTAINER(vboxx),scrwing);
drwing = gtk_drawing_area_new();
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwing),drwing);
gtk_scrolled_window_set_policy(SCROLLWIN(scrwing),ALWAYS,ALWAYS);
scrollbar = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrwing));

MonoTouch: How to resize a view.Frame inside Draw override and draw correctly?

the problem I am having it that if inside the UIView Draw override, I change the view frame size, drawing a rectangle is not working as expected.
If I change the view frame size outside of the Draw override, it works fine. Is this an expected behavior or is it a problem with monotouch only?
This is the code I am using:
class ChildView : UIView
{
public override void Draw (RectangleF rect)
{
base.Draw (rect);
CGContext g = UIGraphics.GetCurrentContext();
//adding 30 points to view height
RectangleF rec = new RectangleF(this.Frame.Location,this.Frame.Size);
rec.Height+=30;
RectangleF rec_bounds = new RectangleF(0,0,rec.Width,rec.Height);
this.Frame=rec;
this.Bounds=rec_bounds;
//drawing a red rectangle to the first half of view height
UIColor.Red.SetFill();
RectangleF _rect = new RectangleF(this.Bounds.Location,this.Bounds.Size);
_rect.Height=_rect.Height/2;
g.FillRect(_rect);
}
}
However, the output of this code is this: (it should draw only 30 points red, but it draws 60 points)
Here is a link to download the project to reproduce this issue:
www.grbytes.com\downloads\RectangleDrawProblem.rar
Καλημέρα!
This behavior is expected. If you want to change the view's frame inside the Draw override, do it before getting the current context. That is because the graphics context also has a size and that is the size of the view at the time you are retrieving it.
Also, there is no need to set both the Bounds and the Frame of the view. You can just set either of them in this case.
By the way, I don't think you need to call base.Draw(). According to the Apple documentation, "If you subclass UIView directly, your implementation of this method does not need to call super."

Resources