
@Fluid Byte - That's what I was thinking last night, but it was something like 4am when I got to bed and I forgot the ideas that I had by the time I got up today


Thanks
Code: Select all
CopyMemory(GUI_LIST_PANEL(), GUI_PANEL_TEMPBUFFER, SizeOf(_GUI_PANEL))
Code: Select all
CopyMemory(H_PANEL, GUI_PANEL_TEMPBUFFER, SizeOf(_GUI_PANEL))
yap.untune wrote:I have no idea what the difference is for a fixed length string and a .s string, is it to do with how they are stored?
Thanks for the explanation KaeruKaeru Gaman wrote:yap.untune wrote:I have no idea what the difference is for a fixed length string and a .s string, is it to do with how they are stored?
a fixed string is located directly at the adress where the pointer of it's name points to.
also, within a struct a fixed string is stored directly.
a dynamic string is located in a seperated dynamic stringpool wich is managed by PB base routines.
at the first location where the first pointer points to (or the part of the structured element)
only the actual pool pointer is stored.
this points to the location in the stringpool, wich can change even if one char is added to the string.
Code: Select all
; // Initialise buffer variables
Protected GUI_PANEL_TEMPHEADER$
; // Get the info from the structure, create temporary structure to store it
GUI_PANEL_TEMPHEADER$ = GUI_LIST_PANEL()\Header$
GUI_PANEL_TEMPBUFFER = AllocateMemory(SizeOf(_GUI_PANEL))
CopyMemory(H_PANEL, GUI_PANEL_TEMPBUFFER, SizeOf(_GUI_PANEL))
; // Remove the element from the list
DeleteElement(GUI_LIST_PANEL())
; // Go to the front (end) of the list and add a new element
LastElement(GUI_LIST_PANEL())
AddElement(GUI_LIST_PANEL())
; // Copy data from buffer to new element
GUI_LIST_PANEL()\Header$ = GUI_PANEL_TEMPHEADER$
CopyMemory(GUI_PANEL_TEMPBUFFER, GUI_LIST_PANEL(), SizeOf(_GUI_PANEL))
FreeMemory(GUI_PANEL_TEMPBUFFER)
; // Deactivate old panel, activate new panel
ChangeCurrentElement(GUI_LIST_PANEL(), GUI_PANEL_CURRENT)
GUI_LIST_PANEL()\Active = #False
LastElement(GUI_LIST_PANEL())
GUI_LIST_PANEL()\Active = #True
Here's a guess, from comparing your code sample with the example Fluid byte posted.untune wrote:No problem, I'm not sure what it's down to yet...
Could someone tell me in the following block of code:
Will any of the parameters relating to allocating/copying memory etc have to take into account an offset of 8 bytes for the LL element pointers?Code: Select all
; // Initialise buffer variables Protected GUI_PANEL_TEMPHEADER$ ; // Get the info from the structure, create temporary structure to store it GUI_PANEL_TEMPHEADER$ = GUI_LIST_PANEL()\Header$ GUI_PANEL_TEMPBUFFER = AllocateMemory(SizeOf(_GUI_PANEL)) copy memory(H_PANEL, GUI_PANEL_TEMPBUFFER, SizeOf(_GUI_PANEL)) ; // Remove the element from the list DeleteElement(GUI_LIST_PANEL()) ; // Go to the front (end) of the list and add a new element LastElement(GUI_LIST_PANEL()) AddElement(GUI_LIST_PANEL()) ; // Copy data from buffer to new element GUI_LIST_PANEL()\Header$ = GUI_PANEL_TEMPHEADER$ CopyMemory(GUI_PANEL_TEMPBUFFER, GUI_LIST_PANEL(), SizeOf(_GUI_PANEL)) FreeMemory(GUI_PANEL_TEMPBUFFER) ; // Deactivate old panel, activate new panel ChangeCurrentElement(GUI_LIST_PANEL(), GUI_PANEL_CURRENT) GUI_LIST_PANEL()\Active = #False LastElement(GUI_LIST_PANEL()) GUI_LIST_PANEL()\Active = #True
I'm clutching at straws now but I've run out of ideas
Code: Select all
; // Get the info from the structure, create temporary structure to store it
GUI_PANEL_TEMPHEADER$ = GUI_LIST_PANEL()\Header$
GUI_PANEL_TEMPBUFFER = AllocateMemory(SizeOf(_GUI_PANEL))
;copy memory(H_PANEL, GUI_PANEL_TEMPBUFFER, SizeOf(_GUI_PANEL)) ; <==what is H_PANEL?, information to copy should be in list GUI_LIST_PANEL()
copy memory(GUI_LIST_PANEL(),GUI_PANEL_TEMPBUFFER, SizeOf(_GUI_PANEL))
Code: Select all
; Window Z-Order for Screen GUI (V4)
; Fluid Byte
; August 11, 2008
; Structures
Structure GUI_WINDOW
Sprite1.l
Sprite2.l
X.w
Y.w
Width.w
Height.w
Title.s
Active.b
Dragging.b
EndStructure
Structure GUI_BUTTON
hWnd.l
X.w
Y.w
Width.w
Height.w
Title.s
State.b
EndStructure
; Constants
#GUI_Font_Caption = 0
#GUI_Font_Gadget = 1
#GUI_Font_Icon = 2
; Linked Lists
Global NewList gwin.GUI_WINDOW()
Global NewList gbtn.GUI_BUTTON()
; Global Varibales
Global GUI_CLRFACE = RGB(113,32,32)
Global GUI_CLRHILIGHT = RGB(145,42,42)
Global GUI_CLRLIGHT = RGB(113,32,32)
Global GUI_CLRSHADOW = RGB(88,25,25)
Global GUI_CLRDKSHADOW = RGB(71,20,20)
Global GUI_LASTWINID
Global GUI_MOUSEBLOCK
Global GUI_EVENTMSG
; Resources
LoadFont(#GUI_Font_Caption,"Arial",9,#PB_Font_Bold)
LoadFont(#GUI_Font_Gadget,"Arial",9)
LoadFont(#GUI_Font_Icon,"Marlett",8)
; -------------------------------------------------------------------------------------------
; FUNCTIONS
; -------------------------------------------------------------------------------------------
Procedure GUI_DrawGradient(X,Y,Width,Height,Color1,Color2,Type=0)
Protected i, sRed.f, sGreen.f, sBlue.f, R1.f, G1.f, B1.f, R2.f, G2.f, B2.f, a
If Type : i = Width : Else : i = Height : EndIf
sRed = Red(Color1) : R1 = (Red (Color1) - Red (Color2)) / i
sGreen = Green(Color1) : G1 = (Green(Color1) - Green(Color2)) / i
sBlue = Blue(Color1) : B1 = (Blue (Color1) - Blue (Color2)) / i
For a = 0 To i-1
R2.f = sRed - a * R1
G2.f = sGreen - a * G1
B2.f = sBlue - a * B1
If Type
Line(A + X,Y,0,Height,RGB(R2,G2,B2)) : Continue
EndIf
Line(X,A + Y,Width,0,RGB(R2,G2,B2))
Next
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_DrawRect(X,Y,Width,Height,State=0)
If State
Box(X,Y,Width,Height,GUI_CLRDKSHADOW)
Box(X + 1,Y + 1,Width - 2,Height - 2,GUI_CLRSHADOW)
Box(X + 2,Y + 2,Width - 4,Height - 4,GUI_CLRFACE)
ProcedureReturn 0
EndIf
Box(X,Y,Width,Height,GUI_CLRDKSHADOW)
Box(X,Y,Width - 1,Height - 1,GUI_CLRLIGHT)
Box(X + 1,Y + 1,Width - 2,Height - 2,GUI_CLRSHADOW)
Box(X + 1,Y + 1,Width - 3,Height - 3,GUI_CLRHILIGHT)
Box(X + 2,Y + 2,Width - 4,Height - 4,GUI_CLRFACE)
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_EventGadget()
Protected Result
If GUI_EVENTMSG
Result = GUI_EVENTMSG
GUI_EVENTMSG = 0
ProcedureReturn Result
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_ReleaseMouseBlock()
If MouseButton(1) = 0 : GUI_MOUSEBLOCK = #False : EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_SetActiveWindow(Handle)
If Handle
Protected tmpString.s, hMemBuffer
; * Retrieve Window title and data from element address in memory
tmpString = gwin()\Title
hMemBuffer = AllocateMemory(SizeOf(GUI_WINDOW))
CopyMemory(gwin(),hMemBuffer,SizeOf(GUI_WINDOW))
; * Remove selected element (data has been temporarily saved)
DeleteElement(gwin())
; * Goto end of list and add a new item so it's last and the new topmost window
LastElement(gwin())
AddElement(gwin())
gwin()\Title = tmpString
; * Copy window data to address of new element
CopyMemory(hMemBuffer,gwin(),SizeOf(GUI_WINDOW))
FreeMemory(hMemBuffer)
; * Activte new window, deactivte old window
gwin()\Active = #True : GUI_LASTWINID = gwin()
ChangeCurrentElement(gwin(),Handle)
gwin()\Active = #False
ProcedureReturn 1
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_OpenWindow(X,Y,Width,Height,Title.s)
Width + 2 + 2 : Height + 27 + 2
; * Create active window #1
hsprActive = CreateSprite(#PB_Any,Width,Height,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(hsprActive))
DrawingMode(#PB_2DDrawing_Transparent)
Box(0,0,Width,Height,GUI_CLRDKSHADOW)
Box(0,0,Width - 1,Height - 1,GUI_CLRLIGHT)
Box(1,1,Width - 2,25,GUI_CLRSHADOW)
Box(1,1,Width - 3,24,GUI_CLRHILIGHT)
Box(2,2,Width - 4,23,GUI_CLRLIGHT)
Box(1,26,Width - 2,Height - 27,GUI_CLRSHADOW)
Box(1,26,Width - 3,Height - 28,GUI_CLRHILIGHT)
Box(2,27,Width - 4,Height - 29,GUI_CLRFACE)
GUI_DrawGradient(2,2,Width - 4,23,GUI_CLRSHADOW,GUI_CLRFACE)
GUI_DrawGradient(2,27,Width - 4,Height - 29,GUI_CLRFACE,GUI_CLRSHADOW)
DrawingFont(FontID(#GUI_Font_Icon))
GUI_DrawRect(Width - 23,6,17,16)
DrawText(Width - 20,9,"r",RGB(230,200,180))
DrawingFont(FontID(#GUI_Font_Caption))
DrawText(12,8,Title,RGB(60,0,0))
DrawText(10,6,Title,#White)
StopDrawing()
; * Create inactive window
hsprInactive = CreateSprite(#PB_Any,Width,Height,#PB_Sprite_Memory)
UseBuffer(hsprInactive)
DisplaySprite(hsprActive,0,0)
UseBuffer(#PB_Default)
; * Create active window #2
UseBuffer(hsprActive)
StartSpecialFX()
ClipSprite(hsprActive,0,0,Width,25)
DisplaySprite(hsprActive,0,0)
DisplayRGBFilter(0,0,Width,Height,45,15,0)
ClipSprite(hsprActive,0,25,Width,Height-25)
DisplaySprite(hsprActive,0,25)
ClipSprite(hsprActive,0,0,Width,Height)
StopSpecialFX()
UseBuffer(#PB_Default)
; * Add new List-Element
If GUI_LASTWINID
ChangeCurrentElement(gwin(),GUI_LASTWINID) : gwin()\Active = #False
EndIf
AddElement(gwin())
gwin()\Sprite1 = hsprActive
gwin()\Sprite2 = hsprInactive
gwin()\X = X
gwin()\Y = Y
gwin()\Width = Width
gwin()\Height = Height
gwin()\Title = Title
gwin()\Active = #True
GUI_LASTWINID = gwin()
ProcedureReturn GUI_LASTWINID
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_CloseWindow(Handle)
If Handle
ChangeCurrentElement(gwin(),Handle)
FreeSprite(gwin()\Sprite1)
FreeSprite(gwin()\Sprite2)
DeleteElement(gwin())
If CountList(gwin()) ! 0
LastElement(gwin())
gwin()\Active = 1
GUI_LASTWINID = gwin()
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_GetActiveWindow()
LastElement(gwin())
ProcedureReturn gwin()
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_PushButton(Handle,X,Y,Width,Height,Title.s)
If Handle
AddElement(gbtn())
gbtn()\hWnd = Handle
gbtn()\X = X
gbtn()\Y = Y
gbtn()\Width = Width
gbtn()\Height = Height
gbtn()\Title = Title
ProcedureReturn gbtn()
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GUI_RenderWindows()
Protected WX, WY, WW, WH, MX = MouseX(), MY = MouseY()
Static MTX, MTY
ForEach gwin()
; // DRAW WINDOWS //
WX = gwin()\X : WY = gwin()\Y : WW = gwin()\Width : WH = gwin()\Height
If gwin()\Active
DisplaySprite(gwin()\Sprite1,WX,WY)
Else
DisplaySprite(gwin()\Sprite2,WX,WY)
EndIf
If gwin()\Dragging
gwin()\X = MX + MTX
gwin()\Y = MY + MTY
EndIf
If MouseButton(1) = 0 : gwin()\Dragging = #False : EndIf
; // DRAW GADGETS //
Protected BX, BY, BW, BH
StartDrawing(ScreenOutput())
DrawingFont(FontID(#GUI_Font_Gadget))
DrawingMode(#PB_2DDrawing_Transparent)
ForEach gbtn()
If gbtn()\hwnd = gwin()
BX = WX + 2 + gbtn()\X : BY = WY + 27 + gbtn()\Y : BW = gbtn()\Width : BH = gbtn()\Height
If MX >= BX And MX <= (BX + gbtn()\Width) And MY >= BY And MY <= (BY + gbtn()\Height)
; * First Button Click
If MouseButton(1) And GUI_MOUSEBLOCK = #False
GUI_MOUSEBLOCK = #True
gbtn()\State = 1
EndIf
; * Button pushed and inside Button
If MouseButton(1) And GUI_MOUSEBLOCK = #True And gbtn()\State
gbtn()\State = 1
GUI_DrawRect(BX,BY,BW,BH,1)
DrawText(BX + BW/2 - TextWidth(gbtn()\Title)/2 + 1,BY + BH/2 - TextHeight(gbtn()\Title)/2 + 1,gbtn()\Title,#White)
EndIf
; * Relased mouse inside Button
If MouseButton(1) = 0 And gbtn()\State
GUI_EVENTMSG = gbtn()
gbtn()\State = 0
EndIf
; * Button pushed but cursor outside button
ElseIf gbtn()\State = 1
gbtn()\State = 2
EndIf
; * Draw Buttons
If gbtn()\State = 0 Or gbtn()\State = 2
GUI_DrawRect(BX,BY,BW,BH)
DrawText(BX + BW/2 - TextWidth(gbtn()\Title)/2,BY + BH/2 - TextHeight(gbtn()\Title)/2,gbtn()\Title,#White)
EndIf
; * Reset Button State
If MouseButton(1) = 0 : gbtn()\State = #False : EndIf
EndIf
Next
StopDrawing()
Next
; // MOUSE ACTIVATE //
If CountList(gwin()) ! 0 And MouseButton(1) And GUI_MOUSEBLOCK = #False
GUI_MOUSEBLOCK = #True
; * Cycle through items from back to front
LastElement(gwin())
hMemCurrent = gwin() ; address of last element / first window
Repeat
WX = gwin()\X : WY = gwin()\Y : WW = gwin()\Width : WH = gwin()\Height
If MX >= WX And MX < (WX + WW) And MY >= WY And MY < (WY + WH)
; * Detect Titlebar click
If MY < (WY + 26)
MTX = gwin()\X - MX
MTY = gwin()\Y - MY
gwin()\Dragging = #True
EndIf
; * Exit loop and don't do anything if clicked window is the active one
If gwin() = hMemCurrent : Break : EndIf
GUI_SetActiveWindow(hMemCurrent)
Break ; we found our window, get outta here
EndIf
Until PreviousElement(gwin()) = 0
EndIf
EndProcedure
; *****************************************************************************************
InitSprite() : InitKeyboard() : InitMouse()
#Fullscreen = 0
; Open Screen
If #Fullscreen
OpenScreen(800,600,32,"Fluid's Screen GUI")
Else
OpenWindow(0,0,0,800,600,"Fluid's Screen GUI",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)
EndIf
; Screen GUI Setup
gwinControls = GUI_OpenWindow(620,20,160,265,"Controls")
gbtnCreateWin1 = GUI_PushButton(gwinControls,10,10,140,27,"Create Window # 1")
gbtnCreateWin2 = GUI_PushButton(gwinControls,10,40,140,27,"Create Window # 2")
gbtnCreateWin3 = GUI_PushButton(gwinControls,10,70,140,27,"Create Window # 3")
gbtnDeleteWin1 = GUI_PushButton(gwinControls,10,120,140,27,"Delete Window # 1")
gbtnDeleteWin2 = GUI_PushButton(gwinControls,10,150,140,27,"Delete Window # 2")
gbtnDeleteWin3 = GUI_PushButton(gwinControls,10,180,140,27,"Delete Window # 3")
gbtnExit = GUI_PushButton(gwinControls,10,230,140,27,"Exit")
; Load Pointer
lpBuffer = AllocateMemory(630)
UnpackMemory(?Cursor,lpBuffer)
CatchSprite(0,lpBuffer)
TransparentSpriteColor(0,RGB(0,128,128))
FreeMemory(lpBuffer)
; Make Backdrop Pattern
CreateSprite(1,64,64)
StartDrawing(SpriteOutput(1))
Box(0,0,64,64,60) : Box(32,0,32,32,67) : Box(0,32,32,32,67)
StopDrawing()
; -----------------------------------------------------------------------------------------
; MAIN LOOP
; -----------------------------------------------------------------------------------------
Repeat
; Event Handling
If #Fullscreen = 0
Repeat
EventID = WindowEvent()
Select EventID
Case #PB_Event_CloseWindow
End
EndSelect
Until EventID = 0
EndIf
FlipBuffers() : ClearScreen(50) ; Update Screen
ExamineKeyboard() : ExamineMouse() ; Check Input Devices
; Background Scrolling
Scroll.f + 0.25
For X=0 To 13
For Y=-1 To 9
DisplaySprite(1,X * 64 - Scroll,Y * 64 + Scroll)
Next
Next
If Scroll = 64 : Scroll = 0 : EndIf
; GUI Handling
GUI_RenderWindows()
Select GUI_EventGadget()
Case gbtnCreateWin1
If gwinUntiled1 = 0
gwinUntiled1 = GUI_OpenWindow(10,10,320,240,"Untitled Window #1")
EndIf
Case gbtnCreateWin2
If gwinUntiled2 = 0
gwinUntiled2 = GUI_OpenWindow(40,50,320,240,"Untitled Window #2")
EndIf
Case gbtnCreateWin3
If gwinUntiled3 = 0
gwinUntiled3 = GUI_OpenWindow(80,90,320,240,"Untitled Window #3")
EndIf
Case gbtnDeleteWin1 : GUI_CloseWindow(gwinUntiled1) : gwinUntiled1 = 0
Case gbtnDeleteWin2 : GUI_CloseWindow(gwinUntiled2) : gwinUntiled2 = 0
Case gbtnDeleteWin3 : GUI_CloseWindow(gwinUntiled3) : gwinUntiled3 = 0
Case gbtnExit : End
EndSelect
GUI_ReleaseMouseBlock()
; FPS COunter
Frames + 1
If ElapsedMilliseconds() >= (TimerInit + 1000)
TimerInit = ElapsedMilliseconds()
FPS = Frames : Frames = 0
EndIf
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10,10,"FPS: " + Str(FPS),#White)
StopDrawing()
DisplayTransparentSprite(0,MouseX(),MouseY()) ; Draw Mouse Cursor
If #Fullscreen = 0 : Delay(1) : EndIf ; Save a little CPU
Until KeyboardPushed(1)
; -----------------------------------------------------------------------------------------
; DATA SECTION
; -----------------------------------------------------------------------------------------
DataSection
Cursor:
Data.l $0276434A,$4A720000,$A9B7AACC,$146320D0,$284A6811,$01232023,$9188409D,$F3000461,$20492601,$0A0401E0
Data.l $E00081C0,$FFC0E015,$09302024,$409C3C04,$66013801,$FE4D02B6,$91FB77FB,$B7C236B7,$BDF63086,$BFEC1EC1
Data.l $C0F36107,$0F625EF7,$008A083D,$87FFF581,$C4592A11,$4287C926,$3EC90540,$69F6974F,$21E5E328,$DDDE6107
Data.l $50B353C6,$0FB86C06,$0000D893
Data.b $90,$48
EndDataSection