what is considered 0.9.30? Is the Lazarus fix snapshot (0.9.29-295xx) considered 0.9.30 or should this only be used with the 0.9.31 stream?
Are plans for 64 bit?
Active svn link is still https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/virtualtreeview-new/trunk/ ?It's https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/virtualtreeview-new/branches/4.8
Because this source need lclextensions but I read somewhere (on mantis?) that this pachage was included into LCL.
Better.Here it is, i'v replaced all ssCtrl with ssCtrlOS so it must be tested to see if there is no conflicts with other functions
Make a patch (please with only that modification) and send me.
Hi, i'm having very strange behaviour with enabled right click selection, multiselection and associated pop up.
If i right click on an item in the tree my pop up come out, then click on pop up item and when pop up disappears the mouse is in state as i'm still holding left mouse button... (so the mouse pointer is binded in that moment to make a selection with rect) as i still holding left mouse button, but i don't. Sometimes it after pop up disappears it is in drag drop state... As i click somewhere it resets to normal state.
btw. i'v tested that ssCtrlOS has nothing to do with this.
Hi again, i'v found one tricky problem and don't really know how to fix it...
As i can see on Mac scrolling with Magic Mouse or with Trackpad call's WMVScroll and then WMHScroll, and sometimes (i think like every NodeHeight) it calls also CMMouseWheel.
When you use the Mouse Wheel of an external usb mouse it calls only CMMouseWheel.
First of all in WMXScroll, ScrollCode is allways SB_THUMBTRACK in which block tsThumbTracking is set, but SB_ENDSCROLL, in wich tsThumbTracking must be unset, is never called. This cause that when you Scroll by mouse wheel Scrollbars are never updated. To fix this i'v write at the end of DoSetOffsetXY DoStateChange([], [tsThumbTracking]);
But there is another problem... CMMouseWheel never invalidates VirtualStringTree's Rect, so when you scroll it's not updated until you click inside the Rect... So i'v putted an Invalidate at the end of CMMouseWheel XD and this works with CMMouseWheel as charm, but now when i scroll by Touchpad sometimes (look above, every NodeHeight) it calls Invalidate and whole scroll jumps for a sec to the top and then back...
In dtVcl its up to the widgetset draw the dragimageIs this automatic or i must call some function or init something? Because with default options Carbon is not drawing anything...
QuoteAre plans for 64 bit?
The trunk should work with 64bit (not tested by me)
Hi, i make new developments on Mac OS X (found some bug, see bugtracker) and would like to ask, why in DragType dtVCL there is not generated a DragImage? Is there a way to make it work? (have see is source that DoDragging (wich has calls to generate the drag image) is only called if there is a OLE drag)
There's still a scrolbar problem on Carbon where the treeview does not update (at least on horizontal scrolling)Useful update on a 1.5y old thread
I am looking into it right now, if anyone has some ideas they want me to test and report back, let me know!
@MISVTry the following:
Can anyone think of a possible workaround for virtual treeview until a fix is available?
{$IFDEF LCLCarbon}
function SetWindowOrgEx(DC: HDC; NewX, NewY: Integer; OldPoint: PPoint): Boolean;
begin
Result := Boolean(SetViewPortOrgEx(DC, -NewX, -NewY, LPPoint(OldPoint)));
end;
{$ENDIF}
//procedure SetCanvasOrigin(Canvas: TCanvas; X, Y: Integer);
//...
if SrcDevContext.HasTransf then
begin
// TK: later with shear and rotation error here?
SrcDevContext.TransfPoint(XSrc, YSrc);
SrcDevContext.TransfExtent(SrcWidth, SrcHeight);
end;
SrcDCOrigin := SrcDevContext.Offset;
Inc(XSrc, SrcDCOrigin.X);
Inc(YSrc, SrcDCOrigin.Y);
if DstDevContext.HasTransf then
begin
// TK: later with shear and rotation error here?
DstDevContext.TransfPoint(X, Y);
DstDevContext.TransfExtent(Width, Height);
end;
DstDCOrigin := DstDevContext.Offset;
Inc(X, DstDCOrigin.X);
Inc(Y, DstDCOrigin.Y);
TCarbonDeviceContext.StretchDraw
Look at TGtk2WidgetSet.StretchCopyArea method specifically what is done at:
if SrcDevContext.HasTransf then begin // TK: later with shear and rotation error here? SrcDevContext.TransfPoint(XSrc, YSrc); SrcDevContext.TransfExtent(SrcWidth, SrcHeight); end; SrcDCOrigin := SrcDevContext.Offset; Inc(XSrc, SrcDCOrigin.X); Inc(YSrc, SrcDCOrigin.Y); if DstDevContext.HasTransf then begin // TK: later with shear and rotation error here? DstDevContext.TransfPoint(X, Y); DstDevContext.TransfExtent(Width, Height); end; DstDCOrigin := DstDevContext.Offset; Inc(X, DstDCOrigin.X); Inc(Y, DstDCOrigin.Y);
Look at TGtk2WidgetSet.StretchCopyArea in gtk2widgetset.inc file for the manipulations (the changes that are done in XSrc and YSrc) that are done inside it through a call to SrcDevContext.TransfPoint
Try to replicate the behavior of TCarbonDeviceContext.StretchDraw in CarbonCanvas file.
{------------------------------------------------------------------------------
Function: TGtk2WidgetSet.StretchCopyArea
Params: DestDC: The destination devicecontext
X, Y: The left/top corner of the destination rectangle
Width, Height: The size of the destination rectangle
SrcDC: The source devicecontext
XSrc, YSrc: The left/top corner of the source rectangle
SrcWidth, SrcHeight: The size of the source rectangle
Mask: An optional mask
XMask, YMask: Only used if Mask<>nil
Rop: The raster operation to be performed
Returns: True if succesful
The StretchBlt function copies a bitmap from a source rectangle into a
destination rectangle using the specified raster operation. If needed, it
resizes the bitmap to fit the dimensions of the destination rectangle.
Sizing is done according to the stretching mode currently set in the
destination device context.
If SrcDC contains a mask the pixmap will be copied with this transparency.
ToDo:
Mirroring
Extended NonDrawable support (Image, Bitmap, etc)
Scale mask
------------------------------------------------------------------------------}
function TGtk2WidgetSet.StretchCopyArea(DestDC: HDC; X, Y, Width, Height: Integer;
SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer;
Mask: HBITMAP; XMask, YMask: Integer;
Rop: Cardinal): Boolean;
var
SrcDevContext: TGtkDeviceContext absolute SrcDC;
DstDevContext: TGtkDeviceContext absolute DestDC;
TempPixmap: PGdkPixmap;
TempMaskBitmap: PGdkBitmap;
SizeChange, ROpIsSpecial: Boolean;
FlipHorz, FlipVert: Boolean;
//--
// NOTE: lots of sub functions removed here
//--
var
NewSrcWidth: Integer;
NewSrcHeight: Integer;
NewWidth: Integer;
NewHeight: Integer;
SrcDCOrigin: TPoint;
DstDCOrigin: TPoint;
SrcWholeWidth, SrcWholeHeight: integer;
DstWholeWidth, DstWholeHeight: integer;
begin
Result := IsValidDC(DestDC) and IsValidDC(SrcDC);
{$IFDEF VerboseStretchCopyArea}
DebugLn('StretchCopyArea Start '+dbgs(Result));
{$ENDIF}
if not Result then Exit;
if SrcDevContext.HasTransf then
begin
// TK: later with shear and rotation error here?
SrcDevContext.TransfPoint(XSrc, YSrc);
SrcDevContext.TransfExtent(SrcWidth, SrcHeight);
end;
SrcDCOrigin := SrcDevContext.Offset;
Inc(XSrc, SrcDCOrigin.X);
Inc(YSrc, SrcDCOrigin.Y);
if DstDevContext.HasTransf then
begin
// TK: later with shear and rotation error here?
DstDevContext.TransfPoint(X, Y);
DstDevContext.TransfExtent(Width, Height);
end;
DstDCOrigin := DstDevContext.Offset;
Inc(X, DstDCOrigin.X);
Inc(Y, DstDCOrigin.Y);
FlipHorz := Width < 0;
if FlipHorz then
begin
Width := -Width;
X := X - Width;
end;
FlipVert := Height < 0;
if FlipVert then
begin
Height := -Height;
Y := Y - Height;
end;
if (Width = 0) or (Height = 0) then exit;
if (SrcWidth = 0) or (SrcHeight = 0) then exit;
SizeChange := (Width <> SrcWidth) or (Height <> SrcHeight) or FlipVert or FlipHorz;
ROpIsSpecial := (Rop <> SRCCOPY);
if SrcDevContext.Drawable = nil then RaiseSrcDrawableNil;
gdk_window_get_size(PGdkWindow(SrcDevContext.Drawable), @SrcWholeWidth, @SrcWholeHeight);
if DstDevContext.Drawable = nil then RaiseDestDrawableNil;
gdk_window_get_size(PGdkWindow(DstDevContext.Drawable), @DstWholeWidth, @DstWholeHeight);
{$IFDEF VerboseStretchCopyArea}
DebugLn('TGtk2WidgetSet.StretchCopyArea BEFORE CLIPPING X='+dbgs(X),' Y='+dbgs(Y),' Width='+dbgs(Width),' Height='+dbgs(Height),
' XSrc='+dbgs(XSrc)+' YSrc='+dbgs(YSrc)+' SrcWidth='+dbgs(SrcWidth)+' SrcHeight='+dbgs(SrcHeight),
' SrcDrawable=',DbgS(TGtkDeviceContext(SrcDC).Drawable),
' SrcOrigin='+dbgs(SrcDCOrigin),
' DestDrawable='+DbgS(TGtkDeviceContext(DestDC).Drawable),
' DestOrigin='+dbgs(DstDCOrigin),
' Mask='+DbgS(Mask)+' XMask='+dbgs(XMask)+' YMask='+dbgs(YMask),
' SizeChange='+dbgs(SizeChange)+' ROpIsSpecial='+dbgs(ROpIsSpecial),
' DestWhole='+dbgs(DstWholeWidth)+','+dbgs(DstWholeHeight),
' SrcWhole='+dbgs(SrcWholeWidth)+','+dbgs(SrcWholeHeight),
'');
{$ENDIF}
{$IFDEF VerboseGtkToDos}{$note use intersectrect here}{$ENDIF}
if X >= DstWholeWidth then Exit;
if Y >= DstWholeHeight then exit;
if X + Width <= 0 then exit;
if Y + Height <=0 then exit;
if XSrc >= SrcWholeWidth then Exit;
if YSrc >= SrcWholeHeight then exit;
if XSrc + SrcWidth <= 0 then exit;
if YSrc + SrcHeight <=0 then exit;
// gdk does not allow copying areas, party laying out of bounds
// -> clip
// clip src to the left
if (XSrc<0) then begin
NewSrcWidth:=SrcWidth+XSrc;
NewWidth:=((Width*NewSrcWidth) div SrcWidth);
{$IFDEF VerboseStretchCopyArea}
DebugLn('StretchCopyArea Cliping Src to left NewSrcWidth='+dbgs(NewSrcWidth),' NewWidth='+dbgs(NewWidth));
{$ENDIF}
if NewWidth = 0 then exit;
inc(X, Width-NewWidth);
if X >= DstWholeWidth then exit;
XSrc:=0;
SrcWidth := NewSrcWidth;
end;
// clip src to the top
if (YSrc<0) then begin
NewSrcHeight:=SrcHeight+YSrc;
NewHeight:=((Height*NewSrcHeight) div SrcHeight);
{$IFDEF VerboseStretchCopyArea}
DebugLn('StretchCopyArea Cliping Src to top NewSrcHeight='+dbgs(NewSrcHeight),' NewHeight='+dbgs(NewHeight));
{$ENDIF}
if NewHeight = 0 then exit;
inc(Y, Height - NewHeight);
if Y >= DstWholeHeight then exit;
YSrc:=0;
SrcHeight := NewSrcHeight;
end;
// clip src to the right
if (XSrc+SrcWidth>SrcWholeWidth) then begin
NewSrcWidth:=SrcWholeWidth-XSrc;
Width:=((Width*NewSrcWidth) div SrcWidth);
{$IFDEF VerboseStretchCopyArea}
DebugLn('StretchCopyArea Cliping Src to right NewSrcWidth='+dbgs(NewSrcWidth),' NewWidth='+dbgs(Width));
{$ENDIF}
if (Width=0) then exit;
if (X+Width<=0) then exit;
SrcWidth:=NewSrcWidth;
end;
// clip src to the bottom
if (YSrc+SrcHeight>SrcWholeHeight) then begin
NewSrcHeight:=SrcWholeHeight-YSrc;
Height:=((Height*NewSrcHeight) div SrcHeight);
{$IFDEF VerboseStretchCopyArea}
DebugLn('StretchCopyArea Cliping Src to bottom NewSrcHeight='+dbgs(NewSrcHeight),' NewHeight='+dbgs(Height));
{$ENDIF}
if (Height=0) then exit;
if (Y+Height<=0) then exit;
SrcHeight:=NewSrcHeight;
end;
if Mask = 0
then begin
XMask := XSrc;
YMask := YSrc;
end;
// mark temporary scaling/rop buffers as uninitialized
TempPixmap := nil;
TempMaskBitmap := nil;
{$IFDEF VerboseStretchCopyArea}
write('TGtk2WidgetSet.StretchCopyArea AFTER CLIPPING X='+dbgs(X)+' Y='+dbgs(Y)+' Width='+dbgs(Width)+' Height='+dbgs(Height),
' XSrc='+dbgs(XSrc),' YSrc='+dbgs(YSrc)+' SrcWidth='+dbgs(SrcWidth)+' SrcHeight='+dbgs(SrcHeight),
' SrcDrawable='+DbgS(SrcDevContext.Drawable),
' DestDrawable='+DbgS(DstDevContext.Drawable),
' Mask='+DbgS(Mask)+' XMask='+dbgs(XMask)+' YMask='+dbgs(YMask),
' SizeChange='+dbgs(SizeChange)+' ROpIsSpecial='+dbgs(ROpIsSpecial));
write(' ROp=');
case ROp of
SRCCOPY : DebugLn('SRCCOPY');
SRCPAINT : DebugLn('SRCPAINT');
SRCAND : DebugLn('SRCAND');
SRCINVERT : DebugLn('SRCINVERT');
SRCERASE : DebugLn('SRCERASE');
NOTSRCCOPY : DebugLn('NOTSRCCOPY');
NOTSRCERASE : DebugLn('NOTSRCERASE');
MERGECOPY : DebugLn('MERGECOPY');
MERGEPAINT : DebugLn('MERGEPAINT');
PATCOPY : DebugLn('PATCOPY');
PATPAINT : DebugLn('PATPAINT');
PATINVERT : DebugLn('PATINVERT');
DSTINVERT : DebugLn('DSTINVERT');
BLACKNESS : DebugLn('BLACKNESS');
WHITENESS : DebugLn('WHITENESS');
else
DebugLn('???');
end;
{$ENDIF}
{$IFDEF VerboseGtkToDos}{$note tode remove, earlier checks require drawable <> nil}{$ENDIF}
if SrcDevContext.Drawable = nil
then begin
if DstDevContext.Drawable = nil
then
Result := NoDrawableToNoDrawable
else
Result := NoDrawableToDrawable;
end
else begin
if DstDevContext.Drawable = nil
then
Result := DrawableToNoDrawable
else
Result := DrawableToDrawable;
end;
if TempPixmap <> nil
then gdk_pixmap_unref(TempPixmap);
if TempMaskBitmap <> nil
then gdk_pixmap_unref(TempMaskBitmap);
end;
procedure TGtkDeviceContext.TransfPoint(var X1, Y1: Integer);
begin
// to do: put affine transformation here (for all Transf.. methods)
X1 := MulDiv(X1, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Y1 := MulDiv(Y1, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
end;
{------------------------------------------------------------------------------
Method: StretchMaskBlt
Params: X, Y - Left/top corner of the destination rectangle
Width, Height - Size of the destination rectangle
SrcDC - Carbon device context
XSrc, YSrc - Left/top corner of the source rectangle
SrcWidth, SrcHeight - Size of the source rectangle
Mask - mask bitmap
XMask, YMask - Left/top corner of the mask rectangle
Rop - Raster operation to be performed (TODO)
Returns: If the function succeeds
Copies a bitmap from a source rectangle into a destination rectangle using
the specified raster operations. If needed it resizes the bitmap to
fit the dimensions of the destination rectangle. Sizing is done according to
the stretching mode currently set in the destination device context.
TODO: copy from any canvas
ROP
stretch mode (should be set by winapi call in DC (MWE))
------------------------------------------------------------------------------}
function TCarbonDeviceContext.StretchDraw(X, Y, Width, Height: Integer;
SrcDC: TCarbonBitmapContext; XSrc, YSrc, SrcWidth, SrcHeight: Integer;
Msk: TCarbonBitmap; XMsk, YMsk: Integer; Rop: DWORD): Boolean;
var
Image, MskImage: CGImageRef;
SubImage, SubMask: Boolean;
Bitmap: TCarbonBitmap;
LayRect, DstRect: CGRect;
ImgRect: CGRect;
LayerContext: CGContextRef;
Layer: CGLayerRef;
UseLayer: Boolean;
begin
Result := False;
Image := nil;
Bitmap := SrcDC.GetBitmap;
if Bitmap <> nil then Image := Bitmap.CGImage;
if Image = nil then Exit;
DstRect := CGRectMake(X, Y, Abs(Width), Abs(Height));
SubMask := (Msk <> nil)
and (Msk.CGImage <> nil)
and ( (XMsk <> 0)
or (YMsk <> 0)
or (Msk.Width <> SrcWidth)
or (Msk.Height <> SrcHeight));
SubImage := ((Msk <> nil) and (Msk.CGImage <> nil))
or (XSrc <> 0)
or (YSrc <> 0)
or (SrcWidth <> Bitmap.Width)
or (SrcHeight <> Bitmap.Height);
if SubMask then
MskImage := Msk.CreateSubImage(Bounds(XMsk, YMsk, SrcWidth, SrcHeight))
else
if Msk <> nil then MskImage := Msk.CGImage
else MskImage := nil;
if SubImage then
Image := Bitmap.CreateSubImage(Bounds(XSrc, YSrc, SrcWidth, SrcHeight));
UseLayer:=Assigned(MskImage)
or (CGImageGetWidth(Image){%H-}<>SrcWidth)
or (CGImageGetHeight(Image){%H-}<>SrcHeight);
try
if not UseLayer then
begin
// Normal drawing
Result := DrawCGImage(X, Y, Width, Height, Image);
end
else
begin
// use temp layer to mask source image
// todo find a way to mask "hard" when stretching, now some soft remains are visible
LayRect := CGRectMake(0, 0, SrcWidth, SrcHeight);
Layer := CGLayerCreateWithContext(SrcDC.CGContext, LayRect.size, nil);
// the sub-image is out of edges
if (CGImageGetWidth(Image){%H-}<>SrcWidth) or (CGImageGetHeight(Image){%H-}<>SrcHeight) then
begin
with ImgRect do
if XSrc<0 then origin.x:=SrcWidth-CGImageGetWidth(Image) else origin.x:=0;
with ImgRect do
if YSrc<0 then origin.y:=0 else origin.y:=SrcHeight-CGImageGetHeight(Image);
ImgRect.size.width:=CGImageGetWidth(Image);
ImgRect.size.height:=CGImageGetHeight(Image);
end
else
ImgRect:=LayRect;
try
LayerContext := CGLayerGetContext(Layer);
CGContextScaleCTM(LayerContext, 1, -1);
CGContextTranslateCTM(LayerContext, 0, -SrcHeight);
SetCGFillping(LayerContext, Width, Height);
if Assigned(MskImage) then CGContextClipToMask(LayerContext, ImgRect, MskImage);
CGContextDrawImage(LayerContext, ImgRect, Image);
CGContextDrawLayerInRect(CGContext, DstRect, Layer);
Result := True;
finally
CGLayerRelease(Layer);
end;
end;
finally
if SubImage then CGImageRelease(Image);
if SubMask then CGImageRelease(MskImage);
end;
//DebugLn('StretchMaskBlt succeeds: ', Format('Dest %d Src %d X %d Y %d',
// [Integer(CGContext),
// Integer(Image),
// X, Y]));
end;
procedure TCarbonDeviceContext.SetWindowOfs(const AWindowOfs: TPoint);
begin
UpdateContextOfs(AWindowOfs, ViewPortOfs);
end;
procedure TCarbonDeviceContext.UpdateContextOfs(const AWindowOfs, AViewOfs: TPoint);
var
dx, dy: Integer;
begin
if isSamePoint(AWindowOfs, fWindowOfs) and isSamePoint(AViewOfs, fViewPortOfs) then Exit;
GetWindowViewTranslate(FWindowOfs, FViewPortOfs, dx{%H-}, dy{%H-});
CGContextTranslateCTM(CGContext, -dx, -dy);
FWindowOfs := AWindowOfs;
FViewPortOfs := AViewOfs;
GetWindowViewTranslate(FWindowOfs, FViewPortOfs, dx, dy);
CGContextTranslateCTM(CGContext, dx, dy);
end;
Is that mean(underlined) can we use this codes under lazarus ?
The only problem for me is the lack of a mac to test.Found this solution: