Перейти к содержанию

Дайджесты за январь-февраль

Обновления гайдов и аддонов

Январь Февраль

Мониторинг серверов и редактор аддонов

Представляем вам две легенды. То, о чем можно было только мечтать, стало реальностью.

Мониторинг серверов Редактор аддонов

Подсказки из игры на вашем сайте

Теперь вы можете отображать сведения о внутриигровых элементах простым наведением курсора мыши.

Подробнее

Апдейтер аддонов

Представляем вам программу для автообновления аддонов и делимся подробностями.

Подробнее Скачать

MoveExample - Перетаскивание панели


Гость WShad

Рекомендуемые сообщения

В данном примере я демонстрирую как реализовать простое перетаскивание панели виджета по рабочему пространству. Прошу обратить внимание на опцию align в разделе расположения панели (файл MainPanel.(WidgetPanel).xdb), данный код рассчитан на то, что она проставлена в WIDGET_ALIGN_LOW (то есть координаты ориентированы от левого верхнего угла). Если ориентацию ставить в другое значение, то правильное расположение нужно вычислять вручную.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо! Наконец-то! :)

Этот код нужен практически всем аддонам, у которых есть GUI.

Ссылка на комментарий
Поделиться на другие сайты

Пожалуйста. Этот код, мне кажется, нужен и большинству стандартных игровых окон/панелей. Странно, что он там не реализован, если для этого все подготовлено.

Да, кстати, можно поставить WIDGET_ALIGN_LOW_ABS - это немного меняет координацию перемещения. В зависимости от размера панели это может быть значительно или не заметно вообще.

Ссылка на комментарий
Поделиться на другие сайты

А как сделать так, чтобы стандарт окна перетаскивались? Куда его вставить?

Ссылка на комментарий
Поделиться на другие сайты

само окошко перетаскивается на ура, но вот проблема, если перетаскивать что угодно, например скилл с панельки или из книги, то вышеупомянутое окно движется вместе с выбранным объектом

не порядок

проблема возникает из-за того, что на событие EVENT_DND_DRAG_TO окошко(wtMainPanel) откликается вместе с любым объектом

Ссылка на комментарий
Поделиться на другие сайты

Молодец! Соображаешь! )

Я привел всего лишь простейший пример, а по хорошему надо проверять какое окно начали тащить(чего я в своем аддоне не сделал). Идентификатор передается в пикаттемпт.

Спасибо FINTERу за найденный баг. Исправил у себя в аддоне. Можете посмотреть. Только просьба идентификатор 700 не использовать, а то мой аддон будет вместе с вашим бегать. )

Бронирую себе диапазон идентификаторов 700-720. Думаю никто не против? )

Ссылка на комментарий
Поделиться на другие сайты

Из темы Исправляйте косяк с перемещением панелей!

Quote:
Есть ещё одна особенность перемещения фреймов, у меня разрешение окна игры нестандартноене 4x3, а 3x4, и особенно заметно на аддонах DarkDPSMeter и DmgMeMetre как фрейм тянется не за указателем мыши, а как бы ближе к верхнему левому углу окна.

Для исправления этого эффекта можно попробовать использовать WIDGET_ALIGN_LOW_ABS, должно помочь. Я об этом уже писал.

Ссылка на комментарий
Поделиться на другие сайты

Да, тут еще немаловажный фактор всплыл... про ID

просто то что должно быть у каждого(Скрытие по ALT+Z и перетаскивание панелей):

Code:
Global( "Drag", false )

Code:
function GetDNDId( container, item )

return container * DND_CONTAINER_STEP + item

end

function GetDNDItem( id )

return math.mod( id, DND_CONTAINER_STEP )

end

function OnToggleUI( params )

панель:Show( params.visible )

if params.visible then

mission.DNDRegister( панель, GetDNDId( DND_WIDGET_MOVE, ваш_id ), false )

end

end

function OnEventDNDPickAttempt( params )

if GetDNDItem(params.srcId) == ваш_id then

Drag = true

end

end

function OnEventDNDDropAttempt( params )

mission.DNDConfirmDropAttempt()

Drag = false

end

function OnEventDNDDragTo( params )

if Drag == true then

local place = панель:GetPlacementPlain()

place.posX = params.posX

place.posY = params.posY

панель:SetPlacementPlain( place )

end

end

Code:
function Init()

common.RegisterEventHandler( OnEventDNDPickAttempt, "EVENT_DND_PICK_ATTEMPT" )

common.RegisterEventHandler( OnEventDNDDragTo, "EVENT_DND_DRAG_TO" )

common.RegisterEventHandler( OnEventDNDDropAttempt, "EVENT_DND_DROP_ATTEMPT" )

common.RegisterEventHandler( OnToggleUI, "SCRIPT_TOGGLE_UI")

mission.DNDRegister( панелька , GetDNDId( DND_WIDGET_MOVE, ваш_id ), false )

end

Так вот, во избежании недоразумений и привязки элементов к нужным панелям, сейчас напишу какие панели имеют ID =)

ВАШ ID=14+ [id_панельки]

ID[чата] = 14007

ID[панелей(где спеллы)] = (1..6)2000..2005 (7..=)2006..2011 (ALT(7..9))2018..2023 CTRL(1..=)2024..2035

ID[chatbarao] = 14666

ID[honorinfo] = 14700

пока перетаскиваемых больше не нашел вещей...

Ссылка на комментарий
Поделиться на другие сайты

Дополню:

DND_EQUIPMENT = 0

DND_INVENTORY = 1

DND_ACTIONBAR = 2

DND_SPELLBOOK = 3

DND_VENDOR = 4

DND_DEPOSITE = 5

DND_WORLD = 6

DND_ALCHEMY = 7

DND_ARMOR_CRAFT = 8

DND_CHARACTER_CONTROL3D = 9

DND_MAIL = 10

DND_AUCTION = 11

DND_LOOTBAG = 12

DND_PLAYER_TRADE = 13

DND_WIDGET_MOVE = 14

DND_WIDGET_RESIZE = 15

Так что 2*** - это не ID спеллов! Это ID элементов панелей быстрого доступа!

P.S.: Приятно видеть что моим кодом активно пользуются. )

Ссылка на комментарий
Поделиться на другие сайты

Code:
 это не ID спеллов
знаю знаю, просто так чуть более чем понятно :)
Ссылка на комментарий
Поделиться на другие сайты

есть такой баг

в оконном режиме мыша убегает в крайний правый угол - а панель тока до середины

скорее всего там берется за базу DC.Width вместо Window.Width

Ссылка на комментарий
Поделиться на другие сайты

В полноэкранном режиме, на широкоформатном экране (16:10), аналогично, но наоборот :)

Если двигать форму из крайнего левого края экрана вправо, то когда курсор проходит ~ 2/3 экрана по оси X, а форма уже у САМОГО правого края экрана. Если двигать дальше вправо, то форма улетает ЗА ПРЕДЕЛЫ экрана. Если её не вернуть, а там "отпустить", то она там и останется, out of radio coverage :)

Такой код как бы предпологает, что либо экран всегда 4:3, либо ширина экрана всегда 1280. Попробую ка я разобраться, что тут можно сделать.

Ссылка на комментарий
Поделиться на другие сайты

Разобрался.

Важное дополнение к скрипту перетаскивания окна

Нужно срочно исправить во всех аддонах одну функцию:

Code:
function OnEventDNDDragTo( params )

if Drag == true then

local screen = widgetsSystem:GetPosConverterParams()

local place = панель:GetPlacementPlain()

place.posX = params.posX * screen.fullVirtualSizeX / screen.realSizeX

place.posY = params.posY * screen.fullVirtualSizeY / screen.realSizeY

панель:SetPlacementPlain( place )

end

end

Оказывается, в игре есть 2 системы координат экрана! Это всё объясняет, и сильно упрощает нам жизнь. widgetsSystem:GetPosConverterParams() возвращает структуру, в которой они описаны:

referenceVirtualSizeX: number( float ) - базовый виртуальный размер окна по X

referenceVirtualSizeY: number( float ) - базовый виртуальный размер окна по X

realSizeX: number( float ) - реальный размер окна по X

realSizeY: number( float ) - реальный размер окна по Y

fullVirtualSizeX: number( float ) - текущий виртуальный размер окна по X

fullVirtualSizeY: number( float ) - текущий виртуальный размер окна по Y

На самом деле, всё очень просто. В игре, например, при разрешении экрана 1920x1200, они будут иметь такие значения:

referenceVirtualSizeX = 1280

referenceVirtualSizeY = 1024

realSizeX = 1920

realSizeY = 1200

fullVirtualSizeX = 1638.4001464844

fullVirtualSizeY = 1024

Здесь, referenceVirtualSizeX и referenceVirtualSizeY - константы, по ним вычисляется "виртуальная" резолюция окна, таким образом, что fullVirtualSizeY тоже константа, всегда равна 1024, а fullVirtualSizeX рассчитывается относительно fullVirtualSizeY, но с учётом пропорций экрана (будь то 4:3, 5:4, 16:9, 16:10, или даже НЕполноэкранное окно ЛЮБЫХ пропорций). Это очень важно! Именно этой виртуальной (fullVirtualSize) системой координат пользуются все оригинальные ниваловские виджеты! Поэтому, этой же системой должны пользоваться и мы, если мы хотим, чтобы расположение аддонов всегда совпадало с расположением встроенных виджетов. Т.е. чтобы наши аддоны рисовались ВСЕГДА там где нужно, и не вылетали за границы экрана при перетаскивании.

При этом есть ещё одно ВАЖНОЕ условие:

НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ WIDGET_ALIGN_LOW_ABS !!!

Многие раньше рекомендовали именно этот параметр, для того, чтобы при перетаскивании, виджет не "улетал" от курсора мыши. Так вот. WIDGET_ALIGN_LOW_ABS, на самом деле, указывает, что координаты виджета в XDB указаны РЕАЛЬНЫЕ ("_ABS" = АБСолютные) координаты, а этого делать просто никогда нельзя! Никогда не используйте реальные координаты, т.к. они у всех людей разные, на разных резолюциях мониторов. А "глюк" с перетаскиванием нужно чинить НЕ этим параметром, а исправленной функцией, которую я привёл выше. В ней, координаты виджета рассчитываются так: КоординатаУказателяМыши * screen.fullVirtualSizeX / screen.realSizeX.

Чуть позже напишу гораздо гораздо подробнее о XDB файлах. Отдельной темой.

Ссылка на комментарий
Поделиться на другие сайты

Большое спасибо за полезную информацию =)

SLA, а нет ли опечатки? ( WidgetsSystemSafe вместо widgetsSystem )

Ссылка на комментарий
Поделиться на другие сайты

Да, я исправил =) В документации написано, что класс называется "WidgetsSystemSafe", но:

API wrote:
WidgetsSystemSafe доступна в каждом аддоне через переменную widgetsSystem.
Ссылка на комментарий
Поделиться на другие сайты

Да, можно :)

Вот, кстати, как раз для библиотеки, вылизанные до почти идеального состояния функции. Что новенького:

  • Панель теперь НЕ отрывается от курсора мыши.
  • Панель теперь цепляется к мышке тем местом, где ухватили(а НЕ левым-верхним углом)

Код стал гораздо проще в обращении, никакой возни с event'ами и Global'ами!

Этот код работает в аддоне "TargetOfTarget", можете посмотреть его в деле. А вот и сам код:

Code:
-- Drag&Drop by SLA, version 2010-08-28.

function DNDInit( wtReacting, wtMovable, ID )

Global( "DragNDrop", {} )

DragNDrop.ID = ID

DragNDrop.wtReacting = wtReacting

DragNDrop.wtMovable = wtMovable

DragNDrop.IsPicked = false

common.RegisterEventHandler( OnEventDNDPickAttempt, "EVENT_DND_PICK_ATTEMPT" )

common.RegisterEventHandler( OnEventDNDDragTo, "EVENT_DND_DRAG_TO" )

common.RegisterEventHandler( OnEventDNDDropAttempt, "EVENT_DND_DROP_ATTEMPT" )

end

function DNDReg()

mission.DNDRegister( DragNDrop.wtReacting , DND_WIDGET_MOVE * DND_CONTAINER_STEP + DragNDrop.ID, true )

end

function DNDUnreg()

OnEventDNDDropAttempt()

mission.DNDUnregister( DragNDrop.wtReacting )

end

function OnEventDNDPickAttempt( params )

if math.mod( params.srcId, DND_CONTAINER_STEP ) == DragNDrop.ID then

DragNDrop.Screen = widgetsSystem:GetPosConverterParams()

DragNDrop.Place = DragNDrop.wtMovable:GetPlacementPlain()

DragNDrop.DeltaX = math.ceil( params.posX * DragNDrop.Screen.fullVirtualSizeX / DragNDrop.Screen.realSizeX - DragNDrop.Place.posX )

DragNDrop.DeltaY = math.ceil( params.posY * DragNDrop.Screen.fullVirtualSizeY / DragNDrop.Screen.realSizeY - DragNDrop.Place.posY )

common.SetCursor( "drag" )

DragNDrop.IsPicked = true

end

end

function OnEventDNDDragTo( params )

if DragNDrop.IsPicked then

DragNDrop.Place.posX = math.ceil( params.posX * DragNDrop.Screen.fullVirtualSizeX / DragNDrop.Screen.realSizeX - DragNDrop.DeltaX )

DragNDrop.Place.posY = math.ceil( params.posY * DragNDrop.Screen.fullVirtualSizeY / DragNDrop.Screen.realSizeY - DragNDrop.DeltaY )

DragNDrop.wtMovable:SetPlacementPlain( DragNDrop.Place )

common.SetCursor( "drag" )

end

end

function OnEventDNDDropAttempt()

if DragNDrop.IsPicked then

mission.DNDConfirmDropAttempt()

common.SetCursor( "default" )

DragNDrop.IsPicked = false

end

end

Как с этим обращаться:

Инициализация всего этого добра делается очень просто:

Code:
DNDInit( wtReacting, wtMovable, ID )

DNDReg() -- Это только в том случае, если панель видима (не скрыта).

Параметры DNDInit() :

wtReacting -- виджет, на который привязывается реакция, т.е. виджет, ЗА КОТОРЫЙ будет перетаскиваться панель. Это может быть сама перетаскиваемая панель (например, wtMainPanel), но НЕ обязательно (!), это может быть что угодно, например, ЗАГОЛОВОК ОКНА.

wtMovable -- виджет, который нужно перемещать. Обычно, это "материнская" панель (например, wtMainPanel).

ID - уникальный ID перемещаемой панели. Число от 2 до 999 (может, можно и больше, я границу максимальных значений не искал).

Ну и, при каждом показе перемещаемой формы, нужно, соответственно, заново регистрировать её, и при сокрытии, соответственно, отрегистрировать:

Code:
Виджет:Show(true)

DNDReg()

Code:
DNDUnreg()

Виджет:Show(false)

P.S. Оказалось, я не один занимался доработкой этих функций. Valltron тоже хорошо потрудился над ними, в своём аддоне "LootInfo", и завтра я стырю у него ещё один наворот -- чтобы виджет невозможно было утащить за пределы окна, когда игра в оконном режиме. Я сам оконным режимом не пользуюсь, поэтому, даже не подумал об этом.

Ссылка на комментарий
Поделиться на другие сайты

SLA давай оберенм в класс, да запихнем в AOClassLibrary.lua - можно в тотже класс WidgetContainerClass - и там сделать методы типа - SetMobvable( true\false, WidgetName ), и он кстати сам будет DNDReg()\DNDUnreg() делать при скрытие и показе фрейма. Как думаешь ?

Ссылка на комментарий
Поделиться на другие сайты

Еше момент :

DragNDrop.Screen = widgetsSystem:GetPosConverterParams()

Ты берешь данные об экране 1 раз при инициализации..... это не верно, так как пользователь может изменить разрешение экрана в ходе работы. Мне кажеться правелнее всеже брать инфц о скрине каждый раз когда пытаешься потащить.....

Ссылка на комментарий
Поделиться на другие сайты

Как сказал SLA - он перепишет и доработает функцию, взяв доработки из LootInfo

там реализовано что при любом изменении размера окна, даже при окне в четверть экрана, будет нормально панель бегать за курсором. И плюс панель не утаскивается за края экрана.

ps: пока я тут над одним аддоном, да програмкой парюсь, учась у АН делась все через Ж, мои наброски уже на библиотеки растащили :)

Ссылка на комментарий
Поделиться на другие сайты

Не только твои. Мы посути маленькое комьюнити. Активных кодеров по пальцам сосчитать, аддон - opensource. И ессно все друг у друга "тырят" ( в хорошем смысле слова ) идеи по реализации. Это гут - ибо это наиболее быстрый способ - обмена опытом. Просто хорошии идеи нужно - обизательно нужно собрать в 1ой библиотеки. Это поможет нам всем и новым кодерам кторые будут приходить писать аддоны для АО.

Ссылка на комментарий
Поделиться на другие сайты

Я и не имел в виду что это плохо, я хотел сказать что у меня не остается времени чтобы активно помогать. А только раздавать на доработку. хотя по сути сейчас занят только аддоном, да Апдейтером, но на них уходит все время. А либа нужна, но чтобы не получилось так, что мы напишем lua внутри lua... %)

Ссылка на комментарий
Поделиться на другие сайты

Вот по этому и нада ее делать уже сейчас. Просто я так погляжу все усилено чегото пишут *)))) И ессно времени не остаеться на "доведение до ума". Я сам также начал писать ДПС метер. Начал писать топорно - либы работало, разбирайся с АПИ и устройством виджетов. Когда почуствовал что, более менее разобрался и уперся в тот факт что начинаю "тонуть" в куче глобальных переменных, и код при просмотре похож на "монстра" - решил отвлечся притормозить разработку аддона и привести код в порядок, так сказать "причесать". Стал отталкиваться от идеи обернуть всю внутреннию возню с виджетами в КлассКонтейнер который бы этим всем управлял, да и не только работу с виджетами нада обернуть в класс. Нада стараться все обернуть в класс. Просто "Чем дальще в лес - тем толще портизаны" *))) Я ктому что чем крупнее аддон ( чем больше в нем окошек, кнопок, панелей, текстов и т.д. ), тем больше код засаряеться всякими глобалами, повторяющимися кусками кода, и все меннее код такого аддона читабелен. Вообщем я за "эстетичность" и "прозрачность" кода. Нада работать в этом направлении

Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...
Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...

Важная информация

Пользуясь сайтом, вы принимаете Условия использования