Project Perfect Mod Forums
:: Home :: Get Hosted :: PPM FAQ :: Forum FAQ :: Privacy Policy :: Search :: Memberlist :: Usergroups :: Register :: Profile :: Log in to check your private messages :: Log in ::


The time now is Thu Mar 28, 2024 9:54 am
All times are UTC + 0
[Dev Info] OS SHP Builder MDI Engine
Moderators: stucuk
Post new topic   Reply to topic Page 1 of 1 [1 Post] Mark the topic unread ::  View previous topic :: View next topic
Author Message
Banshee
Supreme Banshee


Also Known As: banshee_revora (Steam)
Joined: 15 Aug 2002
Location: Brazil

PostPosted: Sat Apr 24, 2004 6:20 am    Post subject:  [Dev Info] OS SHP Builder MDI Engine Reply with quote  Mark this post and the followings unread

Ok, Here I am revealing how the MDI engine works in OS SHP Builder and how it affects the programmer. This uses the code of the OS SHP Builder Beta 3.0 Built 23/04/2004.

Index:

1 - Introduction
2 - The Concepts
3 - The Identifier Changes
4 - Generating New SHPs and New Windows
5 - Editing New SHP Generation Ways
6 - SHP_Data_Matrix.pas
7 - Pointers And Ways To Avoid Circular Reference At FrmSHPImage and FrmPreview
8 - Final Conclusions


1 - Introduction

- MDI stands for Multiples Documents Interface. The MDI engine was implemented to make OS SHP Builder support multiples files like PSP, Photoshop and other good 2D graphic editors do.

BS SHP Builder 1.x and 2.x used to work with only one file and all its data centralized in one place (Form Main). By changing multiples files, a MDI obligates the program to split into files and the interface. Unlike PSP and Photoshop, OS SHP Builder's MDI engine was also made to allow different windows access the same SHP file. So, we had to split the program in editing windows, shp files and interface.

The interface may feature as many SHP files as the user want and each SHP file has as many windows as the user wants, However, only one SHP File and only one Window will be active at a moment. The interface is responsible for indicating the active SHP file with the variable "ActiveData" and the active editing window with the variable "ActiveForm". View the attachment with the Data Structure graphic for further info. In that graphic, the first window of the second SHP File is the active window.

The MDI engine will be totally responsible for the creation and destruction of the interface, shp file and editing window. The descentralization of the file affects the variables used in other forms, although it doesnt affect its way of working.



2 - The Concepts

The interface is the FormMain. The Form Main only contains the top menu, the left toolbar and the statusbar. The Form Main also deals with user selection and TempView. It's the main responsible for the intercomunication of the program.

The editing frame contains only one image and all variables related to image. Each window has its own selected colour and shadow settings, as well as its own show circle settings and also other settings that only directly affects the current image. The editing window also has one variable that indicates which SHP file it belongs to.

The SHP file doesnt contain only the SHP file. It also contains the palette, the undo settings, the filename and the forms linked into it as well as the preview window.

The program accepts bidirectional comunications, which means that the interface can access all shp files that can access all windows linked into each of them and the window can access the shp file linked into them and the interface as well. However, only the interface indicates which shp file is active and which editing window is active.


3 - The Identifier Changes

Here's the new variables at Form Main (interface):

Code:
    ActiveForm : ^TFrmSHPImage;
    ActiveData : TSHPImageData;
    TotalImages : word;


ActiveForm: This pointer holds the memory address of the Form (editing window) that is currently active. To access the variables of this ActiveForm, you need to add a ^ before the dot. I.e.:

ActiveForm^.ShadowMode := false;
ActiveForm^.ActiveColour := 16;
ActiveForm^.ShadowColour := 1;

(Outside FormMain, you must add 'FrmMain.' before the ActiveForm, duh!)

ActiveData: This pointer holds the memory address of the currently active SHP file. To access the variables of this ActiveData, you need to add a ^ before the dot. I.e.:

// Prepare conversion (Note: alg <> 0)
GenerateColourList(ActiveData^.SHPPalette,List,Last,Bitmap.Canvas.Pixels[0,0],false,false,false);
PrepareBank(Start,List,Last);

// Convert Bitmap to the SHP file
LoadFrameImageToSHP(ActiveData^.SHP,ActiveForm^.Frame,Bitmap,List,Last,Start,alg);

// Remove the trash:
ClearColourList(List,Last);
ClearBank(Start);


Total Images: Provides the ID of the SHP. This number only grows, so each SHP file will certainly have a different ID.


Here's the new variables at the SHP File (TSHPImageData)

Code:
TSHPImageForm = ^tshpimageformitem;
tshpimageformitem = record
                     Item : TFrmSHPImage;
                     Next : TSHPImageForm;
                     end;

TSHPImageData = ^tshpimagedataitem;
tshpimagedataitem = record
                    ID : Word;
                    SHP : TSHP;
                    SHPPalette: TPalette;
                    SHPPaletteFilename : string;
                    PaletteMax : Word;
                    UndoList : TUndoRedo;
                    Shadow_Match : TShadowMatch;
                    Filename : string;
                    Form: TSHPImageForm;
                    Preview : ^TFrmPreview;
                    Next: TSHPImageData;
                    end;


ID: ID of the SHP File, used on searchs, close all and other stuff. It might look useless at OS SHP Builder 3.0.

SHP: The heart of the program is here.

SHPPalette: The Palette is no longer a global variable and now each file can have its own palette.

SHPPaletteFilename: This was created with the purpouse of avoiding excessives repaints of the Palette, however it helps also the generation of new shp files.

PaletteMax: I just noticed this variable should be in the editing window, not here. so it will be moved. Anyway, this is the max number of colours of the palette and interacts with shadows.

UndoList: No longer a global variable. Now each file has its own undo list.

ShadowMatch: Cache to speed up the generation of grayed frames.

Filename: The name of the SHP file.

Form: Holds the info about all editing windows linked into the SHP file. When no editing window is linked, it receives the value 'nil'.

Form^.Item: Holds the memory address of one of the editing windows linked to the SHP file. You can control the editing window from it.

Form^.Next: Holds the memory address of the next "Form". If there is no next Form, it's value get set to 'nil'.

Preview Holds the memory address of the Preview window linked to the SHP file. If there is no preview window in the moment, it will receive the value 'nil'. I.e.:

// Close Preview if it's opened
If Data^.Preview <> nil then
Data^.Preview^.Close;

Next: Holds the memory address of the next SHP file. If this is the last SHP file, it will receive 'nil' as value.


And finally, the editing window:

Code:
type
  TFrmSHPImage = class(TForm)
    PaintPanel: TPanel;
    ScrollBox1: TScrollBox;
    PaintAreaPanel: TPanel;
    Image1: TImage;
    procedure ResizePaintArea(var Image1 : TImage; var PaintAreaPannel: TPanel);
    procedure RefreshImage1;
    procedure SetShadowColour(Col: Integer);
    procedure SetActiveColour(Col: Integer);
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure SetShadowMode(Value : boolean);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    First,Last : TPoint2D;
    ActiveColour,ShadowColour : byte;
    Zoom : byte;
    Frame : longword;
    ShadowMode : boolean;
    show_center : boolean;
    DefultCursor : integer;
    ID : word;
    Data : Pointer;
    Address : Pointer;
  end;


First and Last: 2D points that represents the first point that the user clicked and the final point. Usefull for lines, squares, elipses and other stuff....

ActiveColour and ShadowColour: Controls the number of the colour selected by the user for active and shadow frames respectivelly.

Zoom: Controls the current zoom factor value set by the user for this form.

Frame: Controls the number of the frame that is being showed to the user.

ShadowMode: Controls if the window has shadows on or off.

show_center: Controls if the user wants a cross in the image showing the center.

DefultCursor: Stucuk tried to spell DefaultCursor, but apparently he missed the 'a' from Default. Anyway, it's the number/id of the cursor that is appearing when you pass the mouse over the image...

ID: Identification of the form. Currently useless, but might be usefull when we create a view menu that displays the windows that are opened.

Data: Holds the memory address of the SHP file that the window belongs. To avoid circular reference, I had to use the type Pointer for it. Check further info on this below.

Address: Holds the memory address of this form. Whenever the window gets activated, FormMain.ActiveForm receives the value of this variable.


And the global variable is...

Code:
MainData : TSHPImageData;


MainData: Holds the original SHP file, which is a sentinel used when there are no files opened holding several dummy or default values. It's needed to repaint the palette image as well as to allow the user to select the palette before creating or opening a file or importing an image. MainData^.Next will have the first editable SHP file when FrmMain.IsEditable = true.


Other variables:

The other forms have received the variable:

Code:
Data: TSHPImageData;


Data: It holds the memory address of the SHP file that was active when the form was originally activated.

FormBlah := TFormBlah.Create(self);
FormBlah.Data := ActiveData;
FormBlah.Showmodal;



4 - Generating New SHPs and New Windows

There are 3 functions that do that:

AddNewSHPDataItem; {generates a new SHP file. Parameters may vary depending on your intention, since this function is overloaded.}

FrmMain.GenerateNewWindow(var Data: TSHPImageData); {creates a new window for an specific shp file}

procedure LoadNewSHPImageSettings(var Data : TSHPImageData); {fills the window with the settings. Sets captions, variables, image1 sizes, etc...}


5 - Editing New SHP Generation Functions For New Situations

You can create a new version of AddNewSHPDataItem();, as long as the parameters are different and you end with an overload; in the end of the declaration.

6 - SHP_Data_Matrix.pas

This file holds the MainData and the AddNewSHPItem and the LoadNewSHPImageSettings. It was originally made to deal with all MDI functions, although it currently shares this job with Form Main.


7 - Pointers And Ways To Avoid Circular Reference At FrmSHPImage and FrmPreview

To avoids circular references, I had to declare Data as a generic pointer on both TFrmSHPImage and TFrmPreview. To make a good use of this Data, on every procedure/function that uses it, you should put:

Code:

var
SHPData:TSHPImageData;
begin

SHPData := Data;


I personally think this is an idiocy from Delphi, but that's the way it works...


8 - Final Conclusions

The engine is quite fine, although it might be improved and some burocratic things might be able to be removed one day... maybe moving PaletteMax to the editing window or moving ShadowMode for the SHP file... well, Beta Testing might provide us the final answers. In the end, the program still runs in the same way, but with different concepts. I hope this tutorial helps you to understand the concepts behind the SHP builder... Anyway, I am opened for suggestions. If you think is there any way to improve it, post here.



New Data Structure.jpg
 Description:
New Data Structure. The interface acepts multiples SHP files that accepts multiples editing windows and only one Form Preview.
 Filesize:  38.38 KB
 Viewed:  5647 Time(s)

New Data Structure.jpg



Back to top
View user's profile Send private message Visit poster's website Skype Account
Display posts from previous:   
Post new topic   Reply to topic Page 1 of 1 [1 Post] Mark the topic unread ::  View previous topic :: View next topic
 
Share on TwitterShare on FacebookShare on Google+Share on DiggShare on RedditShare on PInterestShare on Del.icio.usShare on Stumble Upon
Quick Reply
Username:


If you are visually impaired or cannot otherwise answer the challenges below please contact the Administrator for help.


Write only two of the following words separated by a sharp: Brotherhood, unity, peace! 

 
You cannot post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © phpBB Group

[ Time: 0.1623s ][ Queries: 14 (0.0107s) ][ Debug on ]