From: Michael H. <mh...@us...> - 2001-01-06 19:52:41
|
Update of /cvsroot/pythianproject/Prototypes/GUISystem In directory usw-pr-cvs1:/tmp/cvs-serv29046/GUISystem Modified Files: StartupForm.pas vglClasses.pas vglEdits.pas vglStdCtrls.pas Log Message: added drag'n'drop, alerts -mike Index: StartupForm.pas =================================================================== RCS file: /cvsroot/pythianproject/Prototypes/GUISystem/StartupForm.pas,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** StartupForm.pas 2001/01/02 21:46:20 1.12 --- StartupForm.pas 2001/01/06 19:52:48 1.13 *************** *** 48,53 **** procedure ButtonOnclick(Sender:TObject); procedure CB1OnChange(Sender:TObject); ! procedure ManagerOnFocusChange(Sender:TObject); procedure go; --- 48,55 ---- procedure ButtonOnclick(Sender:TObject); procedure CB1OnChange(Sender:TObject); ! procedure SBOnChange(Sender: TObject; ScrollCode: TvglScrollCode; var ScrollPos: Integer); procedure ManagerOnFocusChange(Sender:TObject); + procedure DragBoxOnDragOver(what:TvglDragObject; var Accept:boolean); + procedure DragBoxOnDragDrop(what:TvglDragObject); procedure go; *************** *** 109,113 **** begin // test code - InterfaceManager.Desktop.TestText.Text := IntToStr(X)+','+IntToStr(Y)+': '+InterfaceManager.Desktop.GetComponentAt(X,Y).Name; InterfaceManager.MouseMove(X,Y); end; --- 111,114 ---- *************** *** 212,218 **** Label1 := TvglTextBox.Create('Label1',InterfaceManager.Desktop); ! Label1.Top := 192; Label1.Left := 468; ! Label1.Color := clBlack; Label1.Font := 'Courier New'; Label1.Caption := 'FOCUS LOST!'; --- 213,219 ---- Label1 := TvglTextBox.Create('Label1',InterfaceManager.Desktop); ! Label1.Top := 220; Label1.Left := 468; ! Label1.Color := clWhite; Label1.Font := 'Courier New'; Label1.Caption := 'FOCUS LOST!'; *************** *** 224,229 **** SB.Height := 13; SB.Width := 150; ! SB.Position := 15; ! SB.PageSize := 10; LB := TvglSimpleListBox.Create('SimpleListBoxTest', InterfaceManager.Desktop); --- 225,233 ---- SB.Height := 13; SB.Width := 150; ! SB.Max := 255; ! SB.Min := 0; ! SB.Position := 255; ! SB.PageSize := 50; ! SB.OnScroll := SBOnChange; LB := TvglSimpleListBox.Create('SimpleListBoxTest', InterfaceManager.Desktop); *************** *** 253,256 **** --- 257,262 ---- DragBox := TvglDragBox.Create('DragBox1',InterfaceManager.Desktop); DragBox.Bounds := Rect(500,400,550,450); + DragBox.OnDragOver := DragBoxOnDragOver; + DragBox.OnDragDrop := DragBoxOnDragDrop; InterfaceManager.SetNewFocus(LB); *************** *** 286,289 **** --- 292,312 ---- Label1.Lines.Text := 'FOCUS LOST!'; end; + end; + + procedure TfrmStartup.DragBoxOnDragOver(what: TvglDragObject; + var Accept: boolean); + begin + if what.from = Image1 then accept := true else accept := false; + end; + + procedure TfrmStartup.SBOnChange(Sender: TObject; ScrollCode: TvglScrollCode; + var ScrollPos: Integer); + begin + Panel1.TotalAlpha := (1 / 255) * ScrollPos; + end; + + procedure TfrmStartup.DragBoxOnDragDrop(what: TvglDragObject); + begin + InterfaceManager.VGLAlert('You dropped object ['+what.from.Name+'] onto the draggable box! ABCDEFGHIJKLIMNOPQRSTUVWXYZ - this is a test message to force auto alert resizing'); end; Index: vglClasses.pas =================================================================== RCS file: /cvsroot/pythianproject/Prototypes/GUISystem/vglClasses.pas,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** vglClasses.pas 2001/01/02 21:46:20 1.10 --- vglClasses.pas 2001/01/06 19:52:48 1.11 *************** *** 34,41 **** - Pretty much everything! :) - - Bitmapped controls - Resource sharing (done except reference counting/garbage collection) - Name generation/usage (!) ! - Display list optimizations - Components --- 34,40 ---- - Pretty much everything! :) - Resource sharing (done except reference counting/garbage collection) - Name generation/usage (!) ! - Display list optimizations (don't appear to have any effect so uncompleted) - Components *************** *** 49,55 **** - Global Mouse and Keyboard events - Updating (many uses - f.e. Timer) History: ! - 13/12/00 - the code size is about 50kB (vglClasses.Pas), all files have now about 83kB (vglClasses.pas, vglStdCtrls.pas, vglCheckBox.pas) :) --- 48,60 ---- - Global Mouse and Keyboard events - Updating (many uses - f.e. Timer) + - Bitmapped controls + + Bugs: + - Severe bug with TvglAlert memory management (cannot be released without causing an External Exception in MouseMove) + currently causes memory leak :( History: ! - January 2001: Drag'n'drop added. Alert box added ! - 13th December 2000: the code size is about 50kB (vglClasses.Pas), all files have now about 83kB (vglClasses.pas, vglStdCtrls.pas, vglCheckBox.pas) :) *************** *** 108,111 **** --- 113,117 ---- Graphics, // for colour constants OpenGL, + Trace, GLCanvas; *************** *** 115,119 **** VGL_SKIN_1 = 'skin1.png'; // alpha skin VGL_SKINRECT_BACKGROUND :TRect = (Left:3;Top:51;Right:134;Bottom:175); - VGL_SKINRECT_BUTTON :TRect = (Left:3;Top:3;Right:153;Bottom:48); VGL_SKINRECT_MOUSECURSOR :TRect = (Left:3;Top:175;Right:35;Bottom:207); --- 121,124 ---- *************** *** 151,154 **** --- 156,163 ---- end; + TvglDragObject = class; // forward + + TVGLDragOverEvent = procedure(what:TvglDragObject; var Accept:boolean) of object; + TVGLDragDropEvent = procedure(what:TvglDragObject) of object; TVGLMouseButtonEvent = procedure(mb,x,y:integer) of object; TVGLMouseMoveEvent = procedure(x,y:integer) of object; *************** *** 173,190 **** - // an abstract class from which other components are derived TvglComponent = class(TvglBase) - private - FOnGlobalKeyUp: TVGLKeyboardEvent; - FOnKeyDown: TVGLKeyboardEvent; - FOnKeyUp: TVGLKeyboardEvent; - FOnGlobalKeyDown: TVGLKeyboardEvent; - FCached: boolean; - procedure SetOnGlobalKeyDown(const Value: TVGLKeyboardEvent); - procedure SetOnGlobalKeyUp(const Value: TVGLKeyboardEvent); - procedure SetOnKeyDown(const Value: TVGLKeyboardEvent); - procedure SetOnKeyUp(const Value: TVGLKeyboardEvent); - function KeyDataToShiftState(KeyData: Longint): TShiftState; protected FFocusable: Boolean; --- 182,187 ---- *************** *** 200,203 **** --- 197,203 ---- FSavedMouseDown :TvglComponent; FTextured :boolean; // use the skin? or use vector drawing + FVisible :boolean; + FReleased :boolean; // when true will be freed by the interface manager next cycle + // use when component needs to be destroyed but from itself // cache vars here *************** *** 212,222 **** FOnGlobalMouseUp, FOnGlobalMouseDown :TVGLMouseButtonEvent; FOnGlobalMouseMove :TVGLMouseMoveEvent; ! FOnMouseEntry,FOnMouseExit,FOnMouseClick :TNotifyEvent; FOnEnter: TVGLEntryExitEvent; FOnExit: TVGLEntryExitEvent; FOnChildAdd:TVGLChildEvent; ! FVisible :boolean; ! procedure FreeChildren; --- 212,226 ---- FOnGlobalMouseUp, FOnGlobalMouseDown :TVGLMouseButtonEvent; FOnGlobalMouseMove :TVGLMouseMoveEvent; ! FOnDragOver :TVGLDragOverEvent; FOnMouseEntry,FOnMouseExit,FOnMouseClick :TNotifyEvent; FOnEnter: TVGLEntryExitEvent; FOnExit: TVGLEntryExitEvent; FOnChildAdd:TVGLChildEvent; ! FOnGlobalKeyUp: TVGLKeyboardEvent; ! FOnKeyDown: TVGLKeyboardEvent; ! FOnKeyUp: TVGLKeyboardEvent; ! FOnGlobalKeyDown: TVGLKeyboardEvent; ! FCached: boolean; ! FOnDragDrop: TVGLDragDropEvent; procedure FreeChildren; *************** *** 247,251 **** --- 251,265 ---- procedure SetOnEnter(const Value: TVGLEntryExitEvent); procedure SetOnExit(const Value: TVGLEntryExitEvent); + procedure SetOnGlobalKeyDown(const Value: TVGLKeyboardEvent); + procedure SetOnGlobalKeyUp(const Value: TVGLKeyboardEvent); + procedure SetOnKeyDown(const Value: TVGLKeyboardEvent); + procedure SetOnKeyUp(const Value: TVGLKeyboardEvent); + function KeyDataToShiftState(KeyData: Longint): TShiftState; + + // drag'n'drop + function CanAcceptDragObject(dragObject :TvglDragObject):boolean; virtual ; // is overridden by descendants to accept drag objects + procedure DragDrop(dragObject:TvglDragObject); virtual ; // called when an object is dragged + // focusing function GetFocused: Boolean; *************** *** 287,290 **** --- 301,305 ---- constructor Create(aName:string; AOwner:TvglComponent); destructor Destroy; override ; // destroying an object also destroys its children + procedure Release; procedure MoveTo(x,y:integer); *************** *** 337,340 **** --- 352,357 ---- property OnEnter: TVGLEntryExitEvent read FOnEnter write SetOnEnter; property OnExit: TVGLEntryExitEvent read FOnExit write SetOnExit; + property OnDragOver: TVGLDragOverEvent read FOnDragOver write FOnDragOver; + property OnDragDrop :TVGLDragDropEvent read FOnDragDrop write FOnDragDrop; end; *************** *** 343,347 **** DragOrigin :TPoint; CurPoint :TPoint; ! constructor Create(aDragOrigin:TPoint); procedure StartDrag; virtual ; procedure EndDrag; virtual ; --- 360,367 ---- DragOrigin :TPoint; CurPoint :TPoint; ! from :TvglComponent; ! Tag :integer; ! constructor Create(aFrom:TvglComponent; aDragOrigin:TPoint); ! destructor Destroy; override ; procedure StartDrag; virtual ; procedure EndDrag; virtual ; *************** *** 359,363 **** TvglDragCopyObject = class(TvglDragObject) CopyComponent :TvglComponent; ! constructor Create(aDragOrigin:TPoint; aCopyComponent:TvglComponent); end; --- 379,383 ---- TvglDragCopyObject = class(TvglDragObject) CopyComponent :TvglComponent; ! constructor Create(aFrom:TvglComponent; aDragOrigin:TPoint; aCopyComponent:TvglComponent); end; *************** *** 409,412 **** --- 429,433 ---- end; + TvglDraggableImage = class(TvglImage) protected *************** *** 471,474 **** --- 492,497 ---- NewMouseList, OldMouseList, TempMouseList :TvglObjList; + TestData :string; + procedure SetOnCreateDesktop(const Value: TCreateDesktopEvent); *************** *** 483,486 **** --- 506,513 ---- procedure UpdateDragObjects(newPos:TPoint); procedure OverlayDragCopyObjects; + procedure ReleaseDragObjects; + function DragObjectOver(component:TvglComponent):TvglDragObject; + + procedure VGLAlertFree(Sender:TObject); public property Focused: TvglComponent read FFocusedComponent; *************** *** 501,504 **** --- 528,532 ---- procedure DrawAll; virtual; procedure DrawBorder(where:TRect; FImage:TGLBitmap); virtual ; + procedure VGLAlert(msg:string); // displays a general purpose alert // resource management *************** *** 525,529 **** --- 553,559 ---- procedure CopyList(src,dest:TList); function PointInRectInAcc(R: TRect; X, Y, XINACC, YINACC: Integer): Boolean; + implementation + uses vglStdCtrls; function PointInRectInAcc(R: TRect; X, Y, XINACC, YINACC: Integer): Boolean; *************** *** 641,649 **** procedure TvglComponent.FreeChildren; - var a:integer; begin ! a := 0; ! while a < FChildren.Count do ! FChildren[a].Free; end; --- 671,679 ---- procedure TvglComponent.FreeChildren; begin ! while FChildren.Count > 0 do ! begin ! FChildren[0].Free; ! end; end; *************** *** 763,769 **** var i:integer; begin i := FChildren.IndexOf(child); ! if i = -1 then raise EVGLException.Create('TvglComponent.RemoveChild: Unknown child component'); ! FChildren.Delete(i); end; --- 793,802 ---- var i:integer; begin + TraceString('REMOVECHILD'); + if not assigned(child) then raise EVGLException.Create('TvglComponent.RemoveChild: NIL parameter'); + TraceString(' for '+child.name); i := FChildren.IndexOf(child); ! if i = -1 then raise EVGLException.Create('TvglComponent.RemoveChild: Unknown child component ['+child.name+']'); ! FChildren.Delete(i); end; *************** *** 877,880 **** --- 910,923 ---- if FChildren[i] <> nil then FChildren[i].Update(ElapsedTime); + i := 0; + while i < FChildren.Count do + begin + if FChildren[i].FReleased then + begin + TraceString('Releasing: '+Fchildren[i].name); + FChildren[i].Free; + end else + inc(i); + end; end; *************** *** 1111,1116 **** --- 1154,1175 ---- end; + function TvglComponent.CanAcceptDragObject( + dragObject: TvglDragObject): boolean; + begin + if assigned(FOnDragOver) then + FOnDragOver(dragObject,result) + else Result := false; + end; + procedure TvglComponent.DragDrop(dragObject: TvglDragObject); + begin + if assigned(FOnDragDrop) then FOnDragDrop(dragObject); + end; + procedure TvglComponent.Release; + begin + FReleased := true; + end; + { TvglObjList } *************** *** 1140,1144 **** DefaultTextured := true; FDragObjects := TList.Create; ! FLeft := 0; FTop := 0; --- 1199,1203 ---- DefaultTextured := true; FDragObjects := TList.Create; ! TestData := ''; FLeft := 0; FTop := 0; *************** *** 1159,1163 **** --- 1218,1227 ---- procedure TvglInterfaceManager.EndDrag(dragObj: TvglDragObject); + var c:TvglComponent; begin + c := Desktop.GetComponentAt(dragObj.CurPoint.X,dragObj.CurPoint.Y); + if assigned(c) then + if c.CanAcceptDragObject(dragObj) then + c.DragDrop(dragObj); dragObj.EndDrag; if FDragObjects.IndexOf(DragObj) <> -1 then *************** *** 1283,1286 **** --- 1347,1352 ---- i:integer; t:integer; + d:TvglDragObject; + c:TvglComponent; begin // send event *************** *** 1327,1330 **** --- 1393,1406 ---- // do drag ops UpdateDragObjects(Point(X,Y)); + c := Desktop.GetComponentAt(X,Y); + d := DragObjectOver(c); + if assigned(d) then + if c.CanAcceptDragObject(d) then + TestData := ' |accepts|' + else testData := ' |no accept|' + else testdata := ''; + + // update test label + Desktop.TestText.Text := IntToStr(X)+','+IntToStr(Y)+': '+Desktop.GetComponentAt(X,Y).Name + TestData; end; *************** *** 1334,1337 **** --- 1410,1414 ---- Desktop.DoOnMouseUp(Button, x, y); Desktop.DoOnGlobalMouseUp(button, X, Y); + ReleaseDragObjects; end; *************** *** 1595,1603 **** { TvglDragObject } ! constructor TvglDragObject.Create(aDragOrigin: TPoint); begin inherited Create; DragOrigin := aDragOrigin; CurPoint := DragOrigin; end; --- 1672,1688 ---- { TvglDragObject } ! constructor TvglDragObject.Create(aFrom:TvglComponent; aDragOrigin: TPoint); begin inherited Create; DragOrigin := aDragOrigin; CurPoint := DragOrigin; + From := aFrom; + end; + + + destructor TvglDragObject.Destroy; + begin + inherited; + From := nil; // release from object end; *************** *** 1643,1647 **** if assigned(FDragObj) then raise Exception.Create('TvglDragBox.doOnMouseDown: cannot drag more than once at a time!'); ! FDragObj := TvglDragBroadcasterObject.Create(Point(X,Y)); FDragObj.OnDrag := DragHandler; Manager.StartDrag(FDragObj); --- 1728,1732 ---- if assigned(FDragObj) then raise Exception.Create('TvglDragBox.doOnMouseDown: cannot drag more than once at a time!'); ! FDragObj := TvglDragBroadcasterObject.Create(Self,Point(X,Y)); FDragObj.OnDrag := DragHandler; Manager.StartDrag(FDragObj); *************** *** 1680,1687 **** { TvglDragCopyObject } ! constructor TvglDragCopyObject.Create(aDragOrigin: TPoint; aCopyComponent: TvglComponent); begin ! inherited Create(aDragOrigin); CopyComponent := aCopyComponent; end; --- 1765,1772 ---- { TvglDragCopyObject } ! constructor TvglDragCopyObject.Create(aFrom:TvglComponent; aDragOrigin: TPoint; aCopyComponent: TvglComponent); begin ! inherited Create(aFrom,aDragOrigin); CopyComponent := aCopyComponent; end; *************** *** 1693,1697 **** inherited; if assigned(FDragObj) then FDragObj.Free; ! FDragObj := TvglDragCopyObject.Create(Point(x,y),self); Manager.StartDrag(FDragObj); end; --- 1778,1782 ---- inherited; if assigned(FDragObj) then FDragObj.Free; ! FDragObj := TvglDragCopyObject.Create(self,Point(x,y),self); Manager.StartDrag(FDragObj); end; *************** *** 1722,1725 **** --- 1807,1851 ---- CopyComponent.Bounds := b; end; + end; + + function TvglInterfaceManager.DragObjectOver( + component: TvglComponent): TvglDragObject; + var i:integer; + begin + // scan the drag objects to find if any of them intersect with this object + Result := nil; + for i := 0 to FDragObjects.Count-1 do + if PointInRectInAcc(component.Bounds,TvglDragObject(FDragObjects[i]).CurPoint.X,TvglDragObject(FDragObjects[i]).CurPoint.Y,0,0) then + Result := TvglDragObject(FDragObjects[i]); + end; + + procedure TvglInterfaceManager.ReleaseDragObjects; + var i:integer; + begin + // end all drag objects + while FDragObjects.Count > 0 do + begin + EndDrag(TvglDragObject(FDragObjects[0])); + TvglDragObject(FDragObjects[0]).Free; + FDragObjects.Delete(0); + end; + end; + + procedure TvglInterfaceManager.VGLAlert(msg: string); + var alert:TvglAlert; + begin + TraceString(' [mark 1] - VGLAlert'); + alert := TvglAlert.Create('Alert',Desktop,msg); + TraceString(' [mark 2] - Created'); + alert.OnClose := VGLAlertFree; + TraceString(' [mark 3] - about to show'); + alert.Show; + TraceString(' [mark 4] - shown'); + end; + + procedure TvglInterfaceManager.VGLAlertFree(Sender: TObject); + begin + TraceString('[destroy]'); + //TvglAlert(sender).Release; // WARNING: SEVERE BUG HERE!!!! end; Index: vglEdits.pas =================================================================== RCS file: /cvsroot/pythianproject/Prototypes/GUISystem/vglEdits.pas,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** vglEdits.pas 2000/12/17 21:03:00 1.2 --- vglEdits.pas 2001/01/06 19:52:48 1.3 *************** *** 399,402 **** --- 399,403 ---- Cnt, a, i: Integer; begin + Result := -1; if not PointInRect(where, X, Y) then Exit; Index: vglStdCtrls.pas =================================================================== RCS file: /cvsroot/pythianproject/Prototypes/GUISystem/vglStdCtrls.pas,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** vglStdCtrls.pas 2001/01/02 21:46:20 1.9 --- vglStdCtrls.pas 2001/01/06 19:52:48 1.10 *************** *** 6,10 **** --- 6,14 ---- - Michael Hearn (mh...@su...) + To do: + * true word wrapping in TvglTextbox + Notes: + * Added TvglAlert + enhanced text box 6th January 2001 * Changed scrollbar to use skins - 11th December 2000 * Changed listbox to use one TGLText object for increased efficiency, *************** *** 32,36 **** interface ! uses Windows, GLCanvas, Classes, vglClasses, Graphics, SysUtils; const --- 36,40 ---- interface ! uses Windows, GLCanvas, Classes, vglClasses, Graphics, SysUtils{, Trace}; const *************** *** 40,43 **** --- 44,48 ---- VGL_SKINRECT_SCROLLBUTTON_DOWN :TRect = (Left:59;Top:183;Right:72;Bottom:202); VGL_SKINRECT_SCROLL_TAB :TRect = (Left:93;Top:188;Right:119;Bottom:201); + VGL_SKINRECT_BUTTON :TRect = (Left:3;Top:3;Right:153;Bottom:48); VGL_SKINRECT_CHECKBOXSET: TRect = (Left: 3; Top: 208; Right: 16; Bottom: 220); *************** *** 288,304 **** TvglTextBox = class(TvglComponent) - private - function GetFont: string; - procedure SetFont(const Value: string); - procedure SetColor(const Value: TColor); protected FText :TGLText; function GetCaption: string; procedure SetCaption(const Value: string); function GetComponentType:string; override ; function GetLines: TStringList; procedure LinesOnChange(Sender:TObject); procedure UpdateBounds; public property Lines:TStringList read GetLines; --- 293,311 ---- TvglTextBox = class(TvglComponent) protected FText :TGLText; + FAutoSize :boolean; + FProcessing :boolean; // used to flag that we should ignore line changes for a while function GetCaption: string; procedure SetCaption(const Value: string); function GetComponentType:string; override ; function GetLines: TStringList; + function GetFont: string; + procedure SetFont(const Value: string); + procedure SetColor(const Value: TColor); procedure LinesOnChange(Sender:TObject); procedure UpdateBounds; + procedure DrawSelf(where:TRect); override ; public property Lines:TStringList read GetLines; *************** *** 306,313 **** property Font :string read GetFont write SetFont; property Color :TColor write SetColor; constructor Create(aName:string; aOwner:TVGLComponent); destructor Destroy; override ; ! procedure DrawSelf(where:TRect); override ; end; --- 313,321 ---- property Font :string read GetFont write SetFont; property Color :TColor write SetColor; + property AutoSize :boolean read FAutoSize write FAutoSize; constructor Create(aName:string; aOwner:TVGLComponent); destructor Destroy; override ; ! procedure WordWrap; // forces text to fit to bounds as much as possible end; *************** *** 339,342 **** --- 347,372 ---- end; + TvglAlert = class(TvglComponent) + protected + FAlertResult: integer; + FBoxBounds :TRect; + FImage :TGLBitmap; + FOKButton :TvglButton; + FTextBox :TvglTextBox; + FOnClose: TNotifyEvent; + function GetComponentType:string; override ; + procedure OKOnClick(Sender:TObject); + public + property MessageTextBox :TvglTextBox read FTextBox; + property AlertResult :integer read FAlertResult; + property OnClose :TNotifyEvent read FOnClose write FOnClose; + + constructor Create(aName:string; AOwner:TvglComponent; Msg:string); + destructor Destroy; override ; + procedure Show; + procedure DrawSelf(where:TRect); override ; + end; + + implementation uses *************** *** 1553,1559 **** --- 1583,1591 ---- begin inherited Create(aName,aOwner); + FAutoSize := true; FText := TGLText.Create('Arial'); FText.Precache := true; FText.Lines.OnChange := LinesOnChange; + FProcessing := false; end; *************** *** 1567,1570 **** --- 1599,1604 ---- begin inherited DrawSelf(where); + // CLIP + Canvas.SetClipping(where); Canvas.DrawText(where.Left,where.Top,FText); end; *************** *** 1594,1598 **** // update bounds FText.LinesOnChange(Sender); //call text handler to prevent overriding ! UpdateBounds; end; --- 1628,1633 ---- // update bounds FText.LinesOnChange(Sender); //call text handler to prevent overriding ! if not FProcessing then ! UpdateBounds; end; *************** *** 1617,1628 **** longest:integer; begin ! // locate longest line ! longest := 0; ! for i := 0 to FText.Lines.Count-1 do ! if FText.Width[i] > longest then longest := FText.Width[i]; ! Width := longest; ! Height := FText.Lines.Count*FText.QT.GridSquareHeight; end; { TvglEdit } --- 1652,1703 ---- longest:integer; begin ! if FAutoSize then ! begin ! longest := 0; ! for i := 0 to FText.Lines.Count-1 do ! if FText.Width[i] > longest then longest := FText.Width[i]; ! Width := longest; ! Height := FText.Lines.Count*FText.QT.GridSquareHeight; ! end; end; + procedure TvglTextBox.WordWrap; + var + i,j:integer; + s,r:string; + begin + i := 0; + FProcessing := true; + while i < FText.Lines.Count do + begin + //TraceString('scanning line: '+FText.Lines[i]+' ['+IntToStr(FText.Width[i])+'/'+IntToStr(Width)+']'); + if FText.Width[i] > Width-5 then { 5 is a tolerance value, increase to reduce chance of letter clipping } + begin + // we need to locate where the line needs breaking + //TraceString('line '+IntToStr(i)+' needs breaking: '+FText.Lines[i]); + s := ''; + for j := 1 to Length(FText.Lines[i]) do + begin + s := s + FText.Lines[i][j]; + if qtGetStringWidth(FText.QT,s) >= Width then + begin + // break the line here + r := Copy(FText.Lines[i],j+1,Length(FText.Lines[i])); // r now has the rest of the line in + //TraceString(' line '+IntToStr(i)+' replaced with '+s); + FText.Lines[i] := s; + if i+1 = FText.Lines.Count then + FText.Lines.Add(trim(r)) + else FText.Lines.Insert(i+1,trim(r)); + //TraceString(' [inserted at '+IntToStr(i+1)+']'+r); + break; + end; + end; + end; + inc(i); + end; + if AutoSize then Height := FText.Lines.Count*FText.QT.GridSquareHeight; // make correct height + FProcessing := false; + end; + { TvglEdit } *************** *** 1721,1724 **** --- 1796,1877 ---- if CursorY > FLines.Count then CursorY := FLines.Count; if CursorX > Length(Flines[CursorY-1]) then CursorX := Length(Flines[CursorY-1]); + end; + + { TvglAlert } + + constructor TvglAlert.Create(aName: string; AOwner: TvglComponent; Msg:string); + var ALERT_WIDTH :integer; + ALERT_HEIGHT :integer; + begin + inherited Create(aName,aOwner); + ALERT_WIDTH := 300; + Visible := false; + FBounds := Manager.Desktop.Bounds; + FAlertResult := -1; + FImage := TGLBitmap(Manager.GetResource(VGL_SKIN_1)); + + ALERT_HEIGHT := 100; //FTextBox.Height + 10 + (VGL_SKINRECT_BUTTON.Bottom-VGL_SKINRECT_BUTTON.Top); + FBoxBounds := Rect(Manager.ScreenBounds.Right div 2 - (ALERT_WIDTH div 2),Manager.ScreenBounds.Bottom div 2 - (ALERT_HEIGHT div 2),Manager.ScreenBounds.Right div 2 + (ALERT_WIDTH div 2),Manager.ScreenBounds.Bottom div 2 + (ALERT_HEIGHT div 2)); + + FOKButton := TvglButton.Create('vglAlert_OKButton',Self); + FOKButton.Caption := '|O|K'; + FOKButton.HotKey := Ord('O'); + FOKButton.HasHotkey := true; + FOKButton.Bounds := Rect((Width div 2) - (VGL_SKINRECT_BUTTON.Right-VGL_SKINRECT_BUTTON.Left) div 2,FBoxBounds.Bottom - 5 - (VGL_SKINRECT_BUTTON.Bottom-VGL_SKINRECT_BUTTON.Top),0,0); + FOKButton.OnClick := OKOnClick; + + FTextBox := TvglTextbox.Create('vglAlert_TextBox',Self); + FTextBox.AutoSize := false; + FTextBox.Bounds := Rect(FBoxBounds.Left+10,FBoxBounds.Top+10,FBoxBounds.Right-10,FBoxBounds.Bottom-FOKButton.Height-10); + FTextbox.Lines.Text := msg; + FTextBox.Color := clBlack; + //tracestring('* height before = '+inttostr(Ftextbox.height)); + FTextBox.AutoSize := true; + FTextBox.WordWrap; + //tracestring('* height after = '+inttostr(Ftextbox.height)); + //tracestring('* text after = '+ftextbox.lines.text); + // recalculate + ALERT_HEIGHT := 20 + FOKButton.Height + FTextBox.Height; + FBoxBounds := Rect(Manager.ScreenBounds.Right div 2 - (ALERT_WIDTH div 2),Manager.ScreenBounds.Bottom div 2 - (ALERT_HEIGHT div 2),Manager.ScreenBounds.Right div 2 + (ALERT_WIDTH div 2),Manager.ScreenBounds.Bottom div 2 + (ALERT_HEIGHT div 2)); + FOKButton.Bounds := Rect((Width div 2) - (VGL_SKINRECT_BUTTON.Right-VGL_SKINRECT_BUTTON.Left) div 2,FBoxBounds.Bottom - 5 - (VGL_SKINRECT_BUTTON.Bottom-VGL_SKINRECT_BUTTON.Top),0,0); + FTextBox.Bounds := Rect(FBoxBounds.Left+10,FBoxBounds.Top+10,FBoxBounds.Right-10,FBoxBounds.Bottom-FOKButton.Height-10); + end; + + destructor TvglAlert.Destroy; + begin + FImage := nil; + inherited; + end; + + procedure TvglAlert.DrawSelf(where: TRect); + begin + inherited DrawSelf(where); + where := FBoxBounds; + // draw backpanel + Canvas.CurrentColor := clBlack; + Canvas.FillAlpha := 0.5; + Canvas.Rectangle(Manager.Desktop.ScreenBounds); + // draw "window" + Canvas.ImageAlpha := TotalAlpha; + Canvas.TileBitmapSubRect(where,VGL_SKINRECT_BACKGROUND,FImage); + Manager.DrawBorder(where,FImage); + end; + + function TvglAlert.GetComponentType: string; + begin + Result := 'Alert'; + end; + + procedure TvglAlert.OKOnClick(Sender: TObject); + begin + // user wants to cancel alert so tidy up + FAlertResult := 0; + Visible := false; + if assigned(FOnClose) then FOnClose(self); + end; + + procedure TvglAlert.Show; + begin + Visible := true; end; |