Files
TeslaRel410/BORLAND/BC45/SOURCE/OWL/UIHANDLE.CPP
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
  is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
  Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
  (extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
  BT game source (never mixed into CODE/). Round 1-3 state:
  * 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
    (BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
    since 1996.
  * BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
    its binary-recorded line 400 exactly.
  * BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
    (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
    TeamScore=12 flagged [T4]).
  * MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
    (VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
    the period compiler is the drift detector).
  * Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
    (per-TU verification sweep under authentic OPT.MAK flags).
  * README: corrected roadmap - MECH.HPP is the capstone grown with the mech
    TU reconstructions; BTREG.CPP green = the header-family milestone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:33:26 -05:00

217 lines
6.5 KiB
C++

//----------------------------------------------------------------------------
// ObjectWindows
// (C) Copyright 1994 by Borland International, All Rights Reserved
//
//----------------------------------------------------------------------------
#include <owl/owlpch.h>
#include <owl/uihandle.h>
#include <owl/gdiobjec.h>
//
// Construct a UIHandle object given a frame, a style and a handle size
//
TUIHandle::TUIHandle(const TRect& frame, uint style, int thickness)
:
Frame(frame),
Style(style),
HandleBox(thickness, thickness)
{
}
void
TUIHandle::Move(int dx, int dy)
{
Frame.Offset(dx, dy);
}
void
TUIHandle::MoveTo(int x, int y)
{
Frame.Offset(x-Frame.left, y-Frame.top);
}
void
TUIHandle::Size(int w, int h)
{
Frame.right = Frame.left + w;
Frame.top = Frame.top + h;
}
//
// Calculate the outside frame rectangle
//
TRect
TUIHandle::GetBoundingRect() const
{
return (Style&HandlesOut) ? Frame.InflatedBy(HandleBox) : Frame;
}
//
// Compare a given point to various parts of the UIHandle and return where the
// point hit.
//
TUIHandle::TWhere
TUIHandle::HitTest(const TPoint& point) const
{
// Check first to see if point is a total miss
//
TRect outsideFrame = GetBoundingRect();
if (!outsideFrame.Contains(point))
return Outside;
// Next check to see if it is completely inside
//
TRect insideFrame = outsideFrame.InflatedBy(-HandleBox);
if (insideFrame.Contains(point))
return (Style & InsideSpecial) ? Inside : MidCenter;
// If no grapple are used, hit must be in move area
//
if (!(Style & Grapples))
return MidCenter;
// Determine which of the handles was hit. Calulate X and then Y parts
//
int where;
TPoint halfHandle(HandleBox.x/2, HandleBox.y/2);
if (point.x < insideFrame.left)
where = 0; //Left;
else if (point.x >= insideFrame.right)
where = 2; //Right;
else {
int center = insideFrame.left + insideFrame.Width()/2;
if (point.x >= center-halfHandle.x && point.x <= center+halfHandle.x)
where = 1; //Center;
else
return MidCenter;
}
if (point.y < insideFrame.top)
where += 0; //Top;
else if (point.y >= insideFrame.bottom)
where += 6; //Bottom;
else {
int middle = insideFrame.top + insideFrame.Height()/2;
if (point.y >= middle-halfHandle.y && point.y <= middle+halfHandle.y)
where += 3; //Middle;
else
return MidCenter;
}
return (TWhere)where;
}
//
// Helper function to convert a where code into a cursor shape Id
//
uint16
TUIHandle::GetCursorId(TWhere where)
{
static uint16 cursorId[] = {
32642, 32645, 32643, // SIZENWSE, SIZENS, SIZENESW
32644, 32512, 32644, // SIZEWE, ARROW, SIZEWE,
32643, 32645, 32642, // SIZENESW, SIZENS, SIZENWSE
};
if (where == Outside)
return 0;
if (where == Inside)
return 32513; // IBEAM
return cursorId[where];
}
//
// Paint this UIHandle object onto a given dc
//
void
TUIHandle::Paint(TDC& dc) const
{
TRect outerRect = GetBoundingRect();
// Draw a frame rect outside of Frame if indicated by the style
//
if (Style & (Framed | DashFramed)) {
int oldRop2 = dc.GetROP2();
dc.SetROP2(R2_XORPEN);
TRect frame = Frame;
if (Style & Framed) {
dc.FrameRect(frame, TBrush(TColor::Black));
}
else {
TPen dashPen(TColor::White, 1, PS_DASH);
dc.SelectObject(dashPen);
dc.SelectStockObject(NULL_BRUSH);
dc.SetBkColor(TColor::Black);
dc.Rectangle(frame);
dc.RestorePen();
}
// dc.DrawFocusRect(Frame); // a useful dotted rect frame...
if (!(Style&HandlesOut))
outerRect.Inflate(-1, -1);
dc.SetROP2(oldRop2);
}
// Calculate the grapple box rectangle and the midpoint handle topleft offsets
//
TPoint grappleBox = (Style & Grapples) ? HandleBox : TPoint(0, 0);
int center = outerRect.Width()/2 - grappleBox.x/2;
int middle = outerRect.Height()/2 - grappleBox.y/2;
// Draw the 8 grapples if indicated by the style
//
if (Style & Grapples) {
const uint32 rop = DSTINVERT;
dc.PatBlt(outerRect.left, outerRect.top,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.left+center, outerRect.top,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.right-HandleBox.x, outerRect.top,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.left, outerRect.top+middle,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.right-HandleBox.x, outerRect.top+middle,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.left, outerRect.bottom-HandleBox.y,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.left+center, outerRect.bottom-HandleBox.y,
grappleBox.x, grappleBox.y, rop);
dc.PatBlt(outerRect.right-HandleBox.x, outerRect.bottom-HandleBox.y,
grappleBox.x, grappleBox.y, rop);
}
// Draw the hatched border or whole rect if indicated by the style
//
if (Style & (HatchBorder | HatchRect)) {
const uint32 rop = PATINVERT; // opposite color rop: 0x00A000C9L;
static THatch8x8Brush hatchBrush(THatch8x8Brush::Hatch13F1);
dc.SelectObject(hatchBrush); //CQ set brush origin?
if (Style & HatchBorder) {
int center2 = outerRect.Width() - center - grappleBox.x;
int middle2 = outerRect.Height() - middle - grappleBox.y;
dc.PatBlt(outerRect.left+grappleBox.x, outerRect.top,
center-grappleBox.x, HandleBox.y, rop);
dc.PatBlt(outerRect.left+center+grappleBox.x, outerRect.top,
center2-grappleBox.x, HandleBox.y, rop);
dc.PatBlt(outerRect.left, outerRect.top+HandleBox.y,
HandleBox.x, middle-HandleBox.y, rop);
dc.PatBlt(outerRect.left, outerRect.top+middle+grappleBox.y,
HandleBox.x, middle2-HandleBox.y, rop);
dc.PatBlt(outerRect.right-HandleBox.x, outerRect.top+HandleBox.y,
HandleBox.x, middle-HandleBox.y, rop);
dc.PatBlt(outerRect.right-HandleBox.x, outerRect.top+middle+grappleBox.y,
HandleBox.x, middle2-HandleBox.y, rop);
dc.PatBlt(outerRect.left+grappleBox.x, outerRect.bottom-HandleBox.y,
center-grappleBox.x, HandleBox.y, rop);
dc.PatBlt(outerRect.left+center+grappleBox.x, outerRect.bottom-HandleBox.y,
center2-grappleBox.x, HandleBox.y, rop);
}
else {
dc.PatBlt(outerRect, rop);
}
dc.RestoreBrush();
}
}