lainz 9 роки тому
батько
коміт
0e21160933

+ 11 - 1
bcdefaultthememanager.pas

@@ -7,7 +7,7 @@ interface
 uses
 uses
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
   BCButton, BCButtonFocus, BCNumericKeyboard, BCThemeManager,
   BCButton, BCButtonFocus, BCNumericKeyboard, BCThemeManager,
-  BCSamples, CustomDrawnDrawers;
+  BCSamples, CustomDrawnDrawers, BCKeyboard;
 
 
 type
 type
 
 
@@ -167,6 +167,16 @@ begin
           ButtonStyle.Assign(tempButton);
           ButtonStyle.Assign(tempButton);
           UpdateButtonStyle;
           UpdateButtonStyle;
         end;
         end;
+    { BCKeyboard }
+    if (AControl.Components[i] is TBCKeyboard) then
+      with TBCKeyboard(AControl.Components[i]) do
+        if (Assigned(ThemeManager)) and
+          (TBCDefaultThemeManager(ThemeManager).Name = Self.Name) and
+          (tempButton.Name <> TBCKeyboard(AControl.Components[i]).ButtonStyle.Name) then
+        begin
+          ButtonStyle.Assign(tempButton);
+          UpdateButtonStyle;
+        end;
   end;
   end;
 
 
   if removeTempButton then
   if removeTempButton then

+ 475 - 0
bckeyboard.pas

@@ -0,0 +1,475 @@
+unit BCKeyboard;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
+  BCThemeManager, BCNumericKeyboard, BCButton, BCPanel, MouseAndKeyInput,
+  LCLType;
+
+type
+
+  { TBCKeyboard }
+
+  TBCKeyboard = class(TComponent)
+  private
+    FBCThemeManager: TBCThemeManager;
+    FButton: TBCButton;
+    FOnUserChange: TNotifyEvent;
+    FPanel, FRow1, FRow2, FRow3, FRow4: TBCPanel;
+    F_q, F_w, F_e, F_r, F_t, F_y, F_u, F_i, F_o, F_p, F_a, F_s, F_d,
+    F_f, F_g, F_h, F_j, F_k, F_l, F_z, F_x, F_c, F_v, F_b, F_n, F_m,
+    F_shift, F_space, F_back: TBCButton;
+    FVisible: boolean;
+    procedure SetFButton(AValue: TBCButton);
+    procedure SetFPanel(AValue: TBCPanel);
+    procedure SetFThemeManager(AValue: TBCThemeManager);
+  protected
+    procedure PressVirtKey(p: longint);
+    procedure PressShiftVirtKey(p: longint);
+    procedure OnButtonClick(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: integer); virtual;
+    { When value is changed by the user }
+    property OnUserChange: TNotifyEvent read FOnUserChange write FOnUserChange;
+  public
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    // Show in a custom form or panel
+    procedure Show(AControl: TWinControl);
+    // Try to Show in the form where this component is placed
+    procedure Show();
+    // Hide the component
+    procedure Hide();
+    // Update buttons style
+    procedure UpdateButtonStyle;
+  public
+    { The real panel that's used as container for all the numeric buttons }
+    property Panel: TBCPanel read FPanel write SetFPanel;
+    { A fake button that's used as style base for all the numeric buttons }
+    property ButtonStyle: TBCButton read FButton write SetFButton;
+    { If it's visible or not }
+    property Visible: boolean read FVisible;
+  published
+    property ThemeManager: TBCThemeManager read FBCThemeManager write SetFThemeManager;
+  end;
+
+procedure Register;
+
+implementation
+
+procedure Register;
+begin
+  RegisterComponents('BGRA Controls', [TBCKeyboard]);
+end;
+
+{ TBCKeyboard }
+
+procedure TBCKeyboard.SetFThemeManager(AValue: TBCThemeManager);
+begin
+  if FBCThemeManager = AValue then
+    Exit;
+  FBCThemeManager := AValue;
+end;
+
+procedure TBCKeyboard.PressVirtKey(p: longint);
+begin
+  KeyInput.Down(p);
+  KeyInput.Up(p);
+end;
+
+procedure TBCKeyboard.PressShiftVirtKey(p: longint);
+begin
+  KeyInput.Down(VK_SHIFT);
+  KeyInput.Down(p);
+  KeyInput.Up(p);
+  KeyInput.Up(VK_SHIFT);
+end;
+
+procedure TBCKeyboard.OnButtonClick(Sender: TObject; Button: TMouseButton;
+  Shift: TShiftState; X, Y: integer);
+var
+  btn: TBCButton;
+  str: string;
+begin
+  btn := TBCButton(Sender);
+  str := btn.Caption;
+
+  if str = F_shift.Caption then
+  begin
+    F_shift.Down := not F_shift.Down;
+    if not F_shift.Down then
+    begin
+      F_q.Caption := LowerCase(F_q.Caption);
+      F_w.Caption := LowerCase(F_w.Caption);
+      F_e.Caption := LowerCase(F_e.Caption);
+      F_r.Caption := LowerCase(F_r.Caption);
+      F_t.Caption := LowerCase(F_t.Caption);
+      F_y.Caption := LowerCase(F_y.Caption);
+      F_u.Caption := LowerCase(F_u.Caption);
+      F_i.Caption := LowerCase(F_i.Caption);
+      F_o.Caption := LowerCase(F_o.Caption);
+      F_p.Caption := LowerCase(F_p.Caption);
+      F_a.Caption := LowerCase(F_a.Caption);
+      F_s.Caption := LowerCase(F_s.Caption);
+      F_d.Caption := LowerCase(F_d.Caption);
+      F_f.Caption := LowerCase(F_f.Caption);
+      F_g.Caption := LowerCase(F_g.Caption);
+      F_h.Caption := LowerCase(F_h.Caption);
+      F_j.Caption := LowerCase(F_j.Caption);
+      F_k.Caption := LowerCase(F_k.Caption);
+      F_l.Caption := LowerCase(F_l.Caption);
+      F_z.Caption := LowerCase(F_z.Caption);
+      F_x.Caption := LowerCase(F_x.Caption);
+      F_c.Caption := LowerCase(F_c.Caption);
+      F_v.Caption := LowerCase(F_v.Caption);
+      F_b.Caption := LowerCase(F_b.Caption);
+      F_n.Caption := LowerCase(F_n.Caption);
+      F_m.Caption := LowerCase(F_m.Caption);
+    end
+    else
+    begin
+      F_q.Caption := UpperCase(F_q.Caption);
+      F_w.Caption := UpperCase(F_w.Caption);
+      F_e.Caption := UpperCase(F_e.Caption);
+      F_r.Caption := UpperCase(F_r.Caption);
+      F_t.Caption := UpperCase(F_t.Caption);
+      F_y.Caption := UpperCase(F_y.Caption);
+      F_u.Caption := UpperCase(F_u.Caption);
+      F_i.Caption := UpperCase(F_i.Caption);
+      F_o.Caption := UpperCase(F_o.Caption);
+      F_p.Caption := UpperCase(F_p.Caption);
+      F_a.Caption := UpperCase(F_a.Caption);
+      F_s.Caption := UpperCase(F_s.Caption);
+      F_d.Caption := UpperCase(F_d.Caption);
+      F_f.Caption := UpperCase(F_f.Caption);
+      F_g.Caption := UpperCase(F_g.Caption);
+      F_h.Caption := UpperCase(F_h.Caption);
+      F_j.Caption := UpperCase(F_j.Caption);
+      F_k.Caption := UpperCase(F_k.Caption);
+      F_l.Caption := UpperCase(F_l.Caption);
+      F_z.Caption := UpperCase(F_z.Caption);
+      F_x.Caption := UpperCase(F_x.Caption);
+      F_c.Caption := UpperCase(F_c.Caption);
+      F_v.Caption := UpperCase(F_v.Caption);
+      F_b.Caption := UpperCase(F_b.Caption);
+      F_n.Caption := UpperCase(F_n.Caption);
+      F_m.Caption := UpperCase(F_m.Caption);
+    end;
+  end
+  else if str = F_back.Caption then
+  begin
+    {$IFDEF CPUX86_64}
+    Application.ProcessMessages;
+    KeyInput.Press(VK_BACK);
+    Application.ProcessMessages;
+    {$ELSE}
+    Application.QueueAsyncCall(@PressVirtKey, VK_BACK);
+    {$ENDIF}
+  end
+  else
+  begin
+    if str = F_space.Caption then
+      str := ' ';
+    {$IFDEF CPUX86_64}
+    Application.ProcessMessages;
+    KeyInput.Press(Ord(UpperCase(str)[1]));
+    Application.ProcessMessages;
+    {$ELSE}
+    if F_shift.Down then
+      Application.QueueAsyncCall(@PressShiftVirtKey, Ord(UpperCase(str)[1]))
+    else
+      Application.QueueAsyncCall(@PressVirtKey, Ord(UpperCase(str)[1]));
+    {$ENDIF}
+  end;
+
+  if Assigned(FOnUserChange) then
+    FOnUserChange(Self);
+end;
+
+constructor TBCKeyboard.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+
+  FVisible := False;
+
+  FButton := TBCButton.Create(Self);
+
+  FPanel := TBCPanel.Create(Self);
+  FPanel.AutoSize := True;
+  FPanel.ChildSizing.ControlsPerLine := 1;
+  FPanel.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
+  FPanel.Caption := 'Panel1';
+  FPanel.BorderBCStyle := bpsBorder;
+
+  { qwertyuiop }
+
+  FRow1 := TBCPanel.Create(FPanel);
+  FRow1.AutoSize := True;
+  FRow1.Caption := '';
+  FRow1.BorderBCStyle := bpsBorder;
+  FRow1.ChildSizing.ControlsPerLine := 10;
+  FRow1.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
+  FRow1.Parent := FPanel;
+
+  F_q := TBCButton.Create(FRow1);
+  F_q.Caption := 'Q';
+  F_q.Parent := FRow1;
+  F_q.OnMouseDown := @OnButtonClick;
+
+  F_w := TBCButton.Create(FRow1);
+  F_w.Caption := 'W';
+  F_w.Parent := FRow1;
+  F_w.OnMouseDown := @OnButtonClick;
+
+  F_e := TBCButton.Create(FRow1);
+  F_e.Caption := 'E';
+  F_e.Parent := FRow1;
+  F_e.OnMouseDown := @OnButtonClick;
+
+  F_r := TBCButton.Create(FRow1);
+  F_r.Caption := 'R';
+  F_r.Parent := FRow1;
+  F_r.OnMouseDown := @OnButtonClick;
+
+  F_t := TBCButton.Create(FRow1);
+  F_t.Caption := 'T';
+  F_t.Parent := FRow1;
+  F_t.OnMouseDown := @OnButtonClick;
+
+  F_y := TBCButton.Create(FRow1);
+  F_y.Caption := 'Y';
+  F_y.Parent := FRow1;
+  F_y.OnMouseDown := @OnButtonClick;
+
+  F_u := TBCButton.Create(FRow1);
+  F_u.Caption := 'U';
+  F_u.Parent := FRow1;
+  F_u.OnMouseDown := @OnButtonClick;
+
+  F_i := TBCButton.Create(FRow1);
+  F_i.Caption := 'I';
+  F_i.Parent := FRow1;
+  F_i.OnMouseDown := @OnButtonClick;
+
+  F_o := TBCButton.Create(FRow1);
+  F_o.Caption := 'O';
+  F_o.Parent := FRow1;
+  F_o.OnMouseDown := @OnButtonClick;
+
+  F_p := TBCButton.Create(FRow1);
+  F_p.Caption := 'P';
+  F_p.Parent := FRow1;
+  F_p.OnMouseDown := @OnButtonClick;
+
+
+  { asdfghjkl }
+
+  FRow2 := TBCPanel.Create(FPanel);
+  FRow2.AutoSize := True;
+  FRow2.Caption := '';
+  FRow2.BorderBCStyle := bpsBorder;
+  FRow2.ChildSizing.ControlsPerLine := 9;
+  FRow2.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
+  FRow2.Parent := FPanel;
+
+  F_a := TBCButton.Create(FRow2);
+  F_a.Caption := 'A';
+  F_a.Parent := FRow2;
+  F_a.OnMouseDown := @OnButtonClick;
+
+  F_s := TBCButton.Create(FRow2);
+  F_s.Caption := 'S';
+  F_s.Parent := FRow2;
+  F_s.OnMouseDown := @OnButtonClick;
+
+  F_d := TBCButton.Create(FRow2);
+  F_d.Caption := 'D';
+  F_d.Parent := FRow2;
+  F_d.OnMouseDown := @OnButtonClick;
+
+  F_f := TBCButton.Create(FRow2);
+  F_f.Caption := 'F';
+  F_f.Parent := FRow2;
+  F_f.OnMouseDown := @OnButtonClick;
+
+  F_g := TBCButton.Create(FRow2);
+  F_g.Caption := 'G';
+  F_g.Parent := FRow2;
+  F_g.OnMouseDown := @OnButtonClick;
+
+  F_h := TBCButton.Create(FRow2);
+  F_h.Caption := 'H';
+  F_h.Parent := FRow2;
+  F_h.OnMouseDown := @OnButtonClick;
+
+  F_j := TBCButton.Create(FRow2);
+  F_j.Caption := 'J';
+  F_j.Parent := FRow2;
+  F_j.OnMouseDown := @OnButtonClick;
+
+  F_k := TBCButton.Create(FRow2);
+  F_k.Caption := 'K';
+  F_k.Parent := FRow2;
+  F_k.OnMouseDown := @OnButtonClick;
+
+  F_l := TBCButton.Create(FRow2);
+  F_l.Caption := 'L';
+  F_l.Parent := FRow2;
+  F_l.OnMouseDown := @OnButtonClick;
+
+  { zxcvbnm }
+
+  FRow3 := TBCPanel.Create(FPanel);
+  FRow3.AutoSize := True;
+  FRow3.Caption := '';
+  FRow3.BorderBCStyle := bpsBorder;
+  FRow3.ChildSizing.ControlsPerLine := 9;
+  FRow3.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
+  FRow3.Parent := FPanel;
+
+  F_shift := TBCButton.Create(FRow3);
+  F_shift.Caption := '^';
+  F_shift.Parent := FRow3;
+  F_shift.OnMouseDown := @OnButtonClick;
+  F_shift.Down := True;
+
+  F_z := TBCButton.Create(FRow3);
+  F_z.Caption := 'Z';
+  F_z.Parent := FRow3;
+  F_z.OnMouseDown := @OnButtonClick;
+
+  F_x := TBCButton.Create(FRow3);
+  F_x.Caption := 'X';
+  F_x.Parent := FRow3;
+  F_x.OnMouseDown := @OnButtonClick;
+
+  F_c := TBCButton.Create(FRow3);
+  F_c.Caption := 'C';
+  F_c.Parent := FRow3;
+  F_c.OnMouseDown := @OnButtonClick;
+
+  F_v := TBCButton.Create(FRow3);
+  F_v.Caption := 'V';
+  F_v.Parent := FRow3;
+  F_v.OnMouseDown := @OnButtonClick;
+
+  F_b := TBCButton.Create(FRow3);
+  F_b.Caption := 'B';
+  F_b.Parent := FRow3;
+  F_b.OnMouseDown := @OnButtonClick;
+
+  F_n := TBCButton.Create(FRow3);
+  F_n.Caption := 'N';
+  F_n.Parent := FRow3;
+  F_n.OnMouseDown := @OnButtonClick;
+
+  F_m := TBCButton.Create(FRow3);
+  F_m.Caption := 'M';
+  F_m.Parent := FRow3;
+  F_m.OnMouseDown := @OnButtonClick;
+
+  F_back := TBCButton.Create(FRow3);
+  F_back.Caption := '<-';
+  F_back.Parent := FRow3;
+  F_back.OnMouseDown := @OnButtonClick;
+
+  { shift space back }
+
+  FRow4 := TBCPanel.Create(FPanel);
+  FRow4.AutoSize := True;
+  FRow4.Caption := '';
+  FRow4.BorderBCStyle := bpsBorder;
+  FRow4.ChildSizing.ControlsPerLine := 1;
+  FRow4.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
+  FRow4.Parent := FPanel;
+
+  F_space := TBCButton.Create(FRow4);
+  F_space.Caption := '____________________';
+  F_space.Parent := FRow4;
+  F_space.OnMouseDown := @OnButtonClick;
+end;
+
+destructor TBCKeyboard.Destroy;
+begin
+  { Everything inside the panel will be freed }
+  FPanel.Free;
+  inherited Destroy;
+end;
+
+procedure TBCKeyboard.Show(AControl: TWinControl);
+begin
+  FPanel.Parent := AControl;
+  FVisible := True;
+end;
+
+procedure TBCKeyboard.Show;
+begin
+  if Self.Owner is TWinControl then
+    Show(Self.Owner as TWinControl)
+  else
+    raise Exception.Create('The parent is not TWinControl descendant.');
+end;
+
+procedure TBCKeyboard.Hide;
+begin
+  FPanel.Parent := nil;
+  FVisible := False;
+end;
+
+procedure TBCKeyboard.UpdateButtonStyle;
+var
+  shift_down: boolean;
+begin
+  F_q.Assign(FButton);
+  F_w.Assign(FButton);
+  F_e.Assign(FButton);
+  F_r.Assign(FButton);
+  F_t.Assign(FButton);
+  F_y.Assign(FButton);
+  F_u.Assign(FButton);
+  F_i.Assign(FButton);
+  F_o.Assign(FButton);
+  F_p.Assign(FButton);
+  F_a.Assign(FButton);
+  F_s.Assign(FButton);
+  F_d.Assign(FButton);
+  F_f.Assign(FButton);
+  F_g.Assign(FButton);
+  F_h.Assign(FButton);
+  F_j.Assign(FButton);
+  F_k.Assign(FButton);
+  F_l.Assign(FButton);
+  F_z.Assign(FButton);
+  F_x.Assign(FButton);
+  F_c.Assign(FButton);
+  F_v.Assign(FButton);
+  F_b.Assign(FButton);
+  F_n.Assign(FButton);
+  F_m.Assign(FButton);
+
+  shift_down := F_shift.Down;
+  F_shift.Assign(FButton);
+  F_shift.Down := shift_down;
+
+  F_back.Assign(FButton);
+
+  F_space.Assign(FButton);
+end;
+
+procedure TBCKeyboard.SetFButton(AValue: TBCButton);
+begin
+  if FButton = AValue then
+    Exit;
+  FButton := AValue;
+end;
+
+procedure TBCKeyboard.SetFPanel(AValue: TBCPanel);
+begin
+  if FPanel = AValue then
+    Exit;
+  FPanel := AValue;
+end;
+
+end.

+ 2 - 1
bcthememanager.pas

@@ -14,7 +14,8 @@ type
   protected
   protected
 
 
   public
   public
-
+    procedure Apply(AControl: TWinControl); virtual abstract;
+    procedure Apply(); virtual abstract;
   published
   published
 
 
   end;
   end;

+ 7 - 2
bgracontrols.lpk

@@ -23,7 +23,7 @@
       </Linking>
       </Linking>
     </CompilerOptions>
     </CompilerOptions>
     <Version Major="4" Minor="2"/>
     <Version Major="4" Minor="2"/>
-    <Files Count="41">
+    <Files Count="42">
       <Item1>
       <Item1>
         <Filename Value="bcbasectrls.pas"/>
         <Filename Value="bcbasectrls.pas"/>
         <UnitName Value="BCBaseCtrls"/>
         <UnitName Value="BCBaseCtrls"/>
@@ -93,7 +93,7 @@
       </Item14>
       </Item14>
       <Item15>
       <Item15>
         <Filename Value="bcsamples.pas"/>
         <Filename Value="bcsamples.pas"/>
-        <UnitName Value="bcsamples"/>
+        <UnitName Value="BCSamples"/>
       </Item15>
       </Item15>
       <Item16>
       <Item16>
         <Filename Value="bcstylesform.pas"/>
         <Filename Value="bcstylesform.pas"/>
@@ -218,6 +218,11 @@
         <Filename Value="mouseandkeyinput/mouseandkeyinput.pas"/>
         <Filename Value="mouseandkeyinput/mouseandkeyinput.pas"/>
         <UnitName Value="MouseAndKeyInput"/>
         <UnitName Value="MouseAndKeyInput"/>
       </Item41>
       </Item41>
+      <Item42>
+        <Filename Value="bckeyboard.pas"/>
+        <HasRegisterProc Value="True"/>
+        <UnitName Value="BCKeyboard"/>
+      </Item42>
     </Files>
     </Files>
     <RequiredPkgs Count="4">
     <RequiredPkgs Count="4">
       <Item1>
       <Item1>

+ 3 - 1
bgracontrols.pas

@@ -4,6 +4,7 @@
 
 
 unit bgracontrols;
 unit bgracontrols;
 
 
+{$warn 5023 off : no warning about unused units}
 interface
 interface
 
 
 uses
 uses
@@ -16,7 +17,7 @@ uses
   BGRAScript, BGRAShape, BGRASpeedButton, BGRASpriteAnimation, 
   BGRAScript, BGRAShape, BGRASpeedButton, BGRASpriteAnimation, 
   BGRAVirtualScreen, DTAnalogClock, DTAnalogCommon, DTAnalogGauge, 
   BGRAVirtualScreen, DTAnalogClock, DTAnalogCommon, DTAnalogGauge, 
   dtthemedclock, dtthemedgauge, uPSI_BGRAPascalScript, MouseAndKeyInput, 
   dtthemedclock, dtthemedgauge, uPSI_BGRAPascalScript, MouseAndKeyInput, 
-  LazarusPackageIntf;
+  BCKeyboard, LazarusPackageIntf;
 
 
 implementation
 implementation
 
 
@@ -50,6 +51,7 @@ begin
   RegisterUnit('dtthemedclock', @dtthemedclock.Register);
   RegisterUnit('dtthemedclock', @dtthemedclock.Register);
   RegisterUnit('dtthemedgauge', @dtthemedgauge.Register);
   RegisterUnit('dtthemedgauge', @dtthemedgauge.Register);
   RegisterUnit('uPSI_BGRAPascalScript', @uPSI_BGRAPascalScript.Register);
   RegisterUnit('uPSI_BGRAPascalScript', @uPSI_BGRAPascalScript.Register);
+  RegisterUnit('BCKeyboard', @BCKeyboard.Register);
 end;
 end;
 
 
 initialization
 initialization

+ 150 - 0
test/test_bckeyboard/test_bckeyboard.lpi

@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="test_bckeyboard"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+      <XPManifest>
+        <DpiAware Value="True"/>
+      </XPManifest>
+    </General>
+    <BuildModes Count="3">
+      <Item1 Name="Default" Default="True"/>
+      <Item2 Name="Debug">
+        <CompilerOptions>
+          <Version Value="11"/>
+          <PathDelim Value="\"/>
+          <Target>
+            <Filename Value="test_bckeyboard"/>
+          </Target>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+          </SearchPaths>
+          <Parsing>
+            <SyntaxOptions>
+              <IncludeAssertionCode Value="True"/>
+            </SyntaxOptions>
+          </Parsing>
+          <CodeGeneration>
+            <Checks>
+              <IOChecks Value="True"/>
+              <RangeChecks Value="True"/>
+              <OverflowChecks Value="True"/>
+              <StackChecks Value="True"/>
+            </Checks>
+            <VerifyObjMethodCallValidity Value="True"/>
+          </CodeGeneration>
+          <Linking>
+            <Debugging>
+              <DebugInfoType Value="dsDwarf2Set"/>
+              <UseHeaptrc Value="True"/>
+              <TrashVariables Value="True"/>
+              <UseExternalDbgSyms Value="True"/>
+            </Debugging>
+            <Options>
+              <Win32>
+                <GraphicApplication Value="True"/>
+              </Win32>
+            </Options>
+          </Linking>
+        </CompilerOptions>
+      </Item2>
+      <Item3 Name="Release">
+        <CompilerOptions>
+          <Version Value="11"/>
+          <PathDelim Value="\"/>
+          <Target>
+            <Filename Value="test_bckeyboard"/>
+          </Target>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+          </SearchPaths>
+          <CodeGeneration>
+            <SmartLinkUnit Value="True"/>
+            <Optimizations>
+              <OptimizationLevel Value="3"/>
+            </Optimizations>
+          </CodeGeneration>
+          <Linking>
+            <Debugging>
+              <GenerateDebugInfo Value="False"/>
+            </Debugging>
+            <LinkSmart Value="True"/>
+            <Options>
+              <Win32>
+                <GraphicApplication Value="True"/>
+              </Win32>
+            </Options>
+          </Linking>
+        </CompilerOptions>
+      </Item3>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="2">
+      <Item1>
+        <PackageName Value="bgracontrols"/>
+      </Item1>
+      <Item2>
+        <PackageName Value="LCL"/>
+      </Item2>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="test_bckeyboard.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="umain.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="Form1"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="test_bckeyboard"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <Win32>
+          <GraphicApplication Value="True"/>
+        </Win32>
+      </Options>
+    </Linking>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 21 - 0
test/test_bckeyboard/test_bckeyboard.lpr

@@ -0,0 +1,21 @@
+program test_bckeyboard;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
+  Interfaces, // this includes the LCL widgetset
+  Forms, umain
+  { you can add units after this };
+
+{$R *.res}
+
+begin
+  RequireDerivedFormResource:=True;
+  Application.Initialize;
+  Application.CreateForm(TForm1, Form1);
+  Application.Run;
+end.
+

+ 30 - 0
test/test_bckeyboard/umain.lfm

@@ -0,0 +1,30 @@
+object Form1: TForm1
+  Left = 462
+  Height = 240
+  Top = 146
+  Width = 320
+  Caption = 'BC Keyboard'
+  ClientHeight = 240
+  ClientWidth = 320
+  OnShow = FormShow
+  LCLVersion = '1.7'
+  object Edit1: TEdit
+    Left = 0
+    Height = 28
+    Top = 0
+    Width = 320
+    Align = alTop
+    TabOrder = 0
+  end
+  object BCKeyboard1: TBCKeyboard
+    ThemeManager = BCDefaultThemeManager1
+    left = 40
+    top = 16
+  end
+  object BCDefaultThemeManager1: TBCDefaultThemeManager
+    BCStyle = ssFlashPlayer
+    CDStyle = dsDefault
+    left = 127
+    top = 96
+  end
+end

+ 45 - 0
test/test_bckeyboard/umain.pas

@@ -0,0 +1,45 @@
+unit umain;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+  BCKeyboard, BCDefaultThemeManager;
+
+type
+
+  { TForm1 }
+
+  TForm1 = class(TForm)
+    BCDefaultThemeManager1: TBCDefaultThemeManager;
+    BCKeyboard1: TBCKeyboard;
+    Edit1: TEdit;
+    procedure FormShow(Sender: TObject);
+  private
+
+  public
+
+  end;
+
+var
+  Form1: TForm1;
+
+implementation
+
+{$R *.lfm}
+
+{ TForm1 }
+
+procedure TForm1.FormShow(Sender: TObject);
+begin
+  BCDefaultThemeManager1.Apply();
+  BCKeyboard1.Panel.Left:=0;
+  BCKeyboard1.Panel.Top:=Edit1.Height;
+  BCKeyboard1.Show();
+  Form1.Width := BCKeyboard1.Panel.Width;
+end;
+
+end.
+