unit PXT.Widgets.Utility;
(*
 * Copyright (c) 2015 - 2025 Dr. Yuriy Kotsarenko. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 *)
{< Utility functions for Afterwarp UI components when dealing with native frameworks. }
interface

{$INCLUDE PXT.Config.inc}

uses
{$IFDEF FPC}
  StdCtrls,
{$ENDIF}
  Controls, PXT.Types;

// Converts VCL (LCL) button to UI button type.
function MouseButtonToUI(const AButton: Controls.TMouseButton): PXT.Types.TMouseButton;

// Converts UI button type to VCL (LCL) button.
function MouseButtonFromUI(const AButton: PXT.Types.TMouseButton): Controls.TMouseButton;

// Converts VCL (LCL) key code to UI key enumeration.
function PlatformKeyToUI(const APlatformCode: Word): TKey;

// Converts UI application cursor type to VCL (LCL) cursor.
function CursorFromAppCursor(const ACursor: TAppCursor): TCursor;

// Converts UI property type to Pascal-declared string.
function WidgetPropertyTypeToString(const AType: TWidgetPropertyType): string;

implementation

{$IFDEF FPC}
uses
  LCLType;
{$ELSE}
uses
  Windows;
{$ENDIF}

function MouseButtonToUI(const AButton: Controls.TMouseButton): PXT.Types.TMouseButton;
begin
  case AButton of
    Controls.mbLeft:
      Result := PXT.Types.TMouseButton.Left;

    Controls.mbMiddle:
      Result := PXT.Types.TMouseButton.Middle;

    Controls.mbRight:
      Result := PXT.Types.TMouseButton.Right;

    else
      Result := PXT.Types.TMouseButton.None;
  end;
end;

function MouseButtonFromUI(const AButton: PXT.Types.TMouseButton): Controls.TMouseButton;
begin
  case AButton of
    PXT.Types.TMouseButton.Right:
      Result := Controls.mbRight;

    PXT.Types.TMouseButton.Middle:
      Result := Controls.mbMiddle;

  else
    Result := Controls.mbLeft;
  end;
end;

function PlatformKeyToUI(const APlatformCode: Word): TKey;
begin
  case APlatformCode of
    VK_BACK:
      Result := TKey.Backspace;

    VK_TAB:
      Result := TKey.Tab;

    VK_CLEAR:
      Result := TKey.Clear;

    VK_RETURN:
      Result := TKey.Return;

    VK_SHIFT,
    VK_LSHIFT:
      Result := TKey.ShiftLeft;

    VK_RSHIFT:
      Result := TKey.ShiftRight;

    VK_CONTROL,
    VK_LCONTROL:
      Result := TKey.CtrlLeft;

    VK_RCONTROL:
      Result := TKey.CtrlRight;

    VK_MENU,
    VK_LMENU:
      Result := TKey.AltLeft;

    VK_RMENU:
      Result := TKey.AltRight;

    VK_PAUSE:
      Result := TKey.Pause;

    VK_CAPITAL:
      Result := TKey.CapsLock;

    VK_ESCAPE:
      Result := TKey.Escape;

    VK_SPACE:
      Result := TKey.Space;

    VK_PRIOR:
      Result := TKey.PageUp;

    VK_NEXT:
      Result := TKey.PageDown;

    VK_HOME:
      Result := TKey.Home;

    VK_END:
      Result := TKey.&End;

    VK_LEFT:
      Result := TKey.Left;

    VK_UP:
      Result := TKey.Up;

    VK_RIGHT:
      Result := TKey.Right;

    VK_DOWN:
      Result := TKey.Down;

    VK_SELECT:
      Result := TKey.Select;

    VK_PRINT:
      Result := TKey.PrintScreen;

    VK_EXECUTE:
      Result := TKey.Execute;

    VK_INSERT:
      Result := TKey.Insert;

    VK_DELETE:
      Result := TKey.Delete;

    VK_HELP:
      Result := TKey.Help;

    VK_LWIN:
      Result := TKey.SuperLeft;

    VK_RWIN:
      Result := TKey.SuperRight;

    VK_APPS:
      Result := TKey.Apps;

    VK_SLEEP:
      Result := TKey.Sleep;

    VK_MULTIPLY:
      Result := TKey.Multiply;

    VK_DIVIDE:
      Result := TKey.Divide;

    VK_ADD:
      Result := TKey.Add;

    VK_SUBTRACT:
      Result := TKey.Subtract;

    VK_SEPARATOR:
      Result := TKey.Separator;

    VK_DECIMAL:
      Result := TKey.Decimal;

    VK_NUMLOCK:
      Result := TKey.NumLock;

    VK_SCROLL:
      Result := TKey.ScrollLock;

    VK_VOLUME_UP:
      Result := TKey.VolumeUp;

    VK_VOLUME_DOWN:
      Result := TKey.VolumeDown;

    VK_VOLUME_MUTE:
      Result := TKey.VolumeMute;

    VK_MEDIA_PREV_TRACK:
      Result := TKey.MediaPrevTrack;

    VK_MEDIA_NEXT_TRACK:
      Result := TKey.MediaNextTrack;

    VK_MEDIA_STOP:
      Result := TKey.MediaStop;

    VK_MEDIA_PLAY_PAUSE:
      Result := TKey.MediaPlayPause;

{    VK_0..VK_9:
      Result := TKey(Ord('0') + AKey - VK_0);

    VK_A..VK_Z:
      Result := TKey(Ord('a') + AKey - VK_A);}

    VK_NUMPAD0..VK_NUMPAD9:
      Result := TKey(Ord(TKey.Numpad0) + APlatformCode - VK_NUMPAD0);

    VK_F1..VK_F12:
      Result := TKey(Ord(TKey.F1) + APlatformCode - VK_F1);

  else
    Result := TKey.Null;
  end;
end;

function CursorFromAppCursor(const ACursor: TAppCursor): TCursor;
begin
  case ACursor of
    TAppCursor.Arrow:
      Result := crArrow;

    TAppCursor.TextSelect,
    TAppCursor.TextSelectVertical:
      Result := crIBeam;

    TAppCursor.Wait:
      Result := crHourGlass;

    TAppCursor.ArrowWait:
      Result := crAppStart;

    TAppCursor.CrossHair,
    TAppCursor.Cell:
      Result := crCross;

    TAppCursor.LinkSelect:
      Result := crHandPoint;

    TAppCursor.NotAllowed:
      Result := crNo;

    TAppCursor.Help:
      Result := crHelp;

    TAppCursor.Move:
      Result := crSizeAll;

    TAppCursor.ResizeVert:
      Result := crSizeNS;

    TAppCursor.ResizeHoriz:
      Result := crSizeWE;

    TAppCursor.Resize1:
      Result := crSizeNWSE;

    TAppCursor.Resize2:
      Result := crSizeNESW;

    TAppCursor.ResizeTop,
    TAppCursor.ResizeBottom:
      Result := crSizeNS;

    TAppCursor.ResizeLeft,
    TAppCursor.ResizeRight:
      Result := crSizeWE;

    TAppCursor.ResizeTopLeft:
      Result := crSizeNWSE;

    TAppCursor.ResizeTopRight:
      Result := crSizeNESW;

    TAppCursor.ResizeBottomRight:
      Result := crSizeNWSE;

    TAppCursor.ResizeBottomLeft:
      Result := crSizeNESW;
  else
    Result := crArrow;
  end;
end;

function WidgetPropertyTypeToString(const AType: TWidgetPropertyType): string;
begin
  case AType of
    TWidgetPropertyType.Integer:
      Result := 'Integer';

    TWidgetPropertyType.Int64:
      Result := 'Int64';

    TWidgetPropertyType.Float:
      Result := 'Single';

    TWidgetPropertyType.Real:
      Result := 'Double';

    TWidgetPropertyType.Boolean:
      Result := 'Boolean';

    TWidgetPropertyType.Point:
      Result := 'TPoint2f';

    TWidgetPropertyType.Vector:
      Result := 'TVector3f';

    TWidgetPropertyType.Rect:
      Result := 'TFloatRect';

    TWidgetPropertyType.Margins:
      Result := 'TMargins';

    TWidgetPropertyType.Color:
      Result := 'TIntColor';

    TWidgetPropertyType.ColorPair:
      Result := 'TColorPair';

    TWidgetPropertyType.ColorRect:
      Result := 'TColorRect';

    TWidgetPropertyType.Enumeration:
      Result := '(enumeration)';

    TWidgetPropertyType.TextString:
      Result := 'Utf8String';

    TWidgetPropertyType.Font:
      Result := 'TFontParameters';

  else
    Result := 'None';
  end;
end;

end.