home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d6 / RX275D6.ZIP / Units / Picclip.pas < prev    next >
Pascal/Delphi Source File  |  2001-06-24  |  8KB  |  302 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit PicClip;
  11.  
  12. interface
  13.  
  14. {$I RX.INC}
  15.  
  16. uses Messages, Classes, Controls, Windows, RTLConsts, Graphics;
  17.  
  18. type
  19.  
  20. { TPicClip }
  21.   TCellRange = 1..MaxInt;
  22.  
  23.   TPicClip = class(TComponent)
  24.   private
  25.     FPicture: TPicture;
  26.     FRows: TCellRange;
  27.     FCols: TCellRange;
  28.     FBitmap: TBitmap;
  29.     FMasked: Boolean;
  30.     FMaskColor: TColor;
  31.     FOnChange: TNotifyEvent;
  32.     procedure CheckIndex(Index: Integer);
  33.     function GetCell(Col, Row: Cardinal): TBitmap;
  34.     function GetGraphicCell(Index: Integer): TBitmap;
  35.     function GetDefaultMaskColor: TColor;
  36.     function GetIsEmpty: Boolean;
  37.     function GetCount: Integer;
  38.     function GetHeight: Integer;
  39.     function GetWidth: Integer;
  40.     function IsMaskStored: Boolean;
  41.     procedure PictureChanged(Sender: TObject);
  42.     procedure SetHeight(Value: Integer);
  43.     procedure SetPicture(Value: TPicture);
  44.     procedure SetWidth(Value: Integer);
  45.     procedure SetMaskColor(Value: TColor);
  46.   protected
  47.     procedure AssignTo(Dest: TPersistent); override;
  48.     procedure Changed; dynamic;
  49.   public
  50.     constructor Create(AOwner: TComponent); override;
  51.     destructor Destroy; override;
  52.     procedure Assign(Source: TPersistent); override;
  53.     function GetIndex(Col, Row: Cardinal): Integer;
  54.     procedure Draw(Canvas: TCanvas; X, Y, Index: Integer);
  55.     procedure DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer);
  56.     procedure LoadBitmapRes(Instance: THandle; ResID: PChar);
  57.     property Cells[Col, Row: Cardinal]: TBitmap read GetCell;
  58.     property GraphicCell[Index: Integer]: TBitmap read GetGraphicCell;
  59.     property IsEmpty: Boolean read GetIsEmpty;
  60.     property Count: Integer read GetCount;
  61.   published
  62.     property Cols: TCellRange read FCols write FCols default 1;
  63.     property Height: Integer read GetHeight write SetHeight stored False;
  64.     property Masked: Boolean read FMasked write FMasked default True;
  65.     property Rows: TCellRange read FRows write FRows default 1;
  66.     property Picture: TPicture read FPicture write SetPicture;
  67.     property MaskColor: TColor read FMaskColor write SetMaskColor stored IsMaskStored;
  68.     property Width: Integer read GetWidth write SetWidth stored False;
  69.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  70.   end;
  71.  
  72. implementation
  73.  
  74. {$B-}
  75.  
  76. uses SysUtils, VCLUtils, Consts, RXConst;
  77.  
  78. { TPicClip }
  79.  
  80. constructor TPicClip.Create(AOwner: TComponent);
  81. begin
  82.   inherited Create(AOwner);
  83.   FPicture := TPicture.Create;
  84.   FPicture.OnChange := PictureChanged;
  85.   FBitmap := TBitmap.Create;
  86.   FRows := 1;
  87.   FCols := 1;
  88.   FMaskColor := GetDefaultMaskColor;
  89.   FMasked := True;
  90. end;
  91.  
  92. destructor TPicClip.Destroy;
  93. begin
  94.   FOnChange := nil;
  95.   FPicture.OnChange := nil;
  96.   FBitmap.Free;
  97.   FPicture.Free;
  98.   inherited Destroy;
  99. end;
  100.  
  101. procedure TPicClip.Assign(Source: TPersistent);
  102. begin
  103.   if Source is TPicClip then begin
  104.     with TPicClip(Source) do begin
  105.       Self.FRows := Rows;
  106.       Self.FCols := Cols;
  107.       Self.FMasked := Masked;
  108.       Self.FMaskColor := MaskColor;
  109.       Self.FPicture.Assign(FPicture);
  110.     end;
  111.   end
  112.   else if (Source is TPicture) or (Source is TGraphic) then
  113.     FPicture.Assign(Source)
  114.   else inherited Assign(Source);
  115. end;
  116.  
  117. {$IFDEF WIN32}
  118. type
  119.   THack = class(TImageList);
  120. {$ENDIF}
  121.  
  122. procedure TPicClip.AssignTo(Dest: TPersistent);
  123. {$IFDEF WIN32}
  124. var
  125.   I: Integer;
  126.   SaveChange: TNotifyEvent;
  127. {$ENDIF}
  128. begin
  129.   if (Dest is TPicture) then Dest.Assign(FPicture)
  130.   else if (Dest is TGraphic) and (FPicture.Graphic <> nil) and
  131.     (FPicture.Graphic is TGraphic(Dest).ClassType) then
  132.     Dest.Assign(FPicture.Graphic)
  133. {$IFDEF WIN32}
  134.   else if (Dest is TImageList) and not IsEmpty then begin
  135.     with TImageList(Dest) do begin
  136.       SaveChange := OnChange;
  137.       try
  138.         OnChange := nil;
  139.         Clear;
  140.         Width := Self.Width;
  141.         Height := Self.Height;
  142.         for I := 0 to Self.Count - 1 do begin
  143.           if Self.Masked and (MaskColor <> clNone) then
  144.             TImageList(Dest).AddMasked(GraphicCell[I], MaskColor)
  145.           else TImageList(Dest).Add(GraphicCell[I], nil);
  146.         end;
  147.         Masked := Self.Masked;
  148.       finally
  149.         OnChange := SaveChange;
  150.       end;
  151.       THack(Dest).Change;
  152.     end;
  153.   end
  154. {$ENDIF}
  155.   else inherited AssignTo(Dest);
  156. end;
  157.  
  158. procedure TPicClip.Changed;
  159. begin
  160.   if Assigned(FOnChange) then FOnChange(Self);
  161. end;
  162.  
  163. function TPicClip.GetIsEmpty: Boolean;
  164. begin
  165.   Result := (Picture.Graphic = nil) or Picture.Graphic.Empty;
  166. end;
  167.  
  168. function TPicClip.GetCount: Integer;
  169. begin
  170.   if IsEmpty then Result := 0
  171.   else Result := Cols * Rows;
  172. end;
  173.  
  174. procedure TPicClip.Draw(Canvas: TCanvas; X, Y, Index: Integer);
  175. var
  176.   Image: TGraphic;
  177. begin
  178.   if Index < 0 then Image := Picture.Graphic
  179.   else Image := GraphicCell[Index];
  180.   if (Image <> nil) and not Image.Empty then begin
  181.     if FMasked and (FMaskColor <> clNone) and
  182.       (Picture.Graphic is TBitmap) then
  183.       DrawBitmapTransparent(Canvas, X, Y, TBitmap(Image), FMaskColor)
  184.     else Canvas.Draw(X, Y, Image);
  185.   end;
  186. end;
  187.  
  188. procedure TPicClip.DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer);
  189. var
  190.   X, Y: Integer;
  191. begin
  192.   X := (Rect.Left + Rect.Right - Width) div 2;
  193.   Y := (Rect.Bottom + Rect.Top - Height) div 2;
  194.   Draw(Canvas, X, Y, Index);
  195. end;
  196.  
  197. procedure TPicClip.LoadBitmapRes(Instance: THandle; ResID: PChar);
  198. var
  199.   Bmp: TBitmap;
  200. begin
  201.   Bmp := MakeModuleBitmap(Instance, ResID);
  202.   try
  203.     Picture.Assign(Bmp);
  204.   finally
  205.     Bmp.Free;
  206.   end;
  207. end;
  208.  
  209. procedure TPicClip.CheckIndex(Index: Integer);
  210. begin
  211.   if (Index >= Cols * Rows) or (Index < 0) then
  212. {$IFDEF RX_D3}
  213.     raise EListError.CreateFmt(SListIndexError, [Index]);
  214. {$ELSE}
  215.     raise EListError.CreateFmt('%s (%d)', [LoadStr(SListIndexError), Index]);
  216. {$ENDIF}
  217. end;
  218.  
  219. function TPicClip.GetIndex(Col, Row: Cardinal): Integer;
  220. begin
  221.   Result := Col + (Row * Cols);
  222.   if (Result >= Cols * Rows) or IsEmpty then Result := -1;
  223. end;
  224.  
  225. function TPicClip.GetCell(Col, Row: Cardinal): TBitmap;
  226. begin
  227.   Result := GetGraphicCell(GetIndex(Col, Row));
  228. end;
  229.  
  230. function TPicClip.GetGraphicCell(Index: Integer): TBitmap;
  231. begin
  232.   CheckIndex(Index);
  233.   AssignBitmapCell(Picture.Graphic, FBitmap, Cols, Rows, Index);
  234. {$IFDEF RX_D3}
  235.   if Picture.Graphic is TBitmap then
  236.     if FBitmap.PixelFormat <> pfDevice then
  237.       FBitmap.PixelFormat := TBitmap(Picture.Graphic).PixelFormat;
  238.   FBitmap.TransparentColor := FMaskColor or PaletteMask;
  239.   FBitmap.Transparent := (FMaskColor <> clNone) and Masked;
  240. {$ELSE}
  241.   if Masked and (FMaskColor <> clNone) then
  242.     with FBitmap do
  243.       if not Empty then Canvas.Pixels[0, Height - 1] := FMaskColor;
  244. {$ENDIF}
  245.   Result := FBitmap;
  246. end;
  247.  
  248. function TPicClip.GetDefaultMaskColor: TColor;
  249. begin
  250.   Result := clOlive;
  251.   if (Picture.Graphic <> nil) and (Picture.Graphic is TBitmap) then
  252.     Result := TBitmap(Picture.Graphic).TransparentColor and
  253.       not PaletteMask;
  254. end;
  255.  
  256. function TPicClip.GetHeight: Integer;
  257. begin
  258.   Result := Picture.Height div FRows;
  259. end;
  260.  
  261. function TPicClip.GetWidth: Integer;
  262. begin
  263.   Result := Picture.Width div FCols;
  264. end;
  265.  
  266. function TPicClip.IsMaskStored: Boolean;
  267. begin
  268.   Result := MaskColor <> GetDefaultMaskColor;
  269. end;
  270.  
  271. procedure TPicClip.SetMaskColor(Value: TColor);
  272. begin
  273.   if Value <> FMaskColor then begin
  274.     FMaskColor := Value;
  275.     Changed;
  276.   end;
  277. end;
  278.  
  279. procedure TPicClip.PictureChanged(Sender: TObject);
  280. begin
  281.   FMaskColor := GetDefaultMaskColor;
  282.   if not (csReading in ComponentState) then Changed;
  283. end;
  284.  
  285. procedure TPicClip.SetHeight(Value: Integer);
  286. begin
  287.   if (Value > 0) and (Picture.Height div Value > 0) then
  288.     Rows := Picture.Height div Value;
  289. end;
  290.  
  291. procedure TPicClip.SetWidth(Value: Integer);
  292. begin
  293.   if (Value > 0) and (Picture.Width div Value > 0) then
  294.     Cols := Picture.Width div Value;
  295. end;
  296.  
  297. procedure TPicClip.SetPicture(Value: TPicture);
  298. begin
  299.   FPicture.Assign(Value);
  300. end;
  301.  
  302. end.