воскресенье, 25 октября 2009 г.

Позиционирование элементов

Позиционирование - это выравнвание элементов на форме. Бывает, что оно становится головной болью разработчика, потому что набросать визуальные компоненты как попало легче всего, но сделать так, чтобы они принимали определённое положение даже тогда, когда изменяются размеры окна программы, не так-то просто. И я решил уделить время этому вопросу.

Некоторые моменты позиционирования я освещал в статье про браузер, когда выравнивал панель по верху, а поле ввода в ней - по низу. Но это самые простые приёмы, и параметр Align часто не удовлетворяет нужды программистов.

Гораздо более широкие возможности предоставляют нам слои, которые в HiAsm находятся на вкладке "Интерфейс", в группе "Слои". Там 5 компонентов, но на форме ни один не отображается. Несмотря на их "визуальность", они всё равно являются служебными элементами и нужны для выравнивания других компонентов.

Возьмём, например, три редактора текста (Memo). Если нам нужно, чтобы они занимали всю форму, стоя друг рядом с другом, то можно у одного сделать Align=caLeft, у другого Align=caRight, а у среднего - Align=caClient. В таком простом случае большего и не надо.

А вот если нужно задать долю ширины каждого Memo на форме или установить отступы между ними, то без слоёв не обойтись. Рассмотрите пример.

Скачать схему HiAsm

Есть три многострочных поля, в редакторе формы они стоят друг за другом. И есть компонент HBoxLayout - горизонтальный слой. В нём высота всех компонентов равна высоте родительского элемента (у нас это - форма), а ширина задаётся опционально.

У HBoxLayout в параметре Name обязательно указано уникальное (не повторяющееся) имя. А у каждого Memo в группе параметров Layout, параметре Layout выбрано это имя. И теперь все Memo принадлежат этому слою (чтобы узнать, какие компоненты принадлежат слою, нужно нажать Alt и щёлкнуть по HBoxLayout). Но у каждого из них есть ещё параметры WidthScale и HeightScale. Второй нам не нужен, потому что он задаёт долю высоты компонента в слое, а высота в этом слое - во всю форму. А вот в WidthScale нужно указать долю ширины компонента в слое. Чтобы ширина была примерно равной, нужно указать везде 33, т.е. 33%. Но так как 33*3 = 99, то можно у одного из Memo указать 34.

У компонента HBoxLayout есть ещё два параметра - Scale и Padding. Они задают отступы между элементами слоя (между Memo в данном случае) и между слоем и родительским элементом (у нас - форма).

При входе в программу все компоненты сначала разбросаны, но при изменении размеров принимают нужное положение. Чтобы компоненты позиционировались сразу после запуска, нужно вызвать метод doResize компонента HBoxLayout. Событием может служить onCreate у формы.

Есть также вертикальный слой, в котором ширина компонентов равна ширине родительского элемента, а высоту можно задавать.

Скачать схему HiAsm

Здесь позиционирование происходит сразу после запуска программы, а у Memo задействованы не WidthScale, а HeightScale. Причём везде задано по-разному, потому и размеры Memo разные. А в остальном работа с VBoxLayout аналогична предыдущему примеру.

Стоит здесь ещё отметить компонент LayoutSpacer, который задаёт расстояния между элементами слоя, причём здесь расстояние можно задать между любыми двумя компонентами.

Скачать схему HiAsm

Этот компонент отображается в редакторе формы и стоит там как раз между теми элементами, между которыми нужен отступ. А его размеры и определяют отступ.

Очень интересно будет рассмотреть инструментальный слой. Он располагает компоненты так, как на панели инструментов (отсюда и название). Конечно, Memo здесь уже не годятся, но сгодятся кнопки, например.

Скачать схему HiAsm

Теперь родительский элемент у нас - панель. Она и будет панелью инструментов. А в ней - 16 кнопок и флажок. В редакторе формы они расположены довольно произвольно, но инструментальный слой выравнивает их друг за другом. Здесь уже не нужно задавать доли высоты или ширины элементов, потому что они незменны - изменяется лишь положение элементов.

Чтобы размеры родительского элемента (панели) тоже менялись в зависимости от числа рядов элементов, нужно в параметре AutoSize компонента ToolBarLayout указать True.

А зачем же таймер? Да затем, чтобы выравнивание происходило сразу при входе в программу. Тянуть связь от onCreate формы здесь не очень красиво, а таймер сработает через 1 мсек после запуска и всего 1 раз, что нам и нужно.

9 комментариев:

  1. Да, для компановки удобная вещь - слои...
    Вопрос 1. Когда двойным щелчком открываешь компонент "Панель" в примере bh020, то в появившемся окне значок "Панель" окружен светлым прямоугольником. В чем его смысл? Перемещение иконок за его границы вроде ничего не меняют...
    Вопрос 2. Контекстное меню компонентов на рабочем поле HiAsm содержит пункты "Передний план" и "Задний план". Что это такое и как ими пользоваться?

    ОтветитьУдалить
  2. 1. Это редактор мультиэлемента. Я рассказывал про него в статье "Мультиэлементы".
    2. Если компоненты находятся друг на друге (в редакторе формы), то этими пунктами можно управлять, какой компонент спереди.

    ОтветитьУдалить
  3. Здравствуйте! Замечательный у Вас блог :)
    Я только начал изучать HiAsm и сейчас я в ступоре - как зафиксировать размер основной формы программы, т.е. чтоб оно растягивалось, но были какие-то минимальные значения значения при стягивании формы. Спасибо!

    ОтветитьУдалить
  4. Вот так. Правда, при попытке уменьшения будут небольшие мерцания, но где-то на сайте hiasm.com, в разделе Upload был компонент MinMaxInfo, который специально предназначен для ограничения размеров формы. Можете поискать.

    ОтветитьУдалить
  5. Спасибо! MinMaxInfo то что надо...

    ОтветитьУдалить
  6. Ух, слишком сложно для меня работать с этой программой! HiAsm - тёмный лес! Намного легче выравнивать объекты в программе Алгоритм. Но всё-таки жутко хочется научиться работать с HiAsm.

    ОтветитьУдалить
  7. Экспериментируйте, смотрите примеры, общайтесь на форуме hiasm.com. Разберётесь обязательно!

    ОтветитьУдалить
  8. Привет не знаю прочитает ли это кто нибудь. как сделать чтоб в приложении - на квадратном мониторе и прямоугольном - элементы программы были по середине. те программа обрезает их справа . а нужно просто чтоб (viewport) был по центру

    ОтветитьУдалить
  9. те я создал программу - там в центре у меня кнопки - экран 1920x1080 и после уменьшения формы допустим до 800x600 форма смещалась к ним.

    ОтветитьУдалить