diff options
author | Graeme Geldenhuys <graemeg@gmail.com> | 2014-08-20 02:11:13 +0100 |
---|---|---|
committer | Graeme Geldenhuys <graemeg@gmail.com> | 2014-08-20 02:11:13 +0100 |
commit | c8acc2c1666015daeb3038c838e5018c0ecd8903 (patch) | |
tree | 5ad2edaf0e5fb6be146491226dca4d915333d80d /src/gui | |
parent | c45010b6370b50f8e6192ddb7dc3d7762c8c29f7 (diff) | |
parent | d0d8573b046e5020d05c86a970d303084de19b7d (diff) | |
download | fpGUI-c8acc2c1666015daeb3038c838e5018c0ecd8903.tar.xz |
Merge branch 'release-1.2' into master
Diffstat (limited to 'src/gui')
33 files changed, 2693 insertions, 389 deletions
diff --git a/src/gui/fpg_animation.pas b/src/gui/fpg_animation.pas index 36972877..468016f8 100644 --- a/src/gui/fpg_animation.pas +++ b/src/gui/fpg_animation.pas @@ -48,7 +48,7 @@ type protected procedure HandlePaint; override; procedure SetEnabled(const AValue: boolean); override; - procedure SetImageFilename(const AValue: TfpgString); virtual; + procedure SetImageFilename(const AValue: TfpgString); overload; // property Interval: integer read FInterval write SetInterval default 50; property ImageFileName: TfpgString read FImageFilename write SetImageFilename; @@ -58,6 +58,9 @@ type public constructor Create(AOwner: TComponent); override; destructor Destroy; override; + procedure ImageFromByteArray(ABmp: Pointer; ASize: longword); overload; + procedure ImageFromByteArray(ABmp: Pointer; ASize: longword; AMaskSample: TPoint); overload; + procedure SetImageFilename(const AValue: TfpgString; AMaskSample: TPoint); overload; end; @@ -121,7 +124,7 @@ end; procedure TfpgBaseImgAnim.HandlePaint; begin - if (FImageFilename = '') or (FImage = nil) then + if (FImage = nil) then Exit; //==> Canvas.BeginDraw; Canvas.Clear(clWindowBackground); @@ -138,6 +141,11 @@ end; procedure TfpgBaseImgAnim.SetImageFilename(const AValue: TfpgString); begin + SetImageFilename(AValue, Point(0,0)); +end; + +procedure TfpgBaseImgAnim.SetImageFilename(const AValue: TfpgString; AMaskSample: TPoint); +begin if FImageFilename = AValue then Exit; //==> @@ -154,7 +162,29 @@ begin FImage := LoadImage_BMP(FImageFilename); if FTransparent then begin - FImage.CreateMaskFromSample(0, 0); + FImage.CreateMaskFromSample(AMaskSample.X, AMaskSample.Y); + FImage.UpdateImage; + end; + RecalcImageWidth; + Repaint; +end; + +procedure TfpgBaseImgAnim.ImageFromByteArray(ABmp: Pointer; ASize: longword); +begin + ImageFromByteArray(ABmp, ASize, Point(0,0)); +end; + +procedure TfpgBaseImgAnim.ImageFromByteArray(ABmp: Pointer; ASize: longword; AMaskSample: TPoint); +begin + if ABmp=nil then + Exit; + + FTimer.Enabled := False; + FImage.Free; + FImage := CreateImage_BMP(ABmp, ASize); + if FTransparent then + begin + FImage.CreateMaskFromSample(AMaskSample.X, AMaskSample.Y); FImage.UpdateImage; end; RecalcImageWidth; diff --git a/src/gui/fpg_basegrid.pas b/src/gui/fpg_basegrid.pas index 51b50408..cbce739f 100644 --- a/src/gui/fpg_basegrid.pas +++ b/src/gui/fpg_basegrid.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -40,6 +40,7 @@ type TfpgGridHeaderStyle = (ghsButton, ghsThin, ghsFlat); TfpgFocusChangeNotify = procedure(Sender: TObject; ARow, ACol: Integer) of object; + TfpgHeaderClick = procedure(Sender: TObject; ACol: Integer) of object; TfpgRowChangeNotify = procedure(Sender: TObject; ARow: Integer) of object; TfpgCanSelectCellEvent = procedure(Sender: TObject; const ARow, ACol: Integer; var ACanSelect: boolean) of object; TfpgDrawCellEvent = procedure(Sender: TObject; const ARow, ACol: Integer; const ARect: TfpgRect; const AFlags: TfpgGridDrawState; var ADefaultDrawing: boolean) of object; @@ -50,12 +51,14 @@ type // Column 2 is special just for testing purposes. Descendant classes will // override that special behavior anyway. + TfpgBaseGrid = class(TfpgWidget) private FColResizing: boolean; FDragPos: integer; // used for column resizing FHeaderStyle: TfpgGridHeaderStyle; FOnDrawCell: TfpgDrawCellEvent; + FOnHeaderClick: TfpgHeaderClick; FResizedCol: integer; // used for column resizing FDefaultColWidth: integer; FDefaultRowHeight: integer; @@ -70,7 +73,6 @@ type FFirstRow: Integer; FFirstCol: Integer; FXOffset: integer; // used for go_SmoothScroll - FMargin: integer; FFont: TfpgFont; FHeaderFont: TfpgFont; FRowSelect: boolean; @@ -88,6 +90,7 @@ type function GetFontDesc: string; function GetHeaderFontDesc: string; function GetTotalColumnWidth: integer; + function GetAdjustedBorderSizes: TRect; procedure HScrollBarMove(Sender: TObject; position: integer); procedure SetFontDesc(const AValue: string); procedure SetHeaderFontDesc(const AValue: string); @@ -103,8 +106,6 @@ type procedure SetShowGrid(const AValue: boolean); procedure SetShowHeader(const AValue: boolean); function VisibleLines: Integer; - function VisibleWidth: integer; - function VisibleHeight: integer; procedure SetFirstRow(const AValue: Integer); procedure SetAlternativeBGColor(const AValue: TfpgColor); procedure SetBorderStyle(AValue: TfpgEditBorderStyle); @@ -132,11 +133,13 @@ type procedure HandleResize(awidth, aheight: TfpgCoord); override; procedure HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean); override; procedure HandleMouseScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); override; + procedure HandleMouseHorizScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); override; procedure HandleMouseMove(x, y: integer; btnstate: word; shiftstate: TShiftState); override; procedure HandleLMouseUp(x, y: integer; shiftstate: TShiftState); override; procedure HandleLMouseDown(x, y: integer; shiftstate: TShiftState); override; procedure HandleRMouseUp(x, y: integer; shiftstate: TShiftState); override; procedure FollowFocus; virtual; + procedure PrepareCells (firstrow, lastrow, firstcol, lastcol : integer); virtual; property AlternateBGColor: TfpgColor read FAlternativeBGColor write SetAlternativeBGColor default clHilite1; property BorderStyle: TfpgEditBorderStyle read FBorderStyle write SetBorderStyle default ebsDefault; property DefaultColWidth: integer read FDefaultColWidth write SetDefaultColWidth default 64; @@ -166,6 +169,7 @@ type property Options: TfpgGridOptions read FOptions write FOptions default []; property OnDrawCell: TfpgDrawCellEvent read FOnDrawCell write FOnDrawCell; property OnFocusChange: TfpgFocusChangeNotify read FOnFocusChange write FOnFocusChange; + property OnHeaderClick: TfpgHeaderClick read FOnHeaderClick write FOnHeaderClick; property OnRowChange: TfpgRowChangeNotify read FOnRowChange write FOnRowChange; property OnCanSelectCell: TfpgCanSelectCellEvent read FOnCanSelectCell write FOnCanSelectCell; public @@ -176,6 +180,9 @@ type procedure BeginUpdate; procedure EndUpdate; procedure MouseToCell(X, Y: Integer; var ACol, ARow: Integer); + function GetClientRect: TfpgRect; override; + function VisibleWidth: integer; + function VisibleHeight: integer; end; @@ -226,6 +233,32 @@ begin Result := Result + ColumnWidth[i]; end; +// Adjust theme borders based on BorderStyle property +function TfpgBaseGrid.GetAdjustedBorderSizes: TRect; +begin + Result := fpgStyle.GetControlFrameBorders; + case BorderStyle of + ebsNone: + begin + Result.Left := 0; + Result.Right := 0; + Result.Top := 0; + Result.Bottom := 0; + end; + ebsDefault: + begin + // do nothing - the theme values are correct + end; + ebsSingle: + begin + Result.Left := 1; + Result.Right := 1; + Result.Top := 1; + Result.Bottom := 1; + end; + end; +end; + procedure TfpgBaseGrid.SetFontDesc(const AValue: string); begin FFont.Free; @@ -528,7 +561,7 @@ begin hh := 0; if ShowHeader then hh := hh + FHeaderHeight+1; - Result := (Height - (2*FMargin) - hh) div FDefaultRowHeight; + Result := (GetClientRect.Height - hh) div FDefaultRowHeight; end; function TfpgBaseGrid.VisibleWidth: integer; @@ -536,10 +569,10 @@ var sw: integer; begin if FVScrollBar.Visible then - sw := FVScrollBar.Width-1 + sw := FVScrollBar.Width else sw := 0; - Result := Width - (FMargin*2) - sw; + Result := GetClientRect.Width - sw end; function TfpgBaseGrid.VisibleHeight: integer; @@ -547,10 +580,10 @@ var sw: integer; begin if FHScrollBar.Visible then - sw := FHScrollBar.Height-1 + sw := FHScrollBar.Height else sw := 0; - Result := Height - (FMargin*2) - sw; + Result := GetClientRect.Height - sw; end; procedure TfpgBaseGrid.SetFirstRow(const AValue: Integer); @@ -585,76 +618,186 @@ var VHeight: integer; vw: integer; cw: integer; + vl: integer; i: integer; x: integer; -begin - VHeight := Height - 4; - HWidth := Width - 4; - - vw := VisibleWidth; - cw := 0; - for i := 0 to ColumnCount-1 do - cw := cw + ColumnWidth[i]; - - // This needs improving while resizing - if cw > vw then - FHScrollBar.Visible := not (FScrollBarStyle in [ssNone, ssVertical]) - else + hmax: integer; + vmax: integer; + Hfits, showH : boolean; + Vfits, showV : boolean; + crect: TfpgRect; + borders: TRect; + + procedure hideScrollbar (sb : TfpgScrollBar); begin - FHScrollBar.Visible := False; - FFirstCol := 0; - FXOffset := 0; + with sb do + if Visible then + begin + Visible := False; + UpdateWindowPosition; + end; end; - // This needs improving while resizing - if (RowCount > VisibleLines) then - FVScrollBar.Visible := not (FScrollBarStyle in [ssNone, ssHorizontal]) - else + procedure getVisWidth; begin - FVScrollBar.Visible := False; - FFirstRow := 0; + if showV then + vw := HWidth - (FVScrollBar.Width-1) + else + vw := HWidth; + Hfits := vw >= cw; end; - if FVScrollBar.Visible then + procedure getVisLines; + var + hh : integer; // header height begin + hh := 0; + if ShowHeader then + inc (hh, FHeaderHeight+1); + if showH then + inc (hh, FHScrollBar.Height); + vl := (VHeight - hh) div FDefaultRowHeight; + Vfits := vl >= RowCount; + end; + +begin + // if we don't want any scrollbars, hide them and exit + if FScrollBarStyle = ssNone then + begin + hideScrollbar(FHScrollBar); + hideScrollbar(FVScrollBar); + exit; + end; + + borders := GetAdjustedBorderSizes; + // preliminary width/height calculations + crect := GetClientRect; + VHeight := crect.Height; + HWidth := crect.Width; + cw := 0; + for i := 0 to ColumnCount-1 do + cw := cw + ColumnWidth[i]; + showV := False; + showH := False; + getVisWidth; + getVisLines; + + // determine whether to show scrollbars for different configurations + case FScrollBarStyle of + ssHorizontal: + begin + hideScrollbar (FVScrollBar); + if not Hfits then + begin + showH := true; + getVisLines; + end; + end; + ssVertical: + begin + hideScrollbar (FHScrollBar); + if not Vfits then + begin + showV := true; + getVisWidth; + end; + end; + ssAutoBoth: + if not Vfits then + begin + showV := true; + getVisWidth; + if not Hfits then + begin + showH := true; + getVisLines; + getVisWidth; + end; + end + else if not Hfits then + begin + showH := true; + getVisLines; + if not Vfits then + begin + showV := true; + getVisWidth; + getVisLines; + end; + end; + end; + + // set the scrollbar width/height space + if showV then Dec(HWidth, FVScrollBar.Width); - FVScrollBar.Min := 0; + if showH then + Dec(VHeight, FHScrollBar.Height); + + // show or hide the scrollbars + + if showV then + begin + FVScrollBar.Visible := true; + FVScrollBar.Min := 0; if RowCount > 0 then FVScrollBar.SliderSize := VisibleLines / RowCount else FVScrollBar.SliderSize := 0; - FVScrollBar.Max := RowCount-VisibleLines; - FVScrollBar.Position := FFirstRow; + vmax := RowCount - VisibleLines; + if FFirstRow > vmax then + FFirstRow := vmax; + FVScrollBar.Max := vmax; + FVScrollBar.Position := FFirstRow; FVScrollBar.RepaintSlider; + FVScrollBar.Top := borders.Top; + FVScrollBar.Left := Width - FVScrollBar.Width - borders.Right; + FVScrollBar.Height := VHeight; + end + else + begin + FVScrollBar.Visible := false; + if Vfits then + FFirstRow := 0; + // if vertical doesn't fit and no scrollbar, do not change firstrow end; - - if FHScrollBar.Visible then + + if showH then begin - Dec(VHeight, FHScrollBar.Height); + FHScrollBar.Visible := true; FHScrollBar.Min := 0; if go_SmoothScroll in FOptions then begin - FHScrollBar.Max := cw - vw; + hmax := cw - vw; + FHScrollBar.Max := hmax; + if FXOffset>hmax then + FXOffset:=hmax; FHScrollBar.Position := FXOffset; - FHScrollBar.SliderSize := Width / TotalColumnWidth; + FHScrollBar.SliderSize := HWidth / TotalColumnWidth; + FHScrollBar.PageSize := 5; end else begin FHScrollBar.Max := ColumnCount-1; FHScrollBar.Position := FFirstCol; - FHScrollBar.SliderSize := 1 / ColumnCount; + FHScrollBar.SliderSize := 1 / ColumnCount; + FHScrollBar.PageSize := 1; end; FHScrollBar.RepaintSlider; + FHScrollBar.Top := Height - FHScrollBar.Height - borders.Bottom; + FHScrollBar.Left := borders.Left; + FHScrollBar.Width := HWidth; + end + else + begin + FHScrollBar.Visible := False; + if Hfits then + begin + FFirstCol := 0; + FXOffset := 0; + end; + // if horizontal doesn't fit and no scrollbar, do not change firstcol/xoffset end; - FHScrollBar.Top := Height -FHScrollBar.Height - 2; - FHScrollBar.Left := 2; - FHScrollBar.Width := HWidth; - - FVScrollBar.Top := 2; - FVScrollBar.Left := Width - FVScrollBar.Width - 2; - FVScrollBar.Height := VHeight; - FVScrollBar.UpdateWindowPosition; FHScrollBar.UpdateWindowPosition; end; @@ -673,10 +816,12 @@ var clipr: TfpgRect; // clip rectangle drawstate: TfpgGridDrawState; cLeft: integer; - c: integer; + rTop: integer; + firstcol, lastcol, firstrow, lastrow : integer; + cWidths: array of integer; + rect: TRect; begin Canvas.ClearClipRect; - r.SetRect(0, 0, Width, Height); case BorderStyle of ebsNone: @@ -685,51 +830,103 @@ begin end; ebsDefault: begin - Canvas.DrawControlFrame(r); - InflateRect(r, -2, -2); + fpgStyle.DrawControlFrame(Canvas, r); end; ebsSingle: begin Canvas.SetColor(clShadow2); Canvas.DrawRectangle(r); - InflateRect(r, -1, -1); end; end; - Canvas.SetClipRect(r); + r := GetClientRect; + clipr := r; + Canvas.SetClipRect(clipr); Canvas.SetColor(FBackgroundColor); Canvas.FillRectangle(r); - clipr.SetRect(FMargin, FMargin, VisibleWidth, VisibleHeight); - r := clipr; + cLeft := r.Left; // column starting point + rTop := r.Top; // row starting point - cLeft := FMargin; // column starting point if go_SmoothScroll in FOptions then begin if FHScrollBar.Visible then Dec(cLeft, FHScrollBar.Position); - c := 0; + firstcol := 0; end else begin - c := FFirstCol; + firstcol := FFirstCol; end; + // calculate column widths, and first/last columns + if (ColumnCount <= 0) then + begin + firstcol := -1; + lastcol := -2; + end + else + begin + setlength (cWidths, ColumnCount); + r.Left := cLeft; + for col := firstcol to ColumnCount-1 do + begin + cWidths[col] := ColumnWidth[col]; + r.Width := cWidths[col]; + if (go_SmoothScroll in FOptions) and (r.Left <= clipr.Left) then + begin + firstcol := col; + if col>0 then inc (cLeft, cWidths[col-1]); + end; + lastcol := col; + if r.Right >= clipr.Right then + break; + inc (r.Left, r.Width); + end; + // first/last rows... + if (RowCount <= 0) then + begin + firstrow := -1; + lastrow := -2; + end + else + begin + if ShowHeader then + inc (r.Top, FHeaderHeight); + if r.Top > clipr.Bottom then + begin + firstrow := -1; + lastrow := -2; + end + else + begin + firstrow := FFirstRow; + lastrow := firstrow + (clipr.Bottom - r.Top) div DefaultRowHeight; + if lastrow >= RowCount then + lastrow := RowCount-1; + end; + end; + end; + + PrepareCells (firstrow, lastrow, firstcol, lastcol); + + r.Left := cLeft; + r.Top := rTop; + if (ColumnCount > 0) and ShowHeader then begin // Drawing horizontal headers - r.Left := cLeft; r.Height := FHeaderHeight; Canvas.SetFont(FHeaderFont); - for col := c to ColumnCount-1 do + for col := firstcol to lastcol do begin - r.Width := ColumnWidth[col]; + r.Width := cWidths[col]; Canvas.SetClipRect(clipr); Canvas.AddClipRect(r); DrawHeader(col, r, 0); inc(r.Left, r.Width); - if r.Left >= clipr.Right then - Break; // small optimization. Don't draw what we can't see + //if r.Left >= clipr.Right then + // Break; // optimization made obsolete by lastcol end; inc(r.Top, r.Height); end; @@ -740,13 +937,13 @@ begin r.Height := DefaultRowHeight; Canvas.SetFont(FFont); - for row := FFirstRow to RowCount-1 do + for row := firstrow to lastrow do begin r.Left := cLeft; - for col := c to ColumnCount-1 do + for col := firstcol to lastcol do begin drawstate := []; - r.Width := ColumnWidth[col]; + r.Width := cWidths[col]; Canvas.SetClipRect(clipr); if (row = FFocusRow) and (RowSelect or (col = FFocusCol)) and not (go_HideFocusRect in FOptions) then @@ -774,7 +971,6 @@ begin Include(drawstate, gdFocused); if (row = FFocusRow) and (col = FFocusCol) then Include(drawstate, gdSelected); - if DoDrawCellEvent(row, col, r, drawstate) then DrawCell(row, col, r, drawstate); @@ -783,13 +979,13 @@ begin DrawGrid(row, col, r, 0); inc(r.Left, r.Width); - if r.Left >= clipr.Right then - Break; // small optimization. Don't draw what we can't see + //if r.Left >= clipr.Right then + // Break; // optimization made obsolete by lastcol end; // Inc(r.Top, FDefaultRowHeight+1); inc(r.Top, r.Height); - if r.Top >= clipr.Bottom then - break; + //if r.Top >= clipr.Bottom then + // break; // optimization made obsolete by lastrow end; end; // item drawing @@ -1008,49 +1204,66 @@ end; procedure TfpgBaseGrid.HandleMouseScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); var lRow: Integer; - lCol: Integer; begin inherited HandleMouseScroll(x, y, shiftstate, delta); lRow := FFirstRow; - lCol := FFirstCol; - if delta > 0 then // scroll down - inc(FFirstRow, abs(delta)*3) - else // scroll up - if FFirstRow > 0 then - dec(FFirstRow, abs(delta)*3); + // If vertical scrollbar is not visible, but + // horizontal is, Mouse wheel will scroll horizontally. :) + if FHScrollBar.Visible and (not FVScrollBar.Visible) then + begin + HandleMouseHorizScroll(x, y, shiftstate, delta); + Exit; + end; + + inc(FFirstRow, delta*3); // apply limits if FFirstRow > RowCount - VisibleLines then FFirstRow := RowCount - VisibleLines; if FFirstRow < 0 then FFirstRow := 0; - - // scroll left/right - // If vertical scrollbar is not visible, but - // horizontal is. Mouse wheel will scroll horizontally. :) - if FHScrollBar.Visible and (not FVScrollBar.Visible) then - begin - if delta > 0 then // scroll right - begin - if FFirstCol < (ColumnCount-1) then - inc(FFirstCol); - end - else - begin - if FFirstCol > 0 then - dec(FFirstCol); - end; - end; - if (lRow <> FFirstRow) or (lCol <> FFirstCol) then + if lRow <> FFirstRow then begin UpdateScrollBars; RePaint; end; end; +procedure TfpgBaseGrid.HandleMouseHorizScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); +var + old_val: Integer; +begin + inherited HandleMouseHorizScroll(x, y, shiftstate, delta); + + if go_SmoothScroll in Options then + begin + old_val := FXOffset; + inc(FXOffset, delta*FHScrollBar.ScrollStep); + if (FXOffset<0) then + FXOffset:=0; + // finding the maximum Xoffset is tricky, let updatescrollbars do it. + if (FXOffset=old_val) then + Exit; + end + else + begin + old_val := FFirstCol; + inc(FFirstCol, delta); + if FFirstCol<0 then + FFirstCol:=0 + else if FFirstCol > ColumnCount-1 then + FFirstCol:=ColumnCount-1; + if FFirstCol=old_val then + Exit; + end; + + UpdateScrollBars; + RePaint; +end; + procedure TfpgBaseGrid.HandleMouseMove(x, y: integer; btnstate: word; shiftstate: TShiftState); var hh: integer; @@ -1059,6 +1272,7 @@ var colresize: boolean; cLeft: integer; c: integer; + borders: TRect; begin inherited HandleMouseMove(x, y, btnstate, shiftstate); @@ -1082,8 +1296,9 @@ begin begin colresize := False; hh := FHeaderHeight; + borders := GetAdjustedBorderSizes; - cLeft := FMargin; // column starting point + cLeft := borders.Left; // column starting point if go_SmoothScroll in FOptions then begin if FHScrollBar.Visible then @@ -1095,7 +1310,7 @@ begin c := FFirstCol; end; - if (y <= FMargin + hh) then // we are over the Header row + if (y <= (borders.Top + hh)) then // we are over the Header row begin cw := 0; for n := c to ColumnCount-1 do @@ -1120,12 +1335,62 @@ begin end; procedure TfpgBaseGrid.HandleLMouseUp(x, y: integer; shiftstate: TShiftState); +var + lColumn: integer; + hh: integer; { header height } + cLeft: integer; { column left } + c: integer; + n: integer; + cw: integer; + borders: TRect; begin inherited HandleLMouseUp(x, y, shiftstate); + if not FColResizing then + begin + if not ShowHeader then + Exit; + if (ColumnCount = 0) then + Exit; //==> + // searching for the appropriate character position + hh := FHeaderHeight; + borders := GetAdjustedBorderSizes; + + if (y < (borders.Top+hh)) then // inside Header row + begin + {$IFDEF DEBUG} Writeln('header click...'); {$ENDIF} + + cLeft := borders.Left; // column starting point + if go_SmoothScroll in FOptions then + begin + if FHScrollBar.Visible then + Dec(cLeft, FHScrollBar.Position); + c := 0; + end + else + begin + c := FFirstCol; + end; + + cw := 0; + for n := c to ColumnCount-1 do + begin + inc(cw, ColumnWidth[n]); + if x < (cLeft+cw+4) then + begin + if Assigned(FOnHeaderClick) then + FOnHeaderClick(self, n); + Break; + end; + end; { for } + end; + end; {if not FColResizing } + {$IFDEF DEBUG} if FColResizing then + begin Writeln('Column ', FResizedCol,' width = ', ColumnWidth[FResizedCol]); + end; {$ENDIF} FColResizing := False; @@ -1142,6 +1407,7 @@ var pcol: Integer; c: integer; cLeft: integer; + borders: TRect; begin inherited HandleLMouseDown(x, y, shiftstate); @@ -1150,18 +1416,19 @@ begin pcol := FFocusCol; prow := FFocusRow; + borders := GetAdjustedBorderSizes; // searching for the appropriate character position if ShowHeader then - hh := FHeaderHeight+1 + hh := FHeaderHeight else hh := 0; - if ShowHeader and (y <= FMargin+hh) then // inside Header row + if ShowHeader and (y < (borders.Top+hh)) then // inside Header row begin {$IFDEF DEBUG} Writeln('header click...'); {$ENDIF} - cLeft := FMargin; // column starting point + cLeft := borders.Left; // column starting point if go_SmoothScroll in FOptions then begin if FHScrollBar.Visible then @@ -1226,7 +1493,7 @@ begin else hh := 0; - if ShowHeader and (y > FMargin+hh) then // not in Header row + if ShowHeader and (y > (fpgStyle.GetControlFrameBorders.Top + hh)) then // not in Header row begin PopupMenu.ShowAt(self, x, y); end; @@ -1268,7 +1535,7 @@ begin w := 0; for n := FFocusCol downto FFirstCol do begin - w := w + ColumnWidth[n]+1; + w := w + ColumnWidth[n]; if w > VisibleWidth then begin if n = FFocusCol then @@ -1283,7 +1550,14 @@ begin UpdateScrollBars; end; +procedure TfpgBaseGrid.PrepareCells(firstrow, lastrow, firstcol, lastcol: integer); +begin + // for descendents +end; + constructor TfpgBaseGrid.Create(AOwner: TComponent); +var + borders: TRect; begin Updating; inherited Create(AOwner); @@ -1296,7 +1570,6 @@ begin FPrevRow := -1; FFirstRow := 0; FFirstCol := 0; - FMargin := 2; FShowHeader := True; FShowGrid := True; FRowSelect := False; @@ -1306,6 +1579,8 @@ begin FHeaderStyle := ghsButton; FBorderStyle := ebsDefault; + borders := GetAdjustedBorderSizes; + FFont := fpgGetFont('#Grid'); FHeaderFont := fpgGetFont('#GridHeader'); @@ -1317,8 +1592,8 @@ begin FAlternativeBGColor := clHilite1; FColResizing := False; - MinHeight := HeaderHeight + DefaultRowHeight + FMargin; - MinWidth := DefaultColWidth + FMargin; + MinHeight := HeaderHeight + DefaultRowHeight + borders.Top + borders.Bottom; + MinWidth := DefaultColWidth + borders.Left + borders.Right; FVScrollBar := TfpgScrollBar.Create(self); FVScrollBar.Orientation := orVertical; @@ -1329,7 +1604,7 @@ begin FHScrollBar.Orientation := orHorizontal; FHScrollBar.Visible := False; FHScrollBar.OnScroll := @HScrollBarMove; - FHScrollBar.ScrollStep := 5; + FHScrollBar.ScrollStep := 20; end; destructor TfpgBaseGrid.Destroy; @@ -1388,11 +1663,11 @@ begin else hh := 0; - ARow := FFirstRow + ((y - FMargin - hh) div FDefaultRowHeight); + ARow := FFirstRow + ((y - fpgStyle.GetControlFrameBorders.Top - hh) div FDefaultRowHeight); if ARow > RowCount-1 then ARow := RowCount-1; - cLeft := FMargin; // column starting point + cLeft := fpgStyle.GetControlFrameBorders.Left; // column starting point if go_SmoothScroll in FOptions then begin if FHScrollBar.Visible then @@ -1416,6 +1691,19 @@ begin end; end; +function TfpgBaseGrid.GetClientRect: TfpgRect; +var + rect: TRect; +begin + Result := inherited GetClientRect; + rect := fpgStyle.GetControlFrameBorders; + case BorderStyle of +// ebsNone: // nothing to do + ebsDefault: InflateRect(Result, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } + ebsSingle: InflateRect(Result, -1, -1); + end; +end; + end. diff --git a/src/gui/fpg_button.pas b/src/gui/fpg_button.pas index 3bc026de..0cbb1397 100644 --- a/src/gui/fpg_button.pas +++ b/src/gui/fpg_button.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -171,6 +171,9 @@ type property OnDragLeave; property OnDragDrop; property OnDragStartDetected; + property OnEnter; + property OnExit; + property OnKeyPress; property OnMouseDown; property OnMouseExit; property OnMouseEnter; @@ -543,6 +546,9 @@ begin if FEmbedded then Include(lBtnFlags, btfIsEmbedded); + if not Enabled then + Include(lBtnFlags, btfDisabled); + // In the UI Designer we want the button more visible if not (csDesigning in ComponentState) then begin diff --git a/src/gui/fpg_checkbox.pas b/src/gui/fpg_checkbox.pas index 886f69ca..2b4b11d8 100644 --- a/src/gui/fpg_checkbox.pas +++ b/src/gui/fpg_checkbox.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2011 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -210,8 +210,7 @@ begin ix := (2 + (Ord(FChecked) * 2)) - Ord(FChecked); // paint the check (in this case a X) - img := fpgImages.GetImage('sys.checkboxes'); // Do NOT localize - Canvas.DrawImagePart(r.Left, r.Top, img, ix*FBoxSize, 0, FBoxSize, FBoxSize); + fpgStyle.DrawCheckbox(Canvas, r.Left, r.Top, ix*FBoxSize, 0); r := GetClientRect; { max focus rectangle and text boundry } @@ -291,7 +290,7 @@ begin FTextColor := Parent.TextColor; FBackgroundColor := Parent.BackgroundColor; FFocusable := True; - FBoxSize := 13; + FBoxSize := fpgStyle.GetCheckBoxSize; FImgTextSpacing := 6; FChecked := False; FIsPressed := False; diff --git a/src/gui/fpg_colorwheel.pas b/src/gui/fpg_colorwheel.pas index a6b3795b..e699aebc 100644 --- a/src/gui/fpg_colorwheel.pas +++ b/src/gui/fpg_colorwheel.pas @@ -554,7 +554,7 @@ begin Canvas.FillRectangle(r); Canvas.Color := clBlack; - Canvas.DrawControlFrame(r); + fpgStyle.DrawControlFrame(Canvas, r); end; procedure TfpgValueBar.SetMarginWidth(NewWidth: longint); diff --git a/src/gui/fpg_combobox.pas b/src/gui/fpg_combobox.pas index 8c10f195..bb26ada6 100644 --- a/src/gui/fpg_combobox.pas +++ b/src/gui/fpg_combobox.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -100,7 +100,6 @@ type procedure DoOnDropDown; virtual; procedure DoDropDown; virtual; abstract; procedure DoOnCloseUp; virtual; - procedure PaintInternalButton; virtual; function GetDropDownPos(AParent, AComboBox, ADropDown: TfpgWidget): TfpgRect; virtual; property AutoSize: Boolean read FAutoSize write SetAutoSize default False; property DropDownCount: integer read FDropDownCount write SetDropDownCount default 8; @@ -182,14 +181,16 @@ type function CreateComboBox(AOwner: TComponent; x, y, w: TfpgCoord; AList: TStringList; - h: TfpgCoord = 0): TfpgComboBox; + h: TfpgCoord = 24): TfpgComboBox; implementation uses fpg_listbox, - dbugintf, + {$IFDEF DEBUG} + fpg_dbugintf, + {$ENDIF} math; @@ -385,42 +386,6 @@ begin OnCloseUp(self); end; -procedure TfpgBaseComboBox.PaintInternalButton; -var - ar: TfpgRect; - btnflags: TfpgButtonFlags; -begin - Canvas.BeginDraw; - btnflags := []; - ar := FInternalBtnRect; - - { The bounding rectangle for the arrow } - ar.Width := 8; - ar.Height := 6; - ar.Left := FInternalBtnRect.Left + ((FInternalBtnRect.Width-ar.Width) div 2); - ar.Top := FInternalBtnRect.Top + ((FInternalBtnRect.Height-ar.Height) div 2); - - if FBtnPressed then - begin - Include(btnflags, btfIsPressed); - OffsetRect(ar, 1, 1); - end; - // paint button face - fpgStyle.DrawButtonFace(Canvas, - FInternalBtnRect.Left, - FInternalBtnRect.Top, - FInternalBtnRect.Width, - FInternalBtnRect.Height, btnflags); - if Enabled then - Canvas.SetColor(clText1) - else - Canvas.SetColor(clShadow1); - - // paint arrow - fpgStyle.DrawDirectionArrow(Canvas, ar.Left, ar.Top, ar.Width, ar.Height, adDown); - Canvas.EndDraw(FInternalBtnRect); -end; - function TfpgBaseComboBox.GetDropDownPos(AParent, AComboBox, ADropDown: TfpgWidget): TfpgRect; var pt: TPoint; @@ -535,7 +500,9 @@ end; function CreateComboBox(AOwner: TComponent; x, y, w: TfpgCoord; AList: TStringList; - h: TfpgCoord = 0): TfpgComboBox; + h: TfpgCoord): TfpgComboBox; +var + lh: integer; begin Result := TfpgComboBox.Create(AOwner); Result.Left := x; @@ -543,8 +510,9 @@ begin Result.Width := w; Result.Focusable := True; - if h < TfpgComboBox(Result).FFont.Height + (Result.FMargin * 2) then - Result.Height := TfpgComboBox(Result).FFont.Height + (Result.FMargin * 2) + lh := TfpgComboBox(Result).FFont.Height + (Result.FMargin * 2); + if h < lh then + Result.Height := lh else Result.Height := h; @@ -683,7 +651,7 @@ begin inherited HandleLMouseDown(x, y, shiftstate); // button state is down only if user clicked in the button rectangle. FBtnPressed := PtInRect(FInternalBtnRect, Point(x, y)); - PaintInternalButton; + Repaint; DoDropDown; end; @@ -691,7 +659,7 @@ procedure TfpgBaseStaticCombo.HandleLMouseUp(x, y: integer; shiftstate: TShiftSt begin inherited HandleLMouseUp(x, y, shiftstate); FBtnPressed := False; - PaintInternalButton; + Repaint; end; procedure TfpgBaseStaticCombo.HandleMouseScroll(x, y: integer; @@ -722,47 +690,25 @@ end; procedure TfpgBaseStaticCombo.HandlePaint; var r: TfpgRect; + rect: TRect; begin // inherited HandlePaint; Canvas.ClearClipRect; r.SetRect(0, 0, Width, Height); - Canvas.DrawControlFrame(r); - - // internal background rectangle (without frame) - InflateRect(r, -2, -2); + fpgStyle.DrawControlFrame(Canvas, r); + rect := fpgStyle.GetControlFrameBorders; + InflateRect(r, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } Canvas.SetClipRect(r); - if Enabled then - begin - if ReadOnly then - Canvas.SetColor(clWindowBackground) - else - Canvas.SetColor(FBackgroundColor); - end - else - Canvas.SetColor(clWindowBackground); - - Canvas.FillRectangle(r); - - // paint the fake dropdown button - PaintInternalButton; + fpgStyle.DrawStaticComboBox(Canvas, r, Enabled, Focused, ReadOnly, FBackgroundColor, FInternalBtnRect, FBtnPressed); - Dec(r.Width, FInternalBtnRect.Width); - Canvas.SetClipRect(r); +// Dec(r.Width, FInternalBtnRect.Width); +// Canvas.SetClipRect(r); Canvas.SetFont(Font); - if Focused then - begin - Canvas.SetColor(clSelection); - Canvas.SetTextColor(clSelectionText); - InflateRect(r, -1, -1); - Canvas.FillRectangle(r); - end + Canvas.SetTextColor(clSelectionText) else - begin Canvas.SetTextColor(FTextColor); - end; - { adjust rectangle size smaller for text } r.Left := r.Left + Margin; r.Width := r.Width - (Margin*2); diff --git a/src/gui/fpg_customgrid.pas b/src/gui/fpg_customgrid.pas index 83d35aa7..98040374 100644 --- a/src/gui/fpg_customgrid.pas +++ b/src/gui/fpg_customgrid.pas @@ -65,6 +65,7 @@ type FColumns: TFPList; procedure HandleSetFocus; override; procedure SetTextColor(const AValue: TfpgColor); override; + procedure SetBackgroundColor(const AValue: TfpgColor); override; function GetColumns(AIndex: integer): TfpgGridColumn; virtual; procedure DoDeleteColumn(ACol: integer); virtual; procedure DoSetRowCount(AValue: integer); virtual; @@ -140,6 +141,18 @@ begin Update; end; +procedure TfpgCustomGrid.SetBackgroundColor(const AValue: TfpgColor); +var + i: integer; +begin + inherited SetBackgroundColor(AValue); + for i := 0 to ColumnCount-1 do + begin + TfpgGridColumn(FColumns.Items[i]).BackgroundColor := AValue; + end; + RePaint; +end; + function TfpgCustomGrid.GetColumns(AIndex: integer): TfpgGridColumn; begin if (AIndex < 0) or (AIndex > FColumns.Count-1) then diff --git a/src/gui/fpg_dialogs.pas b/src/gui/fpg_dialogs.pas index 8f3639e6..781c0745 100644 --- a/src/gui/fpg_dialogs.pas +++ b/src/gui/fpg_dialogs.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -58,10 +58,10 @@ uses type TfpgMsgDlgType = (mtAbout, mtWarning, mtError, mtInformation, mtConfirmation, mtCustom); - + TfpgMsgDlgBtn = (mbNoButton, mbOK, mbCancel, mbYes, mbNo, mbAbort, mbRetry, mbIgnore, mbAll, mbNoToAll, mbYesToAll, mbHelp, mbClose); - + TfpgMsgDlgButtons = set of TfpgMsgDlgBtn; const @@ -104,7 +104,7 @@ type property CentreText: Boolean read FCentreText write FCentreText default False; property FontDesc: string read GetFontDesc write SetFontDesc; end; - + TfpgBaseDialog = class(TfpgForm) protected @@ -152,8 +152,8 @@ type constructor Create(AOwner: TComponent); override; procedure SetSampleText(AText: string); end; - - + + TfpgFileDialog = class(TfpgBaseDialog) private chlDir: TfpgComboBox; @@ -227,6 +227,7 @@ type {$I charmapdialog.inc} {$I colordialog.inc} {$I inputquerydialog.inc} +{$I inputintegerdialog.inc} {$I managebookmarksdialog.inc} @@ -240,6 +241,7 @@ function SelectDirDialog(const AStartDir: TfpgString = ''): TfpgString; function fpgShowCharMap: TfpgString; function fpgSelectColorDialog(APresetColor: TfpgColor = clBlack): TfpgColor; function fpgInputQuery(const ACaption, APrompt: TfpgString; var Value: TfpgString): Boolean; +function fpgIntegerQuery(const ACaption, APrompt: TfpgString; var Value: Integer; const MaxValue: Integer; const MinValue: Integer = 0): Boolean; implementation @@ -253,8 +255,8 @@ uses {$ENDIF} ,DateUtils ; - - + + procedure WrapText(const AText: String; ALines: TStrings; AFont: TfpgFont; const ALineWidth: Integer; out AWidth: Integer); var @@ -396,7 +398,7 @@ begin dres := dlg.RunOpenFile else dres := dlg.RunSaveFile; - + if dres then Result := dlg.FileName else @@ -532,7 +534,7 @@ var outw: integer; begin WrapText(AMessage, FLines, FFont, FMaxLineWidth, outw); - + // dialog width with 10 pixel border on both sides Width := outw + 2*10; @@ -744,7 +746,7 @@ var NextC; end; end; - + procedure ProcessAliasFont; var i: integer; @@ -785,7 +787,7 @@ begin NextToken; lbFaces.FocusItem := lbFaces.Items.IndexOf(token); - + if c = '-' then begin NextC; @@ -846,7 +848,7 @@ begin MinHeight := Height; FSampleText := 'The quick brown fox jumps over the lazy dog. 0123456789 [oO0,ilLI]'; FMode := 1; // normal fonts - + btnCancel.Left := Width - FDefaultButtonWidth - FSpacing; btnOK.Left := btnCancel.Left - FDefaultButtonWidth - FSpacing; @@ -1000,7 +1002,7 @@ begin Exit; //==> if AText = '' then Exit; //==> - + FSampleText := AText; memSample.Text := FSampleText; end; @@ -1171,7 +1173,7 @@ begin end; { Create lower Panel details } - + pnlFileInfo := TfpgPanel.Create(self); with pnlFileInfo do begin @@ -1194,7 +1196,7 @@ begin OnChange := @edFilenameChanged; OnKeyPress := @edFilenameKeyPressed; end; - + { Filter section } chlFilter := TfpgComboBox.Create(self); @@ -1398,7 +1400,7 @@ begin ExcludeTrailingPathDelimiter(grid.FileList.DirectoryName)) else fsel := ''; - + grid.FileList.FileMask := GetFileFilter; grid.FileList.ShowHidden := ShowHidden; @@ -1407,7 +1409,7 @@ begin ShowMessage(Format(rsErrCouldNotOpenDir, [ADir]), rsError); Exit; //==> end; - + grid.FileList.Sort(soFileName); // we don't want chlDir to call DirChange while populating items @@ -1420,7 +1422,7 @@ begin HighlightFile(fsel) else grid.FocusRow := 0; - + grid.Update; grid.SetFocus; @@ -1583,7 +1585,7 @@ begin if not HighlightFile(fname) then edFilename.Text := fname; - + WindowTitle := rsOpenAFile; btnOK.ImageName := 'stdimg.open'; // Do NOT localize btnOK.Text := rsOpen; @@ -1632,6 +1634,7 @@ end; {$I charmapdialog.inc} {$I colordialog.inc} {$I inputquerydialog.inc} +{$I inputintegerdialog.inc} {$I managebookmarksdialog.inc} diff --git a/src/gui/fpg_edit.pas b/src/gui/fpg_edit.pas index f164ef76..0ed17bfd 100644 --- a/src/gui/fpg_edit.pas +++ b/src/gui/fpg_edit.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -187,6 +187,7 @@ type property OnDragStartDetected; property OnEnter; property OnExit; + property OnKeyChar; property OnKeyPress; property OnMouseEnter; property OnMouseExit; @@ -279,6 +280,7 @@ type property OnChange; property OnEnter; property OnExit; + property OnKeyChar; property OnKeyPress; property OnMouseEnter; property OnMouseExit; @@ -328,6 +330,7 @@ type property OnChange; property OnEnter; property OnExit; + property OnKeyChar; property OnKeyPress; property OnMouseEnter; property OnMouseExit; @@ -375,6 +378,7 @@ type property OnChange; property OnEnter; property OnExit; + property OnKeyChar; property OnKeyPress; property OnMouseEnter; property OnMouseExit; @@ -725,7 +729,7 @@ begin end; ebsDefault: begin - Canvas.DrawControlFrame(r); + fpgStyle.DrawControlFrame(Canvas, r); rect := fpgStyle.GetControlFrameBorders; InflateRect(r, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } end; @@ -754,10 +758,14 @@ var s: TfpgChar; prevval: string; begin + inherited HandleKeyChar(AText, shiftstate, consumed); + if consumed then + Exit; //==> + prevval := Text; s := AText; - if (not consumed) and (not ReadOnly) then + if (not ReadOnly) then begin // Handle only printable characters // UTF-8 characters beyond ANSI range are supposed to be printable @@ -780,8 +788,6 @@ begin if consumed then RePaint; - - inherited HandleKeyChar(AText, shiftstate, consumed); end; procedure TfpgBaseEdit.HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean); @@ -1110,21 +1116,24 @@ begin end; procedure TfpgBaseEdit.SetFontDesc(const AValue: string); +var + rect: TRect; begin FFont.Free; FFont := fpgGetFont(AValue); if AutoSize then begin + rect := fpgStyle.GetControlFrameBorders; case BorderStyle of ebsNone: if Height < FFont.Height + (FHeightMargin * 2) then - Height:= FFont.Height + (FHeightMargin * 2); + Height := FFont.Height + (FHeightMargin * 2); ebsDefault: - if Height < FFont.Height + 4 + (FHeightMargin * 2) then - Height:= FFont.Height + 4 + (FHeightMargin * 2); + if Height < FFont.Height + rect.Top + rect.Bottom + (FHeightMargin * 2) then + Height := FFont.Height + rect.Top + rect.Bottom + (FHeightMargin * 2); ebsSingle: - if Height < FFont.Height + 2 + (FHeightMargin * 2) then - Height:= FFont.Height + 2 + (FHeightMargin * 2); + if Height < FFont.Height + rect.Top + rect.Bottom + (FHeightMargin * 2) then + Height := FFont.Height + rect.Top + rect.Bottom + (FHeightMargin * 2); end; end; Adjust; @@ -1173,18 +1182,24 @@ begin end; procedure TfpgBaseEdit.SetHeightMargin(const AValue: integer); +var + rect: TRect; begin if (FHeightMargin = AValue) or (AValue <= 0) then Exit; //=> FHeightMargin := AValue; - case BorderStyle of - ebsNone: - Height:= FFont.Height + (FHeightMargin * 2); - ebsDefault: - Height:= FFont.Height + 4 + (FHeightMargin * 2); - ebsSingle: - Height:= FFont.Height + 2 + (FHeightMargin * 2); + if AutoSize then + begin + rect := fpgStyle.GetControlFrameBorders; + case BorderStyle of + ebsNone: + Height := FFont.Height + (FHeightMargin * 2); + ebsDefault: + Height := FFont.Height + rect.Top + rect.Bottom + (FHeightMargin * 2); + ebsSingle: + Height := FFont.Height + rect.Top + rect.Bottom + (FHeightMargin * 2); end; + end; Repaint; end; @@ -1420,11 +1435,15 @@ begin end; function TfpgBaseEdit.GetClientRect: TfpgRect; +var + rect: TRect; begin + Result := inherited GetClientRect; + rect := fpgStyle.GetControlFrameBorders; case BorderStyle of - ebsNone: Result := inherited GetClientRect; - ebsDefault: Result.SetRect(2, 2, Width-4, Height-4); - ebsSingle: Result.SetRect(1, 1, Width-2, Height-2); +// ebsNone: // nothing to do + ebsDefault: InflateRect(Result, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } + ebsSingle: InflateRect(Result, -1, -1); end; end; @@ -1866,6 +1885,7 @@ begin FAlignment := taRightJustify; FDecimalSeparator := DecimalSeparator; FThousandSeparator := ThousandSeparator; + FShowThousand := True; FNegativeColor := clRed; FOldColor := TextColor; FMaxLimit := False; @@ -1992,8 +2012,10 @@ begin if ((n >= 48) and (n <= 57) or (AText = '-') and (UTF8Pos(AText, Text) <= 0)) then consumed := False else - consumed := True; + Exit; //==> + inherited HandleKeyChar(AText, shiftstate, consumed); + if FMaxLimit then if GetValue > FMaxValue then SetValue(FMaxValue); @@ -2042,7 +2064,6 @@ end; constructor TfpgEditInteger.Create(AOwner: TComponent); begin inherited Create(AOwner); - FShowThousand := True; FDecimals := 0; end; @@ -2216,8 +2237,10 @@ begin or ((AText = FDecimalSeparator) and (UTF8Pos(AText, Text) <= 0)) then consumed := False else - consumed := True; + Exit; //==> + inherited HandleKeyChar(AText, shiftstate, consumed); + if FMaxLimit then if GetValue > FMaxValue then SetValue(FMaxValue); @@ -2284,7 +2307,6 @@ begin inherited Create(AOwner); FDecimals := -1; FFixedDecimals := -1; - FShowThousand := True; end; { TfpgEditCurrency } @@ -2437,8 +2459,10 @@ begin or ((AText = FDecimalSeparator) and (UTF8Pos(AText, Text) <= 0)) then consumed := False else - consumed := True; + Exit; //==> + inherited HandleKeyChar(AText, shiftstate, consumed); + if FMaxLimit then if GetValue > FMaxValue then SetValue(FMaxValue); @@ -2488,7 +2512,6 @@ constructor TfpgEditCurrency.Create(AOwner: TComponent); begin inherited Create(AOwner); FDecimals := 2; - FShowThousand := True; end; diff --git a/src/gui/fpg_editcombo.pas b/src/gui/fpg_editcombo.pas index 3887cd13..5b011b4d 100644 --- a/src/gui/fpg_editcombo.pas +++ b/src/gui/fpg_editcombo.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -128,15 +128,24 @@ type property Hint; property Items; property Margin; + property ReadOnly; property Text; property TextColor; property Width; property OnChange; property OnCloseUp; + property OnDragEnter; + property OnDragLeave; + property OnDragDrop; + property OnDragStartDetected; property OnDropDown; property OnEnter; property OnExit; + property OnKeyChar; property OnKeyPress; + property OnMouseEnter; + property OnMouseExit; + property OnPaint; property OnShowHint; end; @@ -522,6 +531,9 @@ var prevval: string; i: integer; begin + inherited HandleKeyChar(AText, shiftstate, consumed); + if Consumed then + Exit; //==> prevval := FText; s := AText; consumed := False; @@ -529,7 +541,7 @@ begin FNewItem := False; // Handle only printable characters - // Note: This is now UTF-8 compliant! + // Note: This is not UTF-8 compliant! if Enabled and (Ord(AText[1]) > 31) and (Ord(AText[1]) < 127) or (Length(AText) > 1) then begin if (FMaxLength <= 0) or (UTF8Length(FText) < FMaxLength) then @@ -572,8 +584,6 @@ begin if consumed then RePaint; -// else - inherited HandleKeyChar(AText, shiftstate, consumed); end; procedure TfpgBaseEditCombo.HandleKeyPress(var keycode: word; @@ -687,12 +697,12 @@ begin FBtnPressed := PtInRect(FInternalBtnRect, Point(x, y)); if not FAutoCompletion then begin - PaintInternalButton; + Repaint; DoDropDown; end else if FBtnPressed then begin - PaintInternalButton; + Repaint; DoDropDown; end; end; @@ -702,7 +712,7 @@ procedure TfpgBaseEditCombo.HandleLMouseUp(x, y: integer; begin inherited HandleLMouseUp(x, y, shiftstate); FBtnPressed := False; - PaintInternalButton; + Repaint; end; procedure TfpgBaseEditCombo.HandleRMouseUp(x, y: integer; shiftstate: TShiftState); @@ -717,6 +727,7 @@ end; procedure TfpgBaseEditCombo.HandlePaint; var r: TfpgRect; + rect: TRect; tw, tw2, st, len: integer; Texte: string; @@ -761,25 +772,28 @@ var end; begin - Canvas.BeginDraw; // inherited HandlePaint; Canvas.ClearClipRect; r.SetRect(0, 0, Width, Height); - Canvas.DrawControlFrame(r); - - // internal background rectangle (without frame) - InflateRect(r, -2, -2); + fpgStyle.DrawControlFrame(Canvas, r); + rect := fpgStyle.GetControlFrameBorders; + InflateRect(r, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } Canvas.SetClipRect(r); if Enabled then - Canvas.SetColor(FBackgroundColor) + begin + if ReadOnly then + Canvas.SetColor(clWindowBackground) + else + Canvas.SetColor(FBackgroundColor); + end else Canvas.SetColor(clWindowBackground); Canvas.FillRectangle(r); // paint the fake dropdown button - PaintInternalButton; + fpgStyle.DrawInternalComboBoxButton(Canvas, FInternalBtnRect, Enabled, FBtnPressed); Dec(r.Width, FInternalBtnRect.Width); Canvas.SetClipRect(r); @@ -860,8 +874,6 @@ begin else fpgCaret.UnSetCaret(Canvas); end; - - Canvas.EndDraw; end; constructor TfpgBaseEditCombo.Create(AOwner: TComponent); diff --git a/src/gui/fpg_grid.pas b/src/gui/fpg_grid.pas index b7800b55..3f8b52fb 100644 --- a/src/gui/fpg_grid.pas +++ b/src/gui/fpg_grid.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -68,8 +68,17 @@ type property ScrollBarStyle; property TabOrder; property TopRow; - property OnRowChange; + property OnClick; property OnDoubleClick; + property OnEnter; + property OnExit; + property OnKeyPress; + property OnMouseDown; + property OnMouseEnter; + property OnMouseExit; + property OnMouseMove; + property OnMouseUp; + property OnRowChange; property OnShowHint; end; @@ -106,8 +115,7 @@ type property Columns[AIndex: Integer]: TfpgStringColumn read GetColumns; public constructor Create(AOwner: TComponent); override; - function AddColumn(ATitle: string; AWidth: integer; AAlignment: TAlignment = taLeftJustify; - AbackgroundColor: TfpgColor = clDefault; ATextColor: TfpgColor = clDefault): TfpgStringColumn; overload; + function AddColumn(ATitle: string; AWidth: integer; AAlignment: TAlignment = taLeftJustify; AbackgroundColor: TfpgColor = clDefault; ATextColor: TfpgColor = clDefault): TfpgStringColumn; overload; procedure DeleteRow(AIndex: integer); override; property Cells[ACol, ARow: Integer]: string read GetCell write SetCell; property Objects[ACol, ARow: Integer]: TObject read GetObjects write SetObjects; @@ -160,7 +168,10 @@ type property OnClick; property OnDoubleClick; property OnDrawCell; + property OnEnter; + property OnExit; property OnFocusChange; + property OnHeaderClick; property OnKeyPress; property OnMouseDown; property OnMouseEnter; @@ -171,6 +182,7 @@ type property OnShowHint; end; + function CreateStringGrid(AOwner: TComponent; x, y, w, h: TfpgCoord; AColumnCount: integer = 0): TfpgStringGrid; @@ -330,9 +342,9 @@ end; function TfpgCustomStringGrid.GetCell(ACol, ARow: Integer): string; begin - if ACol > ColumnCount-1 then + if (ACol < 0) or (ACol > ColumnCount-1) then Exit; //==> - if ARow > RowCount-1 then + if (ARow < 0) or (ARow > RowCount-1) then Exit; //==> Result := TfpgStringColumn(FColumns.Items[ACol]).Cells[ARow]; end; diff --git a/src/gui/fpg_hyperlink.pas b/src/gui/fpg_hyperlink.pas index a61cb80d..0f0e0896 100644 --- a/src/gui/fpg_hyperlink.pas +++ b/src/gui/fpg_hyperlink.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2011 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -58,7 +58,7 @@ type property FontDesc; property Height; property Hint; - property HotTrackColor: TfpgColor read FHotTrackColor write SetHotTrackColor default clBlue; + property HotTrackColor: TfpgColor read FHotTrackColor write SetHotTrackColor default clHyperLink; property HotTrackFont: TfpgString read FHTFont write SetHotTrackFont; property Layout; property Left; @@ -66,7 +66,7 @@ type property ParentShowHint; property ShowHint; property Text; - property TextColor default clBlue; + property TextColor default clHyperLink; property URL: TfpgString read FUrl write SetURL; property Top; property Width; @@ -80,7 +80,9 @@ end; implementation uses - fpg_utils; + fpg_utils + ,fpg_constants + ; { TfpgHyperlink } @@ -89,12 +91,12 @@ constructor TfpgHyperlink.Create(AOwner: TComponent); begin inherited Create(AOwner); Width := 120; - FHotTrackColor := clBlue; - TextColor := clBlue; - FUrl := 'http://opensoft.homeip.net/fpgui/'; + FHotTrackColor := clHyperLink; + TextColor := clHyperLink; + FUrl := fpGUIWebsite; FText := 'fpGUI website'; - FHTFont := 'Arial-8:antialias=true:underline:bold'; - FontDesc := 'Arial-8:antialias=true:underline'; + FHTFont := FPG_DEFAULT_SANS + '-8:antialias=true:underline:bold'; + FontDesc := FPG_DEFAULT_SANS + '-8:antialias=true:underline'; end; procedure TfpgHyperlink.SetURL(const Value: TfpgString); diff --git a/src/gui/fpg_iniutils.pas b/src/gui/fpg_iniutils.pas index dec642d3..6bbe83bd 100644 --- a/src/gui/fpg_iniutils.pas +++ b/src/gui/fpg_iniutils.pas @@ -80,7 +80,7 @@ begin lFileName := fpgExtractFileName(AFileName); if lDir = '' then - lDir := GetAppConfigDir(False); + lDir := fpgGetAppConfigDir(False); if not (lDir[Length(lDir)] = PathDelim) then lDir := lDir + PathDelim; @@ -90,12 +90,12 @@ begin if lFileName = '' then - lFileName := ApplicationName + '.ini' + lFileName := fpgApplicationName + '.ini' else if fpgExtractFileExt(lFileName) = '' then lFileName := lFileName + '.ini'; lFileName := lDir + lFileName; - Create(lFileName); + Create(fpgToOSEncoding(lFileName)); end; function TfpgINIFile.ReadString(const ASection, AIdent, ADefault: string): string; diff --git a/src/gui/fpg_listbox.pas b/src/gui/fpg_listbox.pas index bbcd4530..11baed01 100644 --- a/src/gui/fpg_listbox.pas +++ b/src/gui/fpg_listbox.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -63,6 +63,10 @@ type procedure SetPopupFrame(const AValue: boolean); procedure UpdateScrollbarCoords; procedure SetAutoHeight(const AValue: boolean); + function GetScrollBarPage: integer; + procedure SetScrollBarPage(const AValue: integer); + function GetScrollBarWidth: integer; + procedure SetScrollBarWidth(const AValue: integer); protected FFont: TfpgFont; FScrollBar: TfpgScrollBar; @@ -74,7 +78,6 @@ type procedure UpdateScrollBar; procedure FollowFocus; function ListHeight: TfpgCoord; - function ScrollBarWidth: TfpgCoord; function PageLength: integer; procedure ScrollBarMove(Sender: TObject; APosition: integer); procedure DrawItem(num: integer; rect: TfpgRect; flags: integer); virtual; @@ -90,6 +93,8 @@ type procedure HandleShow; override; procedure HandlePaint; override; property AutoHeight: boolean read FAutoHeight write SetAutoHeight default False; + property ScrollBarPage: Integer read GetScrollBarPage write SetScrollBarPage; + property ScrollBarWidth: Integer read GetScrollBarWidth write SetScrollBarWidth; property FocusItem: integer read FFocusItem write SetFocusItem; property FontDesc: string read GetFontDesc write SetFontDesc; property HotTrack: boolean read FHotTrack write FHotTrack default False; @@ -105,6 +110,7 @@ type function RowHeight: integer; virtual; procedure SetFirstItem(item: integer); property Font: TfpgFont read FFont; + property VisibleItems: integer read PageLength; property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnKeyPress; // to allow to detect return or tab key has been pressed property OnScroll: TNotifyEvent read FOnScroll write FOnScroll; @@ -147,6 +153,8 @@ type property Items; property ParentShowHint; property PopupFrame; + property ScrollBarPage; + property ScrollBarWidth; property ShowHint; property TabOrder; property Text; @@ -416,6 +424,33 @@ begin Height := (Succ(PageLength) * RowHeight) + (2 * FMargin); end; +function TfpgBaseListBox.GetScrollBarPage: integer; +begin + Result:= FScrollBar.PageSize; +end; + +procedure TfpgBaseListBox.SetScrollBarPage(const AValue: integer); +begin + if AValue= FScrollBar.PageSize then + Exit; //==> + FScrollBar.PageSize:= AValue; +end; + +function TfpgBaseListBox.GetScrollBarWidth: integer; +begin + if FScrollBar.Visible then + result := FScrollBar.Width + else + result := 0; +end; + +procedure TfpgBaseListBox.SetScrollBarWidth(const AValue: integer); +begin + if AValue = FScrollBar.Width then + Exit; //==> + FScrollBar.Width := AValue; +end; + procedure TfpgBaseListBox.MsgPaint(var msg: TfpgMessageRec); begin // Optimising painting and preventing OnPaint from firing if not needed @@ -482,14 +517,6 @@ begin result := height - (2*FMargin); end; -function TfpgBaseListBox.ScrollBarWidth: TfpgCoord; -begin - if FScrollBar.Visible then - result := FScrollBar.Width - else - result := 0; -end; - function TfpgBaseListBox.PageLength: integer; begin result := (ListHeight div RowHeight)-1; // component height minus 1 line @@ -673,6 +700,7 @@ procedure TfpgBaseListBox.HandlePaint; var n: integer; r: TfpgRect; + rect: TRect; begin //if FUpdateCount > 0 then // Exit; //==> @@ -691,8 +719,9 @@ begin end else begin - Canvas.DrawControlFrame(r); - InflateRect(r, -2, -2); + fpgStyle.DrawControlFrame(Canvas, r); + rect := fpgStyle.GetControlFrameBorders; + InflateRect(r, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } end; Canvas.SetClipRect(r); @@ -797,6 +826,7 @@ begin r.SetBottom(Height - FMargin); Canvas.FillRectangle(r); end; + UpdateScrollBar; end; constructor TfpgBaseListBox.Create(AOwner: TComponent); @@ -1277,4 +1307,3 @@ begin end; end. - diff --git a/src/gui/fpg_listview.pas b/src/gui/fpg_listview.pas index 8703d6de..0278c952 100644 --- a/src/gui/fpg_listview.pas +++ b/src/gui/fpg_listview.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -209,8 +209,6 @@ type TfpgListView = class(TfpgWidget, IfpgLVItemViewer) private - procedure SetShiftIsPressed(const AValue: Boolean); - private FImages: array[TfpgLVItemStates] of TfpgImageList; FSubitemImages: array[TfpgLVItemStates] of TfpgImageList; FItemIndex: Integer; @@ -225,6 +223,7 @@ type FUpdateCount: Integer; FVScrollBar: TfpgScrollBar; FHScrollBar: TfpgScrollBar; + FScrollBarWidth: integer; FColumns: TfpgLVColumns; FItems: TfpgLVItems; FOnPaintItem: TfpgLVPaintItemEvent; @@ -241,7 +240,9 @@ type procedure SetItems(const AValue: TfpgLVItems); procedure SetMultiSelect(const AValue: Boolean); procedure SetOnColumnClick(const AValue: TfpgLVColumnClickEvent); + procedure SetScrollBarWidth(const AValue: integer); procedure SetShowHeaders(const AValue: Boolean); + procedure SetShiftIsPressed(const AValue: Boolean); function SubItemGetImages(AIndex: integer): TfpgImageList; procedure SubItemSetImages(AIndex: integer; const AValue: TfpgImageList); procedure VScrollChange(Sender: TObject; Position: Integer); @@ -308,6 +309,7 @@ type property Hint; property MultiSelect: Boolean read FMultiSelect write SetMultiSelect; property ParentShowHint; + property ScrollBarWidth: Integer read FScrollBarWidth write SetScrollBarWidth; property SelectionFollowsFocus: Boolean read FSelectionFollowsFocus write FSelectionFollowsFocus; property SubItemImages: TfpgImageList index Ord(lisNoState) read SubItemGetImages write SubItemSetImages; property SubItemImagesSelected: TfpgImageList index Ord(lisSelected) read SubItemGetImages write SubItemSetImages; @@ -738,6 +740,15 @@ begin FOnColumnClick:=AValue; end; +procedure TfpgListView.SetScrollBarWidth(const AValue: integer); +begin + if AValue = FScrollBarWidth then + Exit; //==> + FScrollBarWidth := AValue; + FVScrollBar.Width := FScrollBarWidth; + FHScrollBar.Height:= FScrollBarWidth; +end; + procedure TfpgListView.SetShiftIsPressed(const AValue: Boolean); begin if AValue = FShiftIsPressed then @@ -1077,7 +1088,7 @@ end; procedure TfpgListView.MsgPaint(var msg: TfpgMessageRec); begin // Optimises painting and prevents Begin[End]Draw and OnPaint event firing - // in not needed. + // if not needed. if FUpdateCount = 0 then inherited MsgPaint(msg); end; @@ -1404,23 +1415,38 @@ end; procedure TfpgListView.HandlePaint; var ClipRect: TfpgRect; + rect: TRect; begin //if FScrollBarNeedsUpdate then UpdateScrollBarPositions; - fpgStyle.DrawControlFrame(Canvas, 0, 0, Width, Height); - - ClipRect.SetRect(2, 2, Width-4, Height-4); + Canvas.ClearClipRect; + ClipRect.SetRect(0, 0, Width, Height); + fpgStyle.DrawControlFrame(Canvas, ClipRect); + rect := fpgStyle.GetControlFrameBorders; + InflateRect(ClipRect, -rect.Left, -rect.Top); { assuming borders are even on opposite sides } Canvas.SetClipRect(ClipRect); + if Enabled then + begin +// if ReadOnly then +// Canvas.SetColor(clWindowBackground) +// else + Canvas.SetColor(FBackgroundColor); + end + else + Canvas.SetColor(clWindowBackground); + + Canvas.FillRectangle(ClipRect); + // This paints the small square remaining below the vscrollbar // and to the right of the hscrollbar if FVScrollBar.Visible and FHScrollBar.Visible then begin Canvas.Color := clButtonFace; - Canvas.FillRectangle(Width - 2 - FVScrollBar.Width, - Height - 2 - FHScrollBar.Height, - Width - 2, - Height - 2); + Canvas.FillRectangle(FHScrollBar.Left+FHScrollBar.Width, + FVScrollBar.Top+FVScrollBar.Height, + FVScrollBar.Width, + FHScrollBar.Height); end; if FVScrollBar.Visible then @@ -1777,6 +1803,7 @@ begin FSelectionFollowsFocus := True; FItemIndex := -1; FScrollBarNeedsUpdate := True; + FScrollBarWidth := FVScrollBar.Width; end; destructor TfpgListView.Destroy; diff --git a/src/gui/fpg_memo.pas b/src/gui/fpg_memo.pas index df16367b..374c8d47 100644 --- a/src/gui/fpg_memo.pas +++ b/src/gui/fpg_memo.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -145,9 +145,17 @@ type property TabOrder; property TextColor; property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnDragEnter; + property OnDragLeave; + property OnDragDrop; + property OnDragStartDetected; property OnEnter; property OnExit; + property OnKeyChar; property OnKeyPress; + property OnMouseEnter; + property OnMouseExit; + property OnPaint; property OnShowHint; end; @@ -938,7 +946,7 @@ begin end; ebsDefault: begin - Canvas.DrawControlFrame(r); + fpgStyle.DrawControlFrame(Canvas, r); InflateRect(r, -2, -2); end; ebsSingle: @@ -1058,11 +1066,14 @@ var s: string; ls: string; begin - inherited; + inherited HandleKeyChar(AText, shiftstate, consumed); + if consumed then + Exit; //==> + prevval := Text; s := AText; - if (not consumed) and (not ReadOnly) then + if (not ReadOnly) then begin // Printable characters only // Note: This is now UTF-8 compliant! @@ -1082,15 +1093,13 @@ begin FSelEndLine := -1; AdjustCursor; end; - consumed := True; end; if prevval <> Text then if Assigned(FOnChange) then FOnChange(self); - end; - + end; { if not ReadOnly } if consumed then RePaint; @@ -1670,6 +1679,7 @@ begin if FUpdateCount <= 0 then begin Invalidate; + RecalcLongestLine; UpdateScrollBars; end; end; diff --git a/src/gui/fpg_menu.pas b/src/gui/fpg_menu.pas index 91db5992..3f634c02 100644 --- a/src/gui/fpg_menu.pas +++ b/src/gui/fpg_menu.pas @@ -417,6 +417,8 @@ begin inherited HandleMouseMove(x, y, btnstate, shiftstate); newf := CalcMouseCol(x); + if newf = VisibleCount then + Exit; //mouse points over the last item // process menu options if mnuo_nofollowingmouse in FMenuOptions then @@ -467,6 +469,9 @@ begin Exit; // We have no menu items in MainMenu. newf := CalcMouseCol(x); + if newf = VisibleCount then + Exit; //mouse points over the last item + if (FLastItemClicked <> -1) and (FLastItemClicked <> newf) then begin // do nothing @@ -585,6 +590,7 @@ begin FHeight := fpgStyle.MenuFont.Height + 6; // 3px margin top and bottom FMenuOptions := []; FMouseIsOver := False; + FIsContainer := True; end; destructor TfpgMenuBar.Destroy; @@ -660,6 +666,8 @@ begin inc(w, ItemWidth(VisibleItem(n))); inc(n); end; + if x > w then + Result := n; end; function TfpgMenuBar.GetItemPosX(index: integer): integer; diff --git a/src/gui/fpg_panel.pas b/src/gui/fpg_panel.pas index 0a0c6e57..aedb7ace 100644 --- a/src/gui/fpg_panel.pas +++ b/src/gui/fpg_panel.pas @@ -177,6 +177,7 @@ type property OnMouseScroll; property OnMouseUp; property OnPaint; + property OnResize; property OnShowHint; end; @@ -307,8 +308,8 @@ type constructor Create(AOwner: TComponent); override; destructor Destroy; override; property Image: TfpgImage read FImage write SetImage; - property OwnsImage: Boolean read FOwnsImage write FOwnsImage; - property ScaleImage: Boolean read FScaleImage write SetScaleImage; + property OwnsImage: Boolean read FOwnsImage write FOwnsImage default False; + property ScaleImage: Boolean read FScaleImage write SetScaleImage default False; end; @@ -1109,6 +1110,7 @@ begin inherited Create(AOwner); FImage := nil; FOwnsImage := False; + FScaleImage := False; end; destructor TfpgImagePanel.Destroy; diff --git a/src/gui/fpg_popupcalendar.pas b/src/gui/fpg_popupcalendar.pas index 87b9f3ad..fcadd9af 100644 --- a/src/gui/fpg_popupcalendar.pas +++ b/src/gui/fpg_popupcalendar.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -1151,7 +1151,7 @@ begin {%region 'Auto-generated GUI code' -fold} {@VFD_BODY_BEGIN: fpgPopupCalendar} Name := 'fpgPopupCalendar'; - SetPosition(370, 182, 233, 142); + SetPosition(370, 182, 235, 149); Hint := ''; edtYear := TfpgEdit.Create(self); @@ -1268,7 +1268,7 @@ begin with grdName1 do begin Name := 'grdName1'; - SetPosition(0, 23, 233, 119); + SetPosition(0, 23, 235, 125); AddColumn('Sun', 33, taCenter); AddColumn('Mon', 32, taCenter); AddColumn('Tue', 33, taCenter); diff --git a/src/gui/fpg_radiobutton.pas b/src/gui/fpg_radiobutton.pas index 2ce8d566..76f36664 100644 --- a/src/gui/fpg_radiobutton.pas +++ b/src/gui/fpg_radiobutton.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -77,6 +77,17 @@ type property Text: string read FText write SetText; property TextColor; property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnDragEnter; + property OnDragLeave; + property OnDragDrop; + property OnDragStartDetected; + property OnEnter; + property OnExit; + property OnMouseDown; + property OnMouseExit; + property OnMouseEnter; + property OnMouseMove; + property OnMouseUp; property OnShowHint; end; diff --git a/src/gui/fpg_scrollbar.pas b/src/gui/fpg_scrollbar.pas index dd0a4c7c..1ec78952 100644 --- a/src/gui/fpg_scrollbar.pas +++ b/src/gui/fpg_scrollbar.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -21,10 +21,7 @@ unit fpg_scrollbar; { TODO: - * Set slider button to minimum length (default setting) * Create property to enable dynamic sizing of slider button length. - * Paint scroll area between arrow buttons and slider button a different - color on click. } interface @@ -39,7 +36,7 @@ uses type TScrollNotifyEvent = procedure(Sender: TObject; position: integer) of object; - TfpgScrollStyle = (ssNone, ssHorizontal, ssVertical, ssAutoBoth); + TfpgScrollStyle = (ssNone, ssHorizontal, ssVertical, ssAutoBoth, ssBothVisible); TfpgScrollBarPart = (sbpNone, sbpUpBack, sbpPageUpBack, sbpSlider, sbpDownForward, sbpPageDownForward); @@ -137,7 +134,6 @@ end; procedure TfpgScrollBar.HandlePaint; begin - Canvas.BeginDraw; // Do not remove - Scrollbars do painting outside HandlePaint as well! if Orientation = orVertical then begin DrawButton(0, 0, Width, Width, 'sys.sb.up', (FScrollbarDownPart = sbpUpBack) and (FPosition <> FMin), (FPosition <> FMin) and (Parent.Enabled)); @@ -148,9 +144,7 @@ begin DrawButton(0, 0, Height, Height, 'sys.sb.left', (FScrollbarDownPart = sbpUpBack) and (FPosition <> FMin), (FPosition <> FMin) and (Parent.Enabled)); DrawButton(Width-Height, 0, Height, Height, 'sys.sb.right', (FScrollbarDownPart = sbpDownForward) and (FPosition <> FMax), (FPosition <> FMax) and (Parent.Enabled)); end; - DrawSlider(FRecalc); - Canvas.EndDraw; // Do not remove - Scrollbars do painting outside HandlePaint as well! FRecalc := False; end; @@ -165,7 +159,7 @@ begin if not HasHandle then Exit; //==> FRecalc := True; - Invalidate;// DrawSlider(True); + Invalidate; end; procedure TfpgScrollBar.LineUp; @@ -222,7 +216,7 @@ begin FPosition := AValue; if HasHandle then - Invalidate;// DrawSlider(False); + Invalidate; end; procedure TfpgScrollBar.Step(ASteps: Integer); @@ -363,8 +357,6 @@ var area: TfpgCoord; mm: TfpgCoord; begin -// Canvas.BeginDraw; - if SliderSize > 1 then SliderSize := 1; @@ -372,12 +364,12 @@ begin if Orientation = orVertical then begin - Canvas.FillRectangle(0, Width, Width, Height-Width-Width); + Canvas.FillRectangle(0, Width, Width, Height - (2 * Width)); area := Height - (Width shl 1); end else begin - Canvas.FillRectangle(Height, 0, Width-Height-Height, Height); + Canvas.FillRectangle(Height, 0, Width - (2 * Height), Height); area := Width - (Height shl 1); end; @@ -414,7 +406,7 @@ begin else if FScrollbarDownPart in [{sbpDownForward,} sbpPageDownForward] then begin Canvas.SetColor(clShadow1); - Canvas.FillRectangle(0, FSliderPos + FSliderLength, Width, Height - Width - (FSliderPos + FSliderLength)); + Canvas.FillRectangle(0, Width + FSliderPos + FSliderLength, Width, Height - (2 * Width) - (FSliderPos + FSliderLength)); Canvas.SetColor(clScrollBar); end; end @@ -429,22 +421,16 @@ begin else if FScrollbarDownPart in [{sbpDownForward,} sbpPageDownForward] then begin Canvas.SetColor(clShadow1); - Canvas.FillRectangle(FSliderPos + FSliderLength, 0, Width - Height - (FSliderPos + FSliderLength), Height); + Canvas.FillRectangle(Height + FSliderPos + FSliderLength, 0, Width - (2 * Height) - (FSliderPos + FSliderLength), Height); Canvas.SetColor(clScrollBar); end; end; // Paint the slider button if Orientation = orVertical then - begin - Canvas.DrawButtonFace(0, Width + FSliderPos, Width, FSliderLength, [btfIsEmbedded]); -// Canvas.EndDraw(0, Width, Width, Height - Width - Width); - end + Canvas.DrawButtonFace(0, Width + FSliderPos, Width, FSliderLength, [btfIsEmbedded]) else - begin Canvas.DrawButtonFace(Height + FSliderPos, 0, FSliderLength, Height, [btfIsEmbedded]); -// Canvas.EndDraw(Height, 0, Width - Height - Height, Height); - end; end; procedure TfpgScrollBar.HandleLMouseDown(x, y: integer; shiftstate: TShiftState); @@ -587,7 +573,7 @@ begin FSliderPos := area; if ppos <> FSliderPos then - Invalidate; // DrawSlider(False); + Invalidate; if area <> 0 then newp := FMin + Trunc((FMax - FMin) * (FSliderPos / area)) @@ -620,7 +606,7 @@ begin if Visible then begin FRecalc := True; - Invalidate; // DrawSlider(True); + Invalidate; end; if Assigned(FOnScroll) then diff --git a/src/gui/fpg_scrollframe.pas b/src/gui/fpg_scrollframe.pas new file mode 100644 index 00000000..008832ce --- /dev/null +++ b/src/gui/fpg_scrollframe.pas @@ -0,0 +1,530 @@ +{ + fpGUI - Free Pascal GUI Toolkit + + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this + distribution, for details of the copyright. + + See the file COPYING.modifiedLGPL, included in this distribution, + for details about redistributing fpGUI. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + Defines a scrollable frame widget. + + This unit was originally written by David Emerson <dle3ab@angelbase.com> +} +unit fpg_scrollframe; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, + SysUtils, + fpg_base, + fpg_main, + fpg_widget, + fpg_panel, + fpg_scrollbar; + +type + + TfpgScrollFrame = class; + + + TfpgEmbeddingFrame = class (TfpgFrame) + // The purpose of the EmbeddingFrame is to pass scroll events to the ParentScrollFrame + private + FParentScrollFrame : TfpgScrollFrame; + protected + procedure HandleMouseScroll(x, y: integer; shiftstate: TShiftState; + delta: smallint); override; + procedure HandleMouseHorizScroll(x, y: integer; shiftstate: TShiftState; + delta: smallint); override; + public + property ParentScrollFrame : TfpgScrollFrame read FParentScrollFrame write FParentScrollFrame; + end; + + + TfpgAutoSizingFrame = class (TfpgEmbeddingFrame) + private + FMarginBR : integer; + procedure SetMarginBR (AValue: integer); + public + procedure AfterConstruction; override; + procedure AdjustDimsFor (w : TfpgWidget; updatewp: boolean = true); + procedure AdjustDimsWithout (w : TfpgWidget); + procedure RecalcFrameSize; + property MarginBR : integer read FMarginBR write SetMarginBR; // bottom-right margin + end; + + TfpgASFrameClass = class of TfpgAutoSizingFrame; + + + TfpgScrollFrame = class(TfpgFrame) + private + FContentFrame: TfpgAutoSizingFrame; + FVisibleArea: TfpgEmbeddingFrame; + FHScrollBar: TfpgScrollBar; + FVScrollBar: TfpgScrollBar; + FScrollBarStyle: TfpgScrollStyle; + function GetXOffset: integer; + function GetYOffset: integer; + procedure SetXOffset(x: integer); + procedure SetYOffset(y: integer); + protected + procedure HandleMouseScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); override; + procedure HandleMouseHorizScroll(x, y: integer; shiftstate: TShiftState; delta: smallint); override; + procedure HandleResize(awidth, aheight: TfpgCoord); override; + procedure HandleShow; override; + procedure HandlePaint; override; + procedure HScrollBarMove(Sender: TObject; position: integer); + procedure VScrollBarMove(Sender: TObject; position: integer); + procedure UpdateScrollbars; virtual; + property XOffset: integer read GetXOffset write SetXOffset; // these do not... + property YOffset: integer read GetYOffset write SetYOffset; // ...updatewindowposition + public + constructor Create (AOwner: TComponent); override; + constructor Create (AOwner: TComponent; ContentFrameType: TfpgASFrameClass); virtual; + procedure AfterCreate; override; + procedure SetContentFrameType(AContentFrameType: TfpgASFrameClass); + property ContentFrame: TfpgAutoSizingFrame read FContentFrame write FContentFrame; + end; + + +implementation + + +{ TfpgEmbeddingFrame } + +procedure TfpgEmbeddingFrame.HandleMouseScroll(x, y: integer; + shiftstate: TShiftState; delta: smallint); +begin + ParentScrollFrame.HandleMouseScroll(x, y, shiftstate, delta); +end; + +procedure TfpgEmbeddingFrame.HandleMouseHorizScroll(x, y: integer; + shiftstate: TShiftState; delta: smallint); +begin + ParentScrollFrame.HandleMouseHorizScroll(x, y, shiftstate, delta); +end; + + +{ TfpgAutoSizingFrame } + +procedure TfpgAutoSizingFrame.SetMarginBR(AValue: integer); +begin + if FMarginBR=AValue then Exit; + FMarginBR:=AValue; + RecalcFrameSize; +end; + +procedure TfpgAutoSizingFrame.AfterConstruction; +begin + inherited AfterConstruction; + RecalcFrameSize; +end; + +procedure TfpgAutoSizingFrame.AdjustDimsFor (w: TfpgWidget; updatewp: boolean = true); +var + new_w, new_h: integer; +begin + if not w.Visible then + Exit; + new_w := w.Right+MarginBR+1; + new_h := w.Bottom+MarginBR+1; + if (Width < new_w) or (Height < new_h) then + begin + HandleResize(new_w, new_h); + if updatewp then + if ParentScrollFrame is TfpgScrollFrame then + ParentScrollFrame.UpdateScrollbars + else + UpdateWindowPosition; + end; +end; + +procedure TfpgAutoSizingFrame.AdjustDimsWithout (w: TfpgWidget); +begin + if (Width = w.Right+MarginBR+1) + or (Height = w.Bottom+MarginBR+1) then + RecalcFrameSize; +end; + +procedure TfpgAutoSizingFrame.RecalcFrameSize; +var + i : integer; + c : TComponent; + max_w, max_h : integer; + this_need : integer; + par : TfpgWidget; +begin + if ComponentCount=0 then + Exit; + max_w := 1; + max_h := 1; + for i := 0 to ComponentCount-1 do begin + c := Components[i]; + if c is TfpgWidget then + begin + if not TfpgWidget(c).Visible then + continue; + this_need := TfpgWidget(c).right+MarginBR+1; + if (this_need>max_w) then + max_w := this_need; + this_need := TfpgWidget(c).bottom+MarginBR+1; + if (this_need>max_h) then + max_h := this_need; + end; + end; + HandleResize(max_w, max_h); + if ParentScrollFrame is TfpgScrollFrame then + ParentScrollFrame.UpdateScrollbars + else + UpdateWindowPosition; +end; + + +{ TfpgScrollFrame } + +function TfpgScrollFrame.GetXOffset: integer; +begin + result := -FContentFrame.Left; +end; + +function TfpgScrollFrame.GetYOffset: integer; +begin + result := -FContentFrame.Top; +end; + +procedure TfpgScrollFrame.SetXOffset (x: integer); +begin + if ContentFrame.Left = -x then + Exit; + FContentFrame.Left := -x; +end; + +procedure TfpgScrollFrame.SetYOffset (y: integer); +begin + if ContentFrame.Top = -y then + Exit; + FContentFrame.Top := -y; +end; + +procedure TfpgScrollFrame.HandleMouseScroll(x, y: integer; + shiftstate: TShiftState; delta: smallint); +var + old_val, new_val : integer; +begin + inherited HandleMouseScroll(x, y, shiftstate, delta); + with FVScrollBar do + begin + if not Visible then + Exit; + Position:=Position+delta*ScrollStep; + if YOffset=Position then + Exit; + YOffset:=Position; + end; + UpdateScrollbars; +end; + +procedure TfpgScrollFrame.HandleMouseHorizScroll(x, y: integer; + shiftstate: TShiftState; delta: smallint); +begin + inherited HandleMouseHorizScroll(x, y, shiftstate, delta); + with FHScrollBar do + begin + if not Visible then + Exit; + Position:=Position+delta*ScrollStep; + if XOffset=Position then + Exit; + XOffset:=Position; + end; + UpdateScrollbars; +end; + +procedure TfpgScrollFrame.HandleResize(awidth, aheight: TfpgCoord); +begin + inherited HandleResize(awidth, aheight); + if (csLoading in ComponentState) or (csUpdating in ComponentState) then + Exit; //==> + if HasHandle then + UpdateScrollBars; +end; + +procedure TfpgScrollFrame.HandleShow; +begin + inherited HandleShow; + if (csLoading in ComponentState) then + Exit; + UpdateScrollBars; +end; + +procedure TfpgScrollFrame.HandlePaint; +begin + if csDesigning in ComponentState then + begin + // clear background rectangle + Canvas.Clear(clDarkGray); + // When designing, don't draw colors + // but draw an outline + Canvas.SetLineStyle(1, lsDash); + Canvas.DrawRectangle(GetClientRect); + Canvas.SetLineStyle(1, lsSolid); + Canvas.Color := clUIDesignerGreen; + Canvas.DrawLine(0, 0, Width, Height); + Canvas.DrawLine(Width, 0, 0, Height); + Canvas.TextColor := clShadow1; + Canvas.DrawText(5, 5, Name + ': ' + ClassName); + Exit; //==> + end; + + inherited HandlePaint; +end; + +procedure TfpgScrollFrame.HScrollBarMove (Sender: TObject; position: integer); +begin + if position = XOffset then + Exit; + XOffset := position; + FContentFrame.UpdateWindowPosition; +end; + +procedure TfpgScrollFrame.VScrollBarMove (Sender: TObject; position: integer); +begin + if position = YOffset then + Exit; + YOffset := position; + FContentFrame.UpdateWindowPosition; +end; + +procedure TfpgScrollFrame.UpdateScrollbars; +var + contentWidth, contentHeight: integer; + visWidth, visHeight: integer; + Hfits, Vfits : boolean; + showHsb, showVsb : boolean; + prevHideHsb, prevHideVsb : boolean; + + procedure hideScrollbar (sb : TfpgScrollBar); + begin + with sb do + if Visible then + begin + Visible := False; + UpdateWindowPosition; + end; + end; + + procedure getVisWidth; + begin + if showVsb then + visWidth := Width - (FVScrollBar.Width-1) + else + visWidth := Width; + Hfits := visWidth >= contentWidth + end; + + procedure getVisHeight; + begin + if showHsb then + visHeight := Height - (FHScrollBar.Height-1) + else + visHeight := Height; + Vfits := visHeight >= contentHeight; + end; + +begin + if (csLoading in ComponentState) or (csUpdating in ComponentState) then + Exit; //==> + + // if we don't want any scrollbars, hide them and exit + if FScrollBarStyle = ssNone then + begin + hideScrollbar (FHScrollBar); + hideScrollbar (FVScrollBar); + exit; + end; + + // preliminary width/height calculations + prevHideHsb := not FHScrollBar.Visible; + prevHideVsb := not FVScrollBar.Visible; + showVsb := (FScrollBarStyle = ssBothVisible); + showHsb := showVsb; + contentWidth := ContentFrame.Width; + contentHeight := ContentFrame.Height; + getVisWidth; + getVisHeight; + + // determine whether to show scrollbars for different configurations + case FScrollBarStyle of + ssHorizontal: + begin + hideScrollbar (FVScrollBar); + if not Hfits then + begin + showHsb := true; + getVisHeight; + end; + end; + ssVertical: + begin + hideScrollbar (FHScrollBar); + if not Vfits then + begin + showVsb := true; + getVisWidth; + end; + end; + ssAutoBoth: + if not Vfits then + begin + showVsb := true; + getVisWidth; + if not Hfits then + begin + showHsb := true; + getVisHeight; + getVisWidth; + end; + end + else if not Hfits then + begin + showHsb := true; + getVisHeight; + if not Vfits then + begin + showVsb := true; + getVisWidth; + getVisHeight; + end; + end; + end; + + // show or hide the scrollbars + + if showVsb then with FVScrollBar do + begin + if prevHideVsb then + Position := 0; + Visible := true; + Min := 0; + Max := contentHeight - visHeight; // may set position! + YOffset := Position; + if contentHeight > 0 then + SliderSize := visHeight / contentHeight + else + SliderSize := 0; + RepaintSlider; + Top := 0; + Left := visWidth; + Height := visHeight; + PageSize:= visHeight; + end + else + begin + FVScrollBar.Visible := false; + if Vfits then // if vertical doesn't fit and no scrollbar, do not change offset + YOffset := 0; + end; + + if showHsb then with FHScrollBar do + begin + if prevHideHsb then + Position := 0; + Visible := true; + Min := 0; + Max := contentWidth - visWidth; // may set position! + XOffset := Position; + if contentWidth > 0 then + SliderSize := visWidth / contentWidth + else + SliderSize := 0; + RepaintSlider; + Top := visHeight; + Left := 0; + Width := visWidth; + PageSize:= visWidth; + end + else + begin + FHScrollBar.Visible := false; + if Hfits then // if horizontal doesn't fit and no scrollbar, do not change offset + XOffset := 0; + end; + + FVScrollBar.UpdateWindowPosition; + FHScrollBar.UpdateWindowPosition; + + FVisibleArea.SetPosition(0, 0, visWidth, visHeight); + FVisibleArea.UpdateWindowPosition; + + FContentFrame.UpdateWindowPosition; +end; + +constructor TfpgScrollFrame.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + + FVisibleArea := TfpgEmbeddingFrame.Create(self); + FVisibleArea.HandleMove(0, 0); + FVisibleArea.ParentScrollFrame := self; + + FContentFrame := TfpgAutoSizingFrame.Create(FVisibleArea); + FContentFrame.HandleMove(0, 0); + FContentFrame.ParentScrollFrame := self; +end; + +constructor TfpgScrollFrame.Create(AOwner: TComponent; ContentFrameType: TfpgASFrameClass); +begin + inherited Create(AOwner); + + FVisibleArea := TfpgEmbeddingFrame.Create(self); + FVisibleArea.HandleMove(0, 0); + FVisibleArea.ParentScrollFrame := self; + + FContentFrame := ContentFrameType.Create(FVisibleArea); + FContentFrame.HandleMove(0, 0); + FContentFrame.ParentScrollFrame := self; +end; + +procedure TfpgScrollFrame.AfterCreate; +begin + inherited AfterCreate; + + FVScrollBar := TfpgScrollBar.Create(self); + with FVScrollBar do begin + Orientation := orVertical; + OnScroll := @VScrollBarMove; + Position := 0; + ScrollStep := 10; + end; + + FHScrollBar := TfpgScrollBar.Create(self); + with FHScrollBar do begin + Orientation := orHorizontal; + OnScroll := @HScrollBarMove; + Position := 0; + ScrollStep := 10; + end; + + FScrollBarStyle := ssAutoBoth; +end; + +procedure TfpgScrollFrame.SetContentFrameType(AContentFrameType: TfpgASFrameClass); +begin + if Assigned(FContentFrame) then + FContentFrame.Free; + FContentFrame := AContentFrameType.Create(FVisibleArea); + FContentFrame.HandleMove(0, 0); + FContentFrame.ParentScrollFrame := self; +end; + + +end. diff --git a/src/gui/fpg_spinedit.pas b/src/gui/fpg_spinedit.pas index 444fa2c0..6061eb3b 100644 --- a/src/gui/fpg_spinedit.pas +++ b/src/gui/fpg_spinedit.pas @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, @@ -262,7 +262,7 @@ begin newh := h; Result.SetPosition(x, y, w, newh); - if AMaxValue > AMinValue then + if AMaxValue >= AMinValue then begin Result.MinValue := AMinValue; Result.MaxValue := AMaxValue; @@ -288,7 +288,7 @@ begin newh := h; Result.SetPosition(x, y, w, newh); - if AMaxValue > AMinValue then + if AMaxValue >= AMinValue then begin Result.MinValue := AMinValue; Result.MaxValue := AMaxValue; @@ -550,27 +550,23 @@ end; procedure TfpgSpinEditFloat.SetMaxValue(const AValue: extended); begin - if (FMaxValue <> AValue) and (AValue > FMinValue) then + if (FMaxValue <> AValue) and (AValue >= FMinValue) then begin FMaxValue := AValue; if FValue > FMaxValue then - begin FValue := FMaxValue; - FEdit.Value := FValue; - end; + FEdit.Value := FValue; end; end; procedure TfpgSpinEditFloat.SetMinValue(const AValue: extended); begin - if (FMinValue <> AValue) and (AValue < FMaxValue) then + if (FMinValue <> AValue) and (AValue <= FMaxValue) then begin FMinValue := AValue; if FValue < FMinValue then - begin FValue := FMinValue; - FEdit.Value := FValue; - end; + FEdit.Value := FValue; end; end; @@ -990,27 +986,23 @@ end; procedure TfpgSpinEdit.SetMaxValue(const AValue: integer); begin - if (FMaxValue <> AValue) and (AValue > FMinValue) then + if (FMaxValue <> AValue) and (AValue >= FMinValue) then begin FMaxValue := AValue; if FValue > FMaxValue then - begin FValue := FMaxValue; - FEdit.Value := FValue; - end; + FEdit.Value := FValue; end; end; procedure TfpgSpinEdit.SetMinValue(const AValue: integer); begin - if (FMinValue <> AValue) and (AValue < FMaxValue) then + if (FMinValue <> AValue) and (AValue <= FMaxValue) then begin FMinValue := AValue; if FValue < FMinValue then - begin FValue := FMinValue; - FEdit.Value := FValue; - end; + FEdit.Value := FValue; end; end; diff --git a/src/gui/fpg_style_carbon.pas b/src/gui/fpg_style_carbon.pas new file mode 100644 index 00000000..6ad720ee --- /dev/null +++ b/src/gui/fpg_style_carbon.pas @@ -0,0 +1,250 @@ +{ + fpGUI - Free Pascal GUI Toolkit + + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this + distribution, for details of the copyright. + + See the file COPYING.modifiedLGPL, included in this distribution, + for details about redistributing fpGUI. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + Carbon fpGUI styles + + Author: Rochdi Abdelilah +} + +unit fpg_style_carbon; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, + fpg_main, + fpg_base; + +type + + TfpgCarbonStyle = class(TfpgStyle) + public + constructor Create; override; + { General } + procedure DrawControlFrame(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord); override; + function GetControlFrameBorders: TRect; override; + procedure DrawBevel(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; ARaised: boolean = True); override; + procedure DrawDirectionArrow(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; direction: TArrowDirection); override; + procedure DrawString(ACanvas: TfpgCanvas; x, y: TfpgCoord; AText: string; AEnabled: boolean = True); override; + procedure DrawFocusRect(ACanvas: TfpgCanvas; r: TfpgRect); override; + { Buttons } + procedure DrawButtonFace(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; AFlags: TfpgButtonFlags); override; + function GetButtonBorders: TRect; override; + function GetButtonShift: TPoint; override; + function HasButtonHoverEffect: boolean; override; + procedure DrawMenuBar(ACanvas: TfpgCanvas; r: TfpgRect; ABackgroundColor: TfpgColor); override; + procedure DrawMenuRow(ACanvas: TfpgCanvas; r: TfpgRect; AFlags: TfpgMenuItemFlags); override; + procedure DrawMenuItemSeparator(ACanvas: TfpgCanvas; r: TfpgRect); override; + end; + + +implementation + +uses + fpg_stylemanager; + +const + CarbonBaseColors: array [0..15] of TfpgColor = ( + $FF333333, $FF191919, $FF616161, + $FF202020, $FF474747, $FFC0C0C0, + $FF6E6E6E, $FF3399FF, $FFEAEAEA, + $FF2D2D2D, $FF494949, $FF24617A, + $FF353535, $FF434343, $FF313131, + $FF27546A); + +{ TfpgCarbonStyle } + +constructor TfpgCarbonStyle.Create; +begin + inherited Create; + fpgSetNamedColor(clWindowBackground, CarbonBaseColors[0]); + fpgSetNamedColor(clBoxColor, CarbonBaseColors[1]); + fpgSetNamedColor(clShadow1, CarbonBaseColors[2]); + fpgSetNamedColor(clShadow2, CarbonBaseColors[1]); + fpgSetNamedColor(clHilite1, CarbonBaseColors[3]); + fpgSetNamedColor(clHilite2, CarbonBaseColors[4]); + fpgSetNamedColor(clText1, CarbonBaseColors[5]); + fpgSetNamedColor(clText4, CarbonBaseColors[6]); + fpgSetNamedColor(clSelection, CarbonBaseColors[7]); + fpgSetNamedColor(clSelectionText, CarbonBaseColors[8]); + fpgSetNamedColor(clInactiveSel, CarbonBaseColors[7]); + fpgSetNamedColor(clInactiveSelText, CarbonBaseColors[8]); + fpgSetNamedColor(clScrollBar, CarbonBaseColors[9]); + fpgSetNamedColor(clButtonFace, CarbonBaseColors[0]); + fpgSetNamedColor(clListBox, CarbonBaseColors[1]); + fpgSetNamedColor(clGridLines, CarbonBaseColors[2]); + fpgSetNamedColor(clGridHeader, CarbonBaseColors[0]); + fpgSetNamedColor(clWidgetFrame, CarbonBaseColors[2]); + fpgSetNamedColor(clInactiveWgFrame, CarbonBaseColors[10]); + fpgSetNamedColor(clUnset, CarbonBaseColors[11]); + fpgSetNamedColor(clMenuText, CarbonBaseColors[5]); + fpgSetNamedColor(clMenuDisabled, CarbonBaseColors[0]); + fpgSetNamedColor(clHintWindow, CarbonBaseColors[0]); + fpgSetNamedColor(clGridSelection, CarbonBaseColors[7]); + fpgSetNamedColor(clGridSelectionText, CarbonBaseColors[8]); + fpgSetNamedColor(clGridInactiveSel, CarbonBaseColors[7]); + fpgSetNamedColor(clGridInactiveSelText, CarbonBaseColors[8]); + fpgSetNamedColor(clSplitterGrabBar, CarbonBaseColors[7]); +end; + +procedure TfpgCarbonStyle.DrawControlFrame(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord); +var + r: TfpgRect; +begin + r.SetRect(x, y, w, h); + ACanvas.SetColor(clShadow1); + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.DrawRectangle(r); +end; + +function TfpgCarbonStyle.GetControlFrameBorders: TRect; +begin + Result := Rect(1, 1, 1, 1); +end; + +procedure TfpgCarbonStyle.DrawBevel(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; + ARaised: boolean); +begin + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.GradientFill(fpgRect(x,y,w,h), clUnset, CarbonBaseColors[15], gdVertical); + ACanvas.SetColor(clHilite1); + ACanvas.DrawRectangle(x, y, w, h); +end; + +procedure TfpgCarbonStyle.DrawDirectionArrow(ACanvas: TfpgCanvas; + x, y, w, h: TfpgCoord; direction: TArrowDirection); +begin + ACanvas.SetColor(clBoxColor); + inherited DrawDirectionArrow(ACanvas, x + 1, y + 1, w, h, direction); +end; + +procedure TfpgCarbonStyle.DrawString(ACanvas: TfpgCanvas; x, y: TfpgCoord; + AText: string; AEnabled: boolean); +begin + if AText = '' then + Exit; + if not AEnabled then + ACanvas.SetTextColor(clText4) + else + ACanvas.SetTextColor(clText1); + ACanvas.DrawString(x, y, AText); +end; + +procedure TfpgCarbonStyle.DrawButtonFace(ACanvas: TfpgCanvas; + x, y, w, h: TfpgCoord; AFlags: TfpgButtonFlags); +var + r: TfpgRect; +begin + ACanvas.SetColor(clBoxColor); + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.FillRectangle(x, y, w, h); + + r.SetRect(x + 1, y + 1, w - 2, h - 2); + + if (btfIsPressed in AFlags) then + begin + if (btfFlat in AFlags) or (btfHover in AFlags) then + ACanvas.SetColor(clHilite2) + else + begin + ACanvas.GradientFill(r, CarbonBaseColors[14], CarbonBaseColors[13], gdVertical); + ACanvas.SetColor(clInactiveWgFrame); + end; + end + else + begin + if btfHover in AFlags then + begin + ACanvas.GradientFill(r, clHilite2, CarbonBaseColors[12], gdVertical); + ACanvas.SetColor(clShadow1); + end + else + begin + if not ((btfFlat in AFlags) and not (btfIsPressed in AFlags)) then + begin + ACanvas.GradientFill(r, CarbonBaseColors[13], CarbonBaseColors[14], gdVertical); + ACanvas.SetColor(clInactiveWgFrame); + end + else if btfFlat in AFlags then + begin + ACanvas.SetColor(clButtonFace); + ACanvas.FillRectangle(r); + end; + end; + end; + + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.DrawRectangle(r); + if btfIsDefault in AFlags then + begin + ACanvas.SetColor(clUnset); + ACanvas.DrawLine(2, 1, w - 2, 1); + ACanvas.DrawLine(2, h - 2, w - 2, h - 2); + end; +end; + +function TfpgCarbonStyle.GetButtonBorders: TRect; +begin + Result := Rect(2, 2, 2, 2); +end; + +function TfpgCarbonStyle.GetButtonShift: TPoint; +begin + Result := Point(0, 0); +end; + +function TfpgCarbonStyle.HasButtonHoverEffect: boolean; +begin + Result := True; +end; + +procedure TfpgCarbonStyle.DrawMenuRow(ACanvas: TfpgCanvas; r: TfpgRect; + AFlags: TfpgMenuItemFlags); +begin + inherited DrawMenuRow(ACanvas, r, AFlags); + if (mifSelected in AFlags) and not (mifSeparator in AFlags) then + ACanvas.GradientFill(r, clUnset, CarbonBaseColors[15], gdVertical); +end; + + +procedure TfpgCarbonStyle.DrawMenuBar(ACanvas: TfpgCanvas; r: TfpgRect; + ABackgroundColor: TfpgColor); +begin + ACanvas.Clear(clWindowBackground); + ACanvas.SetColor(clShadow1); + ACanvas.DrawLine(r.Left, r.Bottom-1, r.Right + 1, r.Bottom-1); + ACanvas.SetColor(clBoxColor); + ACanvas.DrawLine(r.Left, r.Bottom, r.Right + 1, r.Bottom); +end; + +procedure TfpgCarbonStyle.DrawMenuItemSeparator(ACanvas: TfpgCanvas; r: TfpgRect); +begin + ACanvas.SetColor(clBoxColor); + ACanvas.DrawLine(r.Left + 1, r.Top + 2, r.Right, r.Top + 2); +end; + +procedure TfpgCarbonStyle.DrawFocusRect(ACanvas: TfpgCanvas; r: TfpgRect); +begin + ACanvas.SetColor(clUnset); + ACanvas.SetLineStyle(1, lsSolid); + //InflateRect(r, 1, 1); + ACanvas.DrawRectangle(r); +end; + +initialization + fpgStyleManager.RegisterClass('Carbon', TfpgCarbonStyle); + +end. diff --git a/src/gui/fpg_style_plastic.pas b/src/gui/fpg_style_plastic.pas new file mode 100644 index 00000000..2bb43159 --- /dev/null +++ b/src/gui/fpg_style_plastic.pas @@ -0,0 +1,376 @@ +{ + fpGUI - Free Pascal GUI Toolkit + + Copyright (C) 2006 - 2013 See the file AUTHORS.txt, included in this + distribution, for details of the copyright. + + See the file COPYING.modifiedLGPL, included in this distribution, + for details about redistributing fpGUI. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + Plastic fpGUI styles + + Author: Rochdi Abdelilah +} + +{$define RegPlasticDark} +{$define RegPlasticDarkGray} +{$define RegPlasticMediumGray} +{$define RegPlasticLightGray} + +{$IF not defined(RegPlasticDark) and + not defined(RegPlasticDarkGray) and + not defined(RegPlasticMediumGray) and + not defined(RegPlasticLightGray))} + {$define RegPlasticDark} +{$ifend} + +unit fpg_style_plastic; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, + fpg_main, + fpg_base; + +type + TPlasticColors = array [0..22] of TfpgColor; + PPlasticColors = ^TPlasticColors; + + TfpgPlasticStyle = class(TfpgStyle) + protected + FPlasticColors: PPlasticColors; + procedure LoadPlasticColors; virtual; abstract; + public + constructor Create; override; + { General } + procedure DrawControlFrame(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord); override; overload; + procedure DrawBevel(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; ARaised: boolean = True); override; + procedure DrawDirectionArrow(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; direction: TArrowDirection); override; + procedure DrawString(ACanvas: TfpgCanvas; x, y: TfpgCoord; AText: string; AEnabled: boolean = True); override; + procedure DrawFocusRect(ACanvas: TfpgCanvas; r: TfpgRect); override; + { Buttons } + procedure DrawButtonFace(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; AFlags: TfpgButtonFlags); override; + function GetButtonBorders: TRect; override; + function GetButtonShift: TPoint; override; + function HasButtonHoverEffect: boolean; override; + procedure DrawMenuBar(ACanvas: TfpgCanvas; r: TfpgRect; ABackgroundColor: TfpgColor); override; + { Menus } + procedure DrawMenuItemSeparator(ACanvas: TfpgCanvas; r: TfpgRect); override; + end; + + { TfpgPlasticDarkStyle } + + {$IFDEF RegPlasticDark} + TfpgPlasticDarkStyle = class(TfpgPlasticStyle) + protected + procedure LoadPlasticColors; override; + end; + {$ENDIF} + + { TfpgPlasticDarkGrayStyle } + + {$IFDEF RegPlasticDarkGray} + TfpgPlasticDarkGrayStyle = class(TfpgPlasticStyle) + protected + procedure LoadPlasticColors; override; + end; + {$ENDIF} + + { TfpgPlasticMediumGrayStyle } + + {$IFDEF RegPlasticMediumGray} + TfpgPlasticMediumGrayStyle = class(TfpgPlasticStyle) + protected + procedure LoadPlasticColors; override; + end; + {$ENDIF} + + { TfpgPlasticLightGrayStyle } + + {$IFDEF RegPlasticLightGray} + TfpgPlasticLightGrayStyle = class(TfpgPlasticStyle) + protected + procedure LoadPlasticColors; override; + end; + {$ENDIF} + +implementation + +uses + fpg_stylemanager; + +const + {$IFDEF RegPlasticDark} + PlasticDarkColors: TPlasticColors = + ($FF343434, $FF222222, $FF141414, $FF454545, + $FFDDDDDD, $FF4B5367, $FF464646, $FF101010, + $FF4A669B, $FF373737, $FF303030, $FF1F1F1F, + $FF878787, $FF696969, $FF646464, $FF4E4E4E, + $FF262626, $FF1D1D1D, $FF3D3D3D, $FF272727, + $FF282828, $FF292929, $FF2A2A2A); + {$ENDIF} + {$IFDEF RegPlasticDarkGray} + PlasticDarkGrayColors: TPlasticColors = + ($FF535353, $FF3a3a3a, $FF282828, $FF6A6A6A, + $FFE5E5E5, $FF596678, $FF6A6A6A, $FF303030, + $FF506FAC, $FF575757, $FF4D4D4D, $FF333333, + $FFA0A0A0, $FF919191, $FF848484, $FF757575, + $FF3F3F3F, $FF373737, $FF626262, $FF444444, + $FF464646, $FF474747, $FF484848); + {$ENDIF} + {$IFDEF RegPlasticMediumGray} + PlasticMediumGrayColors: TPlasticColors = + ($FFB8B8B8, $FFFFFFFF, $FF707070, $FFCDCDCD, + $FF373737, $FFB7CDF9, $FFC8C8C8, $FF686868, + $FF74AAF3, $FFBBBBBB, $FFA9A9A9, $FF7F7F7F, + $FFFAFAFA, $FFF7F7F7, $FFFEFEFE, $FFE7E7E7, + $FF8D8D8D, $FF868686, $FFBDBDBD, $FF909090, + $FF919191, $FF929292, $FF959595); + {$ENDIF} + {$IFDEF RegPlasticLightGray} + PlasticLightGrayColors: TPlasticColors = + ($FFD6D6D6, $FFFFFFFF, $FF737373, $FFEBEBEB, + $FF373737, $FFB7CDF9, $FFE8E8E8, $FF7C7C7C, + $FF9BCAFA, $FFD9D9D9, $FFC3C3C3, $FF999999, + $FFFFFFFF, $FFF5F5F5, $FFFEFEFE, $FFE6E6E6, + $FFA9A9A9, $FFA0A0A0, $FFD7D7D7, $FFACACAC, + $FFAEAEAE, $FFB7B7B7, $FFBABABA); + {$ENDIF} + +{ TfpgPlasticLightGrayStyle } + +{$IFDEF RegPlasticLightGray} +procedure TfpgPlasticLightGrayStyle.LoadPlasticColors; +begin + FPlasticColors := @PlasticLightGrayColors; +end; +{$ENDIF} + +{ TfpgPlasticMediumGrayStyle } + +{$IFDEF RegPlasticMediumGray} +procedure TfpgPlasticMediumGrayStyle.LoadPlasticColors; +begin + FPlasticColors := @PlasticMediumGrayColors; +end; +{$ENDIF} + +{ TfpgPlasticDarkGrayStyle } + +{$IFDEF RegPlasticDarkGray} +procedure TfpgPlasticDarkGrayStyle.LoadPlasticColors; +begin + FPlasticColors := @PlasticDarkGrayColors; +end; +{$ENDIF} + +{ TfpgPlasticDarkStyle } + +{$IFDEF RegPlasticDark} +procedure TfpgPlasticDarkStyle.LoadPlasticColors; +begin + FPlasticColors := @PlasticDarkColors; +end; +{$ENDIF} + +{ TfpgPlasticStyle } + +constructor TfpgPlasticStyle.Create; +begin + inherited Create; + LoadPlasticColors; + fpgSetNamedColor(clWindowBackground, FPlasticColors^[0]); + fpgSetNamedColor(clBoxColor, FPlasticColors^[1]); + fpgSetNamedColor(clShadow1, FPlasticColors^[2]); + fpgSetNamedColor(clShadow2, FPlasticColors^[3]); + fpgSetNamedColor(clHilite1, FPlasticColors^[3]); + fpgSetNamedColor(clHilite2, FPlasticColors^[3]); + fpgSetNamedColor(clText1, FPlasticColors^[4]); + fpgSetNamedColor(clText4, FPlasticColors^[2]); + fpgSetNamedColor(clSelection, FPlasticColors^[5]); + fpgSetNamedColor(clSelectionText, FPlasticColors^[4]); + fpgSetNamedColor(clInactiveSel, FPlasticColors^[5]); + fpgSetNamedColor(clInactiveSelText, FPlasticColors^[4]); + fpgSetNamedColor(clScrollBar, FPlasticColors^[6]); + fpgSetNamedColor(clButtonFace, FPlasticColors^[0]); + fpgSetNamedColor(clListBox, FPlasticColors^[1]); + fpgSetNamedColor(clGridLines, FPlasticColors^[7]); + fpgSetNamedColor(clGridHeader, FPlasticColors^[0]); + fpgSetNamedColor(clWidgetFrame, FPlasticColors^[3]); + fpgSetNamedColor(clInactiveWgFrame, FPlasticColors^[2]); + fpgSetNamedColor(clMenuText, FPlasticColors^[4]); + fpgSetNamedColor(clHintWindow, FPlasticColors^[1]); + fpgSetNamedColor(clGridSelection, FPlasticColors^[5]); + fpgSetNamedColor(clGridSelectionText, FPlasticColors^[4]); + fpgSetNamedColor(clGridInactiveSel, FPlasticColors^[5]); + fpgSetNamedColor(clGridInactiveSelText, FPlasticColors^[4]); + fpgSetNamedColor(clSplitterGrabBar, FPlasticColors^[8]); +end; + +procedure TfpgPlasticStyle.DrawDirectionArrow(ACanvas: TfpgCanvas; + x, y, w, h: TfpgCoord; direction: TArrowDirection); +begin + ACanvas.SetColor(clText1); + inherited DrawDirectionArrow(ACanvas, x + 2, y + 1, w - 2, h - 3, direction); +end; + +procedure TfpgPlasticStyle.DrawBevel(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; + ARaised: boolean); +begin + DrawButtonFace(ACanvas, x, y, w, h, [btfIsPressed]); +end; + +procedure TfpgPlasticStyle.DrawString(ACanvas: TfpgCanvas; x, y: TfpgCoord; + AText: string; AEnabled: boolean); +var + lOldColor: TfpgColor; +begin + if AText = '' then + Exit; + lOldColor := ACanvas.TextColor; + if not AEnabled then + ACanvas.SetTextColor(clText4) + else + ACanvas.SetTextColor(clText1); + if lOldColor = clShadow1 then + ACanvas.SetTextColor(clHilite2); + ACanvas.DrawString(x, y, AText); + if lOldColor <> clBlue then + ACanvas.SetTextColor(lOldColor); +end; + +procedure TfpgPlasticStyle.DrawControlFrame(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord); +begin + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.GradientFill(fpgRect(x, y, w, h), clWindowBackground, clScrollBar, gdVertical); + ACanvas.Pixels[x, y + h - 1] := FPlasticColors^[9]; + ACanvas.Pixels[x + w - 1, y + h - 1] := FPlasticColors^[9]; + ACanvas.SetColor(clGridLines); + ACanvas.DrawRectangle(fpgRect(x + 1, y + 1, w - 2, h - 2)); + ACanvas.Pixels[x + 1, y + 1] := FPlasticColors^[10]; + ACanvas.Pixels[x + w - 2, y + 1] := FPlasticColors^[10]; + ACanvas.Pixels[x + 1, y + h - 2] := FPlasticColors^[10]; + ACanvas.Pixels[x + w - 2, y + h - 2] := FPlasticColors^[10]; +end; + +procedure TfpgPlasticStyle.DrawFocusRect(ACanvas: TfpgCanvas; r: TfpgRect); +begin + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.SetColor(clSplitterGrabBar); + ACanvas.DrawRectangle(r); + ACanvas.Pixels[r.Left, r.Top] := FPlasticColors^[9]; + ACanvas.Pixels[r.Left + 1, r.Top + 1] := clSplitterGrabBar; + ACanvas.Pixels[r.Width - 1, r.Top] := FPlasticColors^[9]; + ACanvas.Pixels[r.Width - 2, r.Top + 1] := clSplitterGrabBar; + ACanvas.Pixels[r.Left, r.Height - 1] := FPlasticColors^[9]; + ACanvas.Pixels[r.Left + 1, r.Height - 2] := clSplitterGrabBar; + ACanvas.Pixels[r.Width - 1, r.Height - 1] := FPlasticColors^[9]; + ACanvas.Pixels[r.Width - 2, r.Height - 2] := clSplitterGrabBar; +end; + +procedure TfpgPlasticStyle.DrawButtonFace(ACanvas: TfpgCanvas; + x, y, w, h: TfpgCoord; AFlags: TfpgButtonFlags); +var + r: TfpgRect; +begin + ACanvas.SetLineStyle(1, lsSolid); + r.SetRect(x, y, w, h); + DrawControlFrame(ACanvas, r); + r.SetRect(x + 2, y + 3, w - 4, h - 5); + + if (btfIsPressed in AFlags) then + begin + ACanvas.GradientFill(r, FPlasticColors^[16], FPlasticColors^[17], gdVertical); + ACanvas.SetColor(FPlasticColors^[11]); + end + else + begin + if btfHover in AFlags then + begin + ACanvas.GradientFill(r, FPlasticColors^[14], FPlasticColors^[15], gdVertical); + ACanvas.SetColor(FPlasticColors^[12]); + end + else + begin + if not ((btfFlat in AFlags) and not (btfIsPressed in AFlags)) then + begin + ACanvas.GradientFill(r, FPlasticColors^[15], FPlasticColors^[18], gdVertical); + ACanvas.SetColor(FPlasticColors^[13]); + end + else if btfFlat in AFlags then + begin + ACanvas.SetColor(clWindowBackground); + ACanvas.FillRectangle(r); + end; + end; + end; + if not (btfFlat in AFlags) then + begin + if (btfIsDefault in AFlags) and not (btfIsPressed in AFlags) and + not (btfHasFocus in AFlags) then + ACanvas.SetColor(clSplitterGrabBar); + ACanvas.DrawLine(x + 2, y + 2, x + w - 2, y + 2); + end; + ACanvas.Pixels[x + 2, y + 2] := FPlasticColors^[19]; + ACanvas.Pixels[x + w - 3, y + 2] := FPlasticColors^[20]; + ACanvas.Pixels[x + 2, y + h - 3] := FPlasticColors^[21]; + ACanvas.Pixels[x + w - 3, y + h - 3] := FPlasticColors^[22]; +end; + +function TfpgPlasticStyle.GetButtonBorders: TRect; +begin + Result := Rect(0, 0, 0, 0); +end; + +function TfpgPlasticStyle.GetButtonShift: TPoint; +begin + Result := Point(0, 0); +end; + +function TfpgPlasticStyle.HasButtonHoverEffect: boolean; +begin + Result := True; +end; + +procedure TfpgPlasticStyle.DrawMenuBar(ACanvas: TfpgCanvas; r: TfpgRect; + ABackgroundColor: TfpgColor); +begin + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.SetColor(clWindowBackground); + ACanvas.FillRectangle(r); + ACanvas.SetColor(clShadow2); + ACanvas.DrawLine(r.Left, r.Top, r.Left + r.Right, r.Top); + DrawMenuItemSeparator(ACanvas, fpgRect(r.Left - 1, r.Height - 4, r.Width, r.Height)); +end; + +procedure TfpgPlasticStyle.DrawMenuItemSeparator(ACanvas: TfpgCanvas; r: TfpgRect); +begin + ACanvas.SetColor(clShadow1); + ACanvas.DrawLine(r.Left + 1, r.Top + 2, r.Right, r.Top + 2); + ACanvas.SetColor(clShadow2); + ACanvas.DrawLine(r.Left + 1, r.Top + 3, r.Right, r.Top + 3); +end; + + +initialization + {$IFDEF RegPlasticDark} + fpgStyleManager.RegisterClass('Plastic Dark', TfpgPlasticDarkStyle); + {$ENDIF} + {$IFDEF RegPlasticDarkGray} + fpgStyleManager.RegisterClass('Plastic Dark Gray', TfpgPlasticDarkGrayStyle); + {$ENDIF} + {$IFDEF RegPlasticMediumGray} + fpgStyleManager.RegisterClass('Plastic Medium Gray', TfpgPlasticMediumGrayStyle); + {$ENDIF} + {$IFDEF RegPlasticLightGray} + fpgStyleManager.RegisterClass('Plastic Light Gray', TfpgPlasticLightGrayStyle); + {$ENDIF} +end. diff --git a/src/gui/fpg_style_win8.pas b/src/gui/fpg_style_win8.pas new file mode 100644 index 00000000..f3d99705 --- /dev/null +++ b/src/gui/fpg_style_win8.pas @@ -0,0 +1,541 @@ +{ + fpGUI - Free Pascal GUI Toolkit + + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this + distribution, for details of the copyright. + + See the file COPYING.modifiedLGPL, included in this distribution, + for details about redistributing fpGUI. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit implements a Windows 8 (I think) look-alike style + + Author: Graeme Geldenhuys +} + +unit fpg_style_win8; + +{$mode objfpc}{$H+} + +{ + *********************************************************** + ********** This is still under development! *********** + *********************************************************** + + It needs lots of testing and debugging. +} + +interface + +uses + Classes, + fpg_main, + fpg_base; + +type + TfpgWin8Style = class(TfpgStyle) + private + FImages: TfpgImages; + procedure LoadThemeImages; + public + constructor Create; override; + destructor Destroy; override; + { General } + procedure DrawControlFrame(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord); override; overload; + function GetControlFrameBorders: TRect; override; + { Buttons } + procedure DrawButtonFace(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; AFlags: TfpgButtonFlags); override; overload; + function GetButtonBorders: TRect; override; + { Combobox } + procedure DrawStaticComboBox(ACanvas: TfpgCanvas; r: TfpgRect; const IsEnabled: Boolean; const IsFocused: Boolean; const IsReadOnly: Boolean; const ABackgroundColor: TfpgColor; const AInternalBtnRect: TfpgRect; const ABtnPressed: Boolean); override; + { Checkbox } + procedure DrawCheckbox(ACanvas: TfpgCanvas; x, y: TfpgCoord; ix, iy: TfpgCoord); override; + end; + +implementation + +uses + fpg_stylemanager + ; + +const + Win8BaseColors: array [0..16] of TfpgColor = ( + $FFF0F0F0, $FF606060, $FFABADB3, + $FF202020, $FF474747, $FFC0C0C0, + $FF3399FF, $FF3399FF, $FFFFFFFF, + $FF2D2D2D, $FF494949, $FF24617A, + $FF353535, $FF434343, $FF313131, + $FF27546A, $FFE5E5E5); + + +{%region 'Byte arrays of images' -fold} +const + win8_checkboxes: array[0..2601] of byte = ( + 66, 77, 42, 10, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, + 0, 65, 0, 0, 0, 13, 0, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, + 244, 9, 0, 0,196, 14, 0, 0,196, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188, 0,112,112,112,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,112,112,112, + 112,112,112,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,112,112,112,188,188,188,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,188,188,188,188,188,188,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,188,188,188,188,188, + 188,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 188,188,188, 0,112,112,112,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,112,112,112,112,112,112,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,207,207,207,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,112,112,112,188,188,188, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,188, + 188,188,188,188,188,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,208,208,208,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,188,188,188,188,188,188,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,188,188,188, 0,112,112,112,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,112,112, + 112,112,112,112,255,255,255,255,255,255,255,255,255,255,255,255, 95, + 95, 95, 0, 0, 0,207,207,207,255,255,255,255,255,255,255,255,255, + 255,255,255,112,112,112,188,188,188,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,188,188,188,188,188,188,230,230,230, + 230,230,230,230,230,230,230,230,230,156,156,156,112,112,112,208,208, + 208,230,230,230,230,230,230,230,230,230,230,230,230,188,188,188,188, + 188,188,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,188,188,188, 0,112,112,112,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,112,112,112,112,112,112,255,255,255,255, + 255,255,239,239,239, 63, 63, 63, 0, 0, 0, 0, 0, 0, 47, 47, 47, + 255,255,255,255,255,255,255,255,255,255,255,255,112,112,112,188,188, + 188,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 188,188,188,188,188,188,230,230,230,230,230,230,223,223,223,141,141, + 141,112,112,112,112,112,112,134,134,134,230,230,230,230,230,230,230, + 230,230,230,230,230,188,188,188,188,188,188,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,188,188,188, 0,112,112,112, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,112, + 112,112,112,112,112,255,255,255,239,239,239, 47, 47, 47, 0, 0, 0, + 0, 0, 0, 15, 15, 15, 0, 0, 0,127,127,127,255,255,255,255,255, + 255,255,255,255,112,112,112,188,188,188,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,188,188,188,188,188,188,230,230, + 230,223,223,223,134,134,134,112,112,112,112,112,112,119,119,119,112, + 112,112,171,171,171,230,230,230,230,230,230,230,230,230,188,188,188, + 188,188,188,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,188,188,188, 0,112,112,112,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,112,112,112,112,112,112,255,255,255, + 159,159,159, 0, 0, 0, 15, 15, 15,207,207,207,175,175,175, 0, 0, + 0, 0, 0, 0,207,207,207,255,255,255,255,255,255,112,112,112,188, + 188,188,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,188,188,188,188,188,188,230,230,230,186,186,186,112,112,112,119, + 119,119,208,208,208,193,193,193,112,112,112,112,112,112,208,208,208, + 230,230,230,230,230,230,188,188,188,188,188,188,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,188,188,188, 0,112,112, + 112,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 112,112,112,112,112,112,255,255,255,255,255,255,127,127,127,207,207, + 207,255,255,255,255,255,255, 79, 79, 79, 0, 0, 0, 47, 47, 47,255, + 255,255,255,255,255,112,112,112,188,188,188,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,188,188,188,188,188,188,230, + 230,230,230,230,230,171,171,171,208,208,208,230,230,230,230,230,230, + 149,149,149,112,112,112,134,134,134,230,230,230,230,230,230,188,188, + 188,188,188,188,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,188,188,188, 0,112,112,112,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,112,112,112,112,112,112,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,239, + 239,239, 15, 15, 15, 0, 0, 0,127,127,127,255,255,255,112,112,112, + 188,188,188,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,188,188,188,188,188,188,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,223,223,223,119,119,119,112,112, + 112,171,171,171,230,230,230,188,188,188,188,188,188,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,188,188,188, 0,112, + 112,112,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,112,112,112,112,112,112,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,175,175,175, 0, 0, 0, + 15, 15, 15,255,255,255,112,112,112,188,188,188,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,188,188,188,188,188,188, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,193,193,193,112,112,112,119,119,119,230,230,230,188, + 188,188,188,188,188,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,188,188,188, 0,112,112,112,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,112,112,112,112,112,112,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,127,127,127,223,223,223,255,255,255,112,112, + 112,188,188,188,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,188,188,188,188,188,188,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,171, + 171,171,215,215,215,230,230,230,188,188,188,188,188,188,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,188,188,188, 0, + 112,112,112,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,112,112,112,112,112,112,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,112,112,112,188,188,188,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,188,188,188,188,188, + 188,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 188,188,188,188,188,188,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,188,188,188, 0,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 0); + + +const + win8_radiobuttons: array[0..2601] of byte = ( + 66, 77, 42, 10, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, + 0, 65, 0, 0, 0, 13, 0, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, + 244, 9, 0, 0,196, 14, 0, 0,196, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,255,255,255,255,255,255,255,255,255,209,209,209,168,168, + 168,134,134,134,115,115,115,134,134,134,168,168,168,209,209,209,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 209,209,209,168,168,168,134,134,134,115,115,115,134,134,134,168,168, + 168,209,209,209,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,233,233,233,214,214,214,199,199,199,189,189,189, + 199,199,199,214,214,214,233,233,233,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,233,233,233,214,214,214,199, + 199,199,189,189,189,199,199,199,214,214,214,233,233,233,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,233,233, + 233,214,214,214,199,199,199,189,189,189,199,199,199,214,214,214,233, + 233,233,255,255,255,255,255,255,255,255,255, 0,255,255,255,242,242, + 242,177,177,177,114,114,114,199,199,199,233,233,233,252,252,252,233, + 233,233,199,199,199,114,114,114,177,177,177,242,242,242,255,255,255, + 255,255,255,242,242,242,177,177,177,114,114,114,199,199,199,233,233, + 233,252,252,252,233,233,233,199,199,199,114,114,114,177,177,177,242, + 242,242,255,255,255,255,255,255,249,249,249,218,218,218,189,189,189, + 214,214,214,223,223,223,229,229,229,223,223,223,214,214,214,189,189, + 189,218,218,218,249,249,249,255,255,255,255,255,255,249,249,249,218, + 218,218,189,189,189,214,214,214,223,223,223,229,229,229,223,223,223, + 214,214,214,189,189,189,218,218,218,249,249,249,255,255,255,255,255, + 255,249,249,249,218,218,218,189,189,189,214,214,214,223,223,223,229, + 229,229,223,223,223,214,214,214,189,189,189,218,218,218,249,249,249, + 255,255,255, 0,255,255,255,177,177,177,184,184,184,249,249,249,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,249,249,249, + 184,184,184,177,177,177,255,255,255,255,255,255,177,177,177,184,184, + 184,249,249,249,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,249,249,249,184,184,184,177,177,177,255,255,255,255,255,255, + 218,218,218,209,209,209,228,228,228,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,228,228,228,209,209,209,218,218,218,255, + 255,255,255,255,255,218,218,218,209,209,209,228,228,228,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,228,228,228,209,209, + 209,218,218,218,255,255,255,255,255,255,218,218,218,209,209,209,228, + 228,228,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 228,228,228,209,209,209,218,218,218,255,255,255, 0,209,209,209,114, + 114,114,249,249,249,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,249,249,249,114,114,114,209,209, + 209,209,209,209,114,114,114,249,249,249,255,255,255,171,171,171, 95, + 95, 95, 42, 42, 42, 95, 95, 95,171,171,171,255,255,255,249,249,249, + 114,114,114,209,209,209,233,233,233,189,189,189,228,228,228,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,228,228,228,189,189,189,233,233,233,233,233,233,189,189,189, + 228,228,228,230,230,230,186,186,186,145,145,145,117,117,117,145,145, + 145,186,186,186,230,230,230,228,228,228,189,189,189,233,233,233,233, + 233,233,189,189,189,228,228,228,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,228,228,228,189,189, + 189,233,233,233, 0,168,168,168,199,199,199,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,199,199,199,168,168,168,168,168,168,199,199,199,255, + 255,255,171,171,171, 39, 39, 39, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 39, 39, 39,171,171,171,255,255,255,199,199,199,168,168,168,214,214, + 214,214,214,214,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,214,214,214, + 214,214,214,214,214,214,214,214,214,230,230,230,186,186,186,115,115, + 115,112,112,112,112,112,112,112,112,112,115,115,115,186,186,186,230, + 230,230,214,214,214,214,214,214,214,214,214,214,214,214,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,214,214,214,214,214,214, 0,134,134,134, + 233,233,233,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,233,233,233,134, + 134,134,134,134,134,233,233,233,255,255,255, 95, 95, 95, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 95, 95, 95,255,255, + 255,233,233,233,134,134,134,199,199,199,223,223,223,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,223,223,223,199,199,199,199,199,199,223,223, + 223,230,230,230,145,145,145,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,145,145,145,230,230,230,223,223,223,199,199,199, + 199,199,199,223,223,223,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,223, + 223,223,199,199,199, 0,115,115,115,252,252,252,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,252,252,252,115,115,115,115,115,115,252,252,252, + 255,255,255, 42, 42, 42, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 42, 42, 42,255,255,255,252,252,252,115,115,115,189, + 189,189,229,229,229,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,229,229, + 229,189,189,189,189,189,189,229,229,229,230,230,230,117,117,117,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,117,117,117, + 230,230,230,229,229,229,189,189,189,189,189,189,229,229,229,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,229,229,229,189,189,189, 0,134,134, + 134,233,233,233,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,233,233,233, + 134,134,134,134,134,134,233,233,233,255,255,255, 95, 95, 95, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 95, 95, 95,255, + 255,255,233,233,233,134,134,134,199,199,199,223,223,223,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,223,223,223,199,199,199,199,199,199,223, + 223,223,230,230,230,145,145,145,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,145,145,145,230,230,230,223,223,223,199,199, + 199,199,199,199,223,223,223,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 223,223,223,199,199,199, 0,168,168,168,199,199,199,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,199,199,199,168,168,168,168,168,168,199,199, + 199,255,255,255,171,171,171, 39, 39, 39, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 39, 39, 39,171,171,171,255,255,255,199,199,199,168,168,168, + 214,214,214,214,214,214,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,214, + 214,214,214,214,214,214,214,214,214,214,214,230,230,230,186,186,186, + 115,115,115,112,112,112,112,112,112,112,112,112,115,115,115,186,186, + 186,230,230,230,214,214,214,214,214,214,214,214,214,214,214,214,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,214,214,214,214,214,214, 0,209, + 209,209,114,114,114,249,249,249,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,249,249,249,114,114, + 114,209,209,209,209,209,209,114,114,114,249,249,249,255,255,255,171, + 171,171, 95, 95, 95, 42, 42, 42, 95, 95, 95,171,171,171,255,255,255, + 249,249,249,114,114,114,209,209,209,233,233,233,189,189,189,228,228, + 228,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,230,228,228,228,189,189,189,233,233,233,233,233,233, + 189,189,189,228,228,228,230,230,230,186,186,186,145,145,145,117,117, + 117,145,145,145,186,186,186,230,230,230,228,228,228,189,189,189,233, + 233,233,233,233,233,189,189,189,228,228,228,230,230,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,228,228, + 228,189,189,189,233,233,233, 0,255,255,255,177,177,177,184,184,184, + 249,249,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,249,249,249,184,184,184,177,177,177,255,255,255,255,255,255,177, + 177,177,184,184,184,249,249,249,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,249,249,249,184,184,184,177,177,177,255,255, + 255,255,255,255,218,218,218,209,209,209,228,228,228,230,230,230,230, + 230,230,230,230,230,230,230,230,230,230,230,228,228,228,209,209,209, + 218,218,218,255,255,255,255,255,255,218,218,218,209,209,209,228,228, + 228,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,228, + 228,228,209,209,209,218,218,218,255,255,255,255,255,255,218,218,218, + 209,209,209,228,228,228,230,230,230,230,230,230,230,230,230,230,230, + 230,230,230,230,228,228,228,209,209,209,218,218,218,255,255,255, 0, + 255,255,255,242,242,242,177,177,177,114,114,114,199,199,199,233,233, + 233,252,252,252,233,233,233,199,199,199,114,114,114,177,177,177,242, + 242,242,255,255,255,255,255,255,242,242,242,177,177,177,114,114,114, + 199,199,199,233,233,233,252,252,252,233,233,233,199,199,199,114,114, + 114,177,177,177,242,242,242,255,255,255,255,255,255,249,249,249,218, + 218,218,189,189,189,214,214,214,223,223,223,229,229,229,223,223,223, + 214,214,214,189,189,189,218,218,218,249,249,249,255,255,255,255,255, + 255,249,249,249,218,218,218,189,189,189,214,214,214,223,223,223,229, + 229,229,223,223,223,214,214,214,189,189,189,218,218,218,249,249,249, + 255,255,255,255,255,255,249,249,249,218,218,218,189,189,189,214,214, + 214,223,223,223,229,229,229,223,223,223,214,214,214,189,189,189,218, + 218,218,249,249,249,255,255,255, 0,255,255,255,255,255,255,255,255, + 255,209,209,209,168,168,168,134,134,134,115,115,115,134,134,134,168, + 168,168,209,209,209,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,209,209,209,168,168,168,134,134,134,115,115, + 115,134,134,134,168,168,168,209,209,209,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,233,233,233,214,214,214, + 199,199,199,189,189,189,199,199,199,214,214,214,233,233,233,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,233, + 233,233,214,214,214,199,199,199,189,189,189,199,199,199,214,214,214, + 233,233,233,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,233,233,233,214,214,214,199,199,199,189,189,189,199, + 199,199,214,214,214,233,233,233,255,255,255,255,255,255,255,255,255, + 0); + +{%endregion} + +{ TfpgWin8Style } + +procedure TfpgWin8Style.LoadThemeImages; +begin + //FImages.AddMaskedBMP( // 65x13 in total. 5 images of 13x13 each. + // 'win8.radiobuttons', + // @stdimg_radiobuttons, + // sizeof(stdimg_radiobuttons), 0,0); + + FImages.AddBMP( // 65x13 pixels. 5 images of 13x13 each. + 'win8.radiobuttons', + @win8_radiobuttons, + sizeof(win8_radiobuttons)); + + FImages.AddBMP( // 65x13 pixels. 5 images of 13x13 each. + 'win8.checkboxes', + @win8_checkboxes, + sizeof(win8_checkboxes)); +end; + +constructor TfpgWin8Style.Create; +begin + inherited Create; + FImages := TfpgImages.Create; + LoadThemeImages; + + fpgSetNamedColor(clWindowBackground, Win8BaseColors[0]); + //fpgSetNamedColor(clBoxColor, Win8BaseColors[1]); + fpgSetNamedColor(clShadow1, Win8BaseColors[2]); + fpgSetNamedColor(clShadow2, Win8BaseColors[1]); + //fpgSetNamedColor(clHilite1, Win8BaseColors[3]); + //fpgSetNamedColor(clHilite2, Win8BaseColors[4]); + //fpgSetNamedColor(clText1, Win8BaseColors[5]); + //fpgSetNamedColor(clText4, Win8BaseColors[6]); + fpgSetNamedColor(clSelection, Win8BaseColors[7]); + fpgSetNamedColor(clSelectionText, Win8BaseColors[8]); + //fpgSetNamedColor(clInactiveSel, Win8BaseColors[7]); + //fpgSetNamedColor(clInactiveSelText, Win8BaseColors[8]); + //fpgSetNamedColor(clScrollBar, Win8BaseColors[9]); + //fpgSetNamedColor(clButtonFace, Win8BaseColors[0]); + //fpgSetNamedColor(clListBox, Win8BaseColors[1]); + //fpgSetNamedColor(clGridLines, Win8BaseColors[2]); + //fpgSetNamedColor(clGridHeader, Win8BaseColors[0]); + fpgSetNamedColor(clWidgetFrame, Win8BaseColors[2]); + //fpgSetNamedColor(clInactiveWgFrame, Win8BaseColors[10]); + //fpgSetNamedColor(clUnset, Win8BaseColors[11]); + //fpgSetNamedColor(clMenuText, Win8BaseColors[5]); + //fpgSetNamedColor(clMenuDisabled, Win8BaseColors[0]); + //fpgSetNamedColor(clHintWindow, Win8BaseColors[0]); + //fpgSetNamedColor(clGridSelection, Win8BaseColors[7]); + //fpgSetNamedColor(clGridSelectionText, Win8BaseColors[8]); + //fpgSetNamedColor(clGridInactiveSel, Win8BaseColors[7]); + //fpgSetNamedColor(clGridInactiveSelText, Win8BaseColors[8]); + //fpgSetNamedColor(clSplitterGrabBar, Win8BaseColors[7]); + fpgSetNamedColor(clChoiceListBox, Win8BaseColors[16]); +end; + +destructor TfpgWin8Style.Destroy; +begin + FImages.Free; + inherited Destroy; +end; + +procedure TfpgWin8Style.DrawControlFrame(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord); +var + r: TfpgRect; +begin + r.SetRect(x, y, w, h); + ACanvas.SetLineStyle(1, lsSolid); + ACanvas.SetColor(clWidgetFrame); + ACanvas.DrawRectangle(r); +end; + +function TfpgWin8Style.GetControlFrameBorders: TRect; +begin + Result := Rect(1, 1, 1, 1); +end; + +procedure TfpgWin8Style.DrawButtonFace(ACanvas: TfpgCanvas; x, y, w, h: TfpgCoord; AFlags: TfpgButtonFlags); +var + r: TfpgRect; +begin + r.SetRect(x, y, w, h); + ACanvas.SetLineStyle(1, lsSolid); + if btfDisabled in AFlags then + ACanvas.SetColor(TfpgColor($ffd9d9d9)) + else + begin + if btfIsDefault in AFlags then + ACanvas.SetColor(clSelection) + else + ACanvas.SetColor(TfpgColor($ffacacac)); + end; + ACanvas.DrawRectangle(r); + InflateRect(r, -1, -1); + if btfDisabled in AFlags then + begin + ACanvas.SetColor(TfpgColor($ffefefef)); + ACanvas.FillRectangle(r); + end + else + ACanvas.GradientFill(r, clWindowBackground, TfpgColor($ffe5e5e5), gdVertical); +end; + +function TfpgWin8Style.GetButtonBorders: TRect; +begin + Result := Rect(2, 2, 2, 2); +end; + +procedure TfpgWin8Style.DrawStaticComboBox(ACanvas: TfpgCanvas; r: TfpgRect; + const IsEnabled: Boolean; const IsFocused: Boolean; + const IsReadOnly: Boolean; const ABackgroundColor: TfpgColor; + const AInternalBtnRect: TfpgRect; const ABtnPressed: Boolean); +var + ar: TfpgRect; +begin + //if IsEnabled then + // ACanvas.SetColor(TfpgColor($ffacacac)) + //else + // ACanvas.SetColor(TfpgColor($ffacacac)); + ACanvas.GradientFill(r, clWindowBackground, clChoiceListBox, gdVertical); + + // paint arrow + ACanvas.SetColor(clShadow2); + ar := AInternalBtnRect; + { The bounding rectangle for the arrow } + ar.Width := 8; + ar.Height := 6; + ar.Left := AInternalBtnRect.Left + ((AInternalBtnRect.Width-ar.Width) div 2); + ar.Top := AInternalBtnRect.Top + ((AInternalBtnRect.Height-ar.Height) div 2); + DrawDirectionArrow(ACanvas, ar.Left, ar.Top, ar.Width, ar.Height, adDown); +end; + +procedure TfpgWin8Style.DrawCheckbox(ACanvas: TfpgCanvas; x, y: TfpgCoord; ix, iy: TfpgCoord); +var + img: TfpgImage; + size: integer; +begin + img := FImages.GetImage('win8.checkboxes'); // Do NOT localize - return value is a reference only + size := GetCheckBoxSize; + ACanvas.DrawImagePart(x, y, img, ix, iy, size, size); +end; + + +initialization + fpgStyleManager.RegisterClass('win8', TfpgWin8Style); + +end. + diff --git a/src/gui/fpg_stylemanager.pas b/src/gui/fpg_stylemanager.pas index de49d5a7..a4d47a36 100644 --- a/src/gui/fpg_stylemanager.pas +++ b/src/gui/fpg_stylemanager.pas @@ -25,6 +25,7 @@ interface uses Classes ,Contnrs + ,fpg_base ,fpg_main ; @@ -67,6 +68,7 @@ type function CreateInstance: TfpgStyle; overload; procedure FreeStyleInstance; procedure AssignStyleTypes(const AStrings: TStrings); + function StyleTypesAsString: TfpgString; end; @@ -203,6 +205,19 @@ begin AStrings.Add(TfpgStyleClassMapping(FList.Items[i]).MappingName); end; +function TfpgStyleManager.StyleTypesAsString: TfpgString; +var + i: integer; + s: string; +begin + for i := 0 to FList.Count - 1 do + begin + if i > 0 then + s := ', '; + Result := Result + s + '"' + TfpgStyleClassMapping(FList.Items[i]).MappingName + '"'; + end; +end; + finalization uStyleManager.Free; diff --git a/src/gui/fpg_tab.pas b/src/gui/fpg_tab.pas index 5ef82248..29addb12 100644 --- a/src/gui/fpg_tab.pas +++ b/src/gui/fpg_tab.pas @@ -183,6 +183,10 @@ implementation uses fpg_stringutils; + +const + DFL_TAB_HEIGHT = 21; + DFL_TAB_WIDTH = 0; // compare function used by FPages.Sort @@ -532,7 +536,7 @@ procedure TfpgPageControl.SetFixedTabWidth(const AValue: integer); begin if FFixedTabWidth = AValue then Exit; //==> - if AValue > 5 then + if AValue >= 5 then begin FFixedTabWidth := AValue; RePaint; @@ -543,7 +547,7 @@ procedure TfpgPageControl.SetFixedTabHeight(const AValue: integer); begin if FFixedTabHeight = AValue then Exit; //==> - if AValue > 5 then + if AValue >= 5 then begin FFixedTabHeight := AValue; RePaint; @@ -630,6 +634,11 @@ begin if FTabPosition = AValue then Exit; //==> FTabPosition := AValue; + if FTabPosition = tpNone then + begin + FLeftButton.Visible := False; + FRightButton.Visible := False; + end; RePaint; end; @@ -669,6 +678,8 @@ begin if Mode = 2 then begin r.Height -= 1; + if TabPosition = tpBottom then + r.Top += 1; Canvas.SetColor(ActiveTabColor); end else @@ -691,22 +702,27 @@ begin tpBottom: begin - Canvas.FillRectangle(r.Left, r.Top+1, r.Width-2, r.Height-3); // fill tab background + Canvas.FillRectangle(r.Left, r.Top, r.Width-1, r.Height-2); // fill tab background Canvas.SetColor(clHilite2); Canvas.DrawLine(r.Left, r.Top, r.Left, r.Bottom-1); // left edge Canvas.SetColor(clShadow2); Canvas.DrawLine(r.Left+2, r.Bottom, r.Right-1, r.Bottom); // bottom outer edge Canvas.SetColor(clShadow1); - Canvas.DrawLine(r.Right-1, r.Bottom-1, r.Right-1, r.Top+1); // right inner edge + Canvas.DrawLine(r.Right-1, r.Bottom-1, r.Right-1, r.Top-1); // right inner edge Canvas.DrawLine(r.Left+1, r.Bottom-1, r.Right-1, r.Bottom-1);// bottom inner edge Canvas.SetColor(clShadow2); Canvas.DrawLine(r.Right-1, r.Bottom-1, r.Right, r.Bottom-2); // right rounded edge (1px) - Canvas.DrawLine(r.Right, r.Bottom-2, r.Right, r.Top+1); // right outer edge + Canvas.DrawLine(r.Right, r.Bottom-2, r.Right, r.Top-1); // right outer edge + if Mode = 2 then { selected tab } + begin + Canvas.SetColor(ActiveTabColor); + Canvas.DrawLine(r.Left+1, r.Top-1, r.Right-1, r.Top-1); + end; end; tpLeft: begin - if Mode = 2 then + if Mode = 2 then { selected tab } begin r.Width := r.Width - 1; r.Height := r.Height + 2; @@ -797,7 +813,7 @@ end; procedure TfpgPageControl.RePaintTitles; const - TabHeight = 21; + TAB_HEIGHT = 21; var TabW, TabH: Integer; r2: TfpgRect; @@ -820,7 +836,7 @@ begin TabH:=FixedTabHeight; ActivePageVisible := false; If TabH = 0 then - TabH := TabHeight; + TabH := TAB_HEIGHT; h := TfpgTabSheet(FPages.First); if h = nil then Exit; //==> @@ -913,27 +929,27 @@ begin begin lTxtFlags += TextFlagsDflt; lp := 0; - r2.SetRect(2, Height - ButtonHeight-3, 50, 21); + r2.SetRect(2, Height - ButtonHeight, 50, TabH-2); while h <> nil do begin if h <> ActivePage then begin - toffset := 2; + toffset := 1; h.Visible := False; end else begin - toffset := 4; + toffset := 2; h.Visible := True; - h.SetPosition(FMargin+2, FMargin+2 , Width - (FMargin*2) - 4, Height - r2.Height - (FMargin+2)*2); + h.SetPosition(FMargin+2, FMargin+2 , Width - (FMargin*2) - 4, Height - TabH - (FMargin+2)*2); end; // paint tab button r2.Width := ButtonWidth(h.Text); r3 := DrawTab(r2, h = ActivePage); // paint text on non-active tabs if h <> ActivePage then - Canvas.DrawText(lp + (ButtonWidth(h.Text) div 2) - FFont.TextWidth(GetTabText(h.Text)) div 2, - Height-r2.Height-toffset, GetTabText(h.Text), lTxtFlags); + Canvas.DrawText(lp + (ButtonWidth(h.Text) div 2) - FFont.TextWidth(GetTabText(h.Text)) div 2, + Height-TabH+toffset, GetTabText(h.Text), lTxtFlags); r2.Left := r2.Left + r2.Width; lp := lp + ButtonWidth(h.Text); @@ -946,7 +962,7 @@ begin r2.Left := 0; r2.Top := 0; r2.Width := Width; - r2.Height := Height - r2.Height; + r2.Height := Height - TabH; Canvas.DrawButtonFace(r2, []); // Draw text of ActivePage, because we didn't before. DrawTab(r3, false, 2); @@ -957,7 +973,7 @@ begin begin lTxtFlags += TextFlagsDflt; lp := 0; - r2.SetRect(2, 2, 50, 21); + r2.SetRect(2, 2, 50, TabH); while h <> nil do begin if h <> ActivePage then @@ -974,7 +990,6 @@ begin // paint tab button r2.Width := ButtonWidth(h.Text); r3 := DrawTab(r2, h = ActivePage); - // paint text on non-active tabs if h <> ActivePage then Canvas.DrawText(lp + (ButtonWidth(h.Text) div 2) - FFont.TextWidth(GetTabText(h.Text)) div 2, @@ -1003,7 +1018,7 @@ begin lTxtFlags += [txtVCenter, txtLeft]; lp := 0; TabW := MaxButtonWidth; - r2.SetRect(Width - 2 - TabW, 2, TabW, 21); + r2.SetRect(Width - 2 - TabW, 2, TabW, TabH); while h <> nil do begin if h <> ActivePage then @@ -1048,7 +1063,7 @@ begin lTxtFlags += [txtVCenter, txtLeft]; lp := 0; TabW := MaxButtonWidth; - r2.SetRect(2, 2, TabW, 21); + r2.SetRect(2, 2, TabW, TabH); while h <> nil do begin if h <> ActivePage then diff --git a/src/gui/fpg_trackbar.pas b/src/gui/fpg_trackbar.pas index ad997817..32da0b99 100644 --- a/src/gui/fpg_trackbar.pas +++ b/src/gui/fpg_trackbar.pas @@ -138,6 +138,12 @@ type property OnChange; property OnEnter; property OnExit; + property OnKeyPress; + property OnMouseDown; + property OnMouseEnter; + property OnMouseExit; + property OnMouseMove; + property OnMouseUp; property OnShowHint; end; @@ -439,7 +445,7 @@ begin if Orientation = orVertical then begin - if (y >= Width + FSliderPos) and (y <= Width + FSliderPos + FSliderLength) then + if (y >= FSliderPos) and (y <= FSliderPos + FSliderLength) then begin FSliderDragging := True; FSliderDragPos := y; @@ -516,8 +522,6 @@ begin if newp <> FPosition then begin Position := newp; - RePaint; - DoChange; end; end; @@ -571,12 +575,20 @@ begin if Orientation = orVertical then begin - Canvas.DrawButtonFace(0, Width + FSliderPos, Width, FSliderLength, [btfIsEmbedded]); + r.SetRect((Width-4) div 2, 1, 4, Height {- tw} - 4); + fpgStyle.DrawControlFrame(Canvas, r); + r.SetRect((Width-20) div 2, FSliderPos, 21, FSliderLength); + Canvas.DrawButtonFace(r, []); + //if FShowPosition then + //begin + // Canvas.SetTextColor(TextColor); + // fpgStyle.DrawString(Canvas, Width - tw, (Height - FFont.Height) div 2, IntToStr(Position), Enabled); + //end; end else begin r.SetRect(1, (Height-4) div 2, Width - tw - 4, 4); - Canvas.DrawControlFrame(r); + fpgStyle.DrawControlFrame(Canvas, r); r.SetRect(FSliderPos, (Height-20) div 2, FSliderLength, 21); Canvas.DrawButtonFace(r, []); if FShowPosition then diff --git a/src/gui/fpg_tree.pas b/src/gui/fpg_tree.pas index 8935ec36..7da5205c 100644 --- a/src/gui/fpg_tree.pas +++ b/src/gui/fpg_tree.pas @@ -84,7 +84,6 @@ type FText: TfpgString; FTextColor: TfpgColor; FHasChildren: Boolean; - FTree: TfpgTreeView; procedure SetCollapsed(const AValue: boolean); procedure SetInactSelColor(const AValue: TfpgColor); procedure SetInactSelTextColor(const AValue: TfpgColor); @@ -97,8 +96,11 @@ type procedure SetHasChildren(const AValue: Boolean); procedure DoTreeCheck(ANode: TfpgTreeNode); procedure SetStateImageIndex(const AValue: integer); + protected + FTree: TfpgTreeView; public - constructor Create; + constructor Create; overload; + constructor Create(ATreeView: TfpgTreeView; AText: TfpgString); overload; destructor Destroy; override; // node related function AppendText(AText: TfpgString): TfpgTreeNode; @@ -133,6 +135,7 @@ type property Parent: TfpgTreeNode read FParent write SetParent; property Prev: TfpgTreeNode read FPrev write FPrev; property Text: TfpgString read FText write SetText; + property TreeView: TfpgTreeView read FTree; { determines the + or - image in the treeview } property HasChildren: Boolean read FHasChildren write SetHasChildren; // color settings @@ -273,10 +276,10 @@ type implementation -{.$IFDEF DEBUG} +{$IFDEF DEBUG} uses - dbugintf; -{.$ENDIF} + fpg_dbugintf; +{$ENDIF} type PColumnLeft = ^integer; @@ -394,7 +397,8 @@ begin FData := nil; FFirstSubNode := nil; FLastSubNode := nil; - FText := ''; + FText := ''; + FTree := nil; FImageIndex := -1; FStateImageIndex := -1; FCollapsed := True; @@ -411,6 +415,13 @@ begin FInactSelTextColor := clUnset; end; +constructor TfpgTreeNode.Create(ATreeView: TfpgTreeView; AText: TfpgString); +begin + Create; + FText := AText; + FTree := ATreeView; +end; + destructor TfpgTreeNode.Destroy; begin if FParent <> nil then diff --git a/src/gui/inputintegerdialog.inc b/src/gui/inputintegerdialog.inc new file mode 100644 index 00000000..237fb549 --- /dev/null +++ b/src/gui/inputintegerdialog.inc @@ -0,0 +1,157 @@ +{ + fpGUI - Free Pascal GUI Toolkit + + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this + distribution, for details of the copyright. + + See the file COPYING.modifiedLGPL, included in this distribution, + for details about redistributing fpGUI. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit contains the Input Query dialogs. +} + +{%mainunit fpg_dialogs.pas} + +{$IFDEF read_interface} + +type + + TfpgIntegerDialog = class(TfpgForm) + private + {@VFD_HEAD_BEGIN: fpgIntegerDialog} + lblText: TfpgLabel; + edtInteger: TfpgEditInteger; + btnOK: TfpgButton; + btnCancel: TfpgButton; + {@VFD_HEAD_END: fpgIntegerDialog} + procedure SetupCaptions; + procedure edtIntegerKeyPressed(Sender: TObject; var KeyCode: word; var ShiftState: TShiftState; var Consumed: boolean); + protected + procedure HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean); override; + public + procedure AfterCreate; override; + end; + + +{$ENDIF read_interface} + +{$IFDEF read_implementation} + +function fpgIntegerQuery(const ACaption, APrompt: TfpgString; var Value: Integer; const MaxValue: Integer; const MinValue: Integer): Boolean; +var + dlg: TfpgIntegerDialog; +begin + dlg := TfpgIntegerDialog.Create(nil); + try + dlg.WindowTitle := ACaption; + dlg.lblText.Text := APrompt; + dlg.edtInteger.MaxValue:= MaxValue; + dlg.edtinteger.MinValue:= MinValue; + dlg.edtInteger.Value := Value; + Result := dlg.ShowModal = mrOK; + if Result then + Value := dlg.edtInteger.Value; + finally + dlg.Free; + end; +end; + +{ TfpgIntegerDialog } + +procedure TfpgIntegerDialog.SetupCaptions; +begin + btnOK.Text := rsOK; + btnCancel.Text := rsCancel; +end; + +procedure TfpgIntegerDialog.edtIntegerKeyPressed(Sender: TObject; var KeyCode: word; var ShiftState: TShiftState; var Consumed: boolean); +begin + if KeyCode = keyEnter then + btnOK.Click; +end; + +procedure TfpgIntegerDialog.HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean); +begin + if KeyCode = keyEscape then + begin + consumed := True; + ModalResult := mrCancel; + end; +end; + +procedure TfpgIntegerDialog.AfterCreate; +begin + {%region 'Auto-generated GUI code' -fold} + {@VFD_BODY_BEGIN: fpgIntegerDialog} + Name := 'fpgIntegerDialog'; + SetPosition(100, 150, 208, 97); + WindowTitle := 'IntegerDialog'; + Hint := ''; + WindowPosition := wpOneThirdDown; + + lblText := TfpgLabel.Create(self); + with lblText do + begin + Name := 'lblText'; + SetPosition(8, 8, 208, 16); + Anchors := [anLeft,anRight,anTop]; + FontDesc := '#Label1'; + Hint := ''; + Text := 'lblText'; + end; + + edtInteger := TfpgEditInteger.Create(self); + with edtInteger do + begin + Name := 'edtInteger'; + SetPosition(8, 26, 100, 24); + Anchors := [anLeft,anRight,anTop]; + Hint := ''; + TabOrder := 2; + Text := ''; + FontDesc := '#Edit1'; + Value := 0; + OnKeyPress := @edtIntegerKeyPressed; + end; + + btnOK := TfpgButton.Create(self); + with btnOK do + begin + Name := 'btnOK'; + SetPosition(8, 64, 92, 24); + Anchors := [anRight,anBottom]; + Text := 'OK'; + FontDesc := '#Label1'; + Hint := ''; + ImageName := ''; + ModalResult := mrOK; + TabOrder := 3; + end; + + btnCancel := TfpgButton.Create(self); + with btnCancel do + begin + Name := 'btnCancel'; + SetPosition(108, 64, 92, 24); + Anchors := [anRight,anBottom]; + Text := 'Cancel'; + FontDesc := '#Label1'; + Hint := ''; + ImageName := ''; + ModalResult := mrCancel; + TabOrder := 4; + end; + + {@VFD_BODY_END: fpgIntegerDialog} + {%endregion} + + SetupCaptions; +end; + +{$ENDIF read_implementation} + diff --git a/src/gui/inputquerydialog.inc b/src/gui/inputquerydialog.inc index 6330d02c..b41af217 100644 --- a/src/gui/inputquerydialog.inc +++ b/src/gui/inputquerydialog.inc @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Toolkit - Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2014 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, diff --git a/src/gui/messagedialog.inc b/src/gui/messagedialog.inc index 0e04541d..db894f6d 100644 --- a/src/gui/messagedialog.inc +++ b/src/gui/messagedialog.inc @@ -262,7 +262,6 @@ var y: integer; tw: integer; begin - Canvas.BeginDraw; inherited HandlePaint; case FDialogType of mtAbout: @@ -312,7 +311,6 @@ begin Inc(y, FLineHeight); end; end; - Canvas.EndDraw; end; procedure TfpgMessageDialog.HandleShow; |