EditorFactory - Module for object management in a Canvas

Share your advanced PureBasic knowledge/code with the community.
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

Previous example fixed using CountObjectFrames() + 1 as Index (and not the internal counter) for Creating a new Frame
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

Here is a way way to manage the Scroll Bar for the ScrollAreaGadget

With Editor Factory 1.15, In ObjectDrawing_Frame procedure, you have to add the Swap before and after \pDrawingCallback

Code: Select all

Swap \iX, iX : Swap \iY, iY
\pDrawingCallback(\iObject, iWidth, iHeight, \iCallbackData)
Swap \iX, iX : Swap \iY, iY

Code: Select all

; Example_ScrollArea_Gadget.pb

; Includes the program file
XIncludeFile "EditorFactory.pbi"

; Initializes the Module
UseModule EditorFactory

UsePNGImageDecoder()

EnableExplicit

; --------- Example ---------

; Program constants
Enumeration 1
  #Window
  #Canvas
EndEnumeration

; Object constants starting from 1
Enumeration 1
  #Object1
  #Object2
  #Object3
  #Object4
EndEnumeration

; Gadget constants starting from 100
Enumeration 100
  #FakeScrollArea
  #Gadget1
  #Gadget2
  #Gadget3
  #Gadget4
EndEnumeration

#MinSize = 6

Global ImageEdit.i = CatchImage(#PB_Any, ?edit_png)
Global ImageCancel.i = CatchImage(#PB_Any, ?cancel_png)

Macro _FreeCaptureGadget_(Gadget)   ; Free Image to Capture Image without Resizing
  If IsImage(GetGadgetData(Gadget))   
    FreeImage(GetGadgetData(Gadget)) : SetGadgetData(Gadget, #Null)
  EndIf
EndMacro

Procedure.i ScrollAreaBarWidth(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & #WS_VSCROLL)
    ProcedureReturn GetSystemMetrics_(#SM_CXVSCROLL)                     ; 17
  EndIf
EndProcedure

Procedure.i ScrollAreaBorderWidth(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $200)         ;no Flag or #PB_ScrollArea_Center
    ProcedureReturn GetSystemMetrics_(#SM_CXEDGE)                    ; 2
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $800000)    ;#PB_ScrollArea_Flat
    ProcedureReturn GetSystemMetrics_(#SM_CXBORDER)                  ;1
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $400000)    ;#PB_ScrollArea_Raised
    ProcedureReturn GetSystemMetrics_(#SM_CXFIXEDFRAME)              ;3
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $20000)   ;#PB_ScrollArea_Single
    ProcedureReturn GetSystemMetrics_(#SM_CXBORDER)                  ;1
  EndIf
EndProcedure

Procedure.i ScrollAreaVisibleWidth(Gadget.i)
  ; https://www.purebasic.fr/english/viewtopic.php?p=503690#p503690
  Protected Result.i = GadgetWidth(Gadget)
  CompilerIf (#PB_Compiler_OS = #PB_OS_Windows)
    CompilerIf (#False) ; srod's simple version
      Protected r.RECT
      GetClientRect_(GadgetID(Gadget), @r)
      Result = r\right - r\left
    CompilerElse
      Result - 2 * ScrollAreaBorderWidth(Gadget)
      Result - ScrollAreaBarWidth(Gadget)
    CompilerEndIf
  CompilerElse
    Result - 2 * 2
  CompilerEndIf
  ProcedureReturn (Result)
EndProcedure

Procedure.i ScrollAreaBarHeight(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & #WS_HSCROLL)
    ProcedureReturn GetSystemMetrics_(#SM_CYHSCROLL)                     ; 17
  EndIf
EndProcedure

Procedure.i ScrollAreaBorderHeight(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $200)             ;no Flag or #PB_ScrollArea_Center
    ProcedureReturn GetSystemMetrics_(#SM_CYEDGE)                        ; 2
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $800000)        ;#PB_ScrollArea_Flat
    ProcedureReturn GetSystemMetrics_(#SM_CYBORDER)                      ;1
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $400000)        ;#PB_ScrollArea_Raised
    ProcedureReturn GetSystemMetrics_(#SM_CYFIXEDFRAME)                  ;3
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $20000)       ;#PB_ScrollArea_Single
    ProcedureReturn GetSystemMetrics_(#SM_CYBORDER)                      ;1
  EndIf
EndProcedure

Procedure.i ScrollAreaVisibleHeight(Gadget.i)
  ; https://www.purebasic.fr/english/viewtopic.php?p=503690#p503690
  Protected Result.i = GadgetHeight(Gadget)
  CompilerIf (#PB_Compiler_OS = #PB_OS_Windows)
    CompilerIf (#True) ; srod's simple version
      Protected r.RECT
      GetClientRect_(GadgetID(Gadget), @r)
      Result = r\bottom - r\top
    CompilerElse
      Result - 2 * ScrollAreaBorderHeight(Gadget)
      Result - ScrollAreaBarHeight(Gadget)
    CompilerEndIf
  CompilerElse
    Result - 2 * 2
  CompilerEndIf
  ProcedureReturn (Result)
EndProcedure

;- ----------------
;{ ----------------------------------------------
; CaptureGadget: The message WM_PRINT is sent to a Gadget to request it to be drawn in a picture
; Need some Specific for: SpinGadget (Part1), ComboBoxGadget, EditorGadget, ExplorerComboGadget, SpinGadget (Part2) - (See IceDesign CaptureGadget procedure)
;}
Procedure CaptureGadget(Gadget.i)
  Protected Image.i, hDC.i
  If GadgetWidth(Gadget) > 0 And GadgetHeight(Gadget) > 0
    Image = CreateImage(#PB_Any,GadgetWidth(Gadget),GadgetHeight(Gadget))
    If IsGadget(Gadget)
      hDC =  StartDrawing(ImageOutput(Image))
      If hDC
        DrawingMode(#PB_2DDrawing_Default)
        Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)   ; Gadget_BackColor
        SendMessage_(GadgetID(Gadget),#WM_PRINT,hDC, #PRF_CHILDREN|#PRF_CLIENT|#PRF_NONCLIENT|#PRF_OWNED|#PRF_ERASEBKGND)
        StopDrawing()
      EndIf
    EndIf
  EndIf
  ProcedureReturn Image
EndProcedure

;{ ----------------------------------------------
; Callback procedure to draw on the object
;   Object.i is the number of the object, you can use it to get properties of the currently drawn object
;   Width.i is the current width of the object
;   Height.i is the current height of the object
;   iData.i is a custom data value set in SetObjectDrawingCallback, here it is used as the color
; This procedure will automatically called during the draw of the Object
;}
Procedure ObjectDrawing(Object.i, Width.i, Height.i, iData.i)   ; Draw Captured Image + Border
  Protected Image.i, Resize.b, OffSetX.i, OffSetY.i, DeFlickerFakeScrollArea.b
  ;Debug "ObjectDrawing(" + Str(Object) + ", " + Str(Width) + ", " + Str(Height) + ", " + Str(iData) + ")"
  AddPathBox(0.5, 0.5, Width-1, Height-1)
  If IsGadget(iData)
    If GadgetType(iData) = #PB_GadgetType_ScrollArea
      If IsWindowVisible_(GadgetID(#FakeScrollArea))
        DeFlickerFakeScrollArea = #True
        SendMessage_(WindowID(#Window), #WM_SETREDRAW, #False, 0)
      EndIf
      If GadgetX(iData) <> GetObjectX(Object) Or GadgetY(iData) <> GetObjectY(Object) Or GadgetWidth(iData) <> Width Or GadgetHeight(iData) <> Height
        ResizeGadget(#FakeScrollArea, GetObjectX(Object), GetObjectY(Object), Width, Height)
      EndIf
    EndIf
    If GadgetWidth(iData) <> Width Or GadgetHeight(iData) <> Height
      ResizeGadget(iData, #PB_Ignore, #PB_Ignore, Width, Height)
      Resize = #True
    EndIf
    If IsImage(GetGadgetData(iData))
      If Resize
        FreeImage(GetGadgetData(iData))
        Image = CaptureGadget(iData)
        SetGadgetData(iData, Image)
      Else
        Image = GetGadgetData(iData)
      EndIf
    Else
      Image = CaptureGadget(iData)
      SetGadgetData(iData, Image)
    EndIf
    ;DrawVectorImage(ImageID(Image))
    VectorSourceImage(ImageID(Image), 230, Width, Height) : FillPath(#PB_Path_Preserve)
  Else
    VectorSourceColor($804080C0)
    FillPath(#PB_Path_Preserve)
  EndIf
  If ObjectState(Object) = #State_Selected
    VectorSourceColor($A80000FF)
  Else
    VectorSourceColor($80FF0000)
  EndIf
  StrokePath(1)
  If  DeFlickerFakeScrollArea = #True
    SendMessage_(WindowID(#Window), #WM_SETREDRAW, #True, 0)
    ;RedrawWindow_(WindowID(#Window), #Null, #Null, #RDW_INVALIDATE)
  EndIf
EndProcedure

Procedure BindScrollArea()
  Protected Gadget.i, Object.i 
  Object = GetGadgetData(EventGadget())
  Gadget = GetObjectData(Object)
  SetGadgetAttribute(Gadget, #PB_ScrollArea_X, GetGadgetAttribute(#FakeScrollArea, #PB_ScrollArea_X)) : SetGadgetAttribute(Gadget, #PB_ScrollArea_Y, GetGadgetAttribute(#FakeScrollArea, #PB_ScrollArea_Y))
  _FreeCaptureGadget_(Gadget)
  SetObjectFrameOffset(Object, -GetGadgetAttribute(Gadget, #PB_ScrollArea_X)+ScrollAreaBorderWidth(Gadget), -GetGadgetAttribute(Gadget, #PB_ScrollArea_Y)+ScrollAreaBorderHeight(Gadget))
EndProcedure

;{ ----------------------------------------------
; Create and Set Object
; Gadget is the GadgetID 
; Object is the number of the object
; ParentObject is the number of the Parent Object
; FrameIndex An index of the frame (starting with 1) in which the object should attached (optional)
;
; Set Properties: ObjectData (Gadget), ObjectBoundaries (#Boundary_ParentSize, MinWidth 6, MinHeight 6), ObjectDrawingCallback (iData=Gadget),
; AddObjectHandle (#Handle_Size|#Handle_Position), SetObjectCursor (#PB_Cursor_Hand), ObjectHandleDisplayMode (#Handle_ShowIfSelected)
;}
Procedure CreateSetObject(Gadget.i, Object.i, ParentObject.i=#PB_Default, FrameIndex.i=#PB_Default)
  Protected Parent.i
  CreateObject(#Canvas, Object, GadgetX(Gadget), GadgetY(Gadget), GadgetWidth(Gadget), GadgetHeight(Gadget), ParentObject, FrameIndex)
  SetObjectData(Object, Gadget)
  If GadgetType(Gadget) = #PB_GadgetType_ScrollArea
    AddObjectHandle(Object, #Handle_Custom1, ImageEdit, #Alignment_Bottom | #Alignment_Right, -16, 4)
    SetObjectFrameOffset(Object, ScrollAreaBorderWidth(Gadget), ScrollAreaBorderHeight(Gadget))
    SetObjectFrameClipping(Object, #True, 0, 0, ScrollAreaBarWidth(Gadget) + ScrollAreaBorderWidth(Gadget), ScrollAreaBarHeight(Gadget) + ScrollAreaBorderHeight(Gadget))   ; 2*ScrollAreaBorder - ScrollAreaBorder
  EndIf
  If ParentObject <> #PB_Default And IsGadget(GetObjectData(ParentObject))
    Parent = GetObjectData(ParentObject)
    If GadgetType(Parent) = #PB_GadgetType_ScrollArea
      SetObjectBoundaries(Object, 0, 0, GetGadgetAttribute(Parent, #PB_ScrollArea_InnerWidth)-ScrollAreaBorderWidth(Gadget), GetGadgetAttribute(Parent, #PB_ScrollArea_InnerHeight)-ScrollAreaBorderHeight(Gadget), #MinSize, #MinSize)   ; Set the Boundaries MaxX MaxY to the parent contained scrollable area
    EndIf
  EndIf
  ;AddObjectHandle(Object, #Handle_Size | #Handle_Position)
  ;ObjectHandleDisplayMode(Object, #Handle_ShowIfSelected)
  SetObjectDrawingCallback(Object, @ObjectDrawing(), Gadget)
  SetObjectCursor(Object, #PB_Cursor_Hand)
EndProcedure

;- ----- Main -----
Define Gadget.i

; Create a window
OpenWindow(#Window, 0, 0, 680, 500, "Example Captured ScrollArea Gadget Objects", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

; The Fake ScrollArea must be created before the canvas. It is used when editing the ScrollArea with Operational ScrollBar
ScrollAreaGadget(#FakeScrollArea, 0, 0, 0, 0, 0, 0)
CloseGadgetList()
HideGadget(#FakeScrollArea, #True)
BindGadgetEvent(#FakeScrollArea, @BindScrollArea())

; Create a canvas gadget
CanvasGadget(#Canvas, 0, 0, WindowWidth(#Window), WindowHeight(#Window), #PB_Canvas_Keyboard)

; Initializes the object management for the canvas gadget
If Not InitializeCanvasObjects(#Canvas, #Window)
  Debug "Unable to initialize the object manager !"
EndIf

SetCursorSelectionStyle(#Canvas, #SelectionStyle_Solid|#SelectionStyle_Partially, RGBA(0, 128, 255, 255), 1, RGBA(0, 128, 255, 25))
SetObjectSelectionStyle(#Object_Default, #SelectionStyle_Dashed, $A80000FF, 1, #SelectionStyle_Ignore)
SetObjectBoundaries(#Object_Default, 0, 0, #Boundary_ParentSize, #Boundary_ParentSize, #MinSize, #MinSize)   ; Set the boundaries to the parent size by default
AddObjectHandle(#Object_Default, #Handle_Size | #Handle_Position)
ObjectHandleDisplayMode(#Object_Default, #Handle_ShowIfSelected)
;SetObjectDrawingCallback(#Object_Default, @ObjectDrawing(), Gadget)
;SetObjectCursor(#Object_Default, #PB_Cursor_Hand)

ScrollAreaGadget(#Gadget1, 120, 100, 440, 300, 620, 450, 10)
CloseGadgetList()
HideGadget(#Gadget1, #True)
CreateSetObject(#Gadget1, #Object1)

ButtonGadget(#Gadget2, 40, 40, 200, 60, "Button_1") : HideGadget(#Gadget2, #True)
CreateSetObject(#Gadget2, #Object2, #Object1, 1)

ButtonGadget(#Gadget3, 360, 160, 200, 60, "Button_2") : HideGadget(#Gadget3, #True)
CreateSetObject(#Gadget3, #Object3, #Object1, 1)

; The window's event loop
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow                   ; Exit the program.
      Break
      
    Case #PB_Event_Gadget                        ;-> Event Gadget
  EndSelect
  
  ; Event loop of the objects in the canvas gadget
  Repeat
    Select CanvasObjectsEvent(#Canvas)           ; Something happened in the canvas.
      Case #Event_Handle                         ;-> Event Handle
        Select CanvasObjectsEventType(#Canvas)   ; What type of Events happened on the Handle ?
          Case #EventType_LeftMouseClick
            Select EventHandle(#Canvas)
              Case #Handle_Custom1
                If IsWindowVisible_(GadgetID(#FakeScrollArea))   ; Or With SetGadgetData(#FakeScrollArea, 0|1) -> If GetGadgetData(#FakeScrollArea)
                  AddObjectHandle(EventObject(#Canvas), #Handle_Custom1, ImageEdit, #Alignment_Bottom | #Alignment_Right, -16, 4)
                  HideGadget(#FakeScrollArea, #True)
                Else
                  Gadget = GetObjectData(EventObject(#Canvas))
                  ResizeGadget(#FakeScrollArea, GadgetX(Gadget), GadgetY(Gadget), GadgetWidth(Gadget), GadgetHeight(Gadget))
                  SetGadgetAttribute(#FakeScrollArea, #PB_ScrollArea_InnerWidth, GetGadgetAttribute(Gadget, #PB_ScrollArea_InnerWidth))
                  SetGadgetAttribute(#FakeScrollArea, #PB_ScrollArea_InnerHeight, GetGadgetAttribute(Gadget, #PB_ScrollArea_InnerHeight))
                  SetGadgetAttribute(#FakeScrollArea, #PB_ScrollArea_ScrollStep, GetGadgetAttribute(Gadget, #PB_ScrollArea_ScrollStep))
                  AddObjectHandle(EventObject(#Canvas), #Handle_Custom1, ImageCancel, #Alignment_Bottom | #Alignment_Right, -16, 4)
                  HideGadget(#FakeScrollArea, #False)
                EndIf
            EndSelect
        EndSelect
        
      Case #Event_Object                         ;-> Event Object
        Select CanvasObjectsEventType(#Canvas)   ; What type of events happened on the object?
          Case #EventType_Selected
            ;Debug "Object " + EventObject(#Canvas) + " has been Selected. Put Object on Top."
            SetObjectLayer(EventObject(#Canvas), -1, #PB_Absolute)   ; Push to the last layer (-1), on Top
            If GadgetType(GetObjectData(EventObject(#Canvas))) = #PB_GadgetType_ScrollArea
              SetGadgetData(#FakeScrollArea, EventObject(#Canvas))
            EndIf
            
          Case #EventType_Unselected
            If GadgetType(GetObjectData(EventObject(#Canvas))) = #PB_GadgetType_ScrollArea
              AddObjectHandle(EventObject(#Canvas), #Handle_Custom1, ImageEdit, #Alignment_Bottom | #Alignment_Right, -16, 4)
              HideGadget(#FakeScrollArea, #True)
            EndIf
            
          Case #EventType_Moved,  #EventType_Resized
            Gadget = GetObjectData(EventObject(#Canvas))
            Debug "Gadget " + Gadget + " (" +
                  GetObjectX(EventObject(#Canvas), #Object_LocalPosition) + ", " + GetObjectY(EventObject(#Canvas), #Object_LocalPosition)  + ", " +
                  GetObjectWidth(EventObject(#Canvas)) + ", " + GetObjectHeight(EventObject(#Canvas)) + ") Moved or Resized"
            ResizeGadget(Gadget, GetObjectX(EventObject(#Canvas), #Object_LocalPosition), GetObjectY(EventObject(#Canvas), #Object_LocalPosition), GetObjectWidth(EventObject(#Canvas)), GetObjectHeight(EventObject(#Canvas)))
            
        EndSelect                                ; CanvasObjectsEventType(#Canvas)
        
      Case #Event_None                           ; No Events.
        Break
    EndSelect                                    ; CanvasObjectsEvent(#Canvas)
  ForEver
  
ForEver

End

; Data section for the icon licensed under a Creative Commons Attribution 3.0 License. https://github.com/gammasoft/fatcow
DataSection
  edit_png:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$5845741900000061
  Data.q $72617774666F5374,$2065626F64410065,$6165526567616D49,$00003C65C9717964,$DA78544144495202
  Data.q $FE145114485D539C,$A8B70DB75D1DCCEE,$2221F1FA53458B74,$ED8B20882087DAB0,$A22B220894A7CA47
  Data.q $487CB10C11628A87,$2822494C082A7C62,$A4AD07C36B685C89,$D5B6C20A8B5F0B45,$99FDB775A5D9B6C5
  Data.q $C88C0B66759DEE99,$B9CE77CE7381FDC3,$549506AEB8873DDF,$9223FF1D34E67556,$E38394E3112F6040
  Data.q $EA795E7118B17B1D,$470C217D93E666A4,$1ABDDEF7100FF200,$61A6A58E03DC7DB8,$E87995B4D5D04238
  Data.q $E0DF0E1484282D7C,$254C103A7FA3A584,$5F2EE0897F348553,$6A02446A858A9D02,$037C1B686D6B7AFA
  Data.q $82D436FDFD4B1491,$AF8471F2C7819500,$8F7982ACA25A473D,$400B024B21CB5DAE,$33408D391D9E550C
  Data.q $F7AF818D996184A0,$C51C26604F9B20C8,$FB633E601617C8A7,$380A8CA43E86048B,$204EE638A5C6D0E8
  Data.q $295288244E859D1C,$B87399ECE18E5F46,$4A1C0B6C4F0BD033,$8B39FBF1FD64D414,$7EC49A3DB5B2C244
  Data.q $F66542F3EC3437FB,$B90C94F971AB17B7,$FA0C10DBF53C3EEF,$B187E450841D5721,$E862C2B3E465BECF
  Data.q $09CF189681027D60,$7CA2D787ED87585D,$07F2182BD69A3CF2,$18AE4CD283DDDDD0,$EB378D41C2A2E4C0
  Data.q $03697E303A8D0482,$4A02CEBE02A91C76,$2DE03C6803FCAF02,$FF13F78018B55440,$6219DD8D06D39746
  Data.q $202E8D3C3340B2C7,$95D7CDC19F7C0D3C,$656D365C88FFED68,$0F7C157EB9A0FAB5,$EAA61942F3B60DC7
  Data.q $C45F58C76CA3815A,$8BD2DD50B90ADC64,$3629AF71A8678127,$C6350D9D2E0A1F12,$E7A45625475EE536
  Data.q $E2562777039367B0,$F8548A0705BBFF74,$69AD3B1C94FC8C1E,$37D3ED1DA967E564,$B27700EA5A2CB540
  Data.q $106335100FFCB613,$51C972CB839A5BCC,$F12716160F96BE9E,$05D20DBF000C025F,$00000000F62B0208
  Data.q $826042AE444E4549
  cancel_png:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$4752730100000061
  Data.q $0000E91CCEAE0042,$0000414D41670400,$00000561FC0B8FB1,$0000735948700900,$C701C30E0000C30E
  Data.q $490F02000064A86F,$5F937D4F38544144,$36F73FC71C515348,$11A82D0F42682A2B,$7A2D920F91AD7161
  Data.q $B8F66B88587A8228,$97A0A87A40920E5A,$05293CFED27A2C12,$75356C087A4A30CD,$2411512F65723482
  Data.q $CAB9CB12DA843D45,$A63DDB9EEDD8FEC6,$3E7F7F73970BEB6E,$B9FA28E7B9CE7BDF,$FD78AF2392863A13
  Data.q $55161136BECF1A79,$D729D9D7DB0CF064,$D24206733058CCAA,$629FE656B7B3CF64,$F94CABD1600B2ABB
  Data.q $13D042C90A4CBADC,$161450D2337032B2,$517E7D35BB1E55B3,$B834706F42243648,$A2F7CF2B9662C28A
  Data.q $2CD129051091170A,$F58CCBAEA07052A0,$CA56E100D8AA0A25,$FCD3CBBFAC1C3164,$50D9974806976334
  Data.q $44D45A27BAB0B6B1,$7DCCC09C68EEC248,$98F9DB944C156D94,$4FCD0F6628186EFE,$0B99C244D8B8E652
  Data.q $927E3C1075B4B4ED,$5F7249A3926EFBD0,$E633779E9E2D5027,$A258BBC44D2DA728,$3A37257F59C03FBD
  Data.q $C7DF3441DAAEA9BB,$722852C0CC66A756,$86318362859AC16C,$B7C6A0AE9F897AF6,$927378714F2FD591
  Data.q $2CB1AF5B5A5EE107,$F11C90EA506BFB93,$4EF5DD89BFACA43D,$DBE1E2290A349F18,$2CECFA7D9A0F6B78
  Data.q $FB9347E129E3B16A,$BEA60258C075E9D9,$C81F5BC696BC3ED0,$27858B0D47E6D365,$6B49F1EF6B47C251
  Data.q $AE860BF6F83A9A84,$9E89DFD381DCF1D2,$5C16F5CF0E19E149,$CD621CB4EE0F7926,$72BAE8AB5C071716
  Data.q $3048F60B4B230D9D,$6428A89BCD8481A6,$3BF6C65C4E682B6D,$3CB22F3FF5835F8B,$F11302A681BE83FF
  Data.q $AFFE8CDD8F193717,$49CF07F04F38D617,$0000FD8D1F2B242A,$42AE444E45490000
EndDataSection
Last edited by ChrisR on Wed Feb 03, 2021 6:47 pm, edited 2 times in total.
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: EditorFactory - Module for object management in a Canvas

Post by ShadowStorm »

Hello, ChrisR.

Good example, that's not bad :D

There are still some small bugs but it's not bad at all.
I encourage you to improve :)
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

Hello Shadow,

The Panel Gadget example looks good

For the ScrollArea, there are some display issues when resizing.
Some data is missing in the DrawingCallback procedure to reposition the scrollbars and redefine the offsets.
*Object\iX, *Object\iY is not up to date at that time and I don't get the values with GetObjectX(Object), GetObjectY(Object).

Is it possible to Add them ? something like this in the ObjectDrawing_Frame procedure:

Code: Select all

Swap \iX, iX : Swap \iY, iY
\pDrawingCallback(\iObject, iWidth, iHeight, \iCallbackData)
Swap \iX, iX : Swap \iY, iY
It's just an example of a possible ways.
I will wait for the next version and new features, EditorFactory has a big potential :D
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: EditorFactory - Module for object management in a Canvas

Post by ShadowStorm »

Hi Stargate, okay, I've been thinking about additions.

It would need a command, to disable / enable, the possibility to select the object with the mouse selection.

And also commands to return if the object is selectable or not with the mouse selection square, I explain.

It is useful if you don't want an object to be selectable with mouse selection square, be careful, it has nothing to do with selection of the object itself (the object selection border).

It means that an object will be able to show or not show its selection border if the object is selected or if I click on the object, like here, no change.

But if I disable the possibility that the object is selected with the mouse selection border, then the object is not taken into account if I select it with the mouse.

So if for example I select objects and one of them is not "selectable", then this one is not taken into account in the selection, and if I move objects, those that are not selectable will not move, because they will not be "selectable" with the mouse selection box, do you understand what I mean?

For example it can be used to create scrollbars, the bars will not be "selectable" with the mouse selection box.

Imagine for example that I select objects and "scrollbars" objects with the mouse selection box, then the "scrollbars" will not be selected.

Well, I think you get the point.

Now I also need another function to change the display of the mouse selection on the objects, currently the selection overlaps the objects, I would like a function so that the selection goes below the object and not above it.

You see, it can also be used to make scroll bars, because that way the mouse selection will go under the bar and not over it!

I hope you understand what I'm saying.

@ChrisR, this is especially for you ;)

Editors Factory is only at the beginning of these possibilities, it will grow, and become a bulldozer and all broken !!!
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

A new example of the ScollArea Gadget Captured with scrolling arrows attached
The previous example with real scrollbars is not good with gadgets overlay

Edit: change the arrow images

Code: Select all

; Example_ScrollArea_Arrow_Gadget.pb

; Includes the program file
XIncludeFile "EditorFactory.pbi"

; Initializes the Module
UseModule EditorFactory

UsePNGImageDecoder()

EnableExplicit

; --------- Example ---------

; Program constants
Enumeration 1
  #Window
  #Canvas
EndEnumeration

; Object constants starting from 1
Enumeration 1
  #Object1
  #Object2
  #Object3
  #Object4
EndEnumeration

; Gadget constants starting from 100
Enumeration 100
  #Gadget1
  #Gadget2
  #Gadget3
  #Gadget4
EndEnumeration

#MinSize = 6

Macro _FreeCaptureGadget_(Gadget)   ; Free Image to Capture Image without Resizing
  If IsImage(GetGadgetData(Gadget))   
    FreeImage(GetGadgetData(Gadget)) : SetGadgetData(Gadget, #Null)
  EndIf
EndMacro

Procedure.i ScrollAreaBarWidth(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & #WS_VSCROLL)
    ProcedureReturn GetSystemMetrics_(#SM_CXVSCROLL)                     ; 17
  EndIf
EndProcedure

Procedure.i ScrollAreaBorderWidth(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $200)         ;no Flag or #PB_ScrollArea_Center
    ProcedureReturn GetSystemMetrics_(#SM_CXEDGE)                    ; 2
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $800000)    ;#PB_ScrollArea_Flat
    ProcedureReturn GetSystemMetrics_(#SM_CXBORDER)                  ;1
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $400000)    ;#PB_ScrollArea_Raised
    ProcedureReturn GetSystemMetrics_(#SM_CXFIXEDFRAME)              ;3
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $20000)   ;#PB_ScrollArea_Single
    ProcedureReturn GetSystemMetrics_(#SM_CXBORDER)                  ;1
  EndIf
EndProcedure

Procedure.i ScrollAreaVisibleWidth(Gadget.i)
  ; https://www.purebasic.fr/english/viewtopic.php?p=503690#p503690
  Protected Result.i = GadgetWidth(Gadget)
  CompilerIf (#PB_Compiler_OS = #PB_OS_Windows)
    CompilerIf (#False) ; srod's simple version
      Protected r.RECT
      GetClientRect_(GadgetID(Gadget), @r)
      Result = r\right - r\left
    CompilerElse
      Result - 2 * ScrollAreaBorderWidth(Gadget)
      Result - ScrollAreaBarWidth(Gadget)
    CompilerEndIf
  CompilerElse
    Result - 2 * 2
  CompilerEndIf
  ProcedureReturn (Result)
EndProcedure

Procedure.i ScrollAreaBarHeight(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & #WS_HSCROLL)
    ProcedureReturn GetSystemMetrics_(#SM_CYHSCROLL)                     ; 17
  EndIf
EndProcedure

Procedure.i ScrollAreaBorderHeight(Gadget.i)
  Protected Result.i
  If (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $200)             ;no Flag or #PB_ScrollArea_Center
    ProcedureReturn GetSystemMetrics_(#SM_CYEDGE)                        ; 2
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $800000)        ;#PB_ScrollArea_Flat
    ProcedureReturn GetSystemMetrics_(#SM_CYBORDER)                      ;1
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_STYLE) & $400000)        ;#PB_ScrollArea_Raised
    ProcedureReturn GetSystemMetrics_(#SM_CYFIXEDFRAME)                  ;3
  ElseIf (GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & $20000)       ;#PB_ScrollArea_Single
    ProcedureReturn GetSystemMetrics_(#SM_CYBORDER)                      ;1
  EndIf
EndProcedure

Procedure.i ScrollAreaVisibleHeight(Gadget.i)
  ; https://www.purebasic.fr/english/viewtopic.php?p=503690#p503690
  Protected Result.i = GadgetHeight(Gadget)
  CompilerIf (#PB_Compiler_OS = #PB_OS_Windows)
    CompilerIf (#True) ; srod's simple version
      Protected r.RECT
      GetClientRect_(GadgetID(Gadget), @r)
      Result = r\bottom - r\top
    CompilerElse
      Result - 2 * ScrollAreaBorderHeight(Gadget)
      Result - ScrollAreaBarHeight(Gadget)
    CompilerEndIf
  CompilerElse
    Result - 2 * 2
  CompilerEndIf
  ProcedureReturn (Result)
EndProcedure

;{ ----------------------------------------------
; CaptureGadget: The message WM_PRINT is sent to a Gadget to request it to be drawn in a picture
; Need some Specific for: SpinGadget (Part1), ComboBoxGadget, EditorGadget, ExplorerComboGadget, SpinGadget (Part2) - (See IceDesign CaptureGadget procedure)
;}
Procedure CaptureGadget(Gadget.i)
  Protected Image.i, hDC.i
  If GadgetWidth(Gadget) > 0 And GadgetHeight(Gadget) > 0
    Image = CreateImage(#PB_Any,GadgetWidth(Gadget),GadgetHeight(Gadget))
    If IsGadget(Gadget)
      hDC =  StartDrawing(ImageOutput(Image))
      If hDC
        DrawingMode(#PB_2DDrawing_Default)
        Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)   ; Gadget_BackColor
        SendMessage_(GadgetID(Gadget),#WM_PRINT,hDC, #PRF_CHILDREN|#PRF_CLIENT|#PRF_NONCLIENT|#PRF_OWNED|#PRF_ERASEBKGND)
        StopDrawing()
      EndIf
    EndIf
  EndIf
  ProcedureReturn Image
EndProcedure

;{ ----------------------------------------------
; Callback procedure to draw on the object
;   Object.i is the number of the object, you can use it to get properties of the currently drawn object
;   Width.i is the current width of the object
;   Height.i is the current height of the object
;   iData.i is a custom data value set in SetObjectDrawingCallback, here it is used as the color
; This procedure will automatically called during the draw of the Object
;}
Procedure ObjectDrawing(Object.i, Width.i, Height.i, iData.i)   ; Draw Captured Image + Border
  Protected Image.i, Resize.b, OffSetX.i, OffSetY.i
  ;Debug "ObjectDrawing : (" + Str(Object) + ", " + Str(Width) + ", " + Str(Height) + ", " + Str(iData) + ")"
  AddPathBox(0.5, 0.5, Width-1, Height-1)
  If IsGadget(iData)
    If GadgetWidth(iData) <> Width Or GadgetHeight(iData) <> Height
      ResizeGadget(iData, #PB_Ignore, #PB_Ignore, Width, Height)
      If GadgetType(iData) = #PB_GadgetType_ScrollArea
        SetObjectFrameOffset(Object, -GetGadgetAttribute(iData, #PB_ScrollArea_X)+ScrollAreaBorderWidth(iData), -GetGadgetAttribute(iData, #PB_ScrollArea_Y)+ScrollAreaBorderHeight(iData))
      EndIf
      Resize = #True
    EndIf
    If IsImage(GetGadgetData(iData))
      If Resize
        FreeImage(GetGadgetData(iData))
        Image = CaptureGadget(iData)
        SetGadgetData(iData, Image)
      Else
        Image = GetGadgetData(iData)
      EndIf
    Else
      Image = CaptureGadget(iData)
      SetGadgetData(iData, Image)
    EndIf
    ;DrawVectorImage(ImageID(Image))
    VectorSourceImage(ImageID(Image), 230, Width, Height) : FillPath(#PB_Path_Preserve)
  Else
    VectorSourceColor($804080C0)
    FillPath(#PB_Path_Preserve)
  EndIf
  If ObjectState(Object) = #State_Selected
    VectorSourceColor($A80000FF)
  Else
    VectorSourceColor($80FF0000)
  EndIf
  StrokePath(1)
EndProcedure

;{ ----------------------------------------------
; Create and Set Object
; Gadget is the GadgetID 
; Object is the number of the object
; ParentObject is the number of the Parent Object
; FrameIndex An index of the frame (starting with 1) in which the object should attached (optional)
;
; Set Properties: ObjectData (Gadget), ObjectBoundaries (#Boundary_ParentSize, MinWidth 6, MinHeight 6), ObjectDrawingCallback (iData=Gadget),
; AddObjectHandle (#Handle_Size|#Handle_Position), SetObjectCursor (#PB_Cursor_Hand), ObjectHandleDisplayMode (#Handle_ShowIfSelected)
;}
Procedure CreateSetObject(Gadget.i, Object.i, ParentObject.i=#PB_Default, FrameIndex.i=#PB_Default)
  Protected Parent.i
  CreateObject(#Canvas, Object, GadgetX(Gadget), GadgetY(Gadget), GadgetWidth(Gadget), GadgetHeight(Gadget), ParentObject, FrameIndex)
  SetObjectData(Object, Gadget)
  If GadgetType(Gadget) = #PB_GadgetType_ScrollArea
    ;AddObjectHandle(Object, #Handle_Custom1, CatchImage(#PB_Any, ?arrow_left_png) , #Alignment_Bottom | #Alignment_Left ,  16, -10)
    ;AddObjectHandle(Object, #Handle_Custom2, CatchImage(#PB_Any, ?arrow_right_png), #Alignment_Bottom | #Alignment_Right, -32, -10)
    ;AddObjectHandle(Object, #Handle_Custom3, CatchImage(#PB_Any, ?arrow_up_png)   , #Alignment_Top | #Alignment_Right   , -10,  16)
    ;AddObjectHandle(Object, #Handle_Custom4, CatchImage(#PB_Any, ?arrow_down_png) , #Alignment_Bottom | #Alignment_Right, -10, -32)
    ; How to get the right position ? (Image size 16)
    AddObjectHandle(Object, #Handle_Custom1, CatchImage(#PB_Any, ?arrow_left_png) , #Alignment_Bottom | #Alignment_Left , ScrollAreaBorderWidth(Gadget) + GetSystemMetrics_(#SM_CXHTHUMB) - 16/2                                , -(ScrollAreaBorderHeight(Gadget) + Int(ScrollAreaBarHeight(Gadget)/2))                                   )   ;  11, -10
    AddObjectHandle(Object, #Handle_Custom2, CatchImage(#PB_Any, ?arrow_right_png), #Alignment_Bottom | #Alignment_Right, -(ScrollAreaBorderWidth(Gadget) + ScrollAreaBarWidth(Gadget)  + GetSystemMetrics_(#SM_CXHTHUMB) -16/2), -(ScrollAreaBorderHeight(Gadget) + Int(ScrollAreaBarHeight(Gadget)/2))                                   )   ; -28, -10
    AddObjectHandle(Object, #Handle_Custom3, CatchImage(#PB_Any, ?arrow_up_png)   , #Alignment_Top | #Alignment_Right   , -(ScrollAreaBorderWidth(Gadget) + Int(ScrollAreaBarWidth(Gadget)/2))                                  , ScrollAreaBorderHeight(Gadget) + GetSystemMetrics_(#SM_CYVTHUMB) - 16/2                                  )   ; -10,  11
    AddObjectHandle(Object, #Handle_Custom4, CatchImage(#PB_Any, ?arrow_down_png) , #Alignment_Bottom | #Alignment_Right, -(ScrollAreaBorderWidth(Gadget) + Int(ScrollAreaBarWidth(Gadget)/2))                                  , -(ScrollAreaBorderHeight(Gadget) + ScrollAreaBarHeight(Gadget)  + GetSystemMetrics_(#SM_CYVTHUMB) -16/2) )   ; -10, -28 
    
    SetObjectFrameOffset(Object, ScrollAreaBorderWidth(Gadget), ScrollAreaBorderHeight(Gadget))
    SetObjectFrameClipping(Object, #True, 0, 0, ScrollAreaBarWidth(Gadget) + ScrollAreaBorderWidth(Gadget), ScrollAreaBarHeight(Gadget) + ScrollAreaBorderHeight(Gadget))   ; 2*ScrollAreaBorder - ScrollAreaBorder
  EndIf
  If ParentObject <> #PB_Default And IsGadget(GetObjectData(ParentObject))
    Parent = GetObjectData(ParentObject)
    If GadgetType(Parent) = #PB_GadgetType_ScrollArea
      SetObjectBoundaries(Object, 0, 0, GetGadgetAttribute(Parent, #PB_ScrollArea_InnerWidth)-ScrollAreaBorderWidth(Gadget), GetGadgetAttribute(Parent, #PB_ScrollArea_InnerHeight)-ScrollAreaBorderHeight(Gadget), #MinSize, #MinSize)   ; Set the Boundaries MaxX MaxY to the parent contained scrollable area 
    EndIf
  EndIf
  ;AddObjectHandle(Object, #Handle_Size | #Handle_Position)
  ;ObjectHandleDisplayMode(Object, #Handle_ShowIfSelected)
  SetObjectDrawingCallback(Object, @ObjectDrawing(), Gadget)
  SetObjectCursor(Object, #PB_Cursor_Hand)
EndProcedure

;- ----- Main -----
Define Gadget.i

; Create a window
OpenWindow(#Window, 0, 0, 680, 500, "Example Captured ScrollArea Gadget Objects", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

; Create a canvas gadget
CanvasGadget(#Canvas, 0, 0, WindowWidth(#Window), WindowHeight(#Window), #PB_Canvas_Keyboard)

; Initializes the object management for the canvas gadget
If Not InitializeCanvasObjects(#Canvas, #Window)
  Debug "Unable to initialize the object manager !"
EndIf

SetCursorSelectionStyle(#Canvas, #SelectionStyle_Solid|#SelectionStyle_Partially, RGBA(0, 128, 255, 255), 1, RGBA(0, 128, 255, 25))
SetObjectSelectionStyle(#Object_Default, #SelectionStyle_Dashed, $A80000FF, 1, #SelectionStyle_Ignore)
SetObjectBoundaries(#Object_Default, 0, 0, #Boundary_ParentSize, #Boundary_ParentSize, #MinSize, #MinSize)   ; Set the boundaries to the parent size by default
AddObjectHandle(#Object_Default, #Handle_Size | #Handle_Position)
ObjectHandleDisplayMode(#Object_Default, #Handle_ShowIfSelected)
;SetObjectDrawingCallback(#Object_Default, @ObjectDrawing(), Gadget)
;SetObjectCursor(#Object_Default, #PB_Cursor_Hand)

ScrollAreaGadget(#Gadget1, 120, 100, 440, 300, 620, 450, 10)
CloseGadgetList()
HideGadget(#Gadget1, #True)
CreateSetObject(#Gadget1, #Object1)

ButtonGadget(#Gadget2, 40, 40, 200, 60, "Button_1") : HideGadget(#Gadget2, #True)
CreateSetObject(#Gadget2, #Object2, #Object1, 1)

ButtonGadget(#Gadget3, 360, 160, 200, 60, "Button_2") : HideGadget(#Gadget3, #True)
CreateSetObject(#Gadget3, #Object3, #Object1, 1)

; The window's event loop
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow                   ; Exit the program.
      Break
      
    Case #PB_Event_Gadget                        ;-> Event Gadget
  EndSelect
  
  ; Event loop of the objects in the canvas gadget
  Repeat
    Select CanvasObjectsEvent(#Canvas)           ; Something happened in the canvas.
      Case #Event_Handle                         ;-> Event Handle
        Select CanvasObjectsEventType(#Canvas)   ; What type of Events happened on the Handle ?
          Case #EventType_LeftMouseClick
            Select EventHandle(#Canvas)   ; Moves forward Or backward 1/4 of the width
              Case #Handle_Custom1        ; Debug "Left"
                Gadget = GetObjectData(EventObject(#Canvas))
                SetGadgetAttribute(Gadget, #PB_ScrollArea_X, GetGadgetAttribute(Gadget, #PB_ScrollArea_X) - GadgetWidth(Gadget)/4)
                SetObjectFrameOffset(EventObject(#Canvas), -GetGadgetAttribute(Gadget, #PB_ScrollArea_X)+ScrollAreaBorderWidth(Gadget), -GetGadgetAttribute(Gadget, #PB_ScrollArea_Y)+ScrollAreaBorderHeight(Gadget))
                _FreeCaptureGadget_(Gadget)
              Case #Handle_Custom2       ; Debug "Right"
                Gadget = GetObjectData(EventObject(#Canvas))
                SetGadgetAttribute(Gadget, #PB_ScrollArea_X, GetGadgetAttribute(Gadget, #PB_ScrollArea_X) + GadgetWidth(Gadget)/4)
                SetObjectFrameOffset(EventObject(#Canvas), -GetGadgetAttribute(Gadget, #PB_ScrollArea_X)+ScrollAreaBorderWidth(Gadget), -GetGadgetAttribute(Gadget, #PB_ScrollArea_Y)+ScrollAreaBorderHeight(Gadget))
                _FreeCaptureGadget_(Gadget)
              Case #Handle_Custom3       ; Debug "Up"
                Gadget = GetObjectData(EventObject(#Canvas))
                SetGadgetAttribute(Gadget, #PB_ScrollArea_Y, GetGadgetAttribute(Gadget, #PB_ScrollArea_Y) - GadgetHeight(Gadget)/4)
                SetObjectFrameOffset(EventObject(#Canvas), -GetGadgetAttribute(Gadget, #PB_ScrollArea_X)+ScrollAreaBorderWidth(Gadget), -GetGadgetAttribute(Gadget, #PB_ScrollArea_Y)+ScrollAreaBorderHeight(Gadget))
                _FreeCaptureGadget_(Gadget)
              Case #Handle_Custom4       ; Debug "Down"
                Gadget = GetObjectData(EventObject(#Canvas))
                SetGadgetAttribute(Gadget, #PB_ScrollArea_Y, GetGadgetAttribute(Gadget, #PB_ScrollArea_Y) + GadgetHeight(Gadget)/4)
                SetObjectFrameOffset(EventObject(#Canvas), -GetGadgetAttribute(Gadget, #PB_ScrollArea_X)+ScrollAreaBorderWidth(Gadget), -GetGadgetAttribute(Gadget, #PB_ScrollArea_Y)+ScrollAreaBorderHeight(Gadget))
                _FreeCaptureGadget_(Gadget)
            EndSelect
        EndSelect
        
      Case #Event_Object                         ;-> Event Object
        Select CanvasObjectsEventType(#Canvas)   ; What type of events happened on the object?
          Case #EventType_Selected
            ;Debug "Object " + EventObject(#Canvas) + " has been Selected. Put Object on Top."
            SetObjectLayer(EventObject(#Canvas), -1, #PB_Absolute)   ; Push to the last layer (-1), on Top
            
          Case #EventType_Moved,  #EventType_Resized
            Gadget = GetObjectData(EventObject(#Canvas))
            Debug "Gadget " + Gadget + " (" +
                  GetObjectX(EventObject(#Canvas), #Object_LocalPosition) + ", " + GetObjectY(EventObject(#Canvas), #Object_LocalPosition)  + ", " +
                  GetObjectWidth(EventObject(#Canvas)) + ", " + GetObjectHeight(EventObject(#Canvas)) + ") Moved or Resized"
            ResizeGadget(Gadget, GetObjectX(EventObject(#Canvas), #Object_LocalPosition), GetObjectY(EventObject(#Canvas), #Object_LocalPosition), GetObjectWidth(EventObject(#Canvas)), GetObjectHeight(EventObject(#Canvas)))
            
        EndSelect                                ; CanvasObjectsEventType(#Canvas)
        
      Case #Event_None                           ; No Events.
        Break
    EndSelect                                    ; CanvasObjectsEvent(#Canvas)
  ForEver
  
ForEver

End

DataSection
  arrow_left_png:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$414449C901000061
  Data.q $3010A06463DA7854,$CFD27FE376D05212,$3331FF4A81D4BF1F,$9F4661FF787C7132,$FF3BA80CA24DC883
  Data.q $0C0C1D7BEDEEFCB3,$0BEBEE4E167CC1FF,$89E5417288B5E57D,$F7F3D93C1F0FCE8F,$F961642022A05FDF
  Data.q $16C9B5D147F3EBF8,$CC9EE3B3901A09BF,$93F1FB7F1EDF8FFB,$81919199A8099181,$5DFAB045654B9395
  Data.q $9B230F6B31106182,$308A3F1F77ABD490,$7CC405D8C5813133,$53102A216E2A0557,$4B33F1E8F63EDCB7
  Data.q $08F2B39F20CDA066,$162A23ABD68A6F34,$F7E3F4FC8E1EE602,$19FFFFFFE8A06632,$E5B54F6D3ED8D958
  Data.q $F07A1FA69D1A2927,$F1899B107977E7F7,$2F2CC252AAAA833F,$46BED9601B4485B5,$7FBFFFD5EB938590
  Data.q $CCC2CAC0FD01FE58,$FD47D73462A2A2A0,$9D84D5808006513C,$07F40D3B7C7F7F26,$B8797818FFFFBFC3
  Data.q $B58CAD8BF20A897E,$713A6020019448FE,$D88366EFCF9FCA77,$BB17149065FEFEFF,$4003688545C323BB
  Data.q $7F3FFFB4D579B340,$FFBF9FC301930266,$B24B6EB614555418,$C56BB5DAC06AC1F7,$0FCFA18145D9D9D9
  Data.q $F8F9E4FF7FFF1CC4,$BD76FEAF9D8FFBF5,$7F6F978C0328C9FF,$6B66F1CBD9B031FE,$11FA12181DDFFF71
  Data.q $FCFEB95BADD6C06E,$20355FEFF7FF13F9,$C505E69027086417,$F892682FC3132B26,$BC3030FF5F934C00
  Data.q $BDEDEDEB3F656667,$9DBE00018817A096,$0000B5C0D55711B4,$42AE444E45490000
  arrow_right_png:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$414449CA01000061
  Data.q $3010A06463DA7854,$549752DD37327322,$060FEFEFFBF8CE50,$AB376CEC6C4CFF86,$2408006D11E71935
  Data.q $9A4FD7F7ED727D6C,$63168A8565456930,$87B29BF00DA24ECE,$BFDFBFF5F65C4795,$62666067FC33FFF8
  Data.q $E337697052579062,$ECBA102001944BD9,$FFFCEEFF7FBFF292,$5C0CFFBFFFE18FFF,$13B2C262A20CACEC
  Data.q $90D80065109FA49C,$19B77E7D7E7DB735,$FBC7CFC0C61A06C4,$96D145B167D7E986,$5F960204003289FF
  Data.q $D1482D5DE9F9FA69,$CF8E24A4644BA05F,$F01000DA22B757F5,$F93F9FEFE3E4739C,$898A8886C1191918
  Data.q $01944E5FD30CAD44,$7773BADFC76F5BE9,$7D78C06510FFBFC1,$2417288141CB3FB8,$73C3FEEF786ABC6E
  Data.q $62A9026061FCFFBF,$91D8BFEFF0C3FE62,$B399080D04F79F62,$7F3EAFDFF7DDFF97,$C55604C8C4C6C2FE
  Data.q $0CF9D7347A6FCDC2,$E79DDF7331E0B151,$1303333133285E2F,$A9EA609F2B030324,$E01862D4D839B77C
  Data.q $7AEEB71B96C8E0BB,$666A07FC313330B3,$0B2C2EBD7E9F6364,$56B75C6C06E15797,$7D1F7BCEFFE7C6F4
  Data.q $C5280BF0C4C2CC9E,$73188B89FFFEC821,$C73B133B07272099,$3F0FE200FC4C6027,$1EF212121978FC7E
  Data.q $FCFEB95BADD6C06E,$2B0AAFEFF0CF13F9,$F985027309280323,$1B031FFBF0C6B180,$A40AFE6A047CE534
  Data.q $F6F6F69FB3B3B25F,$2F0004203A544B5E,$00E5AD6E7411AD5A,$AE444E4549000000
  arrow_up_png:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$414449BD01000061
  Data.q $3010A06463DA7854,$F65D9F56A2036E0E,$512661E5867FFFFF,$1B0F3B6337E01924,$83AA1EF79B99EF17
  Data.q $FF7E1937724AAAF8,$01A085F8EC975931,$E6FD7EBF6B2FEB89,$99995938EF378BF4,$171063FEFFBF62C0
  Data.q $D73A6921212EFC11,$3D76B2034E2AF34F,$DFAFF2EEF77BB888,$5FC0C3354330307E,$AA2A0CEC5CDC21A0
  Data.q $186057E45D5391AA,$D7EB8DFB59E07790,$08C4C0C7F9FEFE2B,$2065CE7626620614,$B0C00C516F8FDFFA
  Data.q $EA0C4C2CCCC407F8,$E12A651D931DEA1A,$86DB897254A79806,$5033441BF3FDFD7C,$C6987D67385F8D98
  Data.q $3FD9EBAAD07C9054,$8D958433029BBD3F,$2787DCBD85FDE193,$2C5D1BA01B037F94,$1FCFEFEEF09DEEA8
  Data.q $B5E6E563FFB7400C,$210BD90C7AAC155D,$FC308FE5025BAEAB,$FF70CEC6C4C4C3F9,$83DF6B3373A146D0
  Data.q $4FF4D4172B88300D,$3FDFD3DFFFF0C77E,$2D837C3189AC1BBE,$17E4E1171DE60276,$06DF6F7D275400BE
  Data.q $679806202AD393A1,$619E6C1646180B34,$F838C9E24C4B6BCF,$F60F7C0BCDF5F0F9,$7CB55C4A5EA07EE4
  Data.q $E53028BF2F1738A9,$49078850073103F1,$F8C8C8C4FE207FDD,$65E1F4F97C3F8803,$B75B01B87BCC5444
  Data.q $DFFC4FE7F3FAE56E,$9C21905C80D57FBF,$CD408F80CD179A40,$D3F676764BF4815F,$5244A6B16BDEDEDE
  Data.q $CA3C11B6A7690001,$45490000000056C9
  arrow_down_png:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$414449D401000061
  Data.q $3010A06463DA7854,$BD78DBB3AC030E0E,$88331834ABBB2B73,$0B038CFFE372D4D1,$360CFACF69EE97A7
  Data.q $E92FC35042AE30C0,$9FCF37F1EF28B49D,$634D8FF930882F5A,$47EACAD28C43FCD4,$3AC0EF7960FCBC9F
  Data.q $D00D83DF2B5393A1,$F77C49F754112E8D,$378131690657FBE3,$9F655C53069CECAC,$819A477AD8CE6B22
  Data.q $B08BDF2F2785FFE1,$E841B8383C327073,$4551DA01885ACCEC,$FAFEFF1FD11E2A7C,$5E01063FEFF7F0C1
  Data.q $768997591931064E,$399FFBF9F2417BE2,$5F4F87CF62F17ABF,$D8D9981899999819,$567E7FC6D91D1E19
  Data.q $B4BD2CFA207827DD,$F950A001D787D7FE,$831B1B27033FEFFB,$1E67A07FDD54BC82,$062FD7FDF4D67A3E
  Data.q $27C6CF9024A02666,$2C462051AC4B61B8,$DBC3EBFCDD382DB8,$08209D407FA2901A,$918981919FF8C152
  Data.q $9DD96A13E566CC11,$1C661D1A338B5664,$FF8646C3E5F5FBF2,$479581898BE2D0FF,$E98226ED8660FFD0
  Data.q $FFFFFFF28373ACC0,$C02C1F87F3FFFECF,$64F8DD959991FCC2,$FE7A9213A25DF7B1,$4F2013B909763644
  Data.q $E6575AE2D2FF79FF,$6037001289099C2F,$A2ECECECE2B5DAED,$F310073103F3A740,$ED859194B103FFFC
  Data.q $01FE2027E323233F,$2432F1F8FC7E1FC4,$B75BAD80DC3DE424,$DFEFFE27F3F9FD72,$204E10C82E406ABF
  Data.q $047E652811648BCD,$3A2D025FA40AFE6A,$005E2A96BDEDEDED,$0CFBAA11BBA99700,$4E4549000000005B
EndDataSection
Last edited by ChrisR on Tue Feb 02, 2021 3:24 pm, edited 1 time in total.
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: EditorFactory - Module for object management in a Canvas

Post by ShadowStorm »

Hi, I prefer the first code, I find it more realistic despite its bugs.
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

Yes, It is more realistic, for sure, with the "Fake" ScrollArea in background,
But with the overlay it will be difficult to remove flickering, i guess

On the 2nd example the arrow images were not well chosen.
I have updated the example with more appropriate images, it's better and only the scroll bar is missing.
Only EditorFactory features are used and it's better for drawing gadgets, attached images,... without flickering

I don't know what STARGÅTE has planned for The frame functions
It would be nice to be able to define the position (X, Y, width, Height) to manage borders and inner size
Rather than dealing with:

Code: Select all

SetObjectFrameOffset(Object, ScrollAreaBorderWidth(Gadget), ScrollAreaBorderHeight(Gadget))
SetObjectFrameClipping(Object, #True, 0, 0, ScrollAreaBarWidth(Gadget) + ScrollAreaBorderWidth(Gadget),...
SetObjectBoundaries(Object, 0, 0, GetGadgetAttribute(Parent, #PB_ScrollArea_InnerWidth)-ScrollAreaBorderWidth(Gadget),...
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: EditorFactory - Module for object management in a Canvas

Post by ShadowStorm »

Stargate is a little busy, but it's there.
I also proposed some things, did you see?
I really think it can help :)

Thanks for your code, we'll do a good thing when it's time !
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

ChrisR wrote:Yes, It is more realistic, for sure, with the "Fake" ScrollArea in background,
But with the overlay it will be difficult to remove flickering, i guess
By adding SendMessage WM_SETREDRAW, there is no more flickering and it works well this way for the Scrollbars, now.
Not sure if my examples are appropriate in this thread, sorry for the inconvenience if it is not. As it is here, I have updated the previous example
ShadowStorm
Enthusiast
Enthusiast
Posts: 237
Joined: Tue Feb 14, 2017 12:07 pm

Re: EditorFactory - Module for object management in a Canvas

Post by ShadowStorm »

Very good work @ChrisR.
It works well that way.

This can be further improved, when the
new functions will be there.
I am French, I do not speak English.
My apologies for the mistakes.

I have sometimes problems of expression
I am sometimes quite clumsy, please excuse me and let me know.
Amitris_de
User
User
Posts: 31
Joined: Wed Jan 06, 2021 2:53 pm

Re: EditorFactory - Module for object management in a Canvas

Post by Amitris_de »

Dear developers, is the development of this module continues?
User avatar
STARGÅTE
Addict
Addict
Posts: 2063
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: EditorFactory - Module for object management in a Canvas

Post by STARGÅTE »

Yes, I'm still working on it, but during the last weeks I was too busy with other things, that there was no time for Editor Factory (this is not the only PB project I have).
I will renew the frame-system and will check out, how I can make the interactive with a panel gadget and scrollbar gadget more easy.
During this time I will go through your posts to check all feature requests.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
STARGÅTE
Addict
Addict
Posts: 2063
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: EditorFactory - Module for object management in a Canvas

Post by STARGÅTE »

Short statement from my side.

I have re-written the frame system.
Now, all objects have one "universal" frame, but also can have multiple indexed frames.
The "universal" frame can be used for normal attachments without clipping and so on.
For the indexed frames only one is shown at the same time. The indexed frames have to added to the object first, like in Pure Basic with AddGadgetItem, then other object can be added to this frame.

As I can see, you want to use the images of PB gadget as object images, but for now you have no access to interact with this images (like clicking on the scroll bar or on a panel tab). Up to now I'm not sure how I/we can handle this without program the whole gadget itself, which is not the purpose of this include.
Would it help if I include an additional callback, which is called during the event handling? In this callback you would then have access to the local mouse cursor position and mouse events to check for clicks and hovers.
But how do you know the metrics/dimensions of the scrollbar or a tab in a panel gadget?

@Amitris_de: Please check your post, because all images are invalid and I can no longer see what you wanted to show.

@ChrisR: "I don't know what STARGÅTE has planned for The frame functions
It would be nice to be able to define the position (X, Y, width, Height) to manage borders and inner size
Rather than dealing with:"

What do you mean with (X, Y, width, Height)?

@ShadowStorm: I saw your featuzre request with the disable / enable option for the selection frame. I will check it.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
ChrisR
Addict
Addict
Posts: 1124
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: EditorFactory - Module for object management in a Canvas

Post by ChrisR »

Thanks for the rewriting of the frame system :)
and for the possibility to have multiple indexed frames
STARGÅTE wrote:What do you mean with (X, Y, width, Height)?
It should be more explicit with an example:
The Panel childrens are written in the frame with an offset compare to GetObjectX(Y) of the object Panel :
x = 3 for the left Panel border
y = 25 for the Tab height (24) and top Panel border (1)
If the frame of an object Panel could be defined with (iObject, iFrameIndex, 3, 25, Panel_ItemWidth, Panel_ItemHeight)
It would no longer be required to define SetObjectFrameOffset(Object, LeftOffSet=3, TopOffSet=25)
And boundaries could be defined with something like SetObjectBoundaries(Object, 0, 0, #Boundary_FrameSize, #Boundary_FrameSize)

For a ScrollArea with #PB_ScrollArea_Raised (border=3px)
The frame could be defined with (iObject, iFrameIndex, 3, 3, ScrollArea_InnerWidth, ScrollArea_InnerHeight)

I hope i'm clearer
However, I don't know if it's something that can be done in your powerful module
Post Reply