MiConfigUtils.pas 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. {
  2. MiConfigUtils
  3. ===========
  4. Por Tito Hinostroza 20/12/2016
  5. Descripción
  6. ===========
  7. Unidad con rutinas útiles para implementar las ventanas de configuración.
  8. }
  9. unit MiConfigUtils;
  10. {$mode objfpc}{$H+}
  11. interface
  12. uses
  13. Classes, SysUtils, Graphics, Forms, ComCtrls;
  14. type
  15. TlistFrames = array of TFrame;
  16. //Utilidades para el uso de Frames con "MiCOnfig"
  17. procedure HideAllFrames(form: TForm);
  18. procedure ShowFramePos(frm: TFrame; x, y: integer);
  19. //Utilidades para el uso de TTreeView con Frames con "MiCOnfig"
  20. function IdFromTTreeNode(node: TTreeNode): string;
  21. function TTreeNodeFromId(Id: string; tree: TTreeView): TTreeNode;
  22. function AddNodeToTreeView(tree: TTreeView; id, Caption: string): TTreeNode;
  23. function LinkFrameToTreeView(tree: TTreeView; id, Caption: string;
  24. frame: TFrame = nil): TTreeNode;
  25. function ShowFrameOfNode(form: Tform; node: TTreeNode; x, y: integer): boolean;
  26. implementation
  27. function ListOfFrames(form: TForm): TlistFrames;
  28. //Devuelve la lista de frames del tipo TCfgFrame declarado aquí
  29. var
  30. i: Integer;
  31. n : integer;
  32. f: TFrame;
  33. begin
  34. SetLength(Result,0);
  35. for i:= 0 to form.ComponentCount-1 do begin
  36. if form.Components[i] is TFrame then begin
  37. f:=TFrame(form.Components[i]); //obtiene referencia
  38. n := high(Result)+1; //número de elementos
  39. setlength(Result, n+1); //hace espacio
  40. Result[n] := f; //agrega
  41. end;
  42. end;
  43. end;
  44. procedure HideAllFrames(form: TForm);
  45. //Oculta todos los frames de un formulario
  46. var
  47. f: TFrame;
  48. begin
  49. for f in ListOfFrames(form) do
  50. f.visible := false;
  51. end;
  52. procedure ShowFramePos(frm: TFrame; x, y: integer);
  53. //Muestra el frame en la posición indicada
  54. begin
  55. frm.left:= x;
  56. frm.Top := y;
  57. frm.Visible:=true;
  58. end;
  59. function IdFromTTreeNode(node: TTreeNode): string;
  60. //Returns an ID with indication of the position of a TTreeNode'.
  61. //It has the form: 1, 1.1, 2.1.3. Only works for 3 levels.
  62. var
  63. nivel: Integer;
  64. begin
  65. nivel := node.Level;
  66. case nivel of
  67. 0: Result := IntToStr(node.Index+1); //de un nivel
  68. 1: Result := IntToStr(node.Parent.Index+1) + '.' +
  69. IntToStr(node.Index+1);
  70. 2: Result := IntToStr(node.Parent.Parent.Index+1) + '.' +
  71. IntToStr(node.Parent.Index+1) + '.' +
  72. IntToStr(node.Index+1)
  73. else //de un nivel
  74. Result := '';
  75. end;
  76. end;
  77. function TTreeNodeFromId(Id: string; tree: TTreeView): TTreeNode;
  78. //Returns a TreeNode, given the ID position. If not found, returns NIL.
  79. //Only works for 3 levels.
  80. var
  81. node: TTreeNode;
  82. begin
  83. for node in tree.Items do begin
  84. if IdFromTTreeNode(node) = Id then exit(node);
  85. end;
  86. exit(nil);
  87. end;
  88. function AddNodeToTreeView(tree: TTreeView; id, Caption: string): TTreeNode;
  89. {Agrega un Frame a TTreeNode, de forma simbólica. Lo que se agrega en realidad,
  90. es un nodo, con el nombre indicado.
  91. El campo ID, determina la ubicación del nodo en el árbol, y es de la forma:
  92. <nivel1>.<nivel2>.<nivel3> ... }
  93. function ChildCount(tv: TTreeView; nod: TTreeNode): integer;
  94. {Devuelve la cantidad de nodos hijos (solo en el primer nivel) de un nodo.}
  95. var
  96. node: TTreeNode;
  97. levChild: Integer;
  98. begin
  99. Result := 0;
  100. if nod = nil then levChild := 0 else levChild := nod.Level+1;
  101. for node in tv.Items do begin
  102. if (node.Level = levChild) and (node.Parent = nod) then inc(Result);
  103. end;
  104. end;
  105. function ChildByNumber(tv: TTreeView; nod: TTreeNode; num: integer): TTreeNode;
  106. {Devuelve el nodo hijo número "n" (empieza en 1) de Nod. Debe asegurarse que hay
  107. al menos "n" nodos hijos en el nodo indicado. De otra forma, se puede generar error.}
  108. var
  109. node: TTreeNode;
  110. levChild, nChild: Integer;
  111. begin
  112. nChild := 0;
  113. if nod = nil then levChild := 0 else levChild := nod.Level+1;
  114. for node in tv.Items do begin
  115. if (node.Level = levChild) and (node.Parent = nod) then begin
  116. inc(nChild);
  117. if nChild=num then exit(node);
  118. end;
  119. end;
  120. //No se encontró
  121. exit(nil);
  122. end;
  123. function BuscarNodoN(tv: TTreeView; raiz: TTreeNode; nNod: string): TTreeNode;
  124. {Busca el nodo de orden "nNod". Asegura que el nodo raiz tenga los nodos, indicados. Si no los tiene, los
  125. crea.}
  126. var
  127. n: LongInt;
  128. begin
  129. n := StrToInt(nNod);
  130. if n<=ChildCount(tv, raiz) then begin
  131. //No hay problema, el nodo ya existe
  132. Result := ChildByNumber(tv, raiz, n);
  133. exit;
  134. end else begin
  135. //No hay nodos hijo suficientes, hay que agregar nodos.
  136. while ChildCount(tv, raiz)<n do begin
  137. Result := tv.Items.AddChild(raiz, 'nodo');
  138. end;
  139. end;
  140. end;
  141. var
  142. nod: TTreeNode;
  143. niveles: TStringList;
  144. niv: String;
  145. nodRaiz : TTreeNode;
  146. begin
  147. //Ubica nodo
  148. nod := TTreeNodeFromId(id, tree);
  149. if nod=nil then begin
  150. //No existe el nodo. Hay que crearlo en el nivel indicado
  151. niveles := TStringList.Create;
  152. niveles.Delimiter:='.';
  153. niveles.DelimitedText:=id;
  154. nodRaiz := nil; //inicia en nodo raiz
  155. for niv in niveles do begin
  156. nodRaiz := BuscarNodoN(tree, nodRaiz, niv);
  157. end;
  158. nod := nodRaiz;
  159. niveles.Destroy
  160. end;
  161. nod.Text:=Caption;
  162. if nod.Parent<>nil then //para hacer al nodo visible
  163. nod.Parent.Expanded:=true;
  164. Result := nod;
  165. end;
  166. function LinkFrameToTreeView(tree: TTreeView; id, Caption: string;
  167. frame: TFrame = nil): TTreeNode;
  168. {Crea un nodo en el TreeView y lo asocias a un Frame de configuración (Ver documentación
  169. de MiConfig). Debe llamarse, después de crear el Frame.
  170. El "id", debe ser único y es de la forma: "1", "2.1" o "3.2.1".
  171. Si se indica el Frame en NIL, no se crea configura el Frame,solo se agrega el ítem}
  172. begin
  173. Result := AddNodeToTreeView(tree, id, Caption); //Crea el ítem el el TreeView
  174. if frame<>nil then begin
  175. //Agrega el ID en la etiqueta, para indicar que está asociado a ese nodo
  176. frame.Hint := frame.Hint + id + '|';
  177. end;
  178. end;
  179. function ShowFrameOfNode(form: Tform; node: TTreeNode; x, y: integer): boolean;
  180. {Muestra el frame correspondiente a un nodo. La correspondencia Frame-nodo, debe
  181. haberse indicado con LinkFrameToTreeView().
  182. Si no encuentra el frame para mostrar, devuelve FALSE.}
  183. var
  184. id: String;
  185. f: TFrame;
  186. begin
  187. HideAllFrames(form);
  188. id := IdFromTTreeNode(node);
  189. //Ubica al Frame
  190. for f in ListOfFrames(form) do begin
  191. if pos(id+'|', f.Hint)<>0 then begin
  192. ShowFramePos(f, x, y); //muestra
  193. exit(true);
  194. end;
  195. end;
  196. //No encontró
  197. exit(false)
  198. end;
  199. end.