{$I OVC.INC}

{$B-} {Complete Boolean Evaluation}
{$I+} {Input/Output-Checking}
{$P+} {Open Parameters}
{$T-} {Typed @ Operator}
{$W-} {Windows Stack Frame}
{$X+} {Extended Syntax}

{$IFNDEF Win32}
{$G+} {286 Instructions}
{$N+} {Numeric Coprocessor}

{$C MOVEABLE,DEMANDLOAD,DISCARDABLE}
{$ENDIF}

{*********************************************************}
{*                  OVCTCMMN.PAS 2.00                    *}
{*     Copyright (c) TurboPower Software Co 1995-96      *}
{*                 All rights reserved.                  *}
{*********************************************************}

unit OvcTCmmn;
  {-Orpheus table: common unit}

interface

uses
  {$IFDEF Win32}
  Windows,
  {$ELSE}
  WinTypes, WinProcs,
  {$ENDIF}
  SysUtils, Messages,
  Graphics, Forms, StdCtrls, Classes, Controls, OvcBase, OvcData;

{---Enumeration types}
type
  TOvcTblAdjust = (                {data adjustment in cell}
              otaDefault,          {the default for the next higher class}
              otaTopLeft,          {top left hand corner}
              otaTopCenter,        {top, centered horizontally}
              otaTopRight,         {top right hand corner}
              otaCenterLeft,       {left hand side, centered vertically}
              otaCenter,           {centered vertically and horizontally}
              otaCenterRight,      {right hand side, centered vertically}
              otaBottomLeft,       {bottom left hand corner}
              otaBottomCenter,     {bottom, centered horizontally}
              otaBottomRight);     {bottom right hand corner}

  TOvcTblAccess = (                {cell access types}
              otxDefault,          {the default for the next higher class}
              otxNormal,           {read & write}
              otxReadOnly,         {read only, no write}
              otxInvisible);       {no read or write, ie invisible}

  TOvcTblState = (                 {grid states}
                                   {..Major}
              otsFocused,          {  focused, or cell being edited}
              otsUnfocused,        {  unfocused}
              otsDesigning,        {  being designed}
                                   {..Minor}
              otsNormal,           {  normal}
              otsEditing,          {  cell being edited}
              otsHiddenEdit,       {  ditto, however currently hidden}
              otsMouseSelect,      {  mouse is selecting}
              otsShowSize,         {  row/col sizing cursor shown}
              otsSizing,           {  row/col being resized}
              otsShowMove,         {  row/col move cursor shown}
              otsMoving,           {  row/col is being moved}
                                   {..Qualifiers}
              otsDoingRow,         {  moving/sizing a row}
              otsDoingCol,         {  moving/sizing a column}

              otsANOther);
  TOvcTblStates = set of TOvcTblState;

  TOvcTblKeyNeeds = (              {grid's requirements for keystrokes}
              otkDontCare,         {grid does not need key}
              otkWouldLike,        {grid would like key, but cell can take it}
              otkMustHave);        {grid must have key}

  TOvcTblRegion = (                {table regions}
              otrInMain,           {..main table area}
              otrInLocked,         {..locked row or col area}
              otrInUnused,         {..unused bit}
              otrOutside);         {..outside table client area}

  TOvcTblOption = (                {table options}
              otoBrowseRow,        {Highlight row when browsing}
              otoNoRowResizing,    {No run-time row resizing allowed}
              otoNoColResizing,    {No run-time column resizing allowed}
              otoTabToArrow,       {Tab moves cell to right, ShiftTab left}
              otoEnterToArrow,     {Enter stops editing and moves cell right}
              otoAlwaysEditing,    {Edit mode is always active}
              otoNoSelection,      {No run-time selection allowed}
              otoMouseDragSelect,  {dragging with mouse selects}
              otoRowSelection,     {clicking on row header selects entire row}
              otoColSelection,     {clicking on column header selects entire column}
              otoThumbTrack,       {Scrollbar thumb-tracking}
              otoAllowColMoves,    {Enable column moves}
              otoAllowRowMoves);   {Enable row moves}
  TOvcTblOptionSet = set of TOvcTblOption;

  TOvcScrollBar = (                {scroll bar identifiers}
              otsbVertical,        {..the vertical one}
              otsbHorizontal);     {..the horizontal one}

  TOvcTblActions = (               {configuration actions on rows/columns}
              taGeneral,           {..general}
              taSingle,            {..changing a single row/column}
              taAll,               {..changing all rows/columns}
              taInsert,            {..inserting a row/column}
              taDelete,            {..deleting a row/column}
              taExchange);         {..exchanging two rows/columns}

  TOvcCellDataPurpose = (          {OnGetCellData data request purpose}
              cdpForPaint,         {..for painting}
              cdpForEdit,          {..for editing}
              cdpForSave);         {..for saving an edited data}

  TOvcTextStyle = (                {text painting styles}
              tsFlat,              {..flat}
              tsRaised,            {..raised look}
              tsLowered);          {..lowered look}

  TOvcTblSelectionType = (         {Internal selection type}
              tstDeselectAll,      {..deselect all selections}
              tstAdditional);      {..additional selection/deselection}

  TOvcTblEditorStyle = (           {Table's cell editor style}
              tesNormal,           {..normal (ie nothing special)}
              tesBorder,           {..with border}
              tes3D);              {..3D look}

{---Row/Column number (index) types}
type
  TRowNum = longint;  {actually 0..2 billion}
  TColNum = integer;  {actually 0..16K}

{---record types for cells---}
type
  PCellBitMapInfo = ^TCellBitMapInfo;
  TCellBitMapInfo = record
    BM          : TBitMap;    {bitmap object to display}
    Count       : integer;    {number of glyphs}
    ActiveCount : integer;    {number of active glyphs}
    Index       : integer;    {index of glyph to display}
  end;

  PCellComboBoxInfo = ^TCellComboBoxInfo;
  TCellComboBoxInfo = record
    Index : integer;                {index into Items list}
    case integer of
      0 : (St      : ShortString);  {string value if Index = -1}
      1 : (RTItems : TStrings;      {run-time items list}
           RTSt    : ShortString);  {run-time string value if Index = -1}
  end;

  TOvcCellAttributes = record      {display attributes for a cell}
    caAccess      : TOvcTblAccess;   {..access rights}
    caAdjust      : TOvcTblAdjust;   {..data adjustment}
    caColor       : TColor;          {..background color}
    caFont        : TFont;           {..text font}
    caFontColor   : TColor;          {..text color}
    caFontHiColor : TColor;          {..text highlight color}
    caTextStyle   : TOvcTextStyle;   {..text style}
  end;


{---Table cell ancestor---}
  TOvcTableCellAncestor = class(TComponent)
    protected {private}
      {.Z+}
      FOnCfgChanged : TNotifyEvent;
      {.Z-}
    protected
      {.Z+}
      procedure tcChangeScale(M, D : integer); dynamic;
      procedure tcDoCfgChanged;
      {.Z-}
    public {protected}
      {.Z+}
      procedure tcResetTableValues; virtual; abstract;
      property OnCfgChanged : TNotifyEvent
        write FOnCfgChanged;
      {.Z-}
    public
  end;

{---Table ancestor---}
  TOvcTableAncestor = class(TOvcBase)
    protected {private}
      {.Z+}
      taCellList : TList;
      taLoadList : TStringList;
      {.Z-}

    protected
      {.Z+}
      {streaming routines}
      procedure ChangeScale(M, D : integer); override;
      procedure DefineProperties(Filer : TFiler); override;
      procedure Loaded; override;

      procedure tbFinishLoadingCellList;
      procedure tbReadCellData(Reader : TReader);
      procedure tbWriteCellData(Writer : TWriter);

      procedure tbCellChanged(Sender : TObject); virtual; abstract;
      {.Z-}

    public {protected}
      {.Z+}
      {internal use only methods}
      procedure tbExcludeCell(Cell : TOvcTableCellAncestor);
      procedure tbIncludeCell(Cell : TOvcTableCellAncestor);
      procedure tbNotifyCellsOfTableChange;
      {.Z-}

    public
      constructor Create(AOwner : TComponent); override;
      destructor Destroy; override;

      function FilterKey(var Msg : TWMKey) : TOvcTblKeyNeeds; virtual; abstract;
      procedure ResolveCellAttributes(RowNum : TRowNum; ColNum : TColNum;
                                      var CellAttr : TOvcCellAttributes); virtual; abstract;
  end;

type
  POvcSparseAttr = ^TOvcSparseAttr;
  TOvcSparseAttr = record  {attributes for cells in sparse matrix--INTERNAL USE}
    scaAccess : TOvcTblAccess;
    scaAdjust : TOvcTblAdjust;
    scaColor  : TColor;
    scaFont   : TFont;
    scaCell   : TOvcTableCellAncestor;
  end;

  POvcTableNumberArray = ^TOvcTableNumberArray;
  TOvcTableNumberArray = record {structure passed to GetDisplayedRow(Col)Numbers}
    NumElements : longint;      {..number of elements in Number array}
    Count       : longint;      {..return count of used elements in Number array}
    Number      : array [0..29] of longint; {..Number array}
  end;

{---Row style type}
type
  PRowStyle = ^TRowStyle;
  TRowStyle = record
    Height : Integer; {-1 means default}
    Hidden : boolean;
  end;

{---Short string type (length-byte string)}
{$IFDEF Win32}
type
  POvcShortString = ^ShortString;  {pointer to shortstring}
{$ELSE}
type
  POvcShortString = ^String;       {pointer to pascal string}
{$ENDIF}

{---Exception classes}
type
  EOrpheusTable = class(Exception);

{---Notification events}
type
  TRowNotifyEvent = procedure (Sender : TObject; RowNum : TRowNum) of object;
  TColNotifyEvent = procedure (Sender : TObject; ColNum : TColNum) of object;
  TCellNotifyEvent = procedure (Sender : TObject;
                                RowNum : TRowNum; ColNum : TColNum) of object;
  TCellDataNotifyEvent = procedure (Sender : TObject;
                                    RowNum : TRowNum; ColNum : TColNum;
                                    var Data : pointer;
                                    Purpose : TOvcCellDataPurpose) of object;
  TCellAttrNotifyEvent = procedure (Sender : TObject;
                                    RowNum : TRowNum; ColNum : TColNum;
                                    var CellAttr : TOvcCellAttributes) of object;
  TCellPaintNotifyEvent = procedure (Sender : TObject;
                                     TableCanvas : TCanvas;
                               const CellRect    : TRect;
                                     RowNum      : TRowNum;
                                     ColNum      : TColNum;
                               const CellAttr    : TOvcCellAttributes;
                                     Data        : pointer;
                                 var DoneIt      : boolean) of object;
  TCellBeginEditNotifyEvent = procedure (Sender : TObject;
                                         RowNum : TRowNum; ColNum : TColNum;
                                         var AllowIt : boolean) of object;
  TCellEndEditNotifyEvent = procedure (Sender : TObject;
                                       Cell : TOvcTableCellAncestor;
                                       RowNum : TRowNum; ColNum : TColNum;
                                       var AllowIt : boolean) of object;
  TCellMoveNotifyEvent = procedure (Sender : TObject; Command : word;
                                    var RowNum : TRowNum;
                                    var ColNum : TColNum) of object;
  TCellChangeNotifyEvent = procedure (Sender : TObject;
                                      var RowNum : TRowNum;
                                      var ColNum : TColNum) of object;
  TRowChangeNotifyEvent = procedure (Sender : TObject; RowNum1, RowNum2 : TRowNum;
                                     Action : TOvcTblActions) of object;
  TColChangeNotifyEvent = procedure (Sender : TObject; ColNum1, ColNum2 : TColNum;
                                     Action : TOvcTblActions) of object;
  TSizeCellEditorNotifyEvent = procedure (Sender   : TObject;
                                          RowNum   : TRowNum;
                                          ColNum   : TColNum;
                                      var CellRect : TRect;
                                      var CellStyle: TOvcTblEditorStyle) of object;
  TSelectionIterator = function(RowNum1 : TRowNum; ColNum1 : TColNum;
                                RowNum2 : TRowNum; ColNum2 : TColNum;
                                ExtraData : pointer) : boolean of object;


{---Cell-Table interaction messages---}
const
  ctim_Base = WM_USER + $4545;
  ctim_QueryOptions = ctim_Base;
  ctim_QueryColor = ctim_Base + 1;
  ctim_QueryFont = ctim_Base + 2;
  ctim_QueryLockedCols = ctim_Base + 3;
  ctim_QueryLockedRows = ctim_Base + 4;
  ctim_QueryActiveCol = ctim_Base + 5;
  ctim_QueryActiveRow = ctim_Base + 6;

  ctim_RemoveCell = ctim_Base + 10;
  ctim_StartEdit = ctim_Base + 11;
  ctim_StartEditMouse = ctim_Base + 12;
  ctim_StartEditKey = ctim_Base + 13;

  ctim_SetFocus = ctim_Base + 14;
  ctim_KillFocus = ctim_Base + 15;

  ctim_LoadDefaultCells = ctim_Base + 20;

{---Property defaults}
const
  DefAccess = otxNormal;
  DefAdjust = otaCenterLeft;
  DefBorderStyle = bsSingle;
  DefColCount = 10;
  DefColWidth = 150;
  DefGridColor = clBlack;
  DefHeight = 100;
  DefLockedCols = 1;
  DefLockedRows = 1;
  DefMargin = 4;
  DefRowCount = 10;
  DefRowHeight = 30;
  DefScrollBars = ssBoth;
  DefTableColor = clBtnFace;
  DefWidth = 300;

{---Default color for cells (to force them to table color)}
const
  clOvcTableDefault = $2FFFFFF;

{---Handy extra constants for table's CalcRowColFromXY method}
const
  CRCFXY_RowAbove = -2;    {Y is above all table cells}
  CRCFXY_RowBelow = -1;    {Y is below all table cells}
  CRCFXY_ColToLeft = -2;   {X is to left of all table cells}
  CRCFXY_ColToRight = -1;  {X is to right of all table cells}

{---Handy extra constants for TRowNum variables, Row Heights}
const
  RowLimitChanged = -2;
  UseDefHt = -1;

type {internal use only}
  TOvcTblDisplayItem = record
    Number : longint;
    Offset : Integer;
  end;
  POvcTblDisplayArray = ^TOvcTblDisplayArray;
  TOvcTblDisplayArray = record
    AllocNm : word;
    Count : word;
    Ay : array [0..127] of TOvcTblDisplayItem; {127 is arbitrary}
  end;

{--Utility routines}
function MinI(X, Y : Integer) : Integer;
  {Return the minimum of two integers}
  {$IFNDEF Win32}
  inline($58/      {  pop ax}
         $5A/      {  pop dx}
         $39/$D0/  {  cmp ax, dx}
         $7E/$01/  {  jle @@Exit}
         $92       {  xchg ax, dx}
         );        {@@Exit:}
  {$ENDIF}
function MaxI(X, Y : Integer) : Integer;
  {Return the maximum of two integers}
  {$IFNDEF Win32}
  inline($58/      {  pop ax}
         $5A/      {  pop dx}
         $39/$D0/  {  cmp ax, dx}
         $7D/$01/  {  jge @@Exit}
         $92       {  xchg ax, dx}
         );        {@@Exit:}
  {$ENDIF}
function MaxL(A, B : longint) : longint;
function MinL(A, B : longint) : longint;

function MakeRowStyle(AHeight : Integer; AHidden : boolean) : TRowStyle;
  {-Make a row style variable from a height and hidden flag.}

procedure TableError(Msg : string);
  {-Raise an exception with supplied string}
procedure TableErrorRes(StringCode : word);
  {-Raise an exception with supplied string resource code}

procedure AssignDisplayArray(var A : POvcTblDisplayArray; Num : word);
  {-Table internal: (re)assign a display array}

implementation
