It is currently Thu Jun 20, 2013 8:17 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Simplifiying Class Creation with Interfaces
PostPosted: Tue Mar 20, 2012 7:46 am 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 2506
Location: New Zealand
I was thinking about how to simplify class creation with interfaces to present it in a nice clean easy to follow way
plus enabling it to do function overloading.

Any improvements ?

You still have to do you interface and vtable in the same order but hopefully it's clear enough

Code:

Macro _ClassSetMethod(cls,method)
  PokeI(*this\vt+MethodOffset,method)
  MethodOffset+SizeOf(Integer)
EndMacro
 
Macro _ClassAlloc(ptr,Class,Interfaces)
  Protected MethodOffset
  ptr = AllocateMemory(SizeOf(class))
  ptr\vt = AllocateMemory(SizeOf(Interfaces))
  InitializeStructure(ptr,class)
EndMacro 

Macro _ClassFree(ptr)
  FreeMemory(ptr\vt)
  FreeMemory(ptr)
EndMacro

Macro _ClassOverLoadFunc(cls,interfaceFunc,newfn)
  PokeI(PeekI(cls)+OffsetOf(InterfaceFunc),newfn)
EndMacro

;define class struct
Structure clsFoo
 *vt.i
  bar.i
EndStructure

;define class functions
Procedure clsFoo_Free(*this.clsFoo)
   _ClassFree(*this)
 EndProcedure

Procedure clsFoo_Getbar(*this.clsfoo)
  ProcedureReturn *this\bar
EndProcedure

Procedure clsFoo_SetBar(*this.clsFoo,val.i)
  *this\bar = val
 EndProcedure   

;define constructor   
Procedure New_clsFoo()
  Protected *this.clsFoo
 
  Interface iFoo
    GetBar()
    SetBar(val.i)
    Free()
  EndInterface
   
  _ClassAlloc(*this,clsFoo,iFoo)
  _ClassSetMethod(*this,@clsFoo_Getbar())
  _ClassSetMethod(*this,@clsFoo_SetBar())
  _ClassSetMethod(*this,@clsFoo_Free())
 
  *this\bar = 5
  ProcedureReturn *this
 
EndProcedure

;A user over loaded function
Procedure clsFoo_Getbar2(*this.clsFoo)
  ProcedureReturn *this\bar * 2
EndProcedure
 
 Global foo1.iFoo = New_clsFoo()
 Global foo2.iFoo = New_clsFoo()
 
 Foo1\Setbar(10)
 Foo2\SetBar(40)
 
 Debug foo1\Getbar()
  _ClassOverLoadFunc(Foo1,iFoo\GetBar(),@clsFoo_Getbar2())
 Debug foo1\GetBar()
 
 Debug foo2\GetBar()
 
 Foo1\free()
 Foo2\Free()


Top
 Profile  
 
 Post subject: Re: Simplifiying Class Creation with Interfaces
PostPosted: Tue Mar 20, 2012 11:22 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Tue Apr 27, 2010 3:20 pm
Posts: 115
Location: Wales, United Kingdom
I'll take the opportunity to share with the community the code I have been actively sharing with you, Idle... It's slightly more of a heavy-built concept of doing it, and still heavily under development, but it adds another way of doing things:


*Note - The following code is an amalgamation demonstrating a small part of the project I'm working on. It contains only support for Windows operating system at the moment (the GTK/Linux support will be released with the first RC). Scroll to bottom to see how the construction of 'classes' and 'methods' are implemented.

Code:
;------------------------------------------------------------------------------------------
; Title:        Utility Code
; Description:  Utilities.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     11 March 2012
; Notes:        Part of the Mastiff Framework
;------------------------------------------------------------------------------------------

; - __mfwDQuote -
Macro __mfwDQuot
    "
EndMacro

; - Encapsulate in Double Quotes -
Macro __mfwStr(Content)
    __mfwDQuot#Content#__mfwDQuot
EndMacro

; - Integer Type -
CompilerIf Defined(Integer, #PB_Structure) = #False
    Structure Integer
        i.i
    EndStructure
CompilerEndIf

; - Platform-Specific Include -
Macro __mfwPlatformInclude(File)
    CompilerSelect #PB_Compiler_OS
        CompilerCase #PB_OS_Windows
            XIncludeFile "mfw/msw/" + File
        CompilerCase #PB_OS_Linux
            XIncludeFile "mfw/gtk/" + File
    CompilerEndSelect
EndMacro

; - Common Constants -
Enumeration ;MFW_MOUSEBUTTON
    #MFW_MOUSEBUTTON_LEFT
    #MFW_MOUSEBUTTON_MIDDLE
    #MFW_MOUSEBUTTON_RIGHT
EndEnumeration

Enumeration ;MFW_SCROLL
    #MFW_SCROLL_UP
    #MFW_SCROLL_DOWN
EndEnumeration

   

;------------------------------------------------------------------------------------------
; Title:        Allocator Library
; Description:  Macro to generate memory allocators for structured data object.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     12 March 2012
; Notes:        Part of the Mastiff Framework
;------------------------------------------------------------------------------------------

;XIncludeFile "mfw/utility.pbi"

; - Allocation Mode -
CompilerIf Defined(MFW_ALLOC_USELIST, #PB_Constant) = #False
    #MFW_ALLOC_USELIST = #True ; Set as #True to enable allocations to be done using a LinkedList. (Prevent Memory Leaks)
CompilerEndIf

; - Allocator Macro -
Macro mfwCreateAllocator(Struct)
    CompilerIf #MFW_ALLOC_USELIST = #True
        Global NewList __mfwAllocator_#Struct.Struct()
    CompilerEndIf   
    Procedure.i Struct#_Alloc()
        Protected *obj.Struct
        CompilerIf #MFW_ALLOC_USELIST = #True
            *obj = AddElement(__mfwAllocator_#Struct())
        CompilerElse
            *obj = AllocateMemory(SizeOf(Struct))
            InitializeStructure(*obj, Struct)
        CompilerEndIf
        CompilerIf Defined(Struct#_Constructor, #PB_Procedure)
            Struct#_Constructor(*obj)
        CompilerEndIf
        ProcedureReturn *obj
    EndProcedure   
    Procedure.a Struct#_Destroy(*obj)
        If *obj
            CompilerIf Defined(Struct#_Destructor, #PB_Procedure)
                Struct#_Destructor(*obj)
            CompilerEndIf
            CompilerIf #MFW_ALLOC_USELIST = #True
                ForEach __mfwAllocator_#Struct()
                    If @__mfwAllocator_#Struct() = *obj
                        DeleteElement(__mfwAllocator_#Struct())
                        ProcedureReturn #True
                    EndIf
                Next
            CompilerElse
                FreeMemory(*obj)
                ProcedureReturn #True
            CompilerEndIf
        EndIf
        ProcedureReturn #False
    EndProcedure
    Procedure Struct#_DestroyAll()
        CompilerIf #MFW_ALLOC_USELIST = #True
            ForEach __mfwAllocator_#Struct()
                CompilerIf Defined(Struct#_Destructor, #PB_Procedure)
                    Struct#_Destructor(@__mfwAllocator_#Struct())
                CompilerEndIf
            Next
            ClearList(__mfwAllocator_#Struct())
        CompilerElse
            mfwDebug(__mfwDQuot#Struct#__mfwDQuot + "_DeleteAll() has no effect when #MFW_ALLOC_USELIST = #False")
        CompilerEndIf
    EndProcedure
EndMacro

;------------------------------------------------------------------------------------------
; Title:        Mastiff Core Library
; Description:  Core procedures for use by the rest of the framework.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     16 March 2012
; Notes:        Part of the Mastiff Framework
;------------------------------------------------------------------------------------------

; - Prototypes -
Prototype __mfwCore_Destructor()

; - Global Data -
Structure __mfwGlobData
    List *destructor()
EndStructure

Global __mfwGlobal.__mfwGlobData

; - Register Global Destructor -
Procedure mfwAddGlobalDestructor(*Destructor)
    With __mfwGlobal
        ForEach \destructor()
            If \destructor() = *Destructor
                ProcedureReturn
            EndIf
        Next
        AddElement(\destructor())
        \destructor() = *Destructor
    EndWith
EndProcedure

; - Remove Global Destructor -
Procedure mfwRemoveGlobalDestructor(*Destructor)
    With __mfwGlobal
        ForEach \destructor()
            If \destructor() = *Destructor
                DeleteElement(\destructor())
                ProcedureReturn
            EndIf
        Next
        AddElement(\destructor())
        \destructor() = *Destructor
    EndWith
EndProcedure

; - Call Global Destructors -
Procedure mfwRelease()
    Protected *pDestructor.__mfwCore_Destructor
    With __mfwGlobal
        ForEach \destructor()
            *pDestructor = \destructor()
            *pDestructor()
        Next
    EndWith
EndProcedure

; - End Program -
Macro mfwEnd
    mfwRelease()
    End
EndMacro
   

;------------------------------------------------------------------------------------------
; Title:        Object Creation Library
; Description:  Macros to ease the process of designing interface-based objects.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     15 March 2012
; Notes:        Part of the Mastiff Framework
;------------------------------------------------------------------------------------------

;XIncludeFile "mfw/alloc.pbi"
;XIncludeFile "mfw/core.pbi"

; - Prototypes -
Prototype __mfwObjConstructor(*instance)
Prototype __mfwObjDestructor(*instance)

; - Object Method Info -
Structure __mfwObjMethodInfo
    *pFunction
    name.s
EndStructure

; - Object Info Structure -
Structure __mfwObjInfo
    *pMethodTable
    *pParentObjectInfo
    *pConstructor.__mfwObjConstructor
    *pDestructor.__mfwObjDestructor
    List methodList.__mfwObjMethodInfo()
    Map *methodMap()
EndStructure

; - Method -
Macro mfwMethod(Object, Method)
    __#Object#_#Method
EndMacro

; - Method Pointer -
Macro mfwMethodPtr(Object, Method)
    @__#Object#_#Method#()
EndMacro

; - Base Object -
Structure __mfwObjInstance_Base
    *pMethodTable
    m_isDead.a
    *pObjInfo
    *m_pRelease
    m_objType.s
EndStructure

Interface mfwObject
    Release()
    TypeOf.s()
EndInterface

; - Base Methods -
Procedure.s mfwMethod(mfwObject, TypeOf)(*this.__mfwObjInstance_Base)
    ProcedureReturn *this\m_objType
EndProcedure

Procedure mfwMethod(mfwObject, Release)(*this.__mfwObjInstance_Base)
    CallFunctionFast(*this\m_pRelease)
EndProcedure

; - Implement Base Object -
Global __mfwObjInfo_mfwObject.__mfwObjInfo
With __mfwObjInfo_mfwObject
    AddElement(\methodList())
    \methodList()\name = "Release"
    \methodList()\pFunction = @mfwMethod(mfwObject, Release)()
    AddElement(\methodList())
    \methodList()\name = "TypeOf"
    \methodList()\pFunction = @mfwMethod(mfwObject, TypeOf)()
EndWith

; - Object Data Type -
Macro mfwThisType(ObjectName)
    __mfwObjInstance_#ObjectName
EndMacro

; - Destruct Object -
    Procedure mfwDestructObject(*Object, *Info.__mfwObjInfo)
        If *Info\pParentObjectInfo
            mfwDestructObject(*Object, *Info\pParentObjectInfo)
        EndIf
        If *Info\pDestructor
            *Info\pDestructor(*Object)
        EndIf
    EndProcedure
   
    ; - Construct Object -
    Procedure mfwConstructObject(*Object, *Info.__mfwObjInfo)
        If *Info\pParentObjectInfo
            mfwConstructObject(*Object, *Info\pParentObjectInfo)
        EndIf
        If *Info\pConstructor
            *Info\pConstructor(*Object)
        EndIf
    EndProcedure

; - Define Object -
Macro mfwDefineObject(ObjectName)
    CompilerIf Defined(__mfwObjInfo_#ObjectName, #PB_Variable) = #False
        mfwCreateAllocator(__mfwObjInstance_#ObjectName)
        Global __mfwObjInfo_#ObjectName#.__mfwObjInfo
        Procedure __mfwObjInfo_#ObjectName#_Destructor()
            FreeMemory(__mfwObjInfo_#ObjectName#\pMethodTable)
        EndProcedure
        mfwAddGlobalDestructor(@__mfwObjInfo_#ObjectName#_Destructor())
        __mfwObjInfo_#ObjectName#\pParentObjectInfo = @__mfwObjInfo_mfwObject
        ForEach __mfwObjInfo_mfwObject\methodList()
            AddElement(__mfwObjInfo_#ObjectName#\methodList())
            __mfwObjInfo_#ObjectName#\methodList()\pFunction = __mfwObjInfo_mfwObject\methodList()\pFunction
            __mfwObjInfo_#ObjectName#\methodList()\name = __mfwObjInfo_mfwObject\methodList()\name
            AddMapElement(__mfwObjInfo_#ObjectName#\methodMap(), __mfwObjInfo_mfwObject\methodList()\name)
            __mfwObjInfo_#ObjectName#\methodMap() = @__mfwObjInfo_#ObjectName#\methodList()
        Next       
        Procedure ObjectName#_Release(*object.mfwThisType(ObjectName))
            mfwDestructObject(*object, @__mfwObjInfo_#ObjectName)
            mfwDestroyObject(ObjectName, *object)
        EndProcedure       
    CompilerElse
        CompilerError "Error: Object '" + __mfwStr(ObjectName) + "' already defined"
    CompilerEndIf
EndMacro

; - Define Extended Object -
Macro mfwDefineObjectEx(ObjectName, ParentObject)
    CompilerIf Defined(__mfwObjInfo_#ObjectName, #PB_Variable) = #False
        mfwCreateAllocator(__mfwObjInstance_#ObjectName)
        Global __mfwObjInfo_#ObjectName#.__mfwObjInfo
        __mfwObjInfo_#ObjectName#\pParentObjectInfo = @__mfwObjInfo_#ParentObject
        ForEach __mfwObjInfo_#ParentObject#\methodList()
            AddElement(__mfwObjInfo_#ObjectName#\methodList())
            __mfwObjInfo_#ObjectName#\methodList()\pFunction = __mfwObjInfo_#ParentObject#\methodList()\pFunction
            __mfwObjInfo_#ObjectName#\methodList()\name = __mfwObjInfo_#ParentObject#\methodList()\name
            AddMapElement(__mfwObjInfo_#ObjectName#\methodMap(), __mfwObjInfo_#ParentObject#\methodList()\name)
            __mfwObjInfo_#ObjectName#\methodMap() = @__mfwObjInfo_#ObjectName#\methodList()
        Next
        Procedure ObjectName#_Release(*object.mfwThisType(ObjectName))
            mfwDestructObject(*object, @__mfwObjInfo_#ObjectName)
            mfwDestroyObject(ObjectName, *object)
        EndProcedure
    CompilerElse
        CompilerError "Error: Object '" + __mfwStr(ObjectName) + "' already defined"
    CompilerEndIf
EndMacro

; - Implement Method -
Global *__mfwObjInfo_MethodScope.__mfwObjMethodInfo

Macro mfwImplementMethod(ObjectName, Method)
    If FindMapElement(__mfwObjInfo_#ObjectName#\methodMap(), __mfwStr(Method)) = #False
        LastElement(__mfwObjInfo_#ObjectName#\methodList())
        AddElement(__mfwObjInfo_#ObjectName#\methodList())
        __mfwObjInfo_#ObjectName#\methodList()\pFunction = @__#ObjectName#_#Method#()
        __mfwObjInfo_#ObjectName#\methodList()\name = __mfwStr(Method)
        AddMapElement(__mfwObjInfo_#ObjectName#\methodMap(), __mfwStr(Method))
        __mfwObjInfo_#ObjectName#\methodMap() = @__mfwObjInfo_#ObjectName#\methodList()
    Else
        *__mfwObjInfo_MethodScope = __mfwObjInfo_#ObjectName#\methodMap(__mfwStr(Method))
        *__mfwObjInfo_MethodScope\pFunction = @__#ObjectName#_#Method#()
    EndIf
EndMacro

; - Attribute List Name -
Macro mfwBeginAttributesTable(ObjectName)
    Structure __mfwObjInstance_#ObjectName Extends __mfwObjInstance_Base
    EndMacro   
   
    ; - Begin Attributes List (Extended) -
    Macro mfwBeginAttributesTableEx(ObjectName, ParentObject)
        Structure __mfwObjInstance_#ObjectName Extends __mfwObjInstance_#ParentObject
        EndMacro
       
        ; - End Attributes List -
        Macro mfwEndAttributesTable()
        EndStructure
    EndMacro
   
    ; - Allocate Object Instance -
    Macro mfwAllocObject(ObjectName)
        __mfwObjInstance_#ObjectName#_Alloc()
    EndMacro
   
    Macro mfwDestroyObject(ObjectName, Pointer)
        __mfwObjInstance_#ObjectName#_Destroy(Pointer)
    EndMacro
       
    ; - Initialise Object -
    Macro mfwInitialiseObject(ObjectName, Pointer)
        Pointer\m_objType = __mfwStr(ObjectName)
        Pointer\pMethodTable = __mfwObjInfo_#ObjectName#\pMethodTable
        Pointer\m_pRelease = @ObjectName#_Release()
        Pointer\pObjInfo = @__mfwObjInfo_#ObjectName
        mfwConstructObject(Pointer, @__mfwObjInfo_#ObjectName)       
    EndMacro
   
    ; - Implement Object -
    Macro mfwImplementObject(ObjectName, Abstract = #False)
        CompilerIf Defined(ObjectName#_New, #PB_Procedure) = #False
            CompilerIf Abstract = #False
                Procedure.i ObjectName#_New()
                    Protected.mfwThisType(ObjectName) *obj = mfwAllocObject(ObjectName)
                    mfwInitialiseObject(ObjectName, *obj)
                    ProcedureReturn *obj
                EndProcedure           
            CompilerEndIf
        CompilerEndIf
        __mfwObjInfo_#ObjectName#\pMethodTable = AllocateMemory(ListSize(__mfwObjInfo_#ObjectName#\methodList()) * SizeOf(Integer))
        FirstElement(__mfwObjInfo_#ObjectName#\methodList())
        ForEach __mfwObjInfo_#ObjectName#\methodList()
            PokeI(__mfwObjInfo_#ObjectName#\pMethodTable + (ListIndex(__mfwObjInfo_#ObjectName#\methodList()) * SizeOf(Integer)), __mfwObjInfo_#ObjectName#\methodList()\pFunction)
        Next
        CompilerIf Defined(ObjectName#_Constructor, #PB_Procedure)
            __mfwObjInfo_#ObjectName#\pConstructor = @ObjectName#_Constructor()
        CompilerEndIf
        CompilerIf Defined(ObjectName#_Destructor, #PB_Procedure)
            __mfwObjInfo_#ObjectName#\pDestructor = @ObjectName#_Destructor()
        CompilerEndIf
    EndMacro
   
    ; - TypeOf Function - 
    Procedure.s mfwTypeOf(*Object)
        If *Object
            Protected *obj.__mfwObjInstance_Base = *Object
            ProcedureReturn *obj\m_objType
        EndIf
    EndProcedure

;------------------------------------------------------------------------------------------
; Title:        Windows Platform UI Code
; Description:  Library providing UI routines for Windows based platforms.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     15 March 2012
; Notes:        Part of the Mastiff Framework
;               Internal functions.
;------------------------------------------------------------------------------------------

; - Window Handling Procedures -
Procedure __mfwPlatform_UI_Freeze(*hwnd, state)
    If *hwnd
        If state
            ProcedureReturn SendMessage_(*hwnd, #WM_SETREDRAW, #False, 0)
        Else
            ProcedureReturn SendMessage_(*hwnd, #WM_SETREDRAW, #True, 0)
            RedrawWindow_(*hwnd, 0, 0, #RDW_INTERNALPAINT | #RDW_INVALIDATE)
        EndIf
    EndIf
EndProcedure

Procedure __mfwPlatform_UI_SetProperty(*hwnd, propkey$, *property)
    If *hwnd
        ProcedureReturn SetProp_(*hwnd, propkey$, *property)
    EndIf
EndProcedure

Procedure.i __mfwPlatform_UI_GetProperty(*hwnd, propkey$)
    If *hwnd
        ProcedureReturn GetProp_(*hwnd, propkey$)
    EndIf
    ProcedureReturn #Null
EndProcedure

Procedure __mfwPlatform_UI_RemoveProperty(*hwnd, propkey$)
    If *hwnd
        ProcedureReturn RemoveProp_(*hwnd, propkey$)
    EndIf
EndProcedure

Procedure __mfwPlatform_UI_SetOpacity(*hwnd, opacity.f)
    If *hwnd
        SetWindowLongPtr_(*hwnd, #GWL_EXSTYLE, GetWindowLongPtr_(*hwnd, #GWL_EXSTYLE) | #WS_EX_LAYERED)
        SetLayeredWindowAttributes_(*hwnd, 0, 255 * opacity / 1.0, 2)
    EndIf
EndProcedure
   

;------------------------------------------------------------------------------------------
; Title:        UI Base Object (Abstract)
; Description:  The base object for all UI elements. (Gadgets, Windows)
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     15 March 2012
; Notes:        Part of the Mastiff Framework
;------------------------------------------------------------------------------------------

; - Includes -
;XIncludeFile "mfw/object.pbi"
;__mfwPlatformInclude("ui.pbi")

; - UI Object Family -
Enumeration ;MFW_UIFAMILY
    #MFW_UIFAMILY_WINDOW
    #MFW_UIFAMILY_GADGET
EndEnumeration

; - Standard Event Types -
Enumeration ;MFW_UIEVENT
    #MFW_UIEVENT_CLOSE
    #MFW_UIEVENT_REDRAW
    #MFW_UIEVENT_RESIZE
    #MFW_UIEVENT_TAKEFOCUS
    #MFW_UIEVENT_LOSEFOCUS
    #MFW_UIEVENT_MOUSEENTER
    #MFW_UIEVENT_MOUSEMOVE
    #MFW_UIEVENT_MOUSELEAVE
    #MFW_UIEVENT_MOUSESCROLL
    #MFW_UIEVENT_MOUSEDOUBLECLICK
    #MFW_UIEVENT_MOUSEDOWN
    #MFW_UIEVENT_MOUSEUP
    #MFW_UIEVENT_MAXIMISE
    #MFW_UIEVENT_MINIMISE   ; May not work on Linux.
    #MFW_UIEVENT_RESTORE
    #MFW_UIEVENT_CLICKED    ; (Windows) Requires parent mfwWindow to be specified.
    #MFW_UIEVENT_CUSTOM
    #MFW_UIEVENT_COUNT      ; Do Not Remove.
EndEnumeration

; - Event Handler Prototype -
Prototype p_mfwUIEventHandler(*This, *Event)

; - Event Handler List -
Structure __mfwUI_EvtHandler
    List *pHandler()
EndStructure

; - Interface -
Interface mfwUI Extends mfwObject
    GetHandle.i()
    GetID.i()
    GetFamily.a()
    SetProperty(Key$, *Property)
    GetProperty.i(Key$)
    RemoveProperty(Key$)
    Freeze(State = #True)
    Thaw()
    ConnectEvent(Event, *Handler)
    DisconnectEvent(Event, *Handler)
    PostEvent(*EventData)
    EnableEventHandling(State = #True)
    SetState(State)
    GetState.l()
EndInterface

; - Attributes Table -
mfwBeginAttributesTable(mfwUI)
    *m_pHwnd
    m_family.w
    m_pbID.i
    m_mouseIn.a
    *m_pOldCB
    m_lkwidth.l
    m_lkheight.l
    m_lkstate.l
    Array m_evtHandler.__mfwUI_EvtHandler(#MFW_UIEVENT_COUNT)
mfwEndAttributesTable()

; - Define Object -
mfwDefineObject(mfwUI)

; - Event Structure -
Structure mfwUIEvent
    *Control.mfwUI
    EventType.l
    MouseButton.l
    MouseX.l
    MouseY.l
    MouseScroll.b
    Family.l
    Width.l
    Height.l
EndStructure

; - Event Handling Callback -

;------------------------------------------------------------------------------------------
; Title:        Windows Platform UI Callback Code
; Description:  Callback function for event handling.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     15 March 2012
; Notes:        Part of the Mastiff Framework
;               Internal functions.
;------------------------------------------------------------------------------------------

Procedure __mfwPlatform_UI_Callback(*hWnd, msg, wParam, lParam)
    Protected evt.mfwUIEvent
    Protected *ctrl.mfwUI = __mfwPlatform_UI_GetProperty(*hWnd, "__mfwUI")
    Protected *ctrlChild.mfwUI = #Null
    Protected *ctrlData.mfwThisType(mfwUI) = *ctrl
    If *ctrl
        With evt
            \EventType = -1
            Select msg
                Case #WM_PAINT
                    \EventType = #MFW_UIEVENT_REDRAW
                Case #WM_MOUSEMOVE
                    If *ctrlData\m_mouseIn = #False
                        \EventType = #MFW_UIEVENT_MOUSEENTER
                        *ctrlData\m_mouseIn = #True
                    Else
                        \EventType = #MFW_UIEVENT_MOUSEMOVE
                    EndIf
                    \MouseX = (lParam & $FFFF)
                    \MouseY = (lParam >> 16)
                Case #WM_MOUSELEAVE
                    \EventType = #MFW_UIEVENT_MOUSELEAVE
                    \MouseX = (lParam & $FFFF)
                    \MouseY = (lParam >> 16)
                    *ctrlData\m_mouseIn = #False
                Case #WM_MOUSEWHEEL
                    \EventType = #MFW_UIEVENT_MOUSESCROLL
                    \MouseX = (lParam & $FFFF)
                    \MouseY = (lParam >> 16)
                    If wParam > 0
                        \MouseScroll = #MFW_SCROLL_UP
                    Else
                        \MouseScroll = #MFW_SCROLL_DOWN
                    EndIf
                Case #WM_LBUTTONDOWN
                    \EventType = #MFW_UIEVENT_MOUSEDOWN
                    \MouseButton = #MFW_MOUSEBUTTON_LEFT
                Case #WM_LBUTTONUP
                    \EventType = #MFW_UIEVENT_MOUSEUP
                    \MouseButton = #MFW_MOUSEBUTTON_LEFT
                Case #WM_LBUTTONDBLCLK
                    \EventType = #MFW_UIEVENT_MOUSEDOUBLECLICK
                    \MouseButton = #MFW_MOUSEBUTTON_LEFT
                Case #WM_RBUTTONDOWN
                    \EventType = #MFW_UIEVENT_MOUSEDOWN
                    \MouseButton = #MFW_MOUSEBUTTON_RIGHT
                Case #WM_RBUTTONUP
                    \EventType = #MFW_UIEVENT_MOUSEUP
                    \MouseButton = #MFW_MOUSEBUTTON_RIGHT
                Case #WM_RBUTTONDBLCLK
                    \EventType = #MFW_UIEVENT_MOUSEDOUBLECLICK
                    \MouseButton = #MFW_MOUSEBUTTON_RIGHT
                Case #WM_MBUTTONDOWN
                    \EventType = #MFW_UIEVENT_MOUSEDOWN
                    \MouseButton = #MFW_MOUSEBUTTON_MIDDLE
                Case #WM_MBUTTONUP
                    \EventType = #MFW_UIEVENT_MOUSEUP
                    \MouseButton = #MFW_MOUSEBUTTON_MIDDLE
                Case #WM_MBUTTONDBLCLK
                    \EventType = #MFW_UIEVENT_MOUSEDOUBLECLICK
                    \MouseButton = #MFW_MOUSEBUTTON_MIDDLE
                Case #WM_SETFOCUS
                    \EventType = #MFW_UIEVENT_TAKEFOCUS
                Case #WM_KILLFOCUS
                    \EventType = #MFW_UIEVENT_LOSEFOCUS
                Case #WM_NCDESTROY
                   
                    ProcedureReturn
                Case #WM_COMMAND
                    *ctrlChild = __mfwPlatform_UI_GetProperty(lParam & $FFFF, "__mfwUI")
                    If *ctrlChild
                        \EventType = #MFW_UIEVENT_CLICKED
                        \Control = *ctrlChild
                        \Family = *ctrlChild\GetFamily()
                        *ctrlChild\PostEvent(@evt)
                    EndIf
                Case #WM_CLOSE
                    \EventType = #MFW_UIEVENT_CLOSE
            EndSelect
            If *ctrl\GetFamily() = #MFW_UIFAMILY_WINDOW
                If IsWindow(*ctrlData\m_pbID)
                    If *ctrlData\m_lkstate <> *ctrl\GetState()
                        Select *ctrl\GetState()
                            Case #PB_Window_Maximize
                                \EventType = #MFW_UIEVENT_MAXIMISE
                            Case #PB_Window_Minimize
                                \EventType = #MFW_UIEVENT_MINIMISE
                            Case #PB_Window_Normal
                                \EventType = #MFW_UIEVENT_RESTORE
                        EndSelect
                        *ctrlData\m_lkstate = *ctrl\GetState()
                    EndIf
                    If *ctrlData\m_lkwidth <> WindowWidth(*ctrlData\m_pbID) Or *ctrlData\m_lkheight <> WindowHeight(*ctrlData\m_pbID)
                        \EventType = #MFW_UIEVENT_RESIZE
                        *ctrlData\m_lkwidth = WindowWidth(*ctrlData\m_pbID)
                        *ctrlData\m_lkheight = WindowHeight(*ctrlData\m_pbID)
                        \Width = *ctrlData\m_lkwidth
                        \Height = *ctrlData\m_lkheight
                    EndIf
                EndIf
            EndIf
            If *ctrl\GetFamily() = #MFW_UIFAMILY_GADGET
                If IsGadget(*ctrlData\m_pbID)
                    If *ctrlData\m_lkwidth <> GadgetWidth(*ctrlData\m_pbID) Or *ctrlData\m_lkheight <> GadgetHeight(*ctrlData\m_pbID)
                        \EventType = #MFW_UIEVENT_RESIZE
                        *ctrlData\m_lkwidth = GadgetWidth(*ctrlData\m_pbID)
                        *ctrlData\m_lkheight = GadgetHeight(*ctrlData\m_pbID)
                        \Width = *ctrlData\m_lkwidth
                        \Height = *ctrlData\m_lkheight
                    EndIf
                EndIf
            EndIf
            If \EventType > -1
                *ctrl\PostEvent(@evt)
            EndIf
        EndWith
        If *ctrlData\m_pOldCB
            ProcedureReturn CallWindowProc_(*ctrlData\m_pOldCB, *hWnd, msg, wParam, lParam)
        EndIf
    EndIf   
EndProcedure

; - Define Methods -
Procedure.i mfwMethod(mfwUI, GetHandle)(*this.mfwThisType(mfwUI))
    ProcedureReturn *this\m_pHwnd
EndProcedure

Procedure.i mfwMethod(mfwUI, GetID)(*this.mfwThisType(mfwUI))
    ProcedureReturn *this\m_pbID
EndProcedure

Procedure.w mfwMethod(mfwUI, GetFamily)(*this.mfwThisType(mfwUI))
    ProcedureReturn *this\m_family
EndProcedure

Procedure mfwMethod(mfwUI, SetProperty)(*this.mfwThisType(mfwUI), Key$, *Property)
    ProcedureReturn __mfwPlatform_UI_SetProperty(*this\m_pHwnd, Key$, *Property)
EndProcedure

Procedure mfwMethod(mfwUI, GetProperty)(*this.mfwThisType(mfwUI), Key$)
    ProcedureReturn __mfwPlatform_UI_GetProperty(*this\m_pHwnd, Key$)
EndProcedure

Procedure mfwMethod(mfwUI, RemoveProperty)(*this.mfwThisType(mfwUI), Key$)
    ProcedureReturn __mfwPlatform_UI_RemoveProperty(*this\m_pHwnd, Key$)
EndProcedure

Procedure mfwMethod(mfwUI, Freeze)(*this.mfwThisType(mfwUI), State = #True)
    __mfwPlatform_UI_Freeze(*this\m_pHwnd, State)
EndProcedure

Procedure mfwMethod(mfwUI, Thaw)(*this.mfwThisType(mfwUI))
    __mfwPlatform_UI_Freeze(*this\m_pHwnd, #False)
EndProcedure

Procedure mfwMethod(mfwUI, ConnectEvent)(*this.mfwThisType(mfwUI), Event, *Handler)
    Protected *inst.mfwUI = *this
    If Event > -1 And Event < #MFW_UIEVENT_COUNT And *Handler
        *inst\DisconnectEvent(Event, *Handler)
        AddElement(*this\m_evtHandler(Event)\pHandler())
        *this\m_evtHandler(Event)\pHandler() = *Handler
    EndIf
EndProcedure

Procedure mfwMethod(mfwUI, DisconnectEvent)(*this.mfwThisType(mfwUI), Event, *Handler)
    If Event > -1 And Event < #MFW_UIEVENT_COUNT And *Handler
        ForEach *this\m_evtHandler(Event)\pHandler()
            If *this\m_evtHandler(Event)\pHandler() = *Handler
                DeleteElement(*this\m_evtHandler(Event)\pHandler())
            EndIf
        Next       
    EndIf
EndProcedure

Procedure mfwMethod(mfwUI, PostEvent)(*this.mfwThisType(mfwUI), *EventData)
    Protected *evt.mfwUIEvent
    Protected *proc.p_mfwUIEventHandler
    If *EventData
        *evt = *EventData
        With *evt
            If \EventType > -1 And \EventType < #MFW_UIEVENT_COUNT
                \Control = *this
                ForEach *this\m_evtHandler(\EventType)\pHandler()
                    *proc = *this\m_evtHandler(\EventType)\pHandler()
                    If *proc(*this, *EventData) = #False
                    ProcedureReturn
                    EndIf
                Next
            EndIf
        EndWith               
    EndIf
EndProcedure

Procedure mfwMethod(mfwUI, EnableEventHandling)(*this.mfwThisType(mfwUI), State = #True)
    With *this
        If State
            CompilerSelect #PB_Compiler_OS
                CompilerCase #PB_OS_Windows
                    __mfwPlatform_UI_SetProperty(*this\m_pHwnd, "__mfwUI", *this)
                    \m_pOldCB = SetWindowLongPtr_(\m_pHwnd, #GWL_WNDPROC, @__mfwPlatform_UI_Callback())
            CompilerEndSelect
        Else
            If \m_pOldCB
                SetWindowLongPtr_(\m_pHwnd, #GWL_WNDPROC, \m_pOldCB)
                \m_pOldCB = #Null
            EndIf
        EndIf
    EndWith
EndProcedure

Procedure mfwMethod(mfwUI, SetState)(*this.mfwThisType(mfwUI), State)
    Select *this\m_family
        Case #MFW_UIFAMILY_WINDOW
            SetWindowState(*this\m_pbID, State)
        Case #MFW_UIFAMILY_GADGET
            SetGadgetState(*this\m_pbID, State)
    EndSelect
EndProcedure

Procedure.l mfwMethod(mfwUI, GetState)(*this.mfwThisType(mfwUI))
    Select *this\m_family
        Case #MFW_UIFAMILY_WINDOW
            ProcedureReturn GetWindowState(*this\m_pbID)
        Case #MFW_UIFAMILY_GADGET
            ProcedureReturn GetGadgetState(*this\m_pbID)
    EndSelect
EndProcedure

; - Implement Methods -
mfwImplementMethod(mfwUI, GetHandle)
mfwImplementMethod(mfwUI, GetID)
mfwImplementMethod(mfwUI, GetFamily)
mfwImplementMethod(mfwUI, SetProperty)
mfwImplementMethod(mfwUI, GetProperty)
mfwImplementMethod(mfwUI, RemoveProperty)
mfwImplementMethod(mfwUI, Freeze)
mfwImplementMethod(mfwUI, Thaw)
mfwImplementMethod(mfwUI, ConnectEvent)
mfwImplementMethod(mfwUI, DisconnectEvent)
mfwImplementMethod(mfwUI, PostEvent)
mfwImplementMethod(mfwUI, EnableEventHandling)
mfwImplementMethod(mfwUI, SetState)
mfwImplementMethod(mfwUI, GetState)

; - Constructor -
Procedure mfwUI_Constructor(*this.mfwThisType(mfwUI))
    Protected.mfwUI *instance = *this
    With *this
        \m_pHwnd = #Null
        \m_family = -1
        \m_pbID = -1
        *instance\SetProperty("__mfwUI", *instance)
    EndWith
EndProcedure

; - Implement Object -
mfwImplementObject(mfwUI, #True)

;------------------------------------------------------------------------------------------
; Title:        Window Object
; Description:  Create a Object/Class supporting a Window.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     15 March 2012
; Notes:        Part of the Mastiff Framework
;------------------------------------------------------------------------------------------

; - Includes -
;XIncludeFile "mfw/ui.pbi"

; - Constants -
#MFW_WINDOW_DEFAULTWIDTH = 400
#MFW_WINDOW_DEFAULTHEIGHT = 300
#MFW_WINDOW_DEFAULTTITLE = "New Window"
#MFW_WINDOW_DEFAULTFLAGS = #PB_Window_ScreenCentered | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_SystemMenu
#MFW_WINDOW_DEFAULTCOLOUR = -1

; - Object Interface -
Interface mfwWindow Extends mfwUI
    Close()
    Show()
    Hide(State = #True)
    Enable()
    Disable(State = #True)
    AddKeyboardShortcut(Key, MenuItemID)
    RemoveKeyboardShortcut(Key)
    AddTimer(Timer, Timeout)
    RemoveTimer(Timer)
    SetTitle(Title$)
    GetTitle.s()
    SetSmartRefresh(State = #True)
    SetBounds(MinimalWidth, MinimalHeight, MaximalWidth, MaximalHeight)
    SetActive()
    SetOnTop(State = #True)
    SetPosition(X, Y)
    GetX.l()
    GetY.l()
    SetSize(Width, Height)
    GetWidth.l()
    GetHeight.l()
    SetOpacity(Opacity.f = 1.0)
    SetColour(Color = #MFW_WINDOW_DEFAULTCOLOUR)
    GetColour.l()
    Minimise()
    Maximise()
    Restore()
    IsActive.a()
EndInterface

; - Attributes Table -
mfwBeginAttributesTableEx(mfwWindow, mfwUI)
    m_wndX.l
    m_wndY.l
    m_wndWidth.l
    m_wndHeight.l
    m_wndTitle.s
    m_wndFlags.l
mfwEndAttributesTable()

; - Global Window List -
Global NewList *__mfwWindow_List.mfwWindow()

; - Process Window Events -
Procedure mfwWindowEvent()
    If ListSize(*__mfwWindow_List()) > 0
        WindowEvent()
        ProcedureReturn #True
    EndIf
    ProcedureReturn #False
EndProcedure

; - Global Destructor -
Procedure mfwWindow_ReleaseAll()
    Protected *inst.mfwWindow
    ForEach *__mfwWindow_List()
        *inst = *__mfwWindow_List()
        *inst\Close()
        *inst\Release()
    Next
    ClearList(*__mfwWindow_List())
EndProcedure

mfwAddGlobalDestructor(@mfwWindow_ReleaseAll())

; - Set Creation Parameters -
Procedure mfwWindowCreationParams(*Window.mfwWindow, *Parent.mfwWindow = #Null, X = #PB_Ignore, Y = #PB_Ignore, Width = #MFW_WINDOW_DEFAULTWIDTH, Height = #MFW_WINDOW_DEFAULTHEIGHT, Title$ = #MFW_WINDOW_DEFAULTTITLE, Flags = #MFW_WINDOW_DEFAULTFLAGS)
    Protected *this.mfwThisType(mfwWindow) = *Window
    With *this
        \m_wndX = X
        \m_wndY = Y
        \m_wndWidth = Width
        \m_wndHeight = Height
        \m_wndTitle = Title$
        \m_wndFlags = Flags
    EndWith
EndProcedure


; - Define Object -
mfwDefineObjectEx(mfwWindow, mfwUI)

; - Define Methods -
Procedure mfwMethod(mfwWindow, Close)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        CloseWindow(*this\m_pbID)
        ForEach *__mfwWindow_List()
            If *__mfwWindow_List() = *this
                DeleteElement(*__mfwWindow_List())
                Break
            EndIf
        Next
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Show)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        HideWindow(*this\m_pbID, #False)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Hide)(*this.mfwThisType(mfwWindow), State = #True)
    If IsWindow(*this\m_pbID)
        HideWindow(*this\m_pbID, State)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Enable)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        DisableWindow(*this\m_pbID, #False)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Disable)(*this.mfwThisType(mfwWindow), State = #True)
    If IsWindow(*this\m_pbID)
        DisableWindow(*this\m_pbID, #True)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, AddKeyboardShortcut)(*this.mfwThisType(mfwWindow), Key, MenuID)
    If IsWindow(*this\m_pbID)
        ProcedureReturn AddKeyboardShortcut(*this\m_pHwnd, Key, MenuID)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, RemoveKeyboardShortcut)(*this.mfwThisType(mfwWindow), Key)
    If IsWindow(*this\m_pbID)
        ProcedureReturn RemoveKeyboardShortcut(*this\m_pHwnd, Key)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, AddTimer)(*this.mfwThisType(mfwWindow), Timer, Timeout)
    If IsWindow(*this\m_pbID)
        ProcedureReturn AddWindowTimer(*this\m_pHwnd, Timer, Timeout)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, RemoveTimer)(*this.mfwThisType(mfwWindow), Timer)
    If IsWindow(*this\m_pbID)
        ProcedureReturn RemoveWindowTimer(*this\m_pHwnd, Timer)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetTitle)(*this.mfwThisType(mfwWindow), Title$)
    If IsWindow(*this\m_pbID)
        SetWindowTitle(*this\m_pbID, Title$)
    EndIf
EndProcedure

Procedure.s mfwMethod(mfwWindow, GetTitle)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        ProcedureReturn GetWindowTitle(*this\m_pbID)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetSmartRefresh)(*this.mfwThisType(mfwWindow), State = #True)
    If IsWindow(*this\m_pbID)
        SmartWindowRefresh(*this\m_pbID, State)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetBounds)(*this.mfwThisType(mfwWindow), MinimalWidth, MinimalHeight, MaximalWidth, MaximalHeight)
    If IsWindow(*this\m_pbID)
        WindowBounds(*this\m_pbID, MinimalWidth, MinimalHeight, MaximalWidth, MaximalHeight)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetActive)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        SetActiveWindow(*this\m_pbID)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetOnTop)(*this.mfwThisType(mfwWindow), State = #True)
    If IsWindow(*this\m_pbID)
        StickyWindow(*this\m_pbID, State)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetPosition)(*this.mfwThisType(mfwWindow), X, Y)
    If IsWindow(*this\m_pbID)
        ResizeWindow(*this\m_pbID, X, Y, #PB_Ignore, #PB_Ignore)
    EndIf
EndProcedure

Procedure.l mfwMethod(mfwWindow, GetX)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        ProcedureReturn WindowX(*this\m_pbID)
    EndIf
EndProcedure

Procedure.l mfwMethod(mfwWindow, GetY)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        ProcedureReturn WindowY(*this\m_pbID)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetSize)(*this.mfwThisType(mfwWindow), Width, Height)
    If IsWindow(*this\m_pbID)
        ResizeWindow(*this\m_pbID, #PB_Ignore, #PB_Ignore, Width, Height)
    EndIf
EndProcedure

Procedure.l mfwMethod(mfwWindow, GetWidth)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        ProcedureReturn WindowWidth(*this\m_pbID)
    EndIf
EndProcedure

Procedure.l mfwMethod(mfwWindow, GetHeight)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        ProcedureReturn WindowHeight(*this\m_pbID)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetOpacity)(*this.mfwThisType(mfwWindow), Opacity.f = 1.0)
    If IsWindow(*this\m_pbID)
        If Opacity < 0.0 : Opacity = 0.0 : EndIf
        If Opacity > 1.0 : Opacity = 1.0 : EndIf
        __mfwPlatform_UI_SetOpacity(*this\m_pHwnd, Opacity)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, SetColour)(*this.mfwThisType(mfwWindow), Colour = #MFW_WINDOW_DEFAULTCOLOUR)
    If IsWindow(*this\m_pbID)
        SetWindowColor(*this\m_pbID, Colour)
    EndIf
EndProcedure

Procedure.l mfwMethod(mfwWindow, GetColour)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        ProcedureReturn GetWindowColor(*this\m_pbID)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Minimise)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        SetWindowState(*this\m_pbID, #PB_Window_Minimize)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Maximise)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        SetWindowState(*this\m_pbID, #PB_Window_Maximize)
    EndIf
EndProcedure

Procedure mfwMethod(mfwWindow, Restore)(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        SetWindowState(*this\m_pbID, #PB_Window_Normal)
    EndIf
EndProcedure

Procedure.a mfwMethod(mfwWindow, IsActive)(*this.mfwThisType(mfwWindow))
    If GetActiveWindow() = *this\m_pbID
        ProcedureReturn #True
    EndIf
    ProcedureReturn #False
EndProcedure

; - Implement Methods -
mfwImplementMethod(mfwWindow, Close)
mfwImplementMethod(mfwWindow, Show)
mfwImplementMethod(mfwWindow, Hide)
mfwImplementMethod(mfwWindow, Enable)
mfwImplementMethod(mfwWindow, Disable)
mfwImplementMethod(mfwWindow, AddKeyboardShortcut)
mfwImplementMethod(mfwWindow, RemoveKeyboardShortcut)
mfwImplementMethod(mfwWindow, AddTimer)
mfwImplementMethod(mfwWindow, RemoveTimer)
mfwImplementMethod(mfwWindow, SetTitle)
mfwImplementMethod(mfwWindow, GetTitle)
mfwImplementMethod(mfwWindow, SetSmartRefresh)
mfwImplementMethod(mfwWindow, SetBounds)
mfwImplementMethod(mfwWindow, SetActive)
mfwImplementMethod(mfwWindow, SetOnTop)
mfwImplementMethod(mfwWindow, SetPosition)
mfwImplementMethod(mfwWindow, GetX)
mfwImplementMethod(mfwWindow, GetY)
mfwImplementMethod(mfwWindow, SetSize)
mfwImplementMethod(mfwWindow, GetWidth)
mfwImplementMethod(mfwWindow, GetHeight)
mfwImplementMethod(mfwWindow, SetOpacity)
mfwImplementMethod(mfwWindow, SetColour)
mfwImplementMethod(mfwWindow, GetColour)
mfwImplementMethod(mfwWindow, Minimise)
mfwImplementMethod(mfwWindow, Maximise)
mfwImplementMethod(mfwWindow, Restore)
mfwImplementMethod(mfwWindow, IsActive)

; - Constructor -
Procedure mfwWindow_Constructor(*this.mfwThisType(mfwWindow))
    With *this
        \m_pbID = OpenWindow(#PB_Any, \m_wndX, \m_wndY, \m_wndWidth, \m_wndHeight, \m_wndTitle, \m_wndFlags | #PB_Window_Invisible)
        \m_pHwnd = WindowID(\m_pbID)
        \m_family = #MFW_UIFAMILY_WINDOW
        AddElement(*__mfwWindow_List()) : *__mfwWindow_List() = *this
    EndWith
EndProcedure

; - Destructor -
Procedure mfwWindow_Destructor(*this.mfwThisType(mfwWindow))
    If IsWindow(*this\m_pbID)
        CloseWindow(*this\m_pbID)
    EndIf
EndProcedure

; - Allocator -
Procedure mfwWindow_New(*Parent.mfwWindow = #Null, X = #PB_Ignore, Y = #PB_Ignore, Width = #MFW_WINDOW_DEFAULTWIDTH, Height = #MFW_WINDOW_DEFAULTHEIGHT, Title$ = #MFW_WINDOW_DEFAULTTITLE, Flags = #MFW_WINDOW_DEFAULTFLAGS)
    Protected.mfwThisType(mfwWindow) *this = mfwAllocObject(mfwWindow)
    With *this
        \m_wndX = X
        \m_wndY = Y
        \m_wndWidth = Width
        \m_wndHeight = Height
        \m_wndTitle = Title$
        \m_wndFlags = Flags
    EndWith
    mfwInitialiseObject(mfwWindow, *this)
    ProcedureReturn *this
EndProcedure

; - Implement Object -
mfwImplementObject(mfwWindow)

;------------------------------------------------------------------------------------------
; Title:        Form Test
; Description:  A demonstration of creating a form object.
; Author(s):    Michael R. King (mrking2910@gmail.com)
; Revision:     19 March 2012
;------------------------------------------------------------------------------------------

EnableExplicit

;IncludePath "../include"

; - Include Mastiff Framework -
;XIncludeFile "mfw/window.pbi"

; - Form Object -
Interface MyForm Extends mfwWindow
    MyMethod()
    OnClose(*Event.mfwUIEvent)
EndInterface

mfwBeginAttributesTableEx(MyForm, mfwWindow)
mfwEndAttributesTable()

mfwDefineObjectEx(MyForm, mfwWindow)

Procedure mfwMethod(MyForm, MyMethod)(*this.mfwThisType(MyForm))
    Debug "My Method has been Called!"
EndProcedure

Procedure mfwMethod(MyForm, OnClose)(*this.mfwThisType(MyForm), *Event.mfwUIEvent)
    Protected.MyForm *instance = *this
    Debug "Window has been Closed!"
    *instance\Close()
    *instance\Release()
    ProcedureReturn #False
EndProcedure

mfwImplementMethod(MyForm, MyMethod)
mfwImplementMethod(MyForm, OnClose)

; - Allocator -
Procedure.i MyForm_New()
    Protected.mfwThisType(MyForm) *this = mfwAllocObject(MyForm)
    Protected.MyForm *instance = *this
   
    mfwWindowCreationParams(*this, #Null, #PB_Ignore, #PB_Ignore, 800, 600, "Test Form")
   
    mfwInitialiseObject(MyForm, *this)
   
    *instance\SetColour(RGB(128, 64, 64))
    *instance\SetSmartRefresh(#True)
   
    *instance\EnableEventHandling(#True)
    *instance\ConnectEvent(#MFW_UIEVENT_CLOSE, mfwMethodPtr(MyForm, OnClose))
   
    ProcedureReturn *this
EndProcedure

mfwImplementObject(MyForm)


; - Sample -
Define.MyForm *Form = MyForm_New()

*Form\Show()
*Form\MyMethod()

While mfwWindowEvent()
Wend

mfwRelease()


This 'OOP Layer' supports inheritance, overriding, constructors/destructors, 'typeof', and is hopefully pretty straight forward. The example demonstrates a Window class with built in event handling so all events can be contained within the single window or form class.

All the best!

_________________
Image

.: Windows 7 Professional (32bit) :: Linux Mint 12 (32bit & 64bit) :.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye