unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
StdCtrls, SDL2, SDL2_image, Math;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Panel1: TPanel;
Panel2: TPanel;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Panel1Paint(Sender: TObject);
private
SDLWindow: PSDL_Window;
SDLRenderer: PSDL_Renderer;
CurrentTexture: PSDL_Texture;
procedure InitializeSDL;
procedure ShutdownSDL;
procedure LoadAndDisplayImage(const FileName: string);
procedure RenderImage;
procedure HandleDropEvent(const FilePath: string);
procedure ProcessSDLEvents;
public
end;
var
Form1: TForm1;
SDLEvent: TSDL_Event;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.InitializeSDL;
begin
if SDL_Init(SDL_INIT_VIDEO) < 0 then
raise Exception.Create('Unable to initialize SDL: ' + SDL_GetError);
// Ensure Panel1.Handle is correctly cast to a pointer
SDLWindow := SDL_CreateWindowFrom(Pointer(Panel1.Handle));
if SDLWindow = nil then
raise Exception.Create('Unable to create SDL window: ' + SDL_GetError);
// Create the renderer
SDLRenderer := SDL_CreateRenderer(SDLWindow, -1, SDL_RENDERER_ACCELERATED or SDL_RENDERER_PRESENTVSYNC);
if SDLRenderer = nil then
raise Exception.Create('Unable to create SDL renderer: ' + SDL_GetError);
// Enable SDL's drop events
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
end;
procedure TForm1.ShutdownSDL;
begin
if CurrentTexture <> nil then
SDL_DestroyTexture(CurrentTexture);
if SDLRenderer <> nil then
SDL_DestroyRenderer(SDLRenderer);
if SDLWindow <> nil then
SDL_DestroyWindow(SDLWindow);
IMG_Quit;
SDL_Quit;
end;
procedure TForm1.RenderImage;
var
DstRect: TSDL_Rect;
ImgWidth, ImgHeight, PanelWidth, PanelHeight: Integer;
AspectRatio: Double;
begin
if CurrentTexture = nil then Exit;
// Get image dimensions
SDL_QueryTexture(CurrentTexture, nil, nil, @ImgWidth, @ImgHeight);
// Get panel dimensions
PanelWidth := Panel1.Width;
PanelHeight := Panel1.Height;
// Calculate aspect ratio to fit the image proportionally
AspectRatio := Min(PanelWidth / ImgWidth, PanelHeight / ImgHeight);
DstRect.w := Round(ImgWidth * AspectRatio);
DstRect.h := Round(ImgHeight * AspectRatio);
DstRect.x := (PanelWidth - DstRect.w) div 2;
DstRect.y := (PanelHeight - DstRect.h) div 2;
StatusBar1.Panels[0].Text:= IntToStr(ImgWidth) +'x' + inttostr(ImgHeight);
// Render the image
SDL_RenderClear(SDLRenderer);
SDL_RenderCopy(SDLRenderer, CurrentTexture, nil, @DstRect);
SDL_RenderPresent(SDLRenderer);
end;
procedure TForm1.HandleDropEvent(const FilePath: string);
begin
// Load and display the dropped image file
if FileExists(FilePath) then
begin
LoadAndDisplayImage(FilePath);
Form1.Caption := 'Loaded: ' + ExtractFileName(FilePath);
end
else
ShowMessage('Invalid file dropped: ' + FilePath);
end;
procedure TForm1.ProcessSDLEvents;
begin
while SDL_PollEvent(@SDLEvent) <> 0 do
begin
case SDLEvent.type_ of
SDL_DROPFILE:
begin
HandleDropEvent(SDLEvent.drop._file);
SDL_free(SDLEvent.drop._file); // Free the file path allocated by SDL
end;
SDL_QUITEV:
begin
Close;
end;
end;
end;
end;
procedure TForm1.LoadAndDisplayImage(const FileName: string);
begin
// Clean up the old texture if it exists
if CurrentTexture <> nil then
SDL_DestroyTexture(CurrentTexture);
// Load the new image as a texture
CurrentTexture := IMG_LoadTexture(SDLRenderer, PChar(FileName));
if CurrentTexture = nil then
raise Exception.Create('Nie udało się wczytać tekstury: ' + IMG_GetError);
// Render the image to fit the new size
RenderImage;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
InitializeSDL;
end;
procedure TForm1.Panel1Paint(Sender: TObject);
begin
// Draw a red rectangle (example)
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
SDL_RenderFillRect(sdlRenderer, nil); // Full screen fill
SDL_RenderPresent(sdlRenderer);
RenderImage;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ShutdownSDL;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
LoadAndDisplayImage(OpenDialog1.FileName);
end;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
RenderImage;
end;
end.