Location: PHPKode > scripts > Kreatura > kreatura/kreatura.php
<?php

/*
    This file contains: Kreatura v1.0 class and BaseCell class.
    Please refer to the documentation.
    Feel free to mail me with suggestions, questions, examples...
    This class hasn't been perfectly tested
    
    (C) Tomek Glinski 2004
    tomekglinski at o2.pl
    
    www.kreatura.prv.pl
    www.kreatura.go.pl
    www.actuosus.prv.pl
    www.actuosus.go.pl
    www.tomekglinski.prv.pl
    www.tomekglinski.go.pl
*/




class Kreatura{

    var $Width; // Amount of columns in the table
    var $Height;    // Amount of rows in the table

    var $CellWidth; // Width of table cell if always the same
    var $CellHeight; // Height of table cell if always the same

    var $CellWidthArray=Array(); // Widths of table cells 
    var $CellHeightarray=Array(); // Heights of table cells
    
    var $TableTagArray=Array();    // <table here_it_goes>
    var $Content=Array();   // Array o Cell objects
    
    function Kreatura($Width, $Height){
        if (!is_int($Width) || !is_int($Height) || $Width<1 || $Height<1) die("Kreatura->constructor: invalid parameter(s) ($Width, $Height)<br>\n");
        $this->Width=$Width;
        $this->Height=$Height;
    }
    

    function setColumnWidth($Which, $Val){
        if (!is_int($Which) || $Which < 0 or $Which >= $this->Width) die("Kreatura->setColumnWidth: invalid column number.");
        $this->CellWidthArray[$Which] = $Val;
    }

    function setRowHeight($Which, $Val){
        if (!is_int($Which) || $Which < 0 or $Which >= $this->Height) die("Kreatura->setRowHeight: invalid row number.");
        $this->CellHeightArray[$Which] = $Val;
    }

    function setTableTag($TagName, $TagValue){
        $this->TableTagArray[$TagName]=$TagValue;
    }

    function getTableTag($TagName){
        return $this->TableTagArray[$TagName];
    }

    function delTableTag($TagName){
        if (array_key_exists($TagName, $this->TableTagArray)){
            if (count($this->TableTagArray) == 1) array_pop($this->TableTagArray);
            else $this->TableTagArray[$TagName]=array_pop($this->TableTagArray);
        }
    }

    function setCellsAmount($x, $y){
        if (!is_int($x) or !is_int($y)) die("Kreatura->setCellsAmount: invalid parameter(s)");
        $this->Width=$x;
        $this->Height=$y;
    }

    function setCellsDims($x, $y){
        $this->CellWidth=$x;
        $this->CellHeight=$y;
    }
    
    //returns whole opening TABLE tag
    function getOpeningTableTag(){
        // set some tags
        $this->setTableTag("cellpadding", "0");
        $this->setTableTag("cellspacing", "0");
 
        $ret="<table";
        foreach($this->TableTagArray as $OptName => $OptValue){
            $ret.= " $OptName=\"$OptValue\"";
        }
        $ret.= ">\n";
        return $ret;
    }
    
    function addCell(&$CellObj, $check=true){
        // is the CellObj the object?
        if (!is_object($CellObj)) die("Kreatura->addCell: expecting object");

        // does the Cell fit the matrix?
        if ($CellObj->Xpos + $CellObj->Width > $this->Width) die("Kreatura->addCell: added Cell '".$CellObj->Name."' exceeds the matrix right border");
        if ($CellObj->Ypos + $CellObj->Height > $this->Height) die("Kreatura->addCell: added Cell '".$CellObj->Name."' exceeds the matrix bottom border");
        if ($CellObj->Xpos < 0) die("Kreatura->addCell: added Cell '".$CellObj->Name."' has X position < 0 !?");
        if ($CellObj->Ypos < 0) die("Kreatura->addCell: added Cell '".$CellObj->Name."' has Y position < 0 !?");
                
        
        if ($check){
            // collision with existing Cells
            foreach($this->Content as $Cell2){
                $no_collision=false;
                if ($Cell2->Xpos + $Cell2->Width-1 < $CellObj->Xpos) $no_collision = true;
                if ($Cell2->Xpos > $CellObj->Xpos + $CellObj->Width-1) $no_collision = true;
                if ($Cell2->Ypos + $Cell2->Height-1 < $CellObj->Ypos) $no_collision = true;
                if ($Cell2->Ypos > $CellObj->Ypos + $CellObj->Height-1) $no_collision = true;
                if (!$no_collision) die("Kreatura->addCell: collision of the Cells objects detected. Cells names: '".$CellObj->Name."' and '".$Cell2->Name."'<br>You can switch off on-add collision detection by calling addCell(Cell, <b>false</b>)");
            }
        }
        $this->Content[] = & $CellObj;
    }
    

    function &getCell($CellName){
        for($i=0; $i< count($this->Content); ++$i){
            $t=$this->Content[$i];
            if ($t->Name == $CellName){
                return  $this->Content[$i];
            }
        }
        return null;
    }

    
    function removeCell($CellName){
        $k=null;

        foreach($this->Content as $Key => $Cel){
            if ($Cel->Name == $CellName){
                $k = $Key;
                break;
            }
        }
        if ($k == null) return;
        if (($l = count($this->Content)) == 1 || $this->Content[$l-1]->Name == $CellName) @array_pop($this->Content);
        else $this->Content[$k] = @array_pop($this->Content);
    }
    
    function generate(){
        $tab=Array();
        // create new table with right keys
        foreach($this->Content as $Cel){
            if ($Cel->Visible){
                // collision with existing Cells
                foreach($tab as $Cell2){
                    $no_collision=false;
                    if ($Cell2->Xpos + $Cell2->Width-1 < $Cel->Xpos) $no_collision = true;
                    if ($Cell2->Xpos > $Cel->Xpos + $Cel->Width-1) $no_collision = true;
                    if ($Cell2->Ypos + $Cell2->Height-1 < $Cel->Ypos) $no_collision = true;
                    if ($Cell2->Ypos > $Cel->Ypos + $Cel->Height-1) $no_collision = true;
                    if (!$no_collision) die("Kreatura->generate: collision of the Cells objects detected. Cells names: '".$Cel->Name."' and '".$Cell2->Name."'");
                }
                $tab[] = $Cel;
            }

        }
            
        // sort the Content - from up to down, from left to right
        for ($i=0; $i < count($tab); ++$i){
            for($j = count($tab) - 1; $j > $i; --$j){
                if ($tab[$j]->Ypos < $tab[$j-1]->Ypos or ($tab[$j]->Ypos == $tab[$j-1]->Ypos and $tab[$j]->Xpos < $tab[$j-1]->Xpos)){
                    $buf = $tab[$j];
                    $tab[$j] = $tab[$j-1];
                    $tab[$j-1] = $buf;
                }
            }
        }   

        // Create opening table tag
        $ret = $this->getOpeningTableTag();

        // Filling the table. It has one aditional row and column to preserve sizes
        // additional row - empty cells with width
        $ret.= '<tr><td width="0" height="0">';
        for($i = 0; $i < $this->Width; ++$i){
            if (($wi = $this->CellWidthArray[$i])=="") $ret.= '<td width="'.$this->CellWidth.'">';
            else $ret.= '<td width="'.$wi.'">';
        }
        $ret.= "</tr>\n";

        // going left->right, up->down
        for($y = 0; $y < $this->Height; ++$y){
            //begining row with additional cell - only with height
            if (($wi = $this->CellHeightArray[$y])=="") $ret.= '<tr><td height="'.$this->CellHeight.'">';
            else $ret.= '<tr><td height="'.$wi.'">';

            for($x = 0; $x < $this->Width; ++$x){
                if (is_array($tab))
                foreach($tab as $cel){    // for every Cell object in Kreatura

                    if ($x == $cel->Xpos and $y == $cel->Ypos){ // if actual position is the position of the Cell obj, generate it
                        $ret.= $cel->getOpeningTdTag().$cel->generate()."</td>";
                        $x += $cel->Width - 1;
                        continue 2; // do next x
                    }
                    // check if this position (table cell) belongs to any Cell. If yes, just skip it
                    if ($x >= $cel->Xpos and $x <= $cel->Xpos + $cel->Width - 1 and $y >= $cel->Ypos and $y <= $cel->Ypos + $cel->Height - 1) continue 2;
                }
                // if we got here, it means this table cell is empty
                $ret.= '<td></td>';
            }
            $ret.= "</tr>\n";
        }
        $ret.= "</table>\n";
        return $ret;
    }
}


// *************************************************************************
class BaseCell{
    var $Xpos;   // Position X of the cell in the table
    var $Ypos;   // Position Y of the cell in the table
    var $Width;  // Width of the cell, counted in table cells
    var $Height;  // Height of the cell, counted in table cells
    var $Name;    // Name of cell
    var $Content;   // Content of the cell
    var $TdTagArray=Array();    // <td here_it_goes>
    var $Visible;

    // Constructor
    function BaseCell($Xpos, $Ypos, $Width=1, $Height=1, $Vis=true){
        if (!is_int($Xpos) || !is_int($Ypos) || !is_int($Width) || !is_int($Height) || $Xpos < 0 || $Ypos < 0 || $Width < 1 || $Height < 1) die("Cell->constructor: invalid parameter(s) ($Xpos, $Ypos, $Width, $Height)<br>\n");
        $this->Xpos = $Xpos;
        $this->Ypos = $Ypos;
        $this->Width = $Width;
        $this->Height = $Height;
        $this->Visible = $Vis;
    }
    
    /*
    function setKreatura(& $Kreatura, $check = true){
        if($check and strtolower(get_class($Kreatura)) != "kreatura") die("Cell->setParent: expecting Kreatura class. If your Kreatura class has other name than 'Kreatura', please call setCreatura method with second parameter set to 'false'");
        $this->Kreatura = & $Kreatura;
    }
    */
    
    function setVisible($Vis){
        if (!is_bool($Vis)) die("Cell->set Visible: Expecting boolean value. Cell name: '".$this->Name."'");
        $this->Visible = $Vis;
    }
    
    function setTdTag($TagName, $TagValue){
        $this->TdTagArray[$TagName] = $TagValue;
    }

    function getTdTag($TagName){
        return $this->TdTagArray[$TagName];
    }

    function delTdTag($TagName){
        if (($is=@array_key_exists($TagName, $this->TdTagArray)) and !@array_key_exists($TagName, $buf = @array_pop($this->TdTagArray))) return;
            else @array_push($buf, $this->TdTagArray);
        if ($is) $this->TdTagArray[$TagName] = @array_pop($this->TdTagArray);
    }
    
    //returns whole opening TD tag, for Kreatura object purposes
    function getOpeningTdTag(){
        if ($this->Width > 1) $this->setTdTag("colspan", $this->Width);
        if ($this->Height >1) $this->setTdTag("rowspan", $this->Height);
        $ret="<td";
        foreach($this->TdTagArray as $OptName => $OptValue){
            $ret.= " $OptName=\"$OptValue\"";
        }
        $ret.= ">";
        return $ret;
    }
    
    //works properly only if the Content is HTML code
    function generate(){
        return $this->Content;
    }
}

?>
Return current item: Kreatura