AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte MyInsight, das Delphi 2010 IDE-Insight für's eigene Programm
Thema durchsuchen
Ansicht
Themen-Optionen

MyInsight, das Delphi 2010 IDE-Insight für's eigene Programm

Ein Thema von himitsu · begonnen am 29. Apr 2010 · letzter Beitrag vom 18. Jun 2010
Antwort Antwort
Seite 3 von 3     123   
Benutzerbild von himitsu
himitsu
Registriert seit: 11. Okt 2003
Vor Kurzem gab es doch eine Diskusion darüber, welches Hilfesystem (HLP, CHM, HTML, Wiki, ...) wohl am Besten sei
und dazu kam mir die Idee, warum eigentlich nicht das Coole IDE Insight vom neuen RAD 2010 ins eigene Programm holen?
> Hilfesystem und Stand der Technik
So muß man dann auch in der Hilfe nicht ständig groß und breit erklären wo sich was versteckt.

Für die, welche IDE Insight noch nicht kennen, denen kann ich wärmstens Daniels erstes Delphi 2010-Video empfehlen.
> DP-Videos > Film #14.1
> Im Anhang ist jetzt auch nochmal ein Bild davon


Bei vielen Programmen ist es ja leider so, daß bei der Masse an Menüeinträgen, Dialogen und Optionen keiner mehr weiß wo sich was versteckt.
Hier kommt also dieser Insight-Dialog in Spiel, welcher alles kennt und wo man sehr schnell und leicht etwas suchen kann.

Im Programm könnte man es so lösen, daß zu jedem Dialog, Menü oder sonstwas ein kleines zusätzliches Objekt erstellt wird (falls sich z.B. die Dialog-Instanz nicht direkt nutzen läßt), welches als Schnittstelle zum IInsight diehnt.
In diesem Objekt werden z.B. alle Optionen eines Dialogs an IInsight übergeben und es stellt dann auch den Zugriff auf den Dialog her.
( Im Fall der Demo-Form würde dieses praktisch dem Inhalt von FormCreate und als Callback die OnInsight-Ereignisse sein. )




Tja, hier sind also die ersten Grundzüge dieses Systems:
Vorschläge sind gern gesehn.

Es gibt eine Reihe von Interfaces, um eine Ergebnisliste zu erstellen und zu verwalten, sowie um den Dialog anzuzeigen.
Für Letzteres bräuchtet ihr nur in eurem Programm z.B. die Taste F6 abfangen und dort den Insight-Dialog einblenden.
Delphi-Quellcode:
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_F6 then Insight.Show(Self);
Zuvor muß natürlich noch eine Reihe von Ereignissen registriert/eingetragen werden.
Hierzu wird ein Eintrag in einer Gruppe eingetragen und dazu noch ein Callback angegeben.
Man kann einer Gruppe auch ein OnList-Event zuweisen, womit die untergeordnete Liste bei jedem Anzeigen des Dialogs überarbeitet oder komplett neu erstellt werden könnte. (z.B. gut für sowas die veränderliche "zuletzt bearbeitete Dateien"-Liste).

Im OnClick-Callback erfahrt ihr was gewählt wurde, könnt dann z.B. den entsprechenden Optionsdialog eures Programms einblenden und da das zugehörige Eingabeelement selektieren.

Dem Angang liegt natürlich eine kleine Demo bei, in welcher man eines der Edits/Memos über MyInsight auswählen/fokusieren kann.

Delphi-Quellcode:
TInsightEventC = Procedure(Const Sender: IInsightAction) of Object;
TInsightEventA = Procedure(Const Sender: IInsightAction; Var Allow: Boolean) of Object;
TInsightEventL = Procedure(Const Sender: IInsightCategory) of Object;
TInsightEventS = Procedure(Const Sender: IInsight) of Object;

IInsightAction = Interface(IInsightInternalAction)
  ['{1D521CF5-47DD-4CB7-9124-FD3098694101}']
  Property Parent: IInsightCategory Read GetParent;

  Property Image: TGraphic Read GetImage Write AssignImage;
  Property Text: String Read GetText Write SetText;
  Property Source: String Read GetSource Write SetSource;
  Property Hotkey: TShortCut Read GetHotkey Write SetHotkey;
  Property Hint: String Read GetHint Write SetHint;
  Property Data: Integer Read GetData Write SetData; // for programmers use
  Property OnClick: TInsightEventC Read GetOnClick Write SetOnClick;
End;

IInsightCategory = Interface(IInsightInternalCategory)
  ['{3C1E8994-7CF6-4499-948F-A0A2EC4A484C}']
  Property Parent: IInsight Read GetParent;

  Property Active: Boolean Read GetActive Write SetActive;
  Property Text: String Read GetText Write SetText;
  Property Data: Integer Read GetData Write SetData; // for programmers use

  Function AddAction(Const OnClick: TInsightEventC; Image: TGraphic; Const Text, Hint,
                      Source: String; Data: Integer = 0): IInsightAction; Overload;
  Function AddAction(Const OnClick: TInsightEventC; Image: TGraphic; Const Text, Hint: String;
                      Hotkey: TShortCut; Data: Integer = 0): IInsightAction; Overload;

  Function AddAction: IInsightAction; Overload;
  Function Count: Integer;
  Property Actions[idx: Integer]: IInsightAction Read GetAction; Default;
  Procedure Delete (Action: IInsightAction);
  Procedure Clear;
  Procedure Lock;
  Procedure Unlock;

  Property OnList: TInsightEventL Read GetOnList Write SetOnList;
  Property OnClick: TInsightEventA Read GetOnClick Write SetOnClick;
End;

IInsightActionList = Interface(IInternalInsightActionList)
  ['{78D527B7-63F4-42A0-A59C-99F8D3AE73DD}']
  Property Parent: IInsight Read GetParent;

  Property ActionList: TActionList Read GetActList;
  Property DefaultCategory: String Read GetDefCat Write SetDefCat;
  Property AllInDefault: Boolean Read GetAllInDef Write SetAllInDef;
End;

IInsight = Interface(IInternalInsight)
  ['{15E44350-1A50-43E9-8B96-CE6FB9D6E3AB}']
  Function AddCategory(Const Text: String; Const OnList: TInsightEventL; // if exists "Text" then create an exception
              Data: Integer = 0): IInsightCategory; Overload;

  Function AddCategory(Const Text: String): IInsightCategory; Overload; // if exists "Text" then retun the existing Category
  Function Count: Integer;
  Property Category [ idx: Integer]: IInsightCategory Read GetCategory; Default;
  Property Category [Const Text: String]: IInsightCategory Read GetNameCategory; Default;
  Procedure Delete ( Action: IInsightCategory); Overload;
  Procedure Clear;
  Procedure Lock;
  Procedure Unlock;

  Procedure AddMenu (Menu: TMenu; DefaultCategory: String);
  Procedure AddMainMenu(Menu: TMainMenu; DefaultCategory: String; AllInDefault: Boolean = False);
  Procedure AddPopup (Menu: TPopupMenu; DefaultCategory: String);
  Function CountMenus: Integer;
  Property Menu [idx: Integer]: IInsightMenu Read GetMenu;
  Procedure Delete(Menu: IInsightMenu); Overload;
  Procedure ClearMenus;

  Procedure AddActionList(ActionList: TActionList; DefaultCategory: String; AllInDefault: Boolean = False);
  Function CountActionLists: Integer;
  Property ActionList[idx: Integer]: IInsightActionList Read GetAction;
  Procedure Delete (ActionList: IInsightActionList); Overload;
  Procedure ClearActionLists;

  Property Title: String Read GetTitle Write SetTitle;
  Property AllText: String Read GetAllText Write SetAllText;
  Property OKText: String Read GetOKText Write SetOKText;
  Property CancelText: String Read GetCancelText Write SetCancelText;

  Procedure Show(Owner: TComponent = nil);
  Procedure Hide;
  Function isVisible: Boolean;
  Property SelText: String Read GetSelText Write SetSelText;
  Property DisabledCategories: String Read GetDisList Write SetDisList;
  Procedure DoChanged;

  Property OnShow: TInsightEventS Read GetOnShow Write SetOnShow;
  Property OnClick: TInsightEventA Read GetOnClick Write SetOnClick;
End;



Var Insight: IInsight;

Function CreateNewInsight: IInsight;
Es gibt auch schon eine globale Instanz und theoretisch könnte man auch noch weitere Instanzen erstellen, falls es mal nötig sein sollte und man verschiedene Ergebnislisten bräuchte.

Der Dialog ist noch nicht ganz fertig, aber er sollte dennoch funktionen.
> Die Anzeige der Liste (TreeView) ist noch unvollständig und ich überlege, ob ich nicht auf die VirtualTreeView ausweichen oder etwas Anderes verwenden soll, denn die Verwaltung des TTreeView ist "bescheuert", vorallem da man dort keine Einträge ausblenden kann.
Miniaturansicht angehängter Grafiken
unbenannt_103.png   unbenannt_878.png  
Angehängte Dateien
Dateityp: 7z MyInsight v0.6 inkl. Demo-EXE.7z (348,2 KB, 73x aufgerufen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (18. Jun 2010 um 10:47 Uhr)
 
christio
 
#21
  Alt 18. Jun 2010, 08:01
Hallo,

Ich habe 2 kleine Fehler gefunden:

Bevel2:
Anchor akRight fehlt
ProcessActionList:
vor GetBitmap wird nicht überprüft, ob AL2.Images zugewiesen ist
Img sollte immer neu erzeugt werden, da es sonst zu Überdeckungen kommt
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#22
  Alt 18. Jun 2010, 08:56
Das TBitmap wollte ich eigentlich nur einmal erstellen, um so ein bissl was einzusparen, aber nun wird der Inhalt einfach übermalt, damit die alten Bilder weg sind.
  • Anchor gefixt
  • bei {ImageList}.Images wird nun geprüft, ob es existiert
  • beim ImageIndex wird ebenfalls geprüft, ob das gewünschte Bild überhaupt in der ImageList enthalten ist
  • {TMenuItem}.SubMenuImages und {TMenuItem}.Bitmap wird nun ebenfalls beachtet.
  • der Inhalt des temporäten Bitmaps wird nun vor der Verwendung geleert
    und gleichzeitig wird für eine passendere Hintergrundfarbe gesorgt, falls das Bild transparent ist

Dateien siehe Beitrag #1

Geändert von himitsu (18. Jun 2010 um 09:07 Uhr)
  Mit Zitat antworten Zitat
christio
 
#23
  Alt 18. Jun 2010, 09:34
Danke für die Änderungen.

Wie wird eigentlich das OnList - Event richtig behandelt? Ich probiere die Fensterliste einer MDI - Anwendung (Form.WindowMenu) einzubauen, habe aber mit dem Change und List - Event so meine Probleme.

Denkst du auch an die Funktion Insigth.AddApplicatonManager nach?
  Mit Zitat antworten Zitat
Benutzerbild von Daniela.S
Daniela.S

 
Delphi XE4 Enterprise
 
#24
  Alt 18. Jun 2010, 09:44
Hallo,

das ist echt eine feine Sache, gefällt mir

Wird es auch die Möglichkeit geben den Inhalt eines TActionManagers abzubilden?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#25
  Alt 18. Jun 2010, 10:59
Für das OnList-Ereignis gibt es nun was in der Demo.

Dieses Ereignis wird immer aufgerufen, kurz bevor die Insight-Liste angezeigt wird.
Somit kannst du die Kategorie z.B. immer mit aktuellen Anpassungen versehn, also sie bearbeiten oder neu erstellen.
(die Menüs und Actionlisten werdn auch immer mit den aktuellen Daten geladen)

In der Demo wird einmal die Kategorie etwas bearbeitet.
> eine angezeigte Zahl jedesmal erhöht, wenn die Liste neu angezeigt wird
Und dann wird eine andere Kategorie neu erstellt.

Damit hat man also die Möglichkeit auch dynamische Daten aufzulisten, welche sich öfters mal ändern.



Bei den anderen Action-Sachen ... mal sehn was sich machen läßt.



Ein Fehler wurde auch noch behoben, wenn man im OnList-Ereignis was änderte, dann konnte es zu einer Endlosschleife und dem damit verbundenen Stacküberlauf kommen.

Diese Schleife war zwar bekannt und sollte über das _DoList unterbunden werden, aber das _DoList:=False war unglücklich positioniert und wurde vorzeitig zurückgesetzt.
Delphi-Quellcode:
If not Assigned(_Form) or _DoList Then Exit;
_DoList := True;
...
_DoList := False;

Geändert von himitsu (18. Jun 2010 um 11:05 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz