Worm
02-17-2006, 09:15 AM
Splitter Framework:
Thanks to Tig and Dermot for helping me with the code and optimization.
How To Use:
1. Add these function calls to the following Page Events
On Show
--Sets the splitter cursor to the NS/WE arrows
InitSplitters()
-- SetSplitterMinMax(Name of the Splitter,
-- Minimum X or Y value for for the Left or Top pane,
-- Minimum X or Y value for the Right or Bottom pane)
-- Example that will stop splitter movement
-- 10 pixels from either side of the page.
-- SetSplitterMinMax("vsplit_Vertical", 10, 10)
On Size
DoSplitter_OnSize(e_WindowWidth, e_WindowHeight, e_PageWidth, e_PageHeight, e_Type);
On Mouse Button
DoSplitter_MouseButton(e_Type, e_X, e_Y);
On Mouse Move
DoSplitter_MouseMove(e_X, e_Y);
2. Copy this code to your Global Functions
--[[************************************************** ******]]--
--[[************************************************** ******]]--
--[[****************** SPLITTER FRAMEWORK ******************]]--
--[[************************************************** ******]]--
--[[************************************************** ******]]--
--[[************************************************** ******]]--
--[[ SPLITTER EVENTS ]]--
--[[************************************************** ******]]--
function On_Splitter_Move(m_sSplitterName, m_nDiff)
-- use this function for your own actions
-- when a splitter is moved.
end
--[[************************************************** ******]]--
--[[ Set up a table to reference the objects in AMS ]]--
--[[************************************************** ******]]--
tbObjectType = {}
tbObjectType[OBJECT_BUTTON] = Button;
tbObjectType[OBJECT_LABEL] = Label;
tbObjectType[OBJECT_PARAGRAPH] = Paragraph;
tbObjectType[OBJECT_IMAGE] = Image;
tbObjectType[OBJECT_FLASH] = Flash;
tbObjectType[OBJECT_VIDEO] = Video;
tbObjectType[OBJECT_WEB] = Web;
tbObjectType[OBJECT_INPUT] = Input;
tbObjectType[OBJECT_HOTSPOT] = Hotspot;
tbObjectType[OBJECT_LISTBOX] = ListBox;
tbObjectType[OBJECT_COMBOBOX] = ComboBox;
tbObjectType[OBJECT_PROGRESS] = Progress;
tbObjectType[OBJECT_TREE] = Tree;
tbObjectType[OBJECT_PLUGIN] = Plugin;
-- Function to initialize the splitters with code to change the cursors
-- also initiates the table that holds the ratios for sizing objects
function InitSplitters()
m_nCursor = nil;
m_tblObjectData = {};
tblObjects = Page.EnumerateObjects();
if tblObjects then
for index, sObject in tblObjects do
if String.Left(sObject, 7) == "vsplit_" or String.Left(sObject, 7) == "hsplit_" then
--add the script to the object to set the cursor to NS/EW arrows
m_sScript = Page.GetObjectScript(sObject, "ON ENTER");
if String.Left(sObject, 1) == "v" then
m_sScript = "m_nCursor = 32644\r\n"..m_sScript;
else
m_sScript = "m_nCursor = 32645\r\n"..m_sScript;
end
m_sScript = Page.SetObjectScript(sObject, "ON ENTER", m_sScript);
m_sScript = Page.GetObjectScript(sObject, "ON LEAVE");
m_sScript = [[if not m_blnMoveSplitter then
m_nCursor = nil;
end]].."\r\n"..m_sScript;
m_sScript = Page.SetObjectScript(sObject, "ON LEAVE", m_sScript);
end
-- set the ratio data in a table
local Object = tbObjectType[Page.GetObjectType(sObject)];
local m_XR = Object.GetPos(sObject).X / Page.GetSize().Width;
local m_YR = Object.GetPos(sObject).Y / Page.GetSize().Height;
local m_WR = Object.GetSize(sObject).Width / Page.GetSize().Width;
local m_HR = Object.GetSize(sObject).Height / Page.GetSize().Height;
m_tblObjectData[Table.Count(m_tblObjectData) + 1] = {Name=sObject, PosXR=m_XR , PosYR=m_YR, SizeWR=m_WR, SizeHR=m_HR};
end
end
end
-- Function to set the splitters Min and Max X/Y values
function SetSplitterMinMax(sSplitter, nMin, nMax)
if m_tbMinMax == nil then
m_tbMinMax = {};
end
m_tbMinMax[Table.Count(m_tbMinMax) + 1] = {Splitter=sSplitter, Min=nMin, Max=nMax};
end
-- Function to tell whether a point is in a given
-- objects rectangle
function IsInRect(m_nX, m_nY, m_tblPos, m_tblSize)
local bReturn = false;
if (m_nX >= m_tblPos.X) and (m_nX <= m_tblPos.X + m_tblSize.Width) then
if (m_nY >= m_tblPos.Y) and (m_nY <= m_tblPos.Y + m_tblSize.Height) then
bReturn = true;
end
end
return bReturn;
end
-- Function to set the ratios of the objects on the page. These
-- values are used in positioning the objects and splitters in a Resize
function SetNewRatios()
local z;
for z=1, Table.Count(m_tblObjectData) do
local SplitterObject = tbObjectType[Page.GetObjectType(m_tblObjectData[z].Name)];
m_tblObjectData[z].PosXR = SplitterObject.GetPos(m_tblObjectData[z].Name).X / Page.GetSize().Width
m_tblObjectData[z].PosYR = SplitterObject.GetPos(m_tblObjectData[z].Name).Y / Page.GetSize().Height
m_tblObjectData[z].SizeWR = SplitterObject.GetSize(m_tblObjectData[z].Name).Width / Page.GetSize().Width
m_tblObjectData[z].SizeHR = SplitterObject.GetSize(m_tblObjectData[z].Name).Height / Page.GetSize().Height
end
end
-- Function to detect when a splitter has been selected
function DoSplitter_MouseButton(e_Type, e_X, e_Y)
local bReturn = false;
local Object = nil;
if e_Type == LEFT_BUTTON_DOWN then
-- Get the objects on the page
tblObjects = Page.EnumerateObjects();
--if there are objects, and we are not currently moving a splitter
if tblObjects and not m_blnMoveSplitter then
for index, sObject in tblObjects do
--if the object is a splitter
if (String.Left(sObject, 7) == "vsplit_") or (String.Left(sObject, 7) == "hsplit_") then
--get the object type
Object = tbObjectType[Page.GetObjectType(sObject)];
--if our mouse pointer is inside of a splitters rectangle
if IsInRect(e_X, e_Y, Object.GetPos(sObject), Object.GetSize(sObject)) then
if not m_blnMoveSplitter then
--Get the initial Original Positions and Size
m_nOrigX = Object.GetPos(sObject).X;
m_nOrigY = Object.GetPos(sObject).Y;
m_nSplitterHeight = Object.GetSize(sObject).Height;
m_nSplitterWidth = Object.GetSize(sObject).Width;
end
--set the variables to allow the splitter to move
m_blnMoveSplitter = true;
m_sCurrentSplitter = sObject;
m_XOffset = e_X - Object.GetPos(sObject).X;
m_YOffset = e_Y - Object.GetPos(sObject).Y;
break;
end
end
end
end
else
-- we're no longer on a splitter, reset the variables that
-- allow the splitter to be moved.
m_nCursor = nil;
m_blnMoveSplitter = false;
SetNewRatios();
end
end
-- Function to move the splitter
function DoSplitter_MouseMove(e_X, e_Y)
local z;
if m_nCursor then
-- if we are over a splitter, set the cursor appropriately
local hCursor = DLL.CallFunction(_SystemFolder.."\\User32.dll", "LoadCursorA", "0, "..m_nCursor, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);
local retVal = DLL.CallFunction(_SystemFolder.."\\User32.dll", "SetCursor", hCursor, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);
end
if not System.IsKeyDown(1) then
m_blnMoveSplitter = false;
end
m_nDiff = 0;
if m_blnMoveSplitter then
-- set the application to *NOT* redraw for smoother
-- object movement
Application.SetRedraw(false)
-- get the current splitter's objecy type
local SplitterObject = tbObjectType[Page.GetObjectType(m_sCurrentSplitter)];
m_blnAllowMove = true;
if String.Left(m_sCurrentSplitter, 7) == "vsplit_" then
-- it's a vertical splitter
for z=1, Table.Count(m_tbMinMax) do
if m_sCurrentSplitter == m_tbMinMax[z].Splitter then
-- if we'ver reached the min or mac X value, do not allow
-- the splitter to be moved
if e_X - m_XOffset <= m_tbMinMax[z].Min or e_X + (SplitterObject.GetSize(m_sCurrentSplitter).Width - m_XOffset) >= Page.GetSize().Width - m_tbMinMax[z].Max then
m_blnAllowMove = false;
end
break;
end
end
if m_blnAllowMove then
-- Set the splitters position
SplitterObject.SetPos(m_sCurrentSplitter, e_X - m_XOffset, SplitterObject.GetPos(m_sCurrentSplitter).Y);
-- get the value of pixels the splitter was moved
m_nDiff = e_X - (m_nOrigX + m_XOffset);
for index, sObject in tblObjects do
Object = tbObjectType[Page.GetObjectType(sObject)];
-- if the object hasn't been designated to *NOT* move
if String.Left(sObject, 7) ~= "nomove_" then
-- if the object isn't another vertical splitter
if String.Left(sObject, 7) ~= "vsplit_" then
-- Move the objects
if (Object.GetPos(sObject).X <= m_nOrigX) and ((Object.GetPos(sObject).Y >= m_nOrigY) and (Object.GetPos(sObject).Y <= m_nOrigY + m_nSplitterHeight)) then
if Object.GetSize(sObject).Width + m_nDiff <=0 then
Object.SetSize(sObject, 0, Object.GetSize(sObject).Height);
Application.SetRedraw(true);
Object.SetVisible(sObject, false);
Page.Redraw();
Application.SetRedraw(false);
else
Object.SetVisible(sObject, true);
Object.SetSize(sObject, Object.GetSize(sObject).Width + m_nDiff, Object.GetSize(sObject).Height);
end
elseif (Object.GetPos(sObject).X >= m_nOrigX) and ((Object.GetPos(sObject).Y >= m_nOrigY) and (Object.GetPos(sObject).Y <= m_nOrigY + m_nSplitterHeight)) then
if Object.IsVisible(sObject) then
Object.SetPos(sObject, Object.GetPos(sObject).X + m_nDiff, Object.GetPos(sObject).Y );
Object.SetSize(sObject, Object.GetSize(sObject).Width - m_nDiff, Object.GetSize(sObject).Height);
end
end
end
end
end
-- set our splitters origanal position to the new position
m_nOrigX = m_nOrigX + m_nDiff;
end
elseif String.Left(m_sCurrentSplitter, 7) == "hsplit_" then
-- it's a Horizontal Splitter
for z=1, Table.Count(m_tbMinMax) do
if m_sCurrentSplitter == m_tbMinMax[z].Splitter then
-- if we'ver reached the min or mac X value, do not allow
-- the splitter to be moved
if e_Y - m_YOffset <= m_tbMinMax[z].Min or e_Y + (SplitterObject.GetSize(m_sCurrentSplitter).Height - m_YOffset) >= Page.GetSize().Height - m_tbMinMax[z].Max then
m_blnAllowMove = false;
end
break;
end
end
if m_blnAllowMove then
-- Set the splitters position
SplitterObject.SetPos(m_sCurrentSplitter, SplitterObject.GetPos(m_sCurrentSplitter).X, e_Y - m_YOffset);
-- get the value of pixels the splitter was moved
m_nDiff = e_Y - (m_nOrigY + m_YOffset);
for index, sObject in tblObjects do
Object = tbObjectType[Page.GetObjectType(sObject)];
-- if the object hasn't been designated to *NOT* move
if String.Left(sObject, 7) ~= "nomove_" then
-- if the object isn't another horizontal splitter
if String.Left(sObject, 7) ~= "hsplit_" then
-- Move the objects
if (Object.GetPos(sObject).Y <= m_nOrigY) and ((Object.GetPos(sObject).X >= m_nOrigX) and (Object.GetPos(sObject).X <= m_nOrigX + m_nSplitterWidth)) then
if Object.GetSize(sObject).Height + m_nDiff <= 0 then
Object.SetSize(sObject, Object.GetSize(sObject).Width, 0);
Application.SetRedraw(true);
Object.SetVisible(sObject, false);
Page.Redraw();
Application.SetRedraw(false);
else
Object.SetVisible(sObject, true);
Object.SetSize(sObject, Object.GetSize(sObject).Width, Object.GetSize(sObject).Height + m_nDiff);
end
elseif (Object.GetPos(sObject).Y >= m_nOrigY) and ((Object.GetPos(sObject).X >= m_nOrigX) and (Object.GetPos(sObject).X <= m_nOrigX + m_nSplitterWidth)) then
if Object.IsVisible(sObject) then
Object.SetPos(sObject, Object.GetPos(sObject).X, Object.GetPos(sObject).Y + m_nDiff );
Object.SetSize(sObject, Object.GetSize(sObject).Width, Object.GetSize(sObject).Height - m_nDiff);
end
end
end
end
end
-- set our splitters origanal position to the new position
m_nOrigY = m_nOrigY + m_nDiff;
end
end
-- fire event our own event
On_Splitter_Move(m_sCurrentSplitter, m_nDiff);
-- Allow the app to redraw
Application.SetRedraw(true);
-- Force redraw
Page.Redraw();
end
end
-- Function to Resize all objects and splitters
function DoSplitter_OnSize(e_WindowWidth, e_WindowHeight, e_PageWidth, e_PageHeight, e_Type)
if m_tblObjectData then
-- set redraw to false for smoother object moving
Application.SetRedraw(false)
for z=1, Table.Count(m_tblObjectData) do
m_Object = tbObjectType[Page.GetObjectType(m_tblObjectData[z].Name)];
-- if it's a vertical splitter, don't change its width
if String.Left(m_tblObjectData[z].Name, 7) == "vsplit_" then
m_Object.SetSize(m_tblObjectData[z].Name, m_Object.GetSize(m_tblObjectData[z].Name).Width, e_PageHeight * m_tblObjectData[z].SizeHR)
elseif String.Left(m_tblObjectData[z].Name, 7) == "hsplit_" then
-- if it's a horizontal splitter, don't change its height
m_Object.SetSize(m_tblObjectData[z].Name, e_PageWidth * m_tblObjectData[z].SizeWR, m_Object.GetSize(m_tblObjectData[z].Name).Height)
else
-- change the objects dimensions proportionately
m_Object.SetSize(m_tblObjectData[z].Name, e_PageWidth * m_tblObjectData[z].SizeWR, e_PageHeight * m_tblObjectData[z].SizeHR)
end
-- Set the objects position proportionately
m_Object.SetPos(m_tblObjectData[z].Name, e_PageWidth * m_tblObjectData[z].PosXR, e_PageHeight * m_tblObjectData[z].PosYR)
end
-- redraw!
Application.SetRedraw(true)
end
end
3. Add splitters to your page. The splitters can be any object that has an ON ENTER and ON LEAVE event. Rename your objects to the following convention:
The first 7 characters in the name of an Object that is a Vertical Splitter must be: "vsplit_"
The first 7 characters in the name of an Object that is a Horizontal Splitter must be: "hsplit_"
Once you've named your objects this way, the framework will automatically make them moveable splitters, nothing more to do.
4. Place the objects you want in each pane on the page, size them accordingly.
5. If you have an object that you do not want to be moved by the splitters, rename it to the following convention:
The first 7 characters in the name of an Object that should not be moved by a splitter must be: "nomove_"
6. In the Global Functions there is a code generated event named On_Splitter_Move. Use this event to manually move objects that are not handled correctly by the framework for your design.
Guidelines:
Just like in Ghost Busters, its important to not cross the streams, err splitters. The framework is designed to move/resize any object that falls within a splitters plain of movement. If another splitter is in that area, it too will be moved/resized.
Have Fun!!
Thanks to Tig and Dermot for helping me with the code and optimization.
How To Use:
1. Add these function calls to the following Page Events
On Show
--Sets the splitter cursor to the NS/WE arrows
InitSplitters()
-- SetSplitterMinMax(Name of the Splitter,
-- Minimum X or Y value for for the Left or Top pane,
-- Minimum X or Y value for the Right or Bottom pane)
-- Example that will stop splitter movement
-- 10 pixels from either side of the page.
-- SetSplitterMinMax("vsplit_Vertical", 10, 10)
On Size
DoSplitter_OnSize(e_WindowWidth, e_WindowHeight, e_PageWidth, e_PageHeight, e_Type);
On Mouse Button
DoSplitter_MouseButton(e_Type, e_X, e_Y);
On Mouse Move
DoSplitter_MouseMove(e_X, e_Y);
2. Copy this code to your Global Functions
--[[************************************************** ******]]--
--[[************************************************** ******]]--
--[[****************** SPLITTER FRAMEWORK ******************]]--
--[[************************************************** ******]]--
--[[************************************************** ******]]--
--[[************************************************** ******]]--
--[[ SPLITTER EVENTS ]]--
--[[************************************************** ******]]--
function On_Splitter_Move(m_sSplitterName, m_nDiff)
-- use this function for your own actions
-- when a splitter is moved.
end
--[[************************************************** ******]]--
--[[ Set up a table to reference the objects in AMS ]]--
--[[************************************************** ******]]--
tbObjectType = {}
tbObjectType[OBJECT_BUTTON] = Button;
tbObjectType[OBJECT_LABEL] = Label;
tbObjectType[OBJECT_PARAGRAPH] = Paragraph;
tbObjectType[OBJECT_IMAGE] = Image;
tbObjectType[OBJECT_FLASH] = Flash;
tbObjectType[OBJECT_VIDEO] = Video;
tbObjectType[OBJECT_WEB] = Web;
tbObjectType[OBJECT_INPUT] = Input;
tbObjectType[OBJECT_HOTSPOT] = Hotspot;
tbObjectType[OBJECT_LISTBOX] = ListBox;
tbObjectType[OBJECT_COMBOBOX] = ComboBox;
tbObjectType[OBJECT_PROGRESS] = Progress;
tbObjectType[OBJECT_TREE] = Tree;
tbObjectType[OBJECT_PLUGIN] = Plugin;
-- Function to initialize the splitters with code to change the cursors
-- also initiates the table that holds the ratios for sizing objects
function InitSplitters()
m_nCursor = nil;
m_tblObjectData = {};
tblObjects = Page.EnumerateObjects();
if tblObjects then
for index, sObject in tblObjects do
if String.Left(sObject, 7) == "vsplit_" or String.Left(sObject, 7) == "hsplit_" then
--add the script to the object to set the cursor to NS/EW arrows
m_sScript = Page.GetObjectScript(sObject, "ON ENTER");
if String.Left(sObject, 1) == "v" then
m_sScript = "m_nCursor = 32644\r\n"..m_sScript;
else
m_sScript = "m_nCursor = 32645\r\n"..m_sScript;
end
m_sScript = Page.SetObjectScript(sObject, "ON ENTER", m_sScript);
m_sScript = Page.GetObjectScript(sObject, "ON LEAVE");
m_sScript = [[if not m_blnMoveSplitter then
m_nCursor = nil;
end]].."\r\n"..m_sScript;
m_sScript = Page.SetObjectScript(sObject, "ON LEAVE", m_sScript);
end
-- set the ratio data in a table
local Object = tbObjectType[Page.GetObjectType(sObject)];
local m_XR = Object.GetPos(sObject).X / Page.GetSize().Width;
local m_YR = Object.GetPos(sObject).Y / Page.GetSize().Height;
local m_WR = Object.GetSize(sObject).Width / Page.GetSize().Width;
local m_HR = Object.GetSize(sObject).Height / Page.GetSize().Height;
m_tblObjectData[Table.Count(m_tblObjectData) + 1] = {Name=sObject, PosXR=m_XR , PosYR=m_YR, SizeWR=m_WR, SizeHR=m_HR};
end
end
end
-- Function to set the splitters Min and Max X/Y values
function SetSplitterMinMax(sSplitter, nMin, nMax)
if m_tbMinMax == nil then
m_tbMinMax = {};
end
m_tbMinMax[Table.Count(m_tbMinMax) + 1] = {Splitter=sSplitter, Min=nMin, Max=nMax};
end
-- Function to tell whether a point is in a given
-- objects rectangle
function IsInRect(m_nX, m_nY, m_tblPos, m_tblSize)
local bReturn = false;
if (m_nX >= m_tblPos.X) and (m_nX <= m_tblPos.X + m_tblSize.Width) then
if (m_nY >= m_tblPos.Y) and (m_nY <= m_tblPos.Y + m_tblSize.Height) then
bReturn = true;
end
end
return bReturn;
end
-- Function to set the ratios of the objects on the page. These
-- values are used in positioning the objects and splitters in a Resize
function SetNewRatios()
local z;
for z=1, Table.Count(m_tblObjectData) do
local SplitterObject = tbObjectType[Page.GetObjectType(m_tblObjectData[z].Name)];
m_tblObjectData[z].PosXR = SplitterObject.GetPos(m_tblObjectData[z].Name).X / Page.GetSize().Width
m_tblObjectData[z].PosYR = SplitterObject.GetPos(m_tblObjectData[z].Name).Y / Page.GetSize().Height
m_tblObjectData[z].SizeWR = SplitterObject.GetSize(m_tblObjectData[z].Name).Width / Page.GetSize().Width
m_tblObjectData[z].SizeHR = SplitterObject.GetSize(m_tblObjectData[z].Name).Height / Page.GetSize().Height
end
end
-- Function to detect when a splitter has been selected
function DoSplitter_MouseButton(e_Type, e_X, e_Y)
local bReturn = false;
local Object = nil;
if e_Type == LEFT_BUTTON_DOWN then
-- Get the objects on the page
tblObjects = Page.EnumerateObjects();
--if there are objects, and we are not currently moving a splitter
if tblObjects and not m_blnMoveSplitter then
for index, sObject in tblObjects do
--if the object is a splitter
if (String.Left(sObject, 7) == "vsplit_") or (String.Left(sObject, 7) == "hsplit_") then
--get the object type
Object = tbObjectType[Page.GetObjectType(sObject)];
--if our mouse pointer is inside of a splitters rectangle
if IsInRect(e_X, e_Y, Object.GetPos(sObject), Object.GetSize(sObject)) then
if not m_blnMoveSplitter then
--Get the initial Original Positions and Size
m_nOrigX = Object.GetPos(sObject).X;
m_nOrigY = Object.GetPos(sObject).Y;
m_nSplitterHeight = Object.GetSize(sObject).Height;
m_nSplitterWidth = Object.GetSize(sObject).Width;
end
--set the variables to allow the splitter to move
m_blnMoveSplitter = true;
m_sCurrentSplitter = sObject;
m_XOffset = e_X - Object.GetPos(sObject).X;
m_YOffset = e_Y - Object.GetPos(sObject).Y;
break;
end
end
end
end
else
-- we're no longer on a splitter, reset the variables that
-- allow the splitter to be moved.
m_nCursor = nil;
m_blnMoveSplitter = false;
SetNewRatios();
end
end
-- Function to move the splitter
function DoSplitter_MouseMove(e_X, e_Y)
local z;
if m_nCursor then
-- if we are over a splitter, set the cursor appropriately
local hCursor = DLL.CallFunction(_SystemFolder.."\\User32.dll", "LoadCursorA", "0, "..m_nCursor, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);
local retVal = DLL.CallFunction(_SystemFolder.."\\User32.dll", "SetCursor", hCursor, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);
end
if not System.IsKeyDown(1) then
m_blnMoveSplitter = false;
end
m_nDiff = 0;
if m_blnMoveSplitter then
-- set the application to *NOT* redraw for smoother
-- object movement
Application.SetRedraw(false)
-- get the current splitter's objecy type
local SplitterObject = tbObjectType[Page.GetObjectType(m_sCurrentSplitter)];
m_blnAllowMove = true;
if String.Left(m_sCurrentSplitter, 7) == "vsplit_" then
-- it's a vertical splitter
for z=1, Table.Count(m_tbMinMax) do
if m_sCurrentSplitter == m_tbMinMax[z].Splitter then
-- if we'ver reached the min or mac X value, do not allow
-- the splitter to be moved
if e_X - m_XOffset <= m_tbMinMax[z].Min or e_X + (SplitterObject.GetSize(m_sCurrentSplitter).Width - m_XOffset) >= Page.GetSize().Width - m_tbMinMax[z].Max then
m_blnAllowMove = false;
end
break;
end
end
if m_blnAllowMove then
-- Set the splitters position
SplitterObject.SetPos(m_sCurrentSplitter, e_X - m_XOffset, SplitterObject.GetPos(m_sCurrentSplitter).Y);
-- get the value of pixels the splitter was moved
m_nDiff = e_X - (m_nOrigX + m_XOffset);
for index, sObject in tblObjects do
Object = tbObjectType[Page.GetObjectType(sObject)];
-- if the object hasn't been designated to *NOT* move
if String.Left(sObject, 7) ~= "nomove_" then
-- if the object isn't another vertical splitter
if String.Left(sObject, 7) ~= "vsplit_" then
-- Move the objects
if (Object.GetPos(sObject).X <= m_nOrigX) and ((Object.GetPos(sObject).Y >= m_nOrigY) and (Object.GetPos(sObject).Y <= m_nOrigY + m_nSplitterHeight)) then
if Object.GetSize(sObject).Width + m_nDiff <=0 then
Object.SetSize(sObject, 0, Object.GetSize(sObject).Height);
Application.SetRedraw(true);
Object.SetVisible(sObject, false);
Page.Redraw();
Application.SetRedraw(false);
else
Object.SetVisible(sObject, true);
Object.SetSize(sObject, Object.GetSize(sObject).Width + m_nDiff, Object.GetSize(sObject).Height);
end
elseif (Object.GetPos(sObject).X >= m_nOrigX) and ((Object.GetPos(sObject).Y >= m_nOrigY) and (Object.GetPos(sObject).Y <= m_nOrigY + m_nSplitterHeight)) then
if Object.IsVisible(sObject) then
Object.SetPos(sObject, Object.GetPos(sObject).X + m_nDiff, Object.GetPos(sObject).Y );
Object.SetSize(sObject, Object.GetSize(sObject).Width - m_nDiff, Object.GetSize(sObject).Height);
end
end
end
end
end
-- set our splitters origanal position to the new position
m_nOrigX = m_nOrigX + m_nDiff;
end
elseif String.Left(m_sCurrentSplitter, 7) == "hsplit_" then
-- it's a Horizontal Splitter
for z=1, Table.Count(m_tbMinMax) do
if m_sCurrentSplitter == m_tbMinMax[z].Splitter then
-- if we'ver reached the min or mac X value, do not allow
-- the splitter to be moved
if e_Y - m_YOffset <= m_tbMinMax[z].Min or e_Y + (SplitterObject.GetSize(m_sCurrentSplitter).Height - m_YOffset) >= Page.GetSize().Height - m_tbMinMax[z].Max then
m_blnAllowMove = false;
end
break;
end
end
if m_blnAllowMove then
-- Set the splitters position
SplitterObject.SetPos(m_sCurrentSplitter, SplitterObject.GetPos(m_sCurrentSplitter).X, e_Y - m_YOffset);
-- get the value of pixels the splitter was moved
m_nDiff = e_Y - (m_nOrigY + m_YOffset);
for index, sObject in tblObjects do
Object = tbObjectType[Page.GetObjectType(sObject)];
-- if the object hasn't been designated to *NOT* move
if String.Left(sObject, 7) ~= "nomove_" then
-- if the object isn't another horizontal splitter
if String.Left(sObject, 7) ~= "hsplit_" then
-- Move the objects
if (Object.GetPos(sObject).Y <= m_nOrigY) and ((Object.GetPos(sObject).X >= m_nOrigX) and (Object.GetPos(sObject).X <= m_nOrigX + m_nSplitterWidth)) then
if Object.GetSize(sObject).Height + m_nDiff <= 0 then
Object.SetSize(sObject, Object.GetSize(sObject).Width, 0);
Application.SetRedraw(true);
Object.SetVisible(sObject, false);
Page.Redraw();
Application.SetRedraw(false);
else
Object.SetVisible(sObject, true);
Object.SetSize(sObject, Object.GetSize(sObject).Width, Object.GetSize(sObject).Height + m_nDiff);
end
elseif (Object.GetPos(sObject).Y >= m_nOrigY) and ((Object.GetPos(sObject).X >= m_nOrigX) and (Object.GetPos(sObject).X <= m_nOrigX + m_nSplitterWidth)) then
if Object.IsVisible(sObject) then
Object.SetPos(sObject, Object.GetPos(sObject).X, Object.GetPos(sObject).Y + m_nDiff );
Object.SetSize(sObject, Object.GetSize(sObject).Width, Object.GetSize(sObject).Height - m_nDiff);
end
end
end
end
end
-- set our splitters origanal position to the new position
m_nOrigY = m_nOrigY + m_nDiff;
end
end
-- fire event our own event
On_Splitter_Move(m_sCurrentSplitter, m_nDiff);
-- Allow the app to redraw
Application.SetRedraw(true);
-- Force redraw
Page.Redraw();
end
end
-- Function to Resize all objects and splitters
function DoSplitter_OnSize(e_WindowWidth, e_WindowHeight, e_PageWidth, e_PageHeight, e_Type)
if m_tblObjectData then
-- set redraw to false for smoother object moving
Application.SetRedraw(false)
for z=1, Table.Count(m_tblObjectData) do
m_Object = tbObjectType[Page.GetObjectType(m_tblObjectData[z].Name)];
-- if it's a vertical splitter, don't change its width
if String.Left(m_tblObjectData[z].Name, 7) == "vsplit_" then
m_Object.SetSize(m_tblObjectData[z].Name, m_Object.GetSize(m_tblObjectData[z].Name).Width, e_PageHeight * m_tblObjectData[z].SizeHR)
elseif String.Left(m_tblObjectData[z].Name, 7) == "hsplit_" then
-- if it's a horizontal splitter, don't change its height
m_Object.SetSize(m_tblObjectData[z].Name, e_PageWidth * m_tblObjectData[z].SizeWR, m_Object.GetSize(m_tblObjectData[z].Name).Height)
else
-- change the objects dimensions proportionately
m_Object.SetSize(m_tblObjectData[z].Name, e_PageWidth * m_tblObjectData[z].SizeWR, e_PageHeight * m_tblObjectData[z].SizeHR)
end
-- Set the objects position proportionately
m_Object.SetPos(m_tblObjectData[z].Name, e_PageWidth * m_tblObjectData[z].PosXR, e_PageHeight * m_tblObjectData[z].PosYR)
end
-- redraw!
Application.SetRedraw(true)
end
end
3. Add splitters to your page. The splitters can be any object that has an ON ENTER and ON LEAVE event. Rename your objects to the following convention:
The first 7 characters in the name of an Object that is a Vertical Splitter must be: "vsplit_"
The first 7 characters in the name of an Object that is a Horizontal Splitter must be: "hsplit_"
Once you've named your objects this way, the framework will automatically make them moveable splitters, nothing more to do.
4. Place the objects you want in each pane on the page, size them accordingly.
5. If you have an object that you do not want to be moved by the splitters, rename it to the following convention:
The first 7 characters in the name of an Object that should not be moved by a splitter must be: "nomove_"
6. In the Global Functions there is a code generated event named On_Splitter_Move. Use this event to manually move objects that are not handled correctly by the framework for your design.
Guidelines:
Just like in Ghost Busters, its important to not cross the streams, err splitters. The framework is designed to move/resize any object that falls within a splitters plain of movement. If another splitter is in that area, it too will be moved/resized.
Have Fun!!