mirror of https://gitlab.com/basile.b/dexed.git
353 lines
8.5 KiB
Plaintext
353 lines
8.5 KiB
Plaintext
unit ce_widget;
|
|
|
|
{$MODE OBJFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, FileUtil, Forms, Controls, ExtCtrls, ActnList, Menus,
|
|
ce_interfaces;
|
|
|
|
type
|
|
|
|
(**
|
|
* Base type for an UI module.
|
|
*)
|
|
PTCEWidget = ^TCEWidget;
|
|
TCEWidget = class(TForm, ICEContextualActions, ICEWidgetPersist)
|
|
Content: TPanel;
|
|
Back: TPanel;
|
|
contextMenu: TPopupMenu;
|
|
private
|
|
fUpdating: boolean;
|
|
fDelayDur: Integer;
|
|
fLoopInter: Integer;
|
|
fUpdaterAuto: TTimer;
|
|
fUpdaterDelay: TTimer;
|
|
fWidgUpdateCount: NativeInt;
|
|
procedure setDelayDur(aValue: Integer);
|
|
procedure setLoopInt(aValue: Integer);
|
|
procedure updaterAutoProc(Sender: TObject);
|
|
procedure updaterLatchProc(Sender: TObject);
|
|
//
|
|
procedure optget_LoopInterval(aWriter: TWriter);
|
|
procedure optset_LoopInterval(aReader: TReader);
|
|
procedure optget_UpdaterDelay(aWriter: TWriter);
|
|
procedure optset_UpdaterDelay(aReader: TReader);
|
|
protected
|
|
fID: string;
|
|
// a descendant overrides to implementi a periodic update.
|
|
procedure UpdateByLoop; virtual;
|
|
// a descendant overrides to implement an event driven update.
|
|
procedure UpdateByEvent; virtual;
|
|
// a descendant overrides to implement a delayed update event.
|
|
procedure UpdateByDelay; virtual;
|
|
// May be used for appplication options
|
|
published
|
|
property updaterByLoopInterval: Integer read fLoopInter write setLoopInt;
|
|
property updaterByDelayDuration: Integer read fDelayDur write setDelayDur;
|
|
public
|
|
constructor create(aOwner: TComponent); override;
|
|
destructor destroy; override;
|
|
// restarts the wait period to the delayed update event.
|
|
// if not re-called during 'updaterByDelayDuration' ms then
|
|
// 'UpdateByDelay' is called once.
|
|
procedure beginUpdateByDelay;
|
|
// prevent any pending update.
|
|
procedure stopUpdateByDelay;
|
|
// immediate call any pending update.
|
|
procedure endUpdatebyDelay;
|
|
// increments the updates count.
|
|
procedure beginUpdateByEvent;
|
|
// decrements the update count and call 'UpdateByEvent' if the
|
|
// counter value is null.
|
|
procedure endUpdateByEvent;
|
|
// immediate call 'UpdateByEvent'
|
|
procedure forceUpdateByEvent;
|
|
//
|
|
function contextName: string; virtual;
|
|
function contextActionCount: integer; virtual;
|
|
function contextAction(index: integer): TAction; virtual;
|
|
//
|
|
procedure beforeSave(sender: TObject); virtual;
|
|
procedure declareProperties(aFiler: TFiler); virtual;
|
|
procedure afterLoad(sender: TObject); virtual;
|
|
//
|
|
// returns true if one of the three updater is processing.
|
|
property updating: boolean read fUpdating;
|
|
end;
|
|
|
|
(**
|
|
* TCEWidget list.
|
|
*)
|
|
TCEWidgetList = class(TList)
|
|
private
|
|
function getWidget(index: integer): TCEWidget;
|
|
public
|
|
procedure addWidget(aValue: PTCEWidget);
|
|
property widget[index: integer]: TCEWidget read getWidget;
|
|
end;
|
|
|
|
TWidgetEnumerator = class
|
|
fList: TCEWidgetList;
|
|
fIndex: Integer;
|
|
function getCurrent: TCEWidget;
|
|
Function moveNext: boolean;
|
|
property current: TCEWidget read getCurrent;
|
|
end;
|
|
|
|
operator enumerator(aWidgetList: TCEWidgetList): TWidgetEnumerator;
|
|
|
|
implementation
|
|
{$R *.lfm}
|
|
|
|
(*******************************************************************************
|
|
* TCEWidget
|
|
*)
|
|
|
|
{$REGION Standard Comp/Obj------------------------------------------------------}
|
|
constructor TCEWidget.create(aOwner: TComponent);
|
|
var
|
|
i: NativeInt;
|
|
itm: TmenuItem;
|
|
begin
|
|
inherited;
|
|
fUpdaterAuto := TTimer.Create(self);
|
|
fUpdaterAuto.Interval := 70;
|
|
fUpdaterAuto.OnTimer := @updaterAutoProc;
|
|
fUpdaterDelay := TTimer.Create(self);
|
|
|
|
updaterByLoopInterval := 70;
|
|
updaterByDelayDuration := 1250;
|
|
|
|
for i := 0 to contextActionCount-1 do
|
|
begin
|
|
itm := TMenuItem.Create(self);
|
|
itm.Action := contextAction(i);
|
|
contextMenu.Items.Add(itm);
|
|
end;
|
|
|
|
PopupMenu := contextMenu;
|
|
end;
|
|
|
|
destructor TCEWidget.destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
{$ENDREGION}
|
|
|
|
{$REGION ICEWidgetPersist ------------------------------------------------------}
|
|
procedure TCEWidget.beforeSave(sender: TObject);
|
|
begin
|
|
end;
|
|
|
|
procedure TCEWidget.declareProperties(aFiler: TFiler);
|
|
begin
|
|
// override rules: inhertied must be called. No dots in the property name, property name prefixed with the widget Name
|
|
aFiler.DefineProperty(Name + '_updaterByLoopInterval', @optset_LoopInterval, @optget_LoopInterval, true);
|
|
aFiler.DefineProperty(Name + '_updaterByDelayDuration', @optset_UpdaterDelay, @optget_UpdaterDelay, true);
|
|
end;
|
|
|
|
procedure TCEWidget.afterLoad(sender: TObject);
|
|
begin
|
|
end;
|
|
|
|
procedure TCEWidget.optget_LoopInterval(aWriter: TWriter);
|
|
begin
|
|
aWriter.WriteInteger(fLoopInter);
|
|
end;
|
|
|
|
procedure TCEWidget.optset_LoopInterval(aReader: TReader);
|
|
begin
|
|
updaterByLoopInterval := aReader.ReadInteger;
|
|
end;
|
|
|
|
procedure TCEWidget.optget_UpdaterDelay(aWriter: TWriter);
|
|
begin
|
|
aWriter.WriteInteger(fDelayDur);
|
|
end;
|
|
|
|
procedure TCEWidget.optset_UpdaterDelay(aReader: TReader);
|
|
begin
|
|
updaterByDelayDuration := aReader.ReadInteger;
|
|
end;
|
|
{$ENDREGION}
|
|
|
|
{$REGION ICEContextualActions---------------------------------------------------}
|
|
function TCEWidget.contextName: string;
|
|
begin
|
|
result := '';
|
|
end;
|
|
|
|
function TCEWidget.contextActionCount: integer;
|
|
begin
|
|
result := 0;
|
|
end;
|
|
|
|
function TCEWidget.contextAction(index: integer): TAction;
|
|
begin
|
|
result := nil;
|
|
end;
|
|
{$ENDREGION}
|
|
|
|
{$REGION ICEMultiDocObserver ----------------------------------------------------}
|
|
//procedure TCEWidget.docNew(const aDoc: TCESynMemo);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.docFocused(const aDoc: TCESynMemo);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.docChanged(const aDoc: TCESynMemo);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.docClose(const aDoc: TCESynMemo);
|
|
//begin
|
|
//end;
|
|
{$ENDREGION}
|
|
|
|
{$REGION ICEProjectObserver -----------------------------------------------------}
|
|
//procedure TCEWidget.projNew(const aProject: TCEProject);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.projChange(const aProject: TCEProject);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.projClose(const aProject: TCEProject);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.projCompile(const aProject: TCEProject);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.projRun(const aProject: TCEProject);
|
|
//begin
|
|
//end;
|
|
//
|
|
//procedure TCEWidget.projFocused(const aProject: TCEProject);
|
|
//begin
|
|
//end;
|
|
{$ENDREGION}
|
|
|
|
{$REGION Updaters---------------------------------------------------------------}
|
|
procedure TCEWidget.setDelayDur(aValue: Integer);
|
|
begin
|
|
if aValue < 100 then aValue := 100;
|
|
if fDelayDur = aValue then exit;
|
|
fDelayDur := aValue;
|
|
fUpdaterDelay.Interval := fDelayDur;
|
|
end;
|
|
|
|
procedure TCEWidget.setLoopInt(aValue: Integer);
|
|
begin
|
|
if aValue < 30 then aValue := 30;
|
|
if fLoopInter = aValue then exit;
|
|
fLoopInter := aValue;
|
|
fUpdaterAuto.Interval := fLoopInter;
|
|
end;
|
|
|
|
procedure TCEWidget.beginUpdateByEvent;
|
|
begin
|
|
Inc(fWidgUpdateCount);
|
|
end;
|
|
|
|
procedure TCEWidget.endUpdateByEvent;
|
|
begin
|
|
Dec(fWidgUpdateCount);
|
|
if fWidgUpdateCount > 0 then exit;
|
|
fUpdating := true;
|
|
UpdateByEvent;
|
|
fUpdating := false;
|
|
fWidgUpdateCount := 0;
|
|
end;
|
|
|
|
procedure TCEWidget.forceUpdateByEvent;
|
|
begin
|
|
fUpdating := true;
|
|
UpdateByEvent;
|
|
fUpdating := false;
|
|
fWidgUpdateCount := 0;
|
|
end;
|
|
|
|
procedure TCEWidget.beginUpdateByDelay;
|
|
begin
|
|
fUpdaterDelay.Enabled := false;
|
|
fUpdaterDelay.Enabled := true;
|
|
fUpdaterDelay.OnTimer := @updaterLatchProc;
|
|
end;
|
|
|
|
procedure TCEWidget.stopUpdateByDelay;
|
|
begin
|
|
fUpdaterDelay.OnTimer := nil;
|
|
end;
|
|
|
|
procedure TCEWidget.endUpdateByDelay;
|
|
begin
|
|
updaterLatchProc(nil);
|
|
end;
|
|
|
|
procedure TCEWidget.updaterAutoProc(Sender: TObject);
|
|
begin
|
|
fUpdating := true;
|
|
UpdateByLoop;
|
|
fUpdating := false;
|
|
end;
|
|
|
|
procedure TCEWidget.updaterLatchProc(Sender: TObject);
|
|
begin
|
|
fUpdating := true;
|
|
UpdateByDelay;
|
|
fUpdating := false;
|
|
fUpdaterDelay.OnTimer := nil;
|
|
end;
|
|
|
|
procedure TCEWidget.UpdateByLoop;
|
|
begin
|
|
end;
|
|
|
|
procedure TCEWidget.UpdateByEvent;
|
|
begin
|
|
end;
|
|
|
|
procedure TCEWidget.UpdateByDelay;
|
|
begin
|
|
end;
|
|
{$ENDREGION}
|
|
|
|
{$REGION TCEWidgetList---------------------------------------------------------------}
|
|
function TCEWidgetList.getWidget(index: integer): TCEWidget;
|
|
begin
|
|
result := PTCEWidget(Items[index])^;
|
|
end;
|
|
|
|
procedure TCEWidgetList.addWidget(aValue: PTCEWidget);
|
|
begin
|
|
add(Pointer(aValue));
|
|
end;
|
|
|
|
function TWidgetEnumerator.getCurrent:TCEWidget;
|
|
begin
|
|
result := fList.widget[fIndex];
|
|
end;
|
|
|
|
function TWidgetEnumerator.moveNext: boolean;
|
|
begin
|
|
Inc(fIndex);
|
|
result := fIndex < fList.Count;
|
|
end;
|
|
|
|
operator enumerator(aWidgetList: TCEWidgetList): TWidgetEnumerator;
|
|
begin
|
|
result := TWidgetEnumerator.Create;
|
|
result.fList := aWidgetList;
|
|
result.fIndex := -1;
|
|
end;
|
|
{$ENDREGION}
|
|
|
|
end.
|