PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » CreationGuiPB


CreationGuiPB

Сообщений 1 страница 16 из 16

1

CreationGuiPB

"Copy" — скопировать строку кода элемента
"Save" — сохранить файл со всеми элементами окна. Создаётся рабочий пример, который сразу можно запустить и посмотреть.
Нажатие на строку с координатами и размером (справа вверху) копирует их в буфер обмена. Если элемент не имеет явных текстов и имеет кучу флагов, то проще скопировать только изменяемое числа - размер и координаты.
Стрелки клавиатуры — перемещение элемента. При зажатом Ctrl стрелки изменяют размер элемента.

Скачать: yandex, upload.ee
Видео: upload.ee

https://i.imgur.com/eUjO9MV.png

Изначально писалось для AutoIt3 на AutoIt3`е, но появился запрос редакторов дизайна и я подрихтовал код под PureBasic, то есть изменил имена в списке и сделал правильный вывод синтаксиса при сохранении в файл и при копировании элемента.

Особенности
В отличии от подобных утилит многое тратится на анализатор кода, а автор привязан к некоторому формату GUI заложенным автором проги дизайна. Например числа могут быть прочитаны из ini-файла, точнее размер окна, а координаты рассчитаны в процессе создания и указываются в виде переменных. Аналогично и текст может содержать функцию или массив запроса языковой строки. Отсюда вытекает что нормального дизайнера учитывающего это всё сделать нереально и надо хранить отдельный файл для загрузки интерфейса и проведённые изменения координат переносить в программу. Исходя из этого проще поверх готового окна создать элементы не анализируя код.

План
Есть несколько пунктов плана, которые нужны и легко осуществимы, например ini-файл с флагом диалога запроса имён и т.д.

Сделал тему и начал писать код, но столкнулся с проблемой перетаскивания элементов. То есть проверить что кнопка мыши нажата и при перемещении мыши задавать координаты элементу, создавая перемещение. Надо найти в WinAPI (наверняка есть) и задействовать. Нагуглил GetCursorInfo(), которая возвращает структуру CURSORINFO; функции WindowFromPoint() возвратит дескриптор элемента под курсором. Осталось найти как проверить нажата ли кнопка мыши, WM_LBUTTONDOWN?

Отредактировано AZJIO (Сегодня 13:12:42)

0

2

AZJIO написал(а):

Осталось найти как проверить нажата ли кнопка мыши, тупо WM_LBUTTONDOWN?

GetKeyState с параметром #VK_LBUTTON или #VK_RBUTTON.

AZJIO написал(а):

Нагуглил GetCursorInfo(), которая возвращает структуру CURSORINFO

Проще через GetCursorPos_() или DesktopMouseX() / DesktopMouseY().

0

3

Пока такой код и толком не работает.
1. Вызов GadgetPB(hWnd) приводит к скрытию списка, по которому я изначально кликнул. (Переделал на поиск по списку существующих)
2. Если убрать вызов GadgetPB(hWnd), а id_gadget принудительно назначить 20, то перемещение удается, но нет перерисовки окна в момент перемещения. (добавил перерисовку UpdateWindow_(hGUI))

Код:
;- TOP
; AZJIO 13.11.2024

EnableExplicit

;- # Constants
#Window = 0

Enumeration Gadget
	#btn
	#chTrans
	#lg
	#lvg
	#Coor
	#btnSave
EndEnumeration

Enumeration Menu
	#mL
	#mR
	#mV
	#mN
	#mL1
	#mR1
	#mV1
	#mN1
	#mPos
EndEnumeration


#BackColor = $231504
#BackColor2 = $d6d5d4

;- ● Global
Global hGUI
Global slider03
Global id_Gadget = 20
Define trn = 2
; Define cx, cy
Define hWnd, gx, gy, id_gadget2
Define co.POINT
Define indent.POINT
Define tmp.POINT

Structure GdtID
	id.i
	hdl.i
EndStructure

Global NewList GdtID.GdtID()

;- ● En
#CountStrLang = 9
Global Dim Lng.s(#CountStrLang)
Lng(0) = "Button"
Lng(1) = "CheckBox"
Lng(2) = "Editor"
Lng(3) = "Frame"
Lng(4) = "Text"
Lng(5) = "String"
Lng(6) = "ListView"
Lng(7) = "ListIcon"
Lng(8) = "ComboBox"
Lng(9) = "Option"

Structure Gadgets
	List gdt.i()
EndStructure

Global Dim Gadgets.Gadgets(9)

;- ● Declare
Declare SizeWindowHandler()
Declare AddGadget(item)
Declare GadgetPB(Handle)
Declare moveLR(shift)
Declare moveVN(shift)
Declare moveLR1(shift)
Declare moveVN1(shift)
Declare Save()

; Declare GetGadget(hwnd)

slider03 = 55

;-┌──GUI──┐
hGUI = OpenWindow(#Window, 0, 0, 440, 370,
                  "CreationGuiPB",
                  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
; #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | centered)
If hGUI
	WindowBounds(#Window, 400, 370, #PB_Ignore, #PB_Ignore)
	SetWindowLongPtr_(hGUI, #GWL_EXSTYLE, GetWindowLongPtr_(hGUI, #GWL_EXSTYLE) | #WS_EX_TOPMOST | #WS_EX_LAYERED)
	; 	SetLayeredWindowAttributes_(hGUI, 0, 255, 2)
	; 	SetLayeredWindowAttributes_(hGUI, 0, 255, trn)
	SetLayeredWindowAttributes_(hGUI, #BackColor, 255, trn)

	; 	SetWindowColor(#Window, #BackColor)
	; 	StickyWindow(#Window, #True)
	; 	SetWindowCallback(@Callback_Win())
	; 	SetWindowColor(#Window, $e5e5e5)

	TextGadget(#Coor, 270, 5, 140, 19, "00, 00, 00, 00", #SS_NOTIFY | #SS_LEFTNOWORDWRAP)
	ButtonGadget(#btnSave, 395, 255, 45, 23, "Save")

	ListViewGadget(#lvg, 340, 27, 85, 190)
	AddGadgetItem(#lvg, - 1, "Button")
	AddGadgetItem(#lvg, - 1, "CheckBox")
	AddGadgetItem(#lvg, - 1, "Editor")
	AddGadgetItem(#lvg, - 1, "Frame")
	AddGadgetItem(#lvg, - 1, "Text")
	AddGadgetItem(#lvg, - 1, "String")
	AddGadgetItem(#lvg, - 1, "ListView")
	AddGadgetItem(#lvg, - 1, "ListIcon")
	AddGadgetItem(#lvg, - 1, "ComboBox")
	AddGadgetItem(#lvg, - 1, "Option")

	CheckBoxGadget(#chTrans, 395, 280, 37, 23, "Trns")

	TextGadget(#lg, 0, 0, 250, 260, "")
	SetGadgetColor(#lg, #PB_Gadget_BackColor, #BackColor2)

	BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())


	AddKeyboardShortcut(#Window, #PB_Shortcut_Left, #mL) ; влево
	AddKeyboardShortcut(#Window, #PB_Shortcut_Right, #mR); вправо
	AddKeyboardShortcut(#Window, #PB_Shortcut_Up, #mV)  ; вверх
	AddKeyboardShortcut(#Window, #PB_Shortcut_Down, #mN) ; вниз
	AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_Left, #mL1) ; влево
	AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_Right, #mR1); вправо
	AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_Up, #mV1)  ; вверх
	AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_Down, #mN1) ; вниз

	AddKeyboardShortcut(#Window, #PB_Shortcut_Space, #mPos) ; вставить в позицию

	; 	AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_Shift | #PB_Shortcut_C, ) ; Ctrl+Shift+C
	; 	AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_E, ) ; Ctrl+E
	; 	AddKeyboardShortcut(#Window, #PB_Shortcut_Return, ) ; Enter

	;-┌──Loop──┐
	Repeat
    If GetAsyncKeyState_(#VK_LBUTTON)
    	; co\x = DesktopMouseX()
    	; co\y = DesktopMouseY()
    	; Debug GetGadget(#Window)
    	; Debug ChildWindowFromPoint_(WindowID(#Window), co)
    	GetCursorPos_(@co.POINT)
    	hWnd = WindowFromPoint_(co\x | co\y << 32)
    	id_gadget2 = GadgetPB(hWnd)
    	If id_gadget2 > 20 And IsGadget(id_gadget2)
        co\x = WindowMouseX(#Window)
        co\y = WindowMouseY(#Window)
        indent\x = co\x - GadgetX(id_gadget2)
        indent\y = co\y - GadgetY(id_gadget2)
    	EndIf
    	;     	Debug "Find ID = " +  Str(id_gadget2)
    	;     	Debug "WFP = " +  Str(hWnd)
    	If id_gadget2 > 20 And IsGadget(id_gadget2)
        While GetAsyncKeyState_(#VK_LBUTTON)
        	co\x = WindowMouseX(#Window)
        	co\y = WindowMouseY(#Window)
        	If tmp\x <> co\x Or tmp\y <> co\y
            ResizeGadget(id_gadget2, co\x - indent\x, co\y - indent\y, #PB_Ignore , #PB_Ignore)
            UpdateWindow_(hGUI)
            tmp\x = co\x
            tmp\y = co\y
        	EndIf
        Wend
    	EndIf
    EndIf
    Select WaitWindowEvent()
    	Case #PB_Event_Timer
        If EventTimer() = 0
        	SetGadgetColor(#Coor, #PB_Gadget_BackColor, #PB_Default)
        	RemoveWindowTimer(#Window, 0)
        EndIf

;- ├ Menu
    	Case #PB_Event_Menu
        Select EventMenu()
        	Case #mL
            moveLR( - 1)
        	Case #mR
            moveLR(1)
        	Case #mV
            moveVN( - 1)
        	Case #mN
            moveVN(1)
        	Case #mL1
            moveLR1( - 1)
        	Case #mR1
            moveLR1(1)
        	Case #mV1
            moveVN1( - 1)
        	Case #mN1
            moveVN1(1)
        EndSelect

    	Case #PB_Event_Gadget
        ;- ├ Gadget
        Select EventGadget()
        	Case #btnSave
            Save()
            
            
        	Case #Coor
            SetClipboardText(GetGadgetText(#Coor))
            SetGadgetColor(#Coor, #PB_Gadget_BackColor, $8080FF)
            AddWindowTimer(#Window, 0, 55)
        	Case #chTrans
            If GetGadgetState(#chTrans) & #PB_Checkbox_Checked
            	SetLayeredWindowAttributes_(hGUI, #BackColor, 255 - slider03, trn)
            Else
            	SetLayeredWindowAttributes_(hGUI, #BackColor2, 0, 1)
            EndIf
        	Case #lvg
            AddGadget(GetGadgetState(#lvg))
        EndSelect
    	Case #PB_Event_CloseWindow
        CloseWindow(0)
        End
    EndSelect
	ForEver
	;-└──Loop──┘
EndIf


Procedure Save()
	Protected tmp$, n, i
	For i = 0 To 9
    ForEach Gadgets(i)\gdt()
    	n+1
    	tmp$ + Lng(i) + "Gadget(" + n + ", " + Str(GadgetX(Gadgets(i)\gdt())) + ", " + Str(GadgetY(Gadgets(i)\gdt())) + ", " + Str(GadgetWidth(Gadgets(i)\gdt())) + ", " + Str(GadgetHeight(Gadgets(i)\gdt())) + ", " + #DQUOTE$ + GetGadgetText(Gadgets(i)\gdt()) + #DQUOTE$ + ")" + #CRLF$
    Next
	Next
	SetClipboardText(tmp$)
	MessageRequester("Code on clipboard", tmp$)
EndProcedure


Procedure AddGadget(item)
	Protected w, h, y
	Static n
	y = WindowHeight(#Window) - 50
	w = 120
	h = 30
	n + 1
	id_Gadget + 1
	Select item
    Case - 1
    	ProcedureReturn
    Case 0
    	ButtonGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(0))
    Case 1
    	CheckBoxGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(1))
    Case 2
    	EditorGadget(id_Gadget, 10, y, w, h)
    Case 3
    	;     	FrameGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(3))
    	TextGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(3), #SS_NOTIFY | #WS_BORDER)
    Case 4
    	TextGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(4), #SS_NOTIFY) ; #SS_NOTIFY позволяет перетаскивать
    Case 5
    	StringGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(5))
    Case 6
    	ListViewGadget(id_Gadget, 10, y, w, h)
    Case 7
    	ListIconGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(7), w)
    Case 8
    	ComboBoxGadget(id_Gadget, 10, y, w, h)
    Case 9
    	OptionGadget(id_Gadget, 10, y, w, h, Str(n) + " " + Lng(9))
	EndSelect
	
	AddElement(GdtID())
	GdtID()\id = id_Gadget
	GdtID()\hdl = GadgetID(id_Gadget)
	; 	Debug "Add ID = " +  Str(GdtID()\id)
	; 	Debug  "Add hwnd = " +  Str(GdtID()\hdl)
	AddElement(Gadgets(item)\gdt())
	Gadgets(item)\gdt() = id_Gadget
EndProcedure


Procedure SizeWindowHandler()
	Protected w, h
	w = WindowWidth(#Window)
	h = WindowHeight(#Window)

	ResizeGadget(#lg, #PB_Ignore, #PB_Ignore, w - 190, h - 110)
	ResizeGadget(#lvg, w - 100, #PB_Ignore, #PB_Ignore, #PB_Ignore)
	ResizeGadget(#chTrans, w - 45, #PB_Ignore, #PB_Ignore, #PB_Ignore)
	ResizeGadget(#Coor, w - 170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
	ResizeGadget(#btnSave, w - 45, #PB_Ignore, #PB_Ignore, #PB_Ignore)

	ForEach GdtID()
    ResizeGadget(GdtID()\id, #PB_Ignore, #PB_Ignore, #PB_Ignore, #PB_Ignore)
	Next
EndProcedure


Procedure GadgetPB(Handle)
	ForEach GdtID()
    If GdtID()\hdl = Handle
    	ProcedureReturn GdtID()\id
    EndIf
	Next
	ProcedureReturn 0 ; минимальный ID=20, поэтому используем 0
EndProcedure

Procedure moveLR(shift)
	Protected x
	x = GadgetX(id_Gadget) + shift
	ResizeGadget(id_Gadget, x, #PB_Ignore, #PB_Ignore , #PB_Ignore)
	SetGadgetText(#Coor, Str(x) + ", " + Str(GadgetY(id_Gadget)) + ", " + Str(GadgetWidth(id_Gadget)) + ", " + Str(GadgetHeight(id_Gadget)))
	; 	нарисовать кайму активного
EndProcedure

Procedure moveVN(shift)
	Protected y
	y = GadgetY(id_Gadget) + shift
	ResizeGadget(id_Gadget, #PB_Ignore, y, #PB_Ignore , #PB_Ignore)
	SetGadgetText(#Coor, Str(GadgetX(id_Gadget)) + ", " + Str(y) + ", " + Str(GadgetWidth(id_Gadget)) + ", " + Str(GadgetHeight(id_Gadget)))
EndProcedure

Procedure moveLR1(shift)
	Protected w
	w = GadgetWidth(id_Gadget) + shift
	ResizeGadget(id_Gadget, #PB_Ignore, #PB_Ignore, w , #PB_Ignore)
	SetGadgetText(#Coor, Str(GadgetX(id_Gadget)) + ", " + Str(GadgetY(id_Gadget)) + ", " + Str(w) + ", " + Str(GadgetHeight(id_Gadget)))
EndProcedure

Procedure moveVN1(shift)
	Protected h
	h = GadgetHeight(id_Gadget) + shift
	ResizeGadget(id_Gadget, #PB_Ignore, #PB_Ignore, #PB_Ignore, h)
	SetGadgetText(#Coor, Str(GadgetX(id_Gadget)) + ", " + Str(GadgetY(id_Gadget)) + ", " + Str(GadgetWidth(id_Gadget)) + ", " + Str(h))
EndProcedure

Новый код, клик для включения перетаскивания и клик для отключения, то есть не надо удерживать мышь нажатой.

Код:
;- TOP

EnableExplicit

; XIncludeFile "GadgetPB.pbi"

;- # Constants
#Window = 0

Enumeration
	#btn
	#chTrans
	#lg
	#lvg
EndEnumeration


#BackColor = $231504
#BackColor2 = $d6d5d4

;- ● Global
Global hGUI
Global slider03
Global id_gadget = 20
Define trn = 2
Define cx, cy
Define hWnd, gx, gy, eg, flgDrag
Define co.POINT
Define tmp.POINT
Define sz.POINT


;- ● En
#CountStrLang = 9
Global Dim Lng.s(#CountStrLang)
Lng(0) = "Button"
Lng(1) = "CheckBox"
Lng(2) = "Editor"
Lng(3) = "Frame"
Lng(4) = "Text"
Lng(5) = "String"
Lng(6) = "ListView"
Lng(7) = "ListIcon"
Lng(8) = "ComboBox"
Lng(9) = "Option"

Structure Gadgets
	List gdt.i()
EndStructure

Global Dim Gadgets.Gadgets(9)


;- ● Declare
Declare SizeWindowHandler()
Declare AddGadget(item)
; Declare GetGadget(hwnd)

slider03 = 55

;-┌──GUI──┐
hGUI = OpenWindow(#Window, 0, 0, 440, 370,
                  "CreationGuiPB",
                  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
    	            ; #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | centered)
If hGUI
	WindowBounds(#Window, 400, 370, #PB_Ignore, #PB_Ignore)
	SetWindowLongPtr_(hGUI, #GWL_EXSTYLE, GetWindowLongPtr_(hGUI, #GWL_EXSTYLE) | #WS_EX_TOPMOST | #WS_EX_LAYERED)
; 	SetLayeredWindowAttributes_(hGUI, 0, 255, 2)
; 	SetLayeredWindowAttributes_(hGUI, 0, 255, trn)
	SetLayeredWindowAttributes_(hGUI, #BackColor, 255, trn)

; 	SetWindowColor(#Window, #BackColor)
; 	StickyWindow(#Window, #True)
; 	SetWindowCallback(@Callback_Win())

	ListViewGadget(#lvg, 340, 27, 85, 190)
	AddGadgetItem(#lvg, - 1, "Button")
	AddGadgetItem(#lvg, - 1, "CheckBox")
	AddGadgetItem(#lvg, - 1, "Editor")
	AddGadgetItem(#lvg, - 1, "Frame")
	AddGadgetItem(#lvg, - 1, "Text")
	AddGadgetItem(#lvg, - 1, "String")
	AddGadgetItem(#lvg, - 1, "ListView")
	AddGadgetItem(#lvg, - 1, "ListIcon")
	AddGadgetItem(#lvg, - 1, "ComboBox")
	AddGadgetItem(#lvg, - 1, "Option")

	CheckBoxGadget(#chTrans, 395, 280, 37, 23, "Trns")

	TextGadget(#lg, 0, 0, 250, 260, "")
	SetGadgetColor(#lg, #PB_Gadget_BackColor, #BackColor2)

	BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())


;-┌──Loop──┐
	Repeat
    If flgDrag
    	co\x = WindowMouseX(#Window)
    	co\y = WindowMouseY(#Window)
    	If tmp\x <> co\x Or tmp\y <> co\y
        ResizeGadget(id_gadget, co\x - sz\x, co\y - sz\y, #PB_Ignore , #PB_Ignore)
        tmp\x = co\x
        tmp\y = co\y
    	EndIf
    EndIf
    Select WaitWindowEvent()
    	Case #PB_Event_Gadget
        ;- ├ Gadget
        eg = EventGadget()
        Select eg
        	Case 20 To 2000
            flgDrag = Bool(Not flgDrag)
            If flgDrag
            	id_gadget = eg
            	co\x = WindowMouseX(#Window)
            	co\y = WindowMouseY(#Window)
            	sz\x = co\x - GadgetX(id_gadget)
            	sz\y = co\y - GadgetY(id_gadget)
;             	GetCursorPos_(@co.POINT)
;             	hWnd = WindowFromPoint_(co\x|co\y<<32)
;             	id_gadget = 20
            EndIf
        	Case #chTrans
            If GetGadgetState(#chTrans) & #PB_Checkbox_Checked
            	SetLayeredWindowAttributes_(hGUI, #BackColor, 255 - slider03, trn)
            Else
            	SetLayeredWindowAttributes_(hGUI, #BackColor2, 0, 1)
            EndIf
        	Case #lvg
            AddGadget(GetGadgetState(#lvg))
        EndSelect
    	Case #PB_Event_CloseWindow
        CloseWindow(0)
        End
    EndSelect
	ForEver
;-└──Loop──┘
EndIf


Procedure AddGadget(item)
	Protected w, h
	Static n
	w = 120
	h = 25
	id_Gadget + 1
	n + 1
	Select item
    Case - 1
    	ProcedureReturn
    Case 0
    	ButtonGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(0))
    Case 1
    	CheckBoxGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(1))
    Case 2
;     	EditorGadget(id_Gadget, 10, 280, w, h)
    	TextGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(2), #SS_NOTIFY | #SS_SUNKEN)
    	SetGadgetColor(id_Gadget, #PB_Gadget_BackColor, $ffffff)
    Case 3
    	FrameGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(3))
    Case 4
    	TextGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(4), #SS_NOTIFY)
    Case 5
;     	StringGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(5))
    	TextGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(5), #SS_NOTIFY | #SS_SUNKEN)
    	SetGadgetColor(id_Gadget, #PB_Gadget_BackColor, $ffffff)
    Case 6
;     	ListViewGadget(id_Gadget, 10, 280, w, h) ; , #LBS_NOTIFY
    	TextGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(6), #SS_NOTIFY | #WS_BORDER)
    	SetGadgetColor(id_Gadget, #PB_Gadget_BackColor, $ffffff)
    Case 7
;     	ListIconGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(7), w)
    	TextGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(7), #SS_NOTIFY | #WS_BORDER)
    	SetGadgetColor(id_Gadget, #PB_Gadget_BackColor, $ffffff)
    Case 8
;     	ComboBoxGadget(id_Gadget, 10, 280, w, h)
    	TextGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(8), #SS_NOTIFY | #WS_BORDER)
    	SetGadgetColor(id_Gadget, #PB_Gadget_BackColor, $ffffff)
    Case 9
    	OptionGadget(id_Gadget, 10, 280, w, h, Str(n) + " " + Lng(9))
	EndSelect
	AddElement(Gadgets(item)\gdt())
	Gadgets(item)\gdt() = id_Gadget
EndProcedure


Procedure SizeWindowHandler()
	Protected w, h
	w = WindowWidth(#Window)
	h = WindowHeight(#Window)

	ResizeGadget(#lg, #PB_Ignore, #PB_Ignore, w - 190, h - 110)
	ResizeGadget(#lvg, w - 100, #PB_Ignore, #PB_Ignore, #PB_Ignore)
	ResizeGadget(#chTrans, w - 45, #PB_Ignore, #PB_Ignore, #PB_Ignore)
EndProcedure

В последнем примере для имитации некоторых элементов используется TextGadget() с разным цветом и оформлением рамки. В AutoIt3 используется событие $GUI_EVENT_PRIMARYDOWN = -7. Всё же хотелось бы перетаскивать реальные объекты, потому что им можно было бы применить стили в будущем развивая утилиту, иначе придётся её оставить только ради подгонки координат.

Отредактировано AZJIO (13.11.2024 13:26:11)

0

4

AZJIO написал(а):

В AutoIt3 используется событие $GUI_EVENT_PRIMARYDOWN = -7.

Клик левой кнопкой мышки?

Код:
If Event = #WM_LBUTTONDOWN
  Debug "ЛКМ"
EndIf

Или

Код:
If Event = #PB_Event_LeftClick
  Debug "ЛКМ"
EndIf

0

5

Пётр
Пока не проверял, но это скорее всего "клик", то есть не контролируется нажатие мыши, а просто приходит сообщение о клике/нажатии и не придёт последующего пока не будет отпущено и нажато повторно.

Обновил.
Архив содержит исходник pb
С перемещением элементов окна уже решилось прошлый раз, код выше я время от времени обновлял. Но вот теперь:
1. Добавил сохранение элементов окна в код pb.
2. Добавлено позиционирование кнопкой Pos или пробелом.
3. Добавлено меню (переименовать, запомнить размер, удалить, удалить все). Удалять - клавиша delete.
4. Стрелками двигать элементы вправо/влево, а с Ctrl изменять размер.
5. Добавлен ini-файл
6. Добавлено изменение размера слайдерами (TrackBarGadget)

Критический план:
Пока нет магнетизма к окну.

Отредактировано AZJIO (15.11.2024 15:00:51)

0

6

AZJIO написал(а):

не придёт последующего пока не будет отпущено и нажато повторно.

Код:
If OpenWindow(0, 0, 0, 270, 160, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  LB = #False
  Repeat 
    Event = WaitWindowEvent()
    
    If Event = #WM_LBUTTONDOWN
      LB = #True
    ElseIf Event = #WM_LBUTTONUP
      LB = #False
    ElseIf Event = #WM_MOUSEMOVE And LB = #True
      Debug "ЛКМ MOUSEMOVE"
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf

0

7

Пётр
Я сначала решил сделать ваш вариант через SetWindowCallback, тем более что у меня есть пример WM_MOUSEMOVE и там внутри блока проверяется нажатие (MK_LBUTTON), но оно работало только на поверхности голого GUI, не на кнопках. Потом я попробовал ваш вариант в SetWindowCallback, но с отдельными событиями #WM_LBUTTONUP и #WM_LBUTTONDOWN как у вас в примере, и тоже не получилось. В итоге сделал внутри основного цикла событий, если уж по другому у меня не получается. Нагрузка на процессор сразу упала (при удерживании мыши), потому что в отличии от GetAsyncKeyState, который проверяется в цикле отдельно, #WM_LBUTTONDOWN срабатывает один раз захватывает данные дескриптор элемента под курсором и координаты и далее работает только WM_MOUSEMOVE.

Обновлено
Индивидуальные вещи для Scintilla, ImageGadget, ButtonImageGadget
Восстановлены размеры для всех гаджетов.
Добавлен параметр hide = 20,21,13,23,24,25,26 чтобы скрыть редко используемые элементы.
Добавлен захват окна.
Добавлены почти все элементы окна.

Отредактировано AZJIO (22.11.2024 12:02:36)

0

8

WM_MOUSEMOVE работает только над голым окном, и это отмечено в описании константы
WM_SETCURSOR работает над ВСЕМ окном и гаджетами, и возвращает полезную инфу, оказалась во многие дырки затычка

Global $assot[19][2] = [ _
[1, '1 - Клиентская область'], _
[2, '2 - Заголовок'], _

это константы HT...., они есть у Соковникова, #HTCLIENT и остальные
#WM_MOUSEACTIVATE тоже интересная константа, может тебе пригодится, наверно

по мне, так мало пригодные подобные примочки, предпочитаю руками писать, и чтобы ни каких конкретных координат размеров, чтобы без проблем можно было убрать, добавить, где то в середине
перетусовывать гаджеты часто приходится, пока всё на морде поставишь как надо
а эти примочки голые цифры дают, как тут гаджеты тусовать?

0

9

newJS написал(а):

это константы HT....

Эта справка была написана 15 лет назад и возвращаться к ней я не собираюсь.

newJS написал(а):

WM_SETCURSOR работает над ВСЕМ окном и гаджетами

практически любой гаджет перетягивает поверх другого. Бывает исключения иногда отцепляется или при выборе одного изменяется другой Editor этим страдает, но не критично. Хотя может некоторые #PB_GadgetType_ScrollBar и ещё контейнер и ScrollArea я исключил по разным причинам, один не перетаксивается совсем, другой после потери фокуса невозможно сделать текущим, не принимает клик, если только подменять временно текстовым лейблом, а при сохранении учитывая что указан тип в структуре на выходе сохранять контейнер, то есть правильный. Но я и так делал несколько подмен frame и т.д.

newJS написал(а):

и чтобы ни каких конкретных координат размеров

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

newJS написал(а):

предпочитаю руками писать

Я тоже ручками окна создаю, но не исключаю, что если бы был подобный инструмент, простой, быстро запускающийся, то воспользовался бы им, который я и написал. Ну вот примерчик быстро накидать на форум для описания ошибки. А в проге, кончено расставить координаты там 5 минут работы, может чуть дольше если методом тыка угадывать и не можешь в голове по формуле рассчитать середину или равномерные отступы между кнопками. Куда сложнее писать функционал для кнопки. Поэтому я не понимаю людей которым кровь из носу нужен гуисоздатель и без него они якобы не могут писать код. Ну вот очередной инструмент, бесплатный и легко работающий. Там ещё в ini-файл я не все константы внёс, новые гаджеты добавил, а константы им не прописал. Прога сама константы возьмёт. Я использовал пуриковские константы для указания типа, думаю так правильней и понятней. Ну и ещё надо при захвате элементов прописать условия для разных флагов, например кнопка со стилем чекбокса или группы может менять свой вид и наоборот по смыслу чекбокс, а работает как кнопка. У некоторых могут быть свои классы, например Scintilla, поэтому я добавил при отсутствии стандартного класса поиск слова определяющего его тип. При тестах я обнаружил что некоторые элементы отображаются другим типом, поэтому нужно тестить и вносить условия/правила детектирования.

0

10

AZJIO написал(а):

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

Поменяете шрифт или его размер и "Лёлик, всё пропало!". В винде, линукс и макос разные шрифты!
Аналогично при изменении текста в GUI, например при смене языка.
В этом плане создание окна через Dialog имеет преимущества, т. к. нет явной привязки к координатам.

Код:
#Dialog = 0
#Xml = 0

XML$ = "<window id='0' name='test' text='test' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
       "  <vbox>"+
       "    <panel id='0'>" +
       "      <tab text='First tab'>" +
       "        <vbox expand='item:2'>" +
       "          <hbox>" +
       "            <button text='button 1' id='1'/>" +
       "            <checkbox text='checkbox 1' id='2'/>" +
       "            <button text='button 2' id='3'/>" +
       "          </hbox>" +
       "          <editor text='content' height='150'/>" +
       "        </vbox>" +
       "      </tab>" +
       "      <tab text='Second tab'>" +
       "      </tab>" +
       "    </panel>" +
       "    <singlebox margin='2' expand='no' align='center'>" +
       "      <button text='Сменить текст' id='4'/>" +
       "    </singlebox>" +
        " </vbox>"+
       "</window>"

If ParseXML(#Xml, XML$) And XMLStatus(#Xml) = #PB_XML_Success
  
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
    
    Repeat
      Event = WaitWindowEvent()
      
      If Event = #PB_Event_Gadget And EventGadget() = 4
        SetGadgetItemText(0, 0, "Вкладка 1")
        SetGadgetItemText(0, 1, "Вкладка 2")
        SetGadgetText(1, "Кнопка 1 (слева)")
        SetGadgetText(2, "Выбор чего-то там")
        SetGadgetText(3, "Кнопка 2 (справа)")
        RefreshDialog(#Dialog)
        HideWindow(0, 0, #PB_Window_ScreenCentered)
      EndIf
    Until Event = #PB_Event_CloseWindow 
    
  Else  
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf

Запустите и нажмите на кнопку "Сменить текст".

0

11

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

Обновил
Добавил линукс версию с использованием канваса (только так работает запрос координат при перемещении, и то курсор должен быть не над кнопкой). Нет только захвата окон и немного проигрывает перетаскивание, а в остальном терпимо и работает.

А может мне элементы сделать в виде макета на канвасе чтобы избежать проблем с перетаскиванием? Нам ведь не особо важно идеальная точность вида гаджетов, главное чтобы ящики разместить по позициям.

Отредактировано AZJIO (23.11.2024 14:16:39)

0

12

Пётр
Правильно ли я понял, что программа читает внешний (или внутренний) XML-файл и на его основе создаёт интерфейс? Или всё же это является предкомпилируемой версией, которая подстраивает размеры элементов в момент компилирования на основе длинны текста?
Как на счёт красоты выравнивания? Я до сих пор не понимаю как это работает. Например создаётся кнопка и справа от неё вторая, если текст в первой кнопке больше, то кнопка увеличивается, а следующая за ней сдвигается на заданный отступ? Просто в таком случае кнопки сделанные в виде таблицы примут хаотичный вид. Например есть некоторая вертикальная невидимая линия второго ряда по которой выравниваются элементы чтобы не выглядеть кучей, и что теперь это не будет работать?
В Windows используется DPI в отличии от линукс. Допустим я использую увеличенный шрифт, если он больше 11, то я получаю кривизну интерфейса от винды, даже не от программера создавшего интерфейс, у меня просто имена файлов обрежутся в дереве и я буду видеть огрызки по длине и огрызки по высоте у таких букв как "ур" или для англ "g", у которых завитушки снизу, а нижнее подчёркивание будет выглядеть как пробел (у меня уже так при шрифте Arial-11). Единственный выход в таком случае купить большой монитор и использовать масштабирование 125%, 150%. То есть в винде так не решается интерфейс методом автоматического удлинения как в GTK3 в Linux (кстати GTK2 тоже не применяет авторазмер).
Также старый интерфейс "Свойство экрана" до сих пор содержит мини кнопки, где умещается только шрифт размером 9 и другие старые окна.

Отредактировано AZJIO (23.11.2024 17:13:04)

0

13

Попробовал рисовать в канвасе. В общем работает, но надо как-то "фотографировать" элемент вместо того чтобы рисовать его заново. Если кнопка то там проблем нет - нарисовать поверхность, кайму и текст, а вот сложные элементы кажется эффективней перерисовывать методом копирования созданной поверхности. Например ListIconGadget будет иметь заголовок, пункты, колонки, двойную кайму.

Примерно такой код (могу готовый выложить, но там пока только кнопка перетаскивается):

Код:
Case #lg
	Select EventType()
    Case  #PB_EventType_LeftButtonUp
    	If MouseDown = #True
        GadgetsTypeArray(1)\x = tmp\x - indent\x
        GadgetsTypeArray(1)\y = tmp\y - indent\y
        MouseDown = #False
        If StartDrawing(CanvasOutput(#lg))
        	DrawingMode(#PB_2DDrawing_Transparent)
        	Box(0, 0, cw - 220, ch - 110, #BackColor2)
        	Box(GadgetsTypeArray(1)\x, GadgetsTypeArray(1)\y, GadgetsTypeArray(1)\w, GadgetsTypeArray(1)\h, $bbbbbb)
        	DrawText(GadgetsTypeArray(1)\x, GadgetsTypeArray(1)\y, Str(NG) + " " + GadgetsTypeArray(1)\name, 0, #PB_2DDrawing_Transparent)
        	
        	tmp\x = GadgetsTypeArray(1)\x
        	tmp\y = GadgetsTypeArray(1)\y
        	StopDrawing()
        EndIf
    	EndIf
    	SetTextCoor(id_CurGadget)
    Case  #PB_EventType_LeftButtonDown
    	co\x = GetGadgetAttribute(#lg, #PB_Canvas_MouseX)
    	co\y = GetGadgetAttribute(#lg, #PB_Canvas_MouseY)
    	If co\x > GadgetsTypeArray(1)\x And co\y > GadgetsTypeArray(1)\y And co\x < GadgetsTypeArray(1)\x + GadgetsTypeArray(1)\w And co\y < GadgetsTypeArray(1)\y + GadgetsTypeArray(1)\h
        MouseDown = #True
    	EndIf
    	indent\x = co\x - GadgetsTypeArray(1)\x
    	indent\y = co\y - GadgetsTypeArray(1)\y
    	tmp\x = GadgetsTypeArray(1)\x
    	tmp\y = GadgetsTypeArray(1)\y
    Case #PB_EventType_MouseMove
    	If MouseDown
        co\x = GetGadgetAttribute(#lg, #PB_Canvas_MouseX)
        co\y = GetGadgetAttribute(#lg, #PB_Canvas_MouseY)
        If StartDrawing(CanvasOutput(#lg))
        	DrawingMode(#PB_2DDrawing_Transparent)
        	Box(tmp\x - indent\x - 1, tmp\y - indent\y - 1, GadgetsTypeArray(1)\w + 2, GadgetsTypeArray(1)\h + 2, #BackColor2)
        	Box(co\x - indent\x, co\y - indent\y, GadgetsTypeArray(1)\w, GadgetsTypeArray(1)\h, $bbbbbb)
        	DrawText(co\x - indent\x, co\y - indent\y, Str(NG) + " " + GadgetsTypeArray(1)\name, 0, #PB_2DDrawing_Transparent)
        	tmp\x = co\x
        	tmp\y = co\y
        	StopDrawing()
        EndIf
        SetTextCoor(id_CurGadget)
    	EndIf
	EndSelect

Хотя я понимаю, что при использовании реальных объектов мы видим интерфейс таким каким он будет в реальности, а имитацией можно не добиться объективной визуализации.

Нашёл как сделать. При нажатии мыши нарисовать Image, а потом при перемещении мыши функцией DrawImage() перемещать это изображение.

Отредактировано AZJIO (23.11.2024 20:22:42)

0

14

AZJIO написал(а):

Правильно ли я понял, что программа читает внешний (или внутренний) XML-файл и на его основе создаёт интерфейс?

Да.

AZJIO написал(а):

которая подстраивает размеры элементов в момент компилирования на основе длинны текста?

Если это было бы так, при нажатии кнопки "Сменить текст", гаджеты и окно не подстраивалось под содержимое. Да и в момент компиляции невозможно вычислить какой будет шрифт и его размер на компе где запустят приложение.
Там еще размеры гажетов меняются при изменении мышкой ширины и высоты окна.

AZJIO написал(а):

следующая за ней сдвигается на заданный отступ?

Да.

AZJIO написал(а):

Просто в таком случае кнопки сделанные в виде таблицы примут хаотичный вид.

Это все настраивается. Пример из справки.

Код:
#Dialog = 0
#Xml = 0

XML$ = "<window id='#PB_Any' name='test' text='Gridbox' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
       "    <gridbox columns='6'>" +
       "          <button text='Button 1' />" +
       "          <button text='Button 2' />" +
       "          <button text='Button 3' colspan='3' />" +
       "          <button text='Button 4' />" +
       "          <button text='Button 5' rowspan='2' />" +
       "          <button text='Button 6' />" +
       "          <button text='Button 7' />" +
       "          <button text='Button 8' />" +
       "          <button text='Button 9' />" +
       "          <button text='Button 10' />" +
       "          <button text='Button 11' />" +
       "          <button text='Button 12' />" +
       "    </gridbox>" +
       "  </window>"

If ParseXML(#Xml, XML$) And XMLStatus(#Xml) = #PB_XML_Success
  
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow 
    
  Else  
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf
AZJIO написал(а):

надо как-то "фотографировать"

#WM_PRINT, #WM_PRINTCLIENT и т. д.

0

15

Пётр написал(а):

#WM_PRINT, #WM_PRINTCLIENT и т. д.

Я уже сделал через DrawImage, вот пример:

Код:
Case #lg
	Select EventType()
    Case  #PB_EventType_LeftButtonUp
    	If MouseDown = #True
        GadgetsTypeArray(1)\x = tmp\x - indent\x
        GadgetsTypeArray(1)\y = tmp\y - indent\y
        MouseDown = #False
        If StartDrawing(CanvasOutput(#lg))
        	DrawingMode(#PB_2DDrawing_Transparent)
        	Box(0, 0, cw - 220, ch - 110, #BackColor2)
        	DrawImage(ImageID(0), co\x - indent\x, co\y - indent\y)
        	tmp\x = GadgetsTypeArray(1)\x
        	tmp\y = GadgetsTypeArray(1)\y
        	StopDrawing()
        EndIf
    	EndIf
    	SetTextCoor(id_CurGadget)
    Case  #PB_EventType_LeftButtonDown
    	co\x = GetGadgetAttribute(#lg, #PB_Canvas_MouseX)
    	co\y = GetGadgetAttribute(#lg, #PB_Canvas_MouseY)
    	If co\x > GadgetsTypeArray(1)\x And co\y > GadgetsTypeArray(1)\y And co\x < GadgetsTypeArray(1)\x + GadgetsTypeArray(1)\w And co\y < GadgetsTypeArray(1)\y + GadgetsTypeArray(1)\h
        MouseDown = #True
        If CreateImage(0, GadgetsTypeArray(1)\w, GadgetsTypeArray(1)\h) And StartDrawing(ImageOutput(0))
        	DrawingMode(#PB_2DDrawing_Transparent)
        	Box(0, 0, GadgetsTypeArray(1)\w, GadgetsTypeArray(1)\h, $bbbbbb)
        	DrawText(0, 0, Str(NG) + " " + GadgetsTypeArray(1)\name, 0, #PB_2DDrawing_Transparent)
        	StopDrawing()
        EndIf
    	EndIf
    	indent\x = co\x - GadgetsTypeArray(1)\x
    	indent\y = co\y - GadgetsTypeArray(1)\y
    	tmp\x = GadgetsTypeArray(1)\x
    	tmp\y = GadgetsTypeArray(1)\y
    Case #PB_EventType_MouseMove
    	If MouseDown
        co\x = GetGadgetAttribute(#lg, #PB_Canvas_MouseX)
        co\y = GetGadgetAttribute(#lg, #PB_Canvas_MouseY)
        If StartDrawing(CanvasOutput(#lg))
        	Box(tmp\x - indent\x - 1, tmp\y - indent\y - 1, GadgetsTypeArray(1)\w + 2, GadgetsTypeArray(1)\h + 2, #BackColor2)
        	DrawImage(ImageID(0), co\x - indent\x, co\y - indent\y)
        	tmp\x = co\x
        	tmp\y = co\y
        	StopDrawing()
        EndIf
        SetTextCoor(id_CurGadget)
    	EndIf
	EndSelect

0

16

Пётр написал(а):

#WM_PRINT

Спасибо не знал. Но так как мне важно кроссплатформенный вариант, то потратил немного времени и кода на собственное рисование гаджетов.

Добавил файл на яндексе в архив файл "CreationGuiPB-Canvas(WinLin).pb" и "CreationGuiPB-CanvasWinCapture.pb".

Проблема перед сохранением сделать ReverseList, так как я добавляю элементы в начало списка, то сохранение происходит в обратном порядке.

Обновлено
0.6.1 (27.11.24)
Обновлён функционал сохранения, копирования
Добавлен индивидуальный вид гаджета Календарь.

Видео на ютубе

Отредактировано AZJIO (Сегодня 04:44:03)

0


Вы здесь » PureBasic - форум » PureBasic для Windows » CreationGuiPB