Notes |
|
(0004091)
|
zed
|
16-10-2011 11:46
|
|
Да, такое можно сделать на компоненте VirtualTreeView: http://www.delphi-gems.com/index.php?option=com_content&task=view&id=12&Itemid=38 |
|
|
(0004209)
|
zed
|
27-10-2011 15:39
|
|
И кстати, когда появятся плагины, мне кажется будет очень гармонично сделать все их настройки так же в таблице. Причём, окошко с настройками и таблица будет одна для всех возможных плагинов. Т.е. выбрали в комбобоксе (в простейшем случае) какой-то плагин и динамически занесли все его настройки в табличку, переключились на другой плагин - перерисовали табличку с уже другими настройками.
Ну, это так, мысли вслух :) |
|
|
(0004210)
|
Tolik
|
27-10-2011 19:12
|
|
Я понял, плагин - это такая мантра :)
Омммм... Плагинннн... |
|
|
(0004306)
|
zOn
|
04-11-2011 19:25
|
|
ага. я только за!
и кстати: http://sasgis.org/mantis/view.php?id=963 |
|
|
(0004856)
|
DJ VK
|
11-01-2012 12:34
(edited on: 11-01-2012 12:43) |
|
Есть желание попробовать.
1. ДЛЯ ЗАТРАВКИ. КАКУЮ ТАБЛИЦУ ИСПОЛЬЗОВАТЬ? TMS TAdvGrid не бесплатна, но исходники есть если надо. и проста в использовании. Не люблю выбирать из одного пункта. Предлагаю обсудить кандидатов.
2. Возможно ли ВСЕ праметры вывести из ZMP, втч и скрипт?
3. Можно прикрутить GUID генератор и сделать кнопки "СОЗДАТЬ zmp" и "сделать копию с новым GUID". полезная фича?
Чем хороша Virtual Treeview? TColor или комбо со списком цветов поддерживается ?для поля?
Страшный сайт у них. Вместо 1й кнопки скачать 3 десятка (!) кнопок....
|
|
|
(0004857)
|
zed
|
11-01-2012 12:40
|
|
1. Любую фришную и опенсорсную. TMS не пойдёт.
2. Да, почему бы и нет
3. Фича полезная, но не уверен, что тут она будет к месту. |
|
|
(0004858)
|
zOn
|
11-01-2012 12:43
|
|
3. может отдельной ф-цией потом где-нибудь. а так конечно былобы хорошо иметь инструмент для создания zmp/ кажется даже хотелка была по этому поводу или на форуме писали. |
|
|
(0004859)
|
DJ VK
|
11-01-2012 12:43
|
|
фичу в отдельный пункт меню параметров карты. |
|
|
(0004860)
|
zed
|
11-01-2012 12:46
|
|
>Чем хороша Virtual Treeview?
Я просто предложил, если не устраивает ищите что-то другое, но с оглядкой на п.1. |
|
|
(0004861)
|
DJ VK
|
11-01-2012 12:53
|
|
KGrid бесплатный. Хрен его знает. Нужна возможность отображать цвет. точно как в IDE. |
|
|
(0004862)
|
zed
|
11-01-2012 12:59
|
|
Цвет текста по-моему в любом гриде можно сделать. |
|
|
|
Такая же хренотень нужна чтобы настройки gps редактировать. Я было сунулся сделать на стандартных элементах управления, но понял всю глубину своего заблужения, снёс к чертям и не стал заливать.
Необходимо (особенно для плагинов, но и для gps в частности тоже) уметь строить опции и их значения динамически, и сохранять это дело в строку (сериализовать) без особенного вкорячивания кода в сас. Грубо говоря, давайте загрузим настройки опций из файлика "суперплагин.кфг", а сохраняться и восстанавливаться они должны в секцию "суперсекция". У нас на работе в одном из проектов была такая хрень (в смысле сохранения и восстановления в/из БД произвольных опций), но тут она не прокатит, да и грида как такогвого там не было, не говоря уже про NDA. |
|
|
(0004868)
|
zed
|
11-01-2012 14:30
|
|
>уметь строить опции и их значения динамически, и сохранять это дело в строку (сериализовать) без особенного вкорячивания кода в сас
+1
Я об этом как-то нигде не упомянул, но хотелось бы именно такого. |
|
|
(0004876)
|
DJ VK
|
12-01-2012 08:25
|
|
После упорядочивания zmp как раз подумываал свести в таблицу GPs\GSm а потом и другие опции. Длу ускорения процесса пока что не буду добавлять те параметры которые используются но не редактируются напрямую из программы, например скрипт из ZMP.
KGrid довольно любопытен. установился мгновенно. Обычная таблица с строками. Но !
case InitialCol of
1:
begin
AEditor := TEdit.Create(nil);
end;
2:
begin
AEditor := TComboBox.Create(nil);
TComboBox(AEditor).Style := csDropDown;
end;
3:
begin
AEditor := TButton.Create(nil);
end;
4:
begin
AEditor := TCheckBox.Create(nil);
TCheckBox(AEditor).Font.Color := clRed; // applies only without OS themes (in Delphi)
end;
5:
begin
AEditor := TScrollBar.Create(nil);
TScrollBar(AEditor).Max := 10;
end;
и так любой тип контрола создается динамически на время редактирования.
Один минус. Возможности сгруппировать параметры и скрывать -раскрывать группу я не нашел, а без этого таблица кажется неупорядоченной.
Virtual Tree установился из исходников не сразу. аж три директории прописал, да и еще ошибка - пакаджи лежат на одну папку глубже чем это прописано. так что если svn скачивать будет не айс (это не hg и толку от них мало, проще в папку requires кинуть и все.) Изучаю функции. |
|
|
(0004878)
|
DJ VK
|
12-01-2012 10:15
(edited on: 12-01-2012 10:38) |
|
>уметь строить опции и их значения динамически, и сохранять это дело в строку (сериализовать) без особенного вкорячивания кода в сас
Virtual Tree для вас и создан.
ValueTypes[ParentNode.Index, Node.Index];
PropertyTexts[Node.Parent.Index, Node.Index, ptkText];
DefaultValue[ParentNode.Index, Node.Index];
это что вызывается внешнего. Надо еще присодинить таблицу названий разделов параметров и все. Сам компонент не особо интересует что внутри.
Надо делать оберточку чтоб все это заработало ((((((
|
|
|
|
А насколько он утяжелит сас в плане ресурсов и размера файла? Хотя бы примерно есть оценки? Или из-за унификации туевой хучи контролов будет меньше жрать?
Кстати, а есть там события у внутрених редакторов полей, чтобы они могли реагировать на изменения снаружи или у других полей? |
|
|
(0004880)
|
DJ VK
|
12-01-2012 10:48
|
|
контролов вообще не будет. они будут создаваться динамически однотипно. Это как раз в обёртке надо прописать.
Data := FTree.GetNodeData(Node);
case Data.ValueType of
vtString:
begin
FEdit := TEdit.Create(nil);
with FEdit as TEdit do
begin
Visible := False;
Parent := Tree;
Text := Data.Value;
OnKeyDown := EditKeyDown;
end;
end;
vtNumber:
begin
FEdit := TMaskEdit.Create(nil);
with FEdit as TMaskEdit do
begin
Visible := False;
Parent := Tree;
EditMask := '9999';
Text := Data.Value;
OnKeyDown := EditKeyDown;
end;
end;
1. 100000 записей на моем компе в таблице создаются за 28 миллисекунд. так что ресурсов не жрет.
2. Компненты еще одни добавляются. с исходным кодом.
3. Надо создавать еще 1 юнит. Непосредственно обработчик. за основу взять из демок TPropertyEditLink. и прикрутить к нему и другие типы данных.
4. вместо статической таблицы понадобится класс с набором описаний непосредственно каждой строки таблицы.
как же я ненавижу создавать классы, кто бы знал.... |
|
|
(0004881)
|
DJ VK
|
12-01-2012 10:50
|
|
>>Кстати, а есть там события у внутрених редакторов полей, чтобы они могли реагировать на изменения снаружи или у других полей?
TPropertyEditLink = class(TInterfacedObject, IVTEditLink)
private
FEdit: TWinControl; // One of the property editor classes.
FTree: TVirtualStringTree; // A back reference to the tree calling.
FNode: PVirtualNode; // The node being edited.
FColumn: Integer; // The column of the node being edited.
protected
procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
public
destructor Destroy; override;
function BeginEdit: Boolean; stdcall;
function CancelEdit: Boolean; stdcall;
function EndEdit: Boolean; stdcall;
function GetBounds: TRect; stdcall;
function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
procedure ProcessMessage(var Message: TMessage); stdcall;
procedure SetBounds(R: TRect); stdcall;
end; |
|
|
|
>создаваться динамически однотипно
Может тогда проще создавать их (контролы) из ресурсного потока типа dfm? Редактирование руками снаружи, опубликованные свойства и события автоматом натянутся. |
|
|
(0004883)
|
DJ VK
|
12-01-2012 10:55
(edited on: 12-01-2012 10:57) |
|
Я приложил файлы. Посмотрите как сделано. Довольно примитивный код. Напмню, его придется правит один раз. А затем только динамически создавать описания параметров и после правки распихивать обратно.
Я вот и предложить хочу всем вместе подумать и обернуть содержимое этих 2х файлов в 1 динамический класс с формой (ну может еще несколько юнитов).
|
|
|
(0004885)
|
zed
|
12-01-2012 11:39
|
|
>А насколько он утяжелит сас в плане ресурсов и размера файла?
Думаю килов на 300 точно. Сами сорцы весят 1,6 Мб. В общем, копейки. |
|
|
|
Код простой, но не лишённый недостатков. Основной - создание компонентов не произвольных, а только из закрытого перечня, свойства тоже руками пишутся в коде. События налету не связать с другими объектами. То есть конечно VTV наиболее близок из доступных к идеалу, но я предлагаю создавать объекты несколько по-другому. Возможно не получится, если компонент заточен под приаттаченный код, но тем не менее если получится, будет куда интереснее, проще потом, менее ресурсоёмко и более гибко.
Основная мысль - юзать тот же самый механизм создания объектов из ресурсов, что сама дельфя. Соответственно в настройках опций по-прежнему указывается информация о том, что для этого конкретного свойства редактор - чекбокс. Но чекбокс создаётся не руками, а код его создания (в формате как в dfm) тащится из внешнего файла. Например из инишки. Код вида:
object TMyWindow: TTBXDockablePanel
Left = 65
Top = 0
DockedWidth = 170
DockPos = -6
DockRow = 2
TabOrder = 1
Visible = False
Caption = 'Codecoder'
object MyPanel: TPanel
Left = 0
Top = 0
Width = 170
Height = 551
Align = alClient
AutoSize = True
BevelOuter = bvNone
TabOrder = 0
object MyDock: TTBXDock
Left = 0
Top = 0
Width = 170
Height = 9
end
object MyScrollBox: TScrollBox
Left = 0
Top = 9
Width = 170
Height = 542
HorzScrollBar.Visible = False
VertScrollBar.Smooth = True
VertScrollBar.Tracking = True
Align = alClient
Color = clWhite
ParentColor = False
TabOrder = 1
end
end
end
конкретно тут нет свойств, но обработчики тут тоже натягиваются, проверено.
Далее зовётся код типа
procedure TfrmMain.LoadDFMPlugins;
var
fs: TFileStream;
ms: TMemoryStream;
rd: TReader;
new_panel: TTBXDockablePanel;
new_toggler: TTBXVisibilityToggleItem;
begin
try
ms:=nil;
fs:=nil;
rd:=nil;
try
ms:=TMemoryStream.Create;
// load
fs:=TFileStream.Create('vsagps_fly-on-track.dfm', fmOpenRead);
// convert
ObjectTextToBinary(fs, ms);
// make
ms.Seek(0,soFromBeginning);
new_panel:=nil;
new_toggler:=nil;
try
new_panel:=TTBXDockablePanel.Create(Self);
rd:=TReader.Create(ms, 4096);
rd.OnFindMethod:=PluginDFMReader_FindMethod;
rd.OnFindComponentClass:=PluginDFMReader_FindComponentClass;
rd.ReadRootComponent(new_panel);
new_panel.Parent:=TBDockLeft;
// make visible-toggler
new_toggler:=TTBXVisibilityToggleItem.Create(Self);
new_toggler.Control:=new_panel;
new_toggler.Images:=NPanels.Images;
new_toggler.Caption:=new_panel.Caption;
new_toggler.Hint:=new_panel.Hint;
NPanels.Add(new_toggler);
except
FreeAndNil(new_toggler);
FreeAndNil(new_panel);
end;
finally
FreeAndNil(ms);
FreeAndNil(fs);
FreeAndNil(rd);
end;
except
end;
end;
В общем-то этот код фактически рабочий. Это пример "плагина" в виде dfm, который умеет открываться в программе (да! некоторые уже живут с плагинами!). В приложении к настройкам необходимо только удалить toggler и добавить поиск класса по имени (в этом смысле это тоже фигня, ибо это фактически и так сделано тривиально в обработчике PluginDFMReader_FindComponentClass, код ниже). Конечно что угодно так не создашь, нужна инфа о компоненте, но стандартные слинкованные в сас все создаются замечательно. Обработчик PluginDFMReader_FindMethod вообще пишется ровно один раз для любых случаев, находит объект (именовать внутренние объекты можно через точку) и мапит события. Типа такого (здесь нет обработки внутренних объектов, легко делается через точку межуд именами, меня же интересовали только события главной формы):
procedure TfrmMain.PluginDFMReader_FindMethod(
Reader: TReader;
const MethodName: string;
var Address: Pointer;
var Error: Boolean);
begin
if Error then begin
Address:=self.MethodAddress(MethodName);
if Assigned(Address) then
Error:=FALSE;
end;
end;
Руками только одно надо сделать - обработку хитрых обработок типа "если тут заполнено а здесь выключено, то это посерить, а тут очистить", но такие вещи по любому либо руками, либо писать скрипты.
Причём так как ReadRootComponent не создаёт объект, а только натягивает свойства из потока, но очевидно легко реализуется наследование, которое поможет для плагинов. В этом смысле плагин не будет иметь свой гуй но будет говорить программе "построй для меня гуй по этой схеме", и перед каждым натягиванием свойств на объекты из плагина можно будет легко предварительно (или наоборот после) натягивать базовые свойства для этих объектов (например, так реализуется единое оформление гуя).
Причём что самое приятное - по ресурсам это требует дополнительно почти ноль, аналогичный код и так линкуется в EXE-ху.
procedure TfrmMain.PluginDFMReader_FindComponentClass(
Reader: TReader;
const ClassName: string;
var ComponentClass: TComponentClass);
procedure _Lookup(const AComponent: TComponent);
var i: Integer;
begin
if AComponent.ClassNameIs(ClassName) then begin
ComponentClass := TComponentClass(AComponent.ClassType);
Exit;
end;
if (0<AComponent.ComponentCount) then
for i := 0 to AComponent.ComponentCount - 1 do begin
_Lookup(AComponent.Components[i]);
if Assigned(ComponentClass) then
Exit;
end;
end;
begin
_Lookup(Self);
end;
здесь опять же берутся компоненты среди созданных в главной форме, мне этого хватило, ибо не все компоненты себя (свой класс) честно регистрируют.
Но это касается только создания объектов. Сохранение и восстановление свойств - через приведение к базовому классу типа эдитки. |
|
|
(0004888)
|
DJ VK
|
12-01-2012 13:12
|
|
>>а только из закрытого перечня.
Ну тогда вы можете создать абстрактный класс свойства и его обработки. И наплодить обработчиков целую папку. А я их буду вызывать непосредственно как метод данного свойста. Тогда и тип как таковой не нужен, и код еще короче будет.
как раз щас думаю над i_PropertyArray
Мне написать абстрактный класс не под силу . Да и вообще я на С++ Builder пишу....
Если кто-нибудь сделает затычки, наполнить будет кодом все это уже на порядок проще.
Что нужно.
1. Описание секции. Имя, hint, bool Expanded.
2. Динамический список секций и методы GetCount, GetName, GetHint, IsExpanded
3. Описание свойства. Имя, тип, значение-строка, номер секции, hint.
4. Методы onKeydown, onDblClick, и те что понадобятся при редактировании |
|
|
(0004902)
|
DJ VK
|
12-01-2012 18:11
|
|
vasketsov, вы поймите, редактирование будущих параметров и заранее определенного списка (ну или нескольких) это не одно и то же. Можно создавать динамически любую форму, но это чересчур избыточно для настроек программы и карт. Я за стандартизацию + возможность кастомизации. идеально создать основные типы жесткими, чтобы не задумываться, и сделать тип по умолчанию, в котором и вывод контролов извне перехватывается. (на практике в 99% это будет банальный перечисляемый тип, и возможно обойтись ссылкой на список значений) |
|
|
(0004939)
|
zOn
|
13-01-2012 16:39
|
|
простите, но может это http://www.delphiexpert.ru/view_download.php?id=81 будет в тему? |
|
|
(0004940)
|
DJ VK
|
13-01-2012 18:53
|
|
не очень хорошая таблица. Предыдущие 2 намного функциональнее.
Virtual Treeview уже практически одобрен. Первая часть - фрейм с таблицей уже есть. Единственно что вызывает затруднения - трудоемкость реализации абстрактного класса и семейства наследников-обработчиков разного типа данных. Но все уже в процессе обдумывания. Массив описаний свойств это третья часть сюиты. Быстро не обещаю, юнитов будет не мало. Но главное как говорится начать. |
|
|
(0004942)
|
zed
|
13-01-2012 19:12
|
|
>юнитов будет не мало
Минимализмом САС не страдает (на текущий момент около 700 юнитов), так что, сколько надо, столько и делайте. |
|
|
(0005686)
|
zed
|
27-02-2012 20:17
|
|
>Но главное как говорится начать.
Не хочу торопить, но начать получилось? |
|
|
(0007034)
|
zed
|
16-05-2012 11:52
|
|
Прикрепил юнит с практически готовым PropertyEditor-ом (из демки "Microsoft property editor clone" http://www.delphi-gems.com/supplement/download.php?ID=52 ) + скриншот, как это выглядит в демке. Все необходимые типы данных легко встраиваются (в том числе и диалог с выбором цвета).
Можно использовать практически "как есть", с единственной оговоркой:
// To be Fixed (Urgently!):
// - AV exception in line 586 (DoPaintNode) when more than TWO field categories are
// used - I have COMPLETELY no idea what is wrong? :/
т.е. нужно либо фиксить AV, либо не создавать более 2-х категорий на таблицу (что явно мало). Ну, или взять за основу и написать свой эдитор. |
|
|
(0007142)
|
DJ VK
|
21-05-2012 08:30
(edited on: 21-05-2012 08:36) |
|
попадался такой, было дело. но он вот именно недоделанный.
ох уж эта лицензия, только недавно прога понадобилась с наворотами, прикрутил TMS AdvStringGrid за полчаса и забыл. но tms ни разу не бесплатное, а исходники у них просто огромные, за образец поэтому не возьмешь не переделываю полностью тыщу страниц.
ИМХО если таковой есть, нужен работающий компонент, а не требующий переделок.
|
|
|
(0007366)
|
bk99
|
09-06-2012 06:20
|
|
Заранее прошу прощения за свою досужесть (потому как лезу туда, где ничего не смыслю, а тут и без сопливых скользко). Не останавливает меня только то, что бьют в виртуале не больно. Без синяков.
На Хабре сегодня увидел статейку:
"Долгожданное обновление компонента Virtual Treeview V5.0.0 RC1"
http://habrahabr.ru/post/145519/
На всякий пожарный сообщил сюда, может поможет.
(Хотя, думаю, что кто надо и без меня вкурсе) |
|
|
(0007368)
|
zed
|
09-06-2012 08:11
|
|
>Долгожданное обновление компонента Virtual Treeview V5.0.0 RC1
Ну, это так сказать, официальное объявление. А так, никто не мешает взять из svn самую свежую версию и пользовать на своё здоровье.
Только это всё никакой погоды нам не делает. Вот если бы кто доработал демку "Microsoft property editor clone"... |
|