-
Постов
394 -
Зарегистрирован
-
Посещение
-
Победитель дней
45
Сообщения, опубликованные AngryOwl
-
-
2 минуты назад, GASCHE сказал:
А переменная Button будет видна в этом отдельном потоке в случае завершения процедуры lbxMouseUp?
Да
-
Можно. Используйте события не OnClick или OnItemClick и т.д., а событие OnMouseUp у самого TListBox.
Типа так:
procedure TfmMain.lbxMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); var LI : TListBoxItem; p : TPointF; begin if Assigned(Sender as TListBox) then begin LI := TListBox(Sender).ItemByPoint(X, Y); if Assigned(LI as TListBoxItem) then begin LI.IsSelected := True; TTask.Run(procedure begin if Button = TMouseButton.mbLeft then Do_какая-то_процедура(LI.Index) // просто пример else if Button = TMouseButton.mbRight then TThread.Synchronize(nil, procedure begin p := MessageEvent.GetMousePos; PopupMenu1.Popup(p.X, p.Y); // для вызова контекстного меню выделенного ListBoxItem end); end); end; end; end;
P.S. Отмечу, что использовал TTask и TThread.Synchronize далеко не случайно!
Во-первых TTask.Run запустит ваш обработчик нажатия на выделенный элемент в отдельном потоке, что не будет "тормозить" "выделение" самого ListBoxItem и вообще), а во-вторых - "внутри" вызванного потока сделал синхронизацию с основным потоком, при выводе контекстного меню для ListBoxItem, так как это гарантирует корректную работу с GUI в FMX.
-
-
Я вот тут (с примерами) тоже предлагал свое "видение" этого вопроса.
-
1. Создайте свой стиль для ListBoxItem, например 'listboxitemMystyle', скопировав стандартный и переобозвав его. В своем стиле Итемов просто сделайте невидимым Detail. Или, что еще лучше, - храните Ваши ссылки в TagString Итема.
2. В Style Designer, при редактировании Вашего listboxitemMystyle, вставьте TImage задайте ему необходимые свойства: выравнивание, размеры, отступы и т.д. (не забудьте сделать "растягивание" или что там Вам требуется - просто проверьте в дизайнере). И задайте Вашему TImage имя, например, 'myimagestyle'.
3. При загрузке изображения я бы рекомендовал сначала загрузить изображение в созданный TBitmap, а потом уже грузить его в наш 'myimagestyle'. А самое оптимальное решение - загрузка изображений в "контейнер", в фоновом режиме, а при окончании загрузки, по событию, - отрисовка уже в самом итеме. В любом случае - сначала в битмап, а потом этот битмап в Итем. Иначе, вероятность того что битмап отрисуется в вашем случае - практически нулевая.
4. Далее, при создании итемов:
procedure ContactList_AddItem(Sender: TObject); var newItem : TListBoxItem; newBitmap : TBitmap; begin newItem := TListBoxItem.Create(nil); newItem.StyleLooup := 'listboxitemMystyle'; // хотя будет проще не писать этого, а прописать в ListBox1.DefaultItemStyles.ItemStyle newItem.Text := 'текст'; newItem.TagString := тут может быть Ваша ссылка newBitmap := TBitmap.Create; newBitmap.LoadFrom ....... // грузим картинку newItem.TagObject := newBitmap; newItem.OnApplyStyleLookup := MyItemApplyStyle; ListBox1.AddObject(newItem); end; procedure MyItemApplyStyle(Sender: TObject); var LI : TListBoxItem; tmpBitmap : TBitmap; begin LI := Sender as TListBoxItem; if Assigned(LI) then try LI.BeginUpdate; tmpBitmap := LI.TagObject as TBitmap; if Assigned(tmpBitmap) then LI.StylesData['myimagestyle.bitmap'] := tmpBitmap; // тут вообще можно обновлять все что угодно в этом Итеме finally LI.EndUpdate; end; end;
Собственно все.
Сорри если что не понятно - писал "от руки", без проверки. Но вроде все просто.
- Rusland, Kitty, egorea1999 и 1 другой
- 4
-
Под Андроид, все зависит от того - какая именно задача стоит? Цели этого "списка". Исходя из моего опыта, в некоторых случаях не обойтись без TListView (это не значит, что нельзя TListBox, просто у него ряд своих ограничений, и не только по скорости. Например - не очень "адекватная" работа с Touch. В смысле - прокрутка пальцем списка у TListBox не очень оптимизирована...)
Поэтому - если Ваш список имеет не сложные элементы - я бы порекомендовал бы, наверное, переделать его на TListView. Покажите, или более подробно объясните - какие вообще элементы в каждом Итеме? Какие события обрабатываются? Прокрутка, нажатия, и т.д. В каждом Итеме картинки в каком виде? Их размер и положение? Они прямоугольные? И т.д.
Чем больше деталей Вы предоставите - тем что-то более конкретное можно советовать в Вашем случае. Или даже помочь с кодом (в смысле - с примером реализации).Списки контактов в своей программе я делал - для Винды и Мака - TListBox, а для Андроида - TListView. И разница в коде - была всего в 4 десятка строк в общей сложности.
Повторюсь - у каждого из этих компонентов есть свои преимущества и свои недостатки. Например: TListView - скорость работы, TListBox - более "гибкий" в плане создания любого Итема.
-
Да еклмн - да хоть 100 элементов, хоть 500 - каждый со своей картинкой! Пишите аккуратно и грамотно - и "да прибудет с Вами "сила" (с)
Ничего не тормозит, не глючит, все рисуется замечательно (что касается TListBox)!
Я уже показывал пример. там речь не об этом, но везде TListBox - и в списке контактов и в сообщениях. Потому-что они намнооооого сложнее того (те итемы, с которыми я работаю), что видно. И их реализация на TListView возможна, но она сложнее на порядок.
И еще момент! Скажите - как у Вас называется (в стиле) тот элемент в TListBoxItem, в котором содержится картинка? Не Icon ли случаем? Не помню точно какое название там по умолчанию, а смотреть сейчас лень, но сделайте свое наименование этого TImage, например 'myiconstyle' или еще как, и обновляйте через свой обработчик OnApplyStyleLookup.
З.Ы. И я так понимаю - Вы делаете приложение именно под Win?
З.З.Ы. И ничего переделывать не надо. Просто дайте скрин, или фрагмент скрина вашего приложения, если такое возможно. Визуально увидеть "проблему" - многого стоит. А если сделаете видео - совсем будет ясно. Хотя я и так понимаю - в чем у Вас проблема. И предложенное мной решение - работает.
Не знаю - что там говорил Ярослав, но применение OnApplyStyleLookup - очень простое! Куда проще-то?
-
-
2 часа назад, Kitty сказал:
А как все таки итему присвоить битмап через StylesData?
Битмап нужно где-то хранить.
При вызове OnApplyStyleLookup просто обновляйте его. Как в моем примере. Только в Вашем случае это будет TImage (как понимаю).var StyleObject: TFmxObject; ........ StyleObject := FindStyleResource('picturechat') as TImage; if Assigned(StyleObject) then try TImage(StyleObject).Visible := // TRUE/FALSE TImage(StyleObject).OnClick := // Ваш обработчик, если надо if not MBitmap.IsEmpty then try if not GlobalUseGPUCanvas then TImage(StyleObject).Bitmap.Canvas.BeginScene; TImage(StyleObject).Bitmap := MBitmap; // ваш битмап finally if not GlobalUseGPUCanvas then TImage(StyleObject).Bitmap.Canvas.EndScene; end; finally end;
типа того.
'picturechat' - ваша картинка в стиле Итема
а хранить изображения можно как контейнерах, так и читать из файлов (все достаточно быстро по скорости!)
а вот с подгрузкой из инета - не знаю - Вам самим решать. Оптимально, думаю, загружать в контейнер, предварительно изменив размер до минимально необходимого.
P.S. Забыл про StylesData
можно так:
вместо всего что написано выше, записать просто
StylesData['picturechat.bitmap'] := MBitmap;
-
Я [ZuBy] уважаю! Но не слушайте его, в данном случае! ))))
Я с ним не согласен. Точнее - не совсем.
У TListBox есть ряд свои преимуществ! Причем, зачастую, довольно существенных. Которые никакие TListView не перекрывают. По крайне мере пока.
Во-первых - если речь идет о Винде, то это возможность плавного скроллинга. Чего нет у TListView. Не знаю кому как из разрабов, а рядового пользователя это часто бесит - прокрутка "рывками".
Во-вторых - TListBox и его TListBoxItem'ы все же намного проще "рисовать". В смысле - создание своего шаблона пока еще намного проще чем у TListView. Вы можете для TListBox очень просто создавать свои элементы списка.
Несмотря на то, что TListBox существенно "тормознее" TListView, часто его скорости вполне достаточно.
Все, разумеется, зависит от Ваших конечных целей.
А что касается картинок в Итемах TListBox, то нужно просто переопределить ApplyStyle.
Создайте свою процедуру, например ItemApplyStyle;
Присвойте, при создании Итема, свой обработчик. Например
newItem.OnApplyStyleLookup := ItemApplyStyle;
А в ItemApplyStyle сделайте обновление картинки. Типа так:procedure TContactActions.ItemApplyStyle(Sender: TObject); var StyleObject: TFmxObject; lbx : TListBox; LI : TListBoxItem; begin LI := Sender as TListBoxItem; LI.BeginUpdate; try StyleObject := LI.FindStyleResource('picture') as TCircle; if Assigned(StyleObject) then begin TCircle(StyleObject).Fill.Bitmap.Bitmap.Canvas.BeginScene(); try TCircle(StyleObject).Fill.Bitmap.Bitmap := ____тут_ваш_битмап__; finally TCircle(StyleObject).Fill.Bitmap.Bitmap.Canvas.EndScene; end; end; finally LI.EndUpdate; end; end;
Разумеется, все проверки и прочее - это уж Вы сами. И в моем примере это TCircle, а у Вас что - сами решите.
Ну и можно для краткости (если там просто TImage) не писать все через StyleObject, а покороче, через StylesData['_имя_.bitmap'] и т.д.
Ну и что на Delphi - не обессудьте! ) Смысл тут простой.
Думаю, что в целом идея ясна.
-
29 минут назад, wamaco сказал:
360 Total Security - тот еще "антивирусник"! )))
Давайте уже - если кто-то на что-то хочет поругаться - киньте это для начала в www.virustotal.com (например)
Ничего не хочу сказать - но у меня ничего ни на что не ругнулось!
И я бы скорее сказал - что 360 TS - большее зло, чем некоторые "вирусы" ...
-
3 часа назад, ZuBy сказал:
не смог воспроизвести вашу ситуацию, есть подозрение на стиль. попробуйте при добавлении Item'a, прогрузить стиль вручную
Во-первых - спасибо за подсказку (прогрузить стили)!
А во-вторых - решение конечно еще тот "костыль", но работает.Перед тем как прокрутить TListBox в конец (любым способом), потребовалось пробежать по всем Итемам и применить им стиль!
for i := 0 to TListBox(Sender).Items.Count - 1 do TListBox(Sender).ListItems[i].ApplyStyleLookup;
И только после это - все работает как надо. И никак иначе...
Есть, конечно, над чем поработать - например на скоростью. Но пока меня решение устраивает.
Спасибо! Вопрос решен!
-
Только что, rakhmet сказал:
Хм...
Выглядит замечательно. Спасибо за сэмпл. Я как-то не подумал о том, чтобы ручками ВСЁ окно перерисовать самостоятельно. Теперь осталось разобраться, как это работает.
"Ищите и обрящите" (с)))
На форуме есть темы, связанные с этим вопросом. В том числе и я где-то тут описывал - как делать такие формы. -
Мне лень (сорри!) что-то изобретать - просто сделаю скрин проекта, который сейчас у меня открыт. И он абсолютно одинаково выглядит и работает и под виндой и под макосью!
-
Речь идет (RageGod спрашивает) - что именно Вы используете для этого "списка"?
Если TListBox и используете TListBoxItem, то все очень просто! Измените стиль для 'listboxitemstyle', добавив ему линию или битмап с выравниванием Bottom, толщиной в один пиксель (типа того...) и все.
Или создайте свой новый стиль для Итемов и применяйте его в нужных случаях.
А если Вы используете TListView, то раньше надо было делать все "ручками", в коде, но это не сложно совсем. А сейчас вообще можно в конструкторе!
-
15 минут назад, rakhmet сказал:
Т.е. проще уйти на тот же XCode/Swift, чем найти "транслированное sdk под делфи" - я правильно понял намёк?
Ну если Вы уже кодили на XCode/Swift, то в Вашем случае возможно и проще... Смотря какая конечная цель.
А если говорить именно о Вашей проблеме, то что Вам мешает сделать свое окно полностью, в шапке которого можете размещать хоть проигрываемое видео, не говоря уже про кнопочки с битмапами. Причем окна свои можно сделать "вылитыми" макосовскими... Хотя не вижу в этом необходимости (как по мне - так они не очень удобны).
Сделайте свой стиль, свои окна, с тенями, с кнопками с битмапами. С чем угодно!
-
8 минут назад, kami сказал:
Ну, с моей стороны будет костылирование, а не решение, но...
Попробуйте сделать отложенный скролл вниз, возможно что в фоне еще идут какие-то вычисления...
Например:
TTask.Run(TThread.Queue(ScrollToLast));
Спасибо! Но, к сожалению, эффект тот же...
-
Привет друзья!
Возникла странная ситуация при работе с TListBox. А именно - при попытке прокрутки списка в его конец.
Условно:
- есть список итемов (сообщения чата);
- загрузка сообщений происходит в процедуре "синхронизированной" с главным потоком и заключена в TListBox(listbox1).BeginUpdate и TListBox(listbox1).EndUpdate;
- все замечательно грузится
НО! После загрузки Итемов требуется прокрутить список в его конец. И вот тут начинаются "приколы".
Как только не пытаться прокрутить список в его конец (разные способы, см.ниже) - всегда получается, что список прокручивается до конца, но немного "откатывается" вверх. Размер его автоматического скролла "обратно" зависит от количества Item в TListBox! Чем больше кол-во Item - тем больше назад откатывается скролл.
Способы прокрутки в конец списка - значения не имеют. Всегда одно и то же.
procedure TChatListBoxEx.ScrollToLast; var Item: TListBoxItem; begin // ВАРИАНТ 1 Item := ListItems[Items.Count - 1]; if Assigned(Item) then ScrollToItem(Item); // ВАРИАНТ 2 ViewportPosition:= TPointF.Create(0, Item.ParentedRect.Top); // ВАРИАНТ 3 ScrollBy(0, ViewportPosition.Y - Item.ParentedRect.Top); // ВАРИАНТ 4 BeginUpdate; try ItemIndex := Items.Count - 1; finally EndUpdate; end; end;
Предупреждая ваши вопросы, сразу скажу - пробовал и другие варианты, просто перечислять не стал все. Пробовал и эмитировать нажатие клавиши END при "активном" списке.
Все синхронизируется, типа
TThread.Synchronize(nil, listbox1.ScrollToLast);
Эффект всегда один и тот же...
НО! Если загрузить список, независимо от кол-ва элементов списка, а потом в программе вызвать ScrollToLast, подождав некоторое время, а не сразу, например по нажатию на какую-нибудь кнопку, то список прокрутится в конец НОРМАЛЬНО!
Будьте добры - кто сталкивался с подобной ситуацией, или кто что-то может посоветовать?
Или наши Гуру смогут ответить на этот вопрос?
Видео, чтобы было понятнее что происходит, прилагаю.
RAD Studio 10.1 Berlin (эффект наблюдается на всех версиях Windows - XP, Vista, 7, 8, 10. На других ОС пока не пробовал...)
Заранее благодарен!
P.S. Возник вопрос (как вариант решения проблемы) - как узнать, что произошло событие окончания отрисовки TListBox? А именно - список заполнился, выполнилась отрисовка и можно прокручивать.
-
Примените стиль 'transparentlistboxstyle' для TListBox.
-
Добрый вечер, друзья!
Кто в курсе, подскажите - возможен ли плавный скроллинг содержимого TListView при работе приложения под Windows?
Если с мобильным вариантом все ОК, на "автомате" - т.е. плавный скроллинг там работает по умолчанию, то с работой под Windows что-то не понятно как это включить/реализовать.
Например, чтобы сделать плавный скролл содержимого TListBox, достаточно написать
TScrollBox(__listbox1___).AniCalculations.Animation := True;
А есть ли что-то аналогичное для TListView?
Заранее благодарен за ответы!
-
16 часов назад, wassail сказал:
То-есть использовать под Windows с компонентами FireMonkey напрямую из библиотек OpenGL или Vulkan нельзя? (на канве или в TImage ). А из DirectX? Ну а как тогда, например, подключать шейдеры из внешних файлов для создания различных эффектов? Тоже нельзя? Просветите, пожалуйста.
Тут я, к сожалению, не советчик. У меня нет такого опыта работы с использованием Firemonkey и OpenGL или Vulkan.
-
-
Это Toast. Смотрите тут.
-
Посмотрите тут.
[Статья] Жизненный цикл объектов в Delphi. Часть 1. Windows, OSX. Что же использовать Destroy, Free, FreeAndNil или DisposeOf?
в Статьи и заметки
Опубликовано
Очень просто и доходчиво! Методичку писать можно! )