Руководство программиста в Photon (1037671), страница 23
Текст из файла (страница 23)
Для понимания того, как различные контейнеры выполняют управление геометрией, важно понимать геометрию виджета. См. "Геометрия виджета" во введении к настоящему руководству.
Согласование геометрии
При реализации виджета во всех виджетах иерархии семейства виджета запускается процесс согласования геометрии. Каждому потомку виджета даётся благоприятная возможность просчитать свои размеры. Это проходит волной вниз через все виджеты семейства, в результате чего пересчитываются размеры каждого потомка.
Как только каждый потомок пересчитал свои желаемые размеры, родительский виджет может попытаться определить расположение для своих потомков. Компоновка, выполняемая виджетом, зависит от:
-
политики компоновки виджетов;
-
любого размера, установленного для виджета;
-
размерами и желаемой позицией для каждого из потомков.
Если приложение задаёт размер для виджета, то он может выбирать, как располагать потомков, используя только это доступное пространство. На это влияет политика изменения размеров, установленная для виджета. Ресурс Pt_ARG_RESIZE_FLAGS устанавливает флаги, определяющие политику изменения размеров для виджета. Флаги задают в отдельности политику изменения ширины и высоты виджета. Если для какого-либо из измерений политика не определена, виджет не пытается изменять свои размеры а этом измерении при выполнении компоновки. Любая другая политика изменения размеров позволяет виджету увеличиваться в этом измерении, чтобы приспособиться под своих потомков. Более детально это описано в разделе "Политика изменения размеров" ниже.
Если виджет не имеет предопределённых размеров, он пытается изменить свои размеры, чтобы приспособиться по всем потомкам, используя соответсвующую политику компоновки. Таким образом, он вначале пытается определить правильную компоновку и затем определяет пространство, необходимое для подгонки под эту компоновку.
Процесс компоновки определяет желаемое местоположение каждого потомка. Политика компоновки, используемая для виджета, управляет, как процесс компоновки пытается позиционировать потомков один относительно другого. Она должна принимать в расчёт размеры потомков. Контейнер отвечает за фиксирование позиции каждого потомка, так что политика компоновки может выбирать, принимать или нет во внимание атрибуты позиции потомков.
Выполняя компоновку, виджет может также принимать во внимание политику изменения размеров. Основываясь на этой политике, он определяет, должен ли он корректировать их ширину или высоту, или же изменять компоновку, что объясняется ограничением пространства. Виджет пытается выбрать компоновку, которая бы наилучшим образом совмещала ограничения, налагаемые какими-либо ограничениями размеров и политикой компоновки. После определения желаемой позиции для каждого из своих потомков виджет вычисляет ширину и высоту, требуемые им для размещения потомков в этих местоположениях. Он изменяет при необходимости их размеры, чтобы приладить каждый из потомков в желаемой позиции. Если это невозможно, потому что этого не позволяет политика изменения размеров, виджет пересчитывает позицию, чтобы пристроить потомков внутри доступного свободного места.
После того как компоновка успешно установлена, виджет устанавливает позицию для каждого потомка путём внесения изменения в атрибуты позиции потомков.
Политика изменения размеров
Любые изменения виджета, которые могут оказать действие на объём пространства, требуемого для отображения его содержания, могут приводить к изменению размеров самого этого виджета, с тем чтобы вместить его содержание. На это влияет политика изменения размеров, назначенная виджету.
Политика изменения размеров действует на базовые виджеты и на контейнеры. Контейнер проверяет свою политику изменения размеров при компоновке своих потомков, чтобы определить, будет ли он изменять свои размеры, чтобы разместить всех потомков в их желаемом местоположении. Во время процесса согласования геометрии это действие распространяется вверх по семейству виджетов до тех пор, пока не определяется размер виджета окна.
Политикой изменения размеров управляет ресурс Pt_ARG_RESIZE_FLAGS. Этот ресурс состоит из отдельного набора флагов для ширины и высоты. Значение флагов определяет условия, в которых виджет пересчитывает соответствующий размер. Значения проверяются каждый раз, когда виджет реализуется или изменяется его содержание.
Если политика изменения размеров конфликтует с анкерами, Pt_ARG_RESIZE_FLAGS переписывает Pt_ARG_ANCHOR_OFFSETS и Pt_ARG_ANCHOR_FLAGS.
Имеются следующие флаги изменения размеров:
Pt_RESIZE_X_ALWAYS
Пересчитывает размер виджета всякий раз, когда изменяется значение размера x. Виджет растёт или сжимается в горизонтальном направлении в соответствии с изменением его содержания.
Например, следующий рисунок показывает кнопку с установленным флагом Pt_RESIZE_X_ALWAYS при изменении надписи с "Hello" к "Hello, world" и к "Hi".
Pt_RESIZE_Y_ALWAYS
Пересчитывает размер виджета всякий раз, когда изменяется значение размера y. Виджет растёт или сжимается в вертикальном направлении в соответствии с изменением его содержания.
Pt_RESIZE_XY_ALWAYS
Пересчитывает размер виджета всякий раз, когда изменяется значение размера x или y. Виджет растёт или сжимается в обоих направлениях в соответствии с изменением его содержания.
Флаг Pt_RESIZE_XY_ALWAYS в PhAB не определён. Он представляется для Вашего удобства, когда установка флагов изменения размеров осуществляется из Вашего программного кода.
Pt_RESIZE_X_AS_REQUIRED
Пересчитывает размер виджета всякий раз при изменении размера x и не производит подгонку при наличии свободного пространства. Например, следующий рисунок показывает кнопку с установленным флагом Pt_RESIZE_X_AS_REQUIRED при изменении надписи с "Hello" к "Hello, world" и к "Hi".
Pt_RESIZE_Y_AS_REQUIRED
Пересчитывает размер виджета всякий раз при изменении размера y и не производит подгонку при наличии свободного пространства.
Pt_RESIZE_XY_AS_REQUIRED
Пересчитывает размер виджета всякий раз при изменении размера x или y и не производит подгонку при наличии свободного пространства.
Флаг Pt_RESIZE_XY_AS_REQUIRED в PhAB не определён. Он предоставляется для Вашего удобства, когда установка флагов изменения размеров осуществляется из Вашего программного кода.
Эти флаги также могут быть модифицированы значениями другого набора флагов, а именно
-
Pt_RESIZE_X_INITIAL
-
Pt_RESIZE_Y_INITIAL
-
Pt_RESIZE_XY_INITIAL
Флаг Pt_RESIZE_XY_INITIAL в PhAB не определён. Он предоставляется для Вашего удобства, когда установка флагов изменения размеров осуществляется из Вашего программного кода.
Если Вы установили какой-либо из этих "инициализирующих" флагов, виджет не будет изменять свои размеры в ответ на изменение данных – он изменяет свои размеры только в процессе согласования геометрии всякий раз, когда реализуется. Виджет либо делает себя в точности по размерам своего содержимого, либо увеличивается в размерах, чтобы разместить своё содержимое, если его размеры в этот момент недостаточно велики.
Если никакой из флагов изменения размеров не установлен, виджет не пытается расчитать свои собственные размеры, а использует те размеры, которые были установлены приложением (таким образом, возможно, обрезая в результате содержимое виджета).
Например, следующий рисунок показывает кнопку, у которой не установлены никакие флаги изменения размеров, при изменении надписи с "Hello" к "Hello, world" и к "Hi":
Установка политики изменения размеров в PhAB
Вы можете установить эти флаги в PhAB при редактировании флагов изменения размеров контейнера Pt_ARG_RESIZE_FLAGS, как показано ниже:
Установка политики изменения размеров в программном коде приложения
Вы можете также установить флаги изменения размеров контейнера в Вашем программном коде, используя метод, описанный в главе "Управление ресурсами в программном коде приложения".
Предоставляются битовые маски, позволяющие управлять путём установки битов. Имеется по одной битовой маске для политики изменения размеров по x и по y:
-
Pt_RESIZE_X_BITS
-
Pt_RESIZE_Y_BITS
-
Pt_RESIZE_XY_BITS
Например, чтобы сделать контейнер вырастающим для размещения всех своих потомков, если его размеры при реализации виджета недостаточно велики, установите оба флага установки размеров initial (начальный) и required (требуемый) по координатам x и y:
Pt_SetResource(ABW_my_container, Pt_ARG_RESIZE_FLAGS,
(Pt_RESIZE_XY_INITIAL | Pt_RESIZE_XY_AS_REQUIRED),
Pt_RESIZE_X_BITS | Pt_RESIZE_Y_BITS);
Чтобы установить список аргументов для очистки политики изменения размеров по х:
Pt_SetResource(ABW_my_container, Pt_ARG_RESIZE_FLAGS,
Pt_FALSE, Pt_RESIZE_X_BITS);
Имеется также несколько констант, упрощающих установку этих флагов. Например, есть константа, представляющая битовую маску для установки одновременно флагов по x и по y, и есть константы для наложения изменений для каждого флага по координатам x или y. Все эти константы определены в хеадер-файле <photon/PtWidget.h>
Абсолютное позиционирование
Самой основной формой компоновки, которую может обеспечить контейнер, является позиционирование своих потомков без наложения каких-либо ограничений на их размеры или позиционирование. В такой ситуации порождённый виджет закрепляется в своём собственном положении внутри контейнера, и контейнер не изменяет его размеров.
Виджет, использующий эту политику компоновки, является чем-то аналогичным доске объявлений. Вы можете прикнопить сообщение на доске объявлений и они остаются там, куда их прикнопили. Все контейнерные виджеты могут выполнять абсолютное позиционирование.
Простейшим путём позиционирования и установления размеров каждого потомка является использование мыши в PhAB.
Чтобы задать позицию каждого из потомков из программного кода Вашего приложения, Вы должны установить для каждого потомка ресурс Pt_ARG_POS. Если виджеты должны быть согласованы или быть предопределённых размеров, Вы также должны установить для каждого потомка ресурс Pt_ARG_DIM. Задаваемая Вами позиция является относительной верхнего левого угла холста родителя, так что при позиционировании потомков Вы можете не принимать во внимание границы родителя. По умолчанию все виджеты, позиционируемые абсолютно, используют политику изменения размеров Pt_AS_REQUIRED и Pt_INITIAL. Другими словами, начальные размеры контейнера выбираются при его реализации. Контейнер делается достаточно большим, чтобы разместить всех потомков в заданном местоположении и давая им возможность после реализации принять свои размеры.
Простейшим путём выполнения абсолютного позиционирования является размещение и позиционирование виджетов внутри главного виджета PtWindow приложения. Если Вам необходимо создать контейнерный виджет, выполняющий абсолютное позиционирование, как часть другого контейнера, Вы можете использовать виджет PtContainer.
Выравнивание виджетов с использованием групп
Виджеты PtGroup являются виджетами контейнерного класса, которые могут управлять геометрией своих потомков. Вы найдёте это полезным для выравнивания виджетов по горизонтали, вертикали или как матрицу. Они также обладают уникальной способностью растягивать порождённые виджеты.
PhAB расширяет полезность этого класса виджетов путём превращения их в ориентированную на действие команду "Group". Используя эту команду, Вы можете выбирать несколько виджетов внутри модуля и группировать их вместе в один групповой виджет. Если Вы попытаетесь выбрать любой виджет из группы, щёлкнув на нём, будет выбрана вся группа.
Когда Вы выбираете группу, панель управления ресурсами показывает ресурсы, имеющиеся в распоряжении виджетного класса PtGroup. Это включает ресурсы, позволяющие Вам выравнивать виджеты внутри группы и устанавливать эксклюзивное по выбору поведение.
Виджет PtGroup может быть использован для расстановки группы виджетов по строкам, колонкам или в виде таблицы. Для управления этим используется несколько ресурсов, и они интерпретируются несколько по-разному в зависимости от желаемой компоновки потомков.
Объединение виджетов в группу
Чтобы объединить виджеты в группу:
-
Выберите виджеты, используя либо метод ограничивающего прямоугольника, либо метод "Shift и щелчок"(как описано в главе "Создание виджетов в PhAB").
Вы можете использовать "Shift и щелчок", если собираетесь выравнивать виджеты по порядку, используя ресурс "Orientation". Первый выбранный Вами виджет становится первым внутри группы. Если порядок не важен или выравнивание не требуется, приятнее работать с методом ограничивающего прямоугольника.
-
Выполните одно из следующих действий:
-
Выберите пункт "Group Together" из меню "Edit".
-
Нажмите <Ctrl>+<G>
-
Щёлкните на кнопке "Group" на панели инструментов PhAB:
PhAB сгруппирует виджеты и выберет группу.
Получение доступа к виджетам в группе
Несмотря на то, что PhAB интерпретирует группу как один виджет, Вы по-прежнему можете получить доступ к любому отдельному виджету, входящему в группу. Чтобы это сделать, используйте клавиши "Следующая" и "Предыдущая" в панели управления ресурсами или ответными реакциями, или выберите виджет непосредственно из панели дерева модулей. Более подробно это описано в разделе "Выбор виджетов" в главе "Создание виджетов в PhAB".
Горизонтальное или вертикальное выравнивание виджетов
Ресурс ориентации Pt_ARG_GROUP_ORIENTATION управляет тем, выравниваются ли потомки группового виджета построчно или по колонкам. Значение Pt_GROUP_VERTICAL приводит к тому, что потомки выстраиваются вертикально, тогда как значение Pt_GROUP_HORIZONTAL – к тому, что они выстраиваются горизонтально. Вы можете управлять величиной свободного пространства, остающегося между виджетами, выстроенными в групповом виджете, путём использования ресурса Pt_ARG_GROUP_SPACING. Значение ресурса даёт число пикселей, оставляемых между виджетами.