<?xml version="1.0" encoding="UTF-8"?>        <rss version="2.0"
             xmlns:atom="http://www.w3.org/2005/Atom"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
             xmlns:admin="http://webns.net/mvcb/"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:content="http://purl.org/rss/1.0/modules/content/">
        <channel>
            <title>
									HTML5 in general - Quartex Pascal Forum				            </title>
            <link>https://quartexdeveloper.com/community/html5-in-general/</link>
            <description>Quartex Pascal Discussion Board</description>
            <language>en-US</language>
            <lastBuildDate>Sun, 08 Mar 2026 20:34:00 +0000</lastBuildDate>
            <generator>wpForo</generator>
            <ttl>60</ttl>
							                    <item>
                        <title>Mediaplayer</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/mediaplayer/</link>
                        <pubDate>Fri, 31 Jan 2025 09:59:12 +0000</pubDate>
                        <description><![CDATA[Hi,
you might be wondering how to create a media player. Technically, all you need is a simple video element. However, in most cases, additional functionality is required, which is why libr...]]></description>
                        <content:encoded><![CDATA[<p>Hi,</p>
<p>you might be wondering how to create a media player. Technically, all you need is a simple video element. However, in most cases, additional functionality is required, which is why libraries like Shaka Player or DashJS are commonly used.</p>
<p>This class is designed to help you build a media player. While you could theoretically place everything inside TQTXVideo.</p>
<p>Due to nostalgic reasons I chose to structure it similarly to Delphi, where the player logic and the player window are separated into different classes. </p>
<p>A sample implementation would look like this:<br /><br /></p>
<pre contenteditable="false">var LVideo = TQTXVideo.Create(self, procedure(AVideoElement: TQTXVideo)
  begin
   var LPlayer = TQTXBasePlayer.createDefault(AVideoElement);
   LPlayer.OpenMedia('https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4');
   AVideoElement.Style.width := '100%';
   AVideoElement.Style.height := '100%';
   LPlayer.OnLoadedData := procedure(Sender: TObject)
   begin
    LPlayer.Play();
   end;
  end);</pre>
<p>The whole unit is the following one.</p>
<pre contenteditable="false">unit qtx.mediaplayer;

interface

uses
  qtx.sysutils, qtx.classes, qtx.dom.widgets, qtx.dom.types;


type
  TQTXVideo = class;
  TQTXVideoConstructor = procedure (AVideoElement: TQTXVideo);

  TQTXVideo = class(TQTXWidget)
  protected
   FVideoHandle: THandle;
  public
   constructor Create(AOwner: TQTXComponent; CB: TQTXVideoConstructor); reintroduce; virtual;
  end;


  TQTXBasePlayer = class
  protected
   FVideoHandle: THandle;
   FOnLoadedData: TNotifyEvent;
   FPoster: String;

   procedure InitializePlayer;virtual;
   procedure SetPoster(const AValue: String);virtual;
  public

   constructor Create(const AVideo: TQTXVideo);

   procedure Play;virtual;
   procedure Stop;virtual;
   procedure OpenMedia(AMediaFile: String; ALicenseServer, ACertServer: String = '');virtual;
   function IsPlaying: Boolean;

   property OnLoadedData: TNotifyEvent read FOnLoadedData write FOnLoadedData;
   property Poster: String read FPoster write SetPoster;

   class function createDefault(const AVideo: TQTXVideo): TQTXBasePlayer;
  end;

  TQTXShakaPlayer = class(TQTXBasePlayer)
  private
   FVideoPlayer: THandle;
  protected
   procedure InitializePlayer;override;
  public
   procedure OpenMedia(AMediaFile: String; ALicenseServer, ACertServer: String = '');override;
  end;

  TQTXShakaUIPlayer = class(TQTXShakaPlayer)
  protected
   FShakaUI: THandle;
   procedure InitializePlayer;override;
   procedure SetPoster(const AValue: String);override;
  end;

implementation

var FInitialized: Boolean = false;
    document external "document": JDocument;

{ TQTXBasePlayer }
class function TQTXBasePlayer.createDefault(const AVideo: TQTXVideo): TQTXBasePlayer;
begin
 result := TQTXShakaUIPlayer.create(AVideo);
end;

constructor TQTXBasePlayer.Create(const AVideo: TQTXVideo);
begin
 FVideoHandle := AVideo.FVideoHandle;
 InitializePlayer;
end;

procedure TQTXBasePlayer.Play;
begin
 if FVideoHandle &lt;&gt; nil then
  FVideoHandle.play();
end;

procedure TQTXBasePlayer.Stop;
begin
 if FVideoHandle &lt;&gt; nil then
  FVideoHandle.pause();
end;

procedure TQTXBasePlayer.InitializePlayer;
begin
end;

procedure TQTXBasePlayer.OpenMedia(AMediaFile: String; ALicenseServer, ACertServer:String = '');
begin
 if FVideoHandle &lt;&gt; nil then
   FVideoHandle.src := AMediaFile;
end;

function TQTXBasePlayer.IsPlaying(): Boolean;
begin
 result := (FVideoHandle &lt;&gt; nil) and (not FVideoHandle.paused);
end;

procedure TQTXBasePlayer.SetPoster(const AValue: String);
begin
 FPoster := AValue;
end;

{ TQTXShakaPlayer }

procedure TQTXShakaPlayer.InitializePlayer;

 procedure doLoadedData();
 begin
  if assigned(FOnLoadedData) then FOnLoadedData(self);
 end;

 procedure performError(AError: String);
 begin
  Stop;
 end;

begin
 if not FInitialized then
 begin
  FInitialized := true;
  asm
   shaka.polyfill.installAll();
   shaka.polyfill.PatchedMediaKeysApple.install();
  end;
 end;

 asm
  const videoElement = @self.FVideoHandle;
  videoElement.onloadeddata = @doLoadedData;

    var currentTime = [];
    videoElement.addEventListener("timeupdate", function() {
      if (!videoElement.seeking) {
       currentTime = videoElement.currentTime;
      }
    });

    let player;
    if (shaka.Player.isBrowserSupported())
    {
         player = new shaka.Player();
         player.attach(videoElement);
         player.configure('preferredTextLanguage', '');
         player.addEventListener('error', function(event) {
          var error = event.detail;
          @performError(error.code + ' - ' + error.message);
         });

         videoElement.player = player;

         @self.FVideoPlayer = player;
    }
 end;
end;

procedure TQTXShakaPlayer.OpenMedia(AMediaFile: String; ALicenseServer, ACertServer: String='');
begin
 asm
  const player = @FVideoPlayer;
  const videoElement = @FVideoHandle;

  const playerConfig = {
        manifest: {
          dash: {
            ignoreMinBufferTime: true,
          },
          defaultPresentationDelay: 0
        },
        streaming: {
          lowLatencyMode: true,
          inaccurateManifestTolerance: 0,
          rebufferingGoal: 0.1,
          preferNativeHls: true,
        },
        abr: {
          enabled: true,
          useNetworkInformation: false,
          defaultBandwidthEstimate: 1000000 / 240,
          switchInterval: 120,
        },

      };

  if (@ALicenseServer !== "null" &amp;&amp; @ALicenseServer !== null) {
        playerConfig.drm = {
          advanced: {
            "com.apple.fps": {
              serverCertificateUri: @ACertServer
            }
          },
          servers: {
            "com.widevine.alpha": @ALicenseServer,
            "com.apple.fps": @ALicenseServer,
          },
        };
      }

  videoElement.playbackRate = 1.0;

  player.configure(playerConfig);
  player.load(@AMediaFile);
 end;
end;


{ TQTXShakaUIPlayer }
procedure TQTXShakaUIPlayer.InitializePlayer;
begin
 inherited InitializePlayer;
 asm
  const video = @FVideoHandle;
  video.controls = false;
  video.style.width = '100%';

  const player = @FVideoPlayer;
  player.configure('ui.addPictureInPictureButton', true);

  video.parentElement.addEventListener('keyup', function(event) {
      if (!video.paused &amp;&amp; event.key.toLowerCase() === 'f') {
        event.preventDefault();
        video.requestFullscreen();
      }
  });

  const ui = new shaka.ui.Overlay(player, video.parentElement, video);
  const config = {
      'addSeekBar': true,
      'seekBarColors': {
        base: 'rgba(255,255,255,.2)',
        buffered: 'rgba(255,255,255,.4)',
        played: '#2f80ed',
      }
    }
  ui.configure(config);
  @FShakaUI = ui;
 end;
end;

procedure TQTXShakaUIPlayer.SetPoster(const AValue: String);
begin
 inherited SetPoster(AValue);
 FVideoHandle.Poster := AValue;
end;

{ TQTXVideo }
constructor TQTXVideo.Create(AOwner: TQTXComponent; CB: TQTXVideoConstructor);
begin
  inherited Create(AOwner, procedure(Widget: TQTXWidget)
  begin
   FVideoHandle := document.createElement('video');
   Widget.Handle.appendChild(FVideoHandle);
   PositionMode := TQTXWidgetPositionMode.cpAbsolute;
   if assigned(CB) then CB(self);
  end);
end;

(* Example Player

  Add this to your index.html

   &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.12.6/shaka-player.compiled.js" &gt;&lt;/script&gt;
   &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.12.6/shaka-player.ui.min.js" &gt;&lt;/script&gt;
   &lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.12.6/controls.min.css" /&gt;


*)

end.
</pre>
<p> </p>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/mediaplayer/</guid>
                    </item>
				                    <item>
                        <title>Sidemenu</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/sidemenu-2/</link>
                        <pubDate>Tue, 18 Jun 2024 20:09:22 +0000</pubDate>
                        <description><![CDATA[Jons Desktop system lacks on one small thing. You get confused by the buttons if you have more than a bunch of icons. The attached unit has a slim side menu which tries to solve that issue.T...]]></description>
                        <content:encoded><![CDATA[<p>Jons Desktop system lacks on one small thing. You get confused by the buttons if you have more than a bunch of icons. The attached unit has a slim side menu which tries to solve that issue.<br /><br />The usage is quite simple:</p>
<pre contenteditable="false">var FToolbar := TQTXSideMenuList.Create( self, procedure (Toolbar: TQTXSideMenuList)
      begin
        Toolbar.RightMenu := true;
        Toolbar.Add(false, 'fa-chart-simple', 'Auswertungen', nil);
        Toolbar.Add(false, 'fa-tv', 'Alle Sender', nil);
        Toolbar.Add(false, 'fa-cube', 'Paketübersicht', nil);
        Toolbar.Add(false, 'fa-home', 'Haushaltsverwaltung', nil);

        Toolbar.Add(false, 'fa-user-group', 'Gruppenverwaltung', nil);
        Toolbar.Add(false, 'fa-globe', 'Netzwerke verwalten', nil);
        Toolbar.Add(false, 'fa-cogs', ' Portal-Benutzerverwaltung', nil);
        Toolbar.Add(false, 'fa-house-signal', 'Aktive Verbindungen', nil);

        Toolbar.Add(false, 'fa-users', 'Kundenaktivitäten', nil);
        Toolbar.Add(false, 'fa-film', 'Apps verwalten', nil);
        Toolbar.Add(false, 'fa-info', 'Änderungsprotokoll', nil);
        Toolbar.Add(false, 'fa-newspaper', 'Nachrichtenverwaltung', nil);

        Toolbar.Add(true, 'fa-power-off', 'Abmelden', nil);
      end);</pre>
<div id="wpfa-1593" class="wpforo-attached-file"><a class="wpforo-default-attachment" href="//login.quartexdeveloper.com/wp-content/uploads/wpforo/default_attachments/1718741391-desktopsidemenupas_.zip" target="_blank" title="desktop.sidemenu.pas_.zip"><i class="fas fa-paperclip"></i>&nbsp;desktop.sidemenu.pas_.zip</a></div>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/sidemenu-2/</guid>
                    </item>
				                    <item>
                        <title>QR Code Generator</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/qr-code-generator/</link>
                        <pubDate>Fri, 07 Jun 2024 19:32:34 +0000</pubDate>
                        <description><![CDATA[If you ever need to generate a QR code you might check the following project:usage is quite simple, create a qrCode class and render it into an element. For example like this. 
function gen...]]></description>
                        <content:encoded><![CDATA[<p>If you ever need to generate a QR code you might check the following project: <a href="https://github.com/jeromeetienne/jquery-qrcode">https://github.com/jeromeetienne/jquery-qrcode</a><br />The usage is quite simple, create a qrCode class and render it into an element. For example like this. </p>
<pre contenteditable="false">function generateQRCode(const AText: String): String;
begin
 asm
            var tempDiv = document.createElement("div");
            document.body.appendChild(tempDiv);
            var qrCode = new QRCode(tempDiv, {
                text: @AText,
                width: 256,
                height: 256,
                correctLevel: QRCode.CorrectLevel.H
            });

            setTimeout(() =&gt; {
                var qrImage = tempDiv.getElementsByTagName("img");
                var canvas = document.createElement("canvas");
                document.body.appendChild(canvas);
                var context = canvas.getContext("2d");
                canvas.width = qrImage.width;
                canvas.height = qrImage.height;
                context.drawImage(qrImage, 0, 0);

                var base64Jpg = canvas.toDataURL("image/jpeg");
                @result = base64Jpg;

                canvas.remove();
                tempDiv.remove();
            }, 100);
  end;
end;</pre>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/qr-code-generator/</guid>
                    </item>
				                    <item>
                        <title>Sidemenu</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/sidemenu/</link>
                        <pubDate>Wed, 17 Apr 2024 18:58:45 +0000</pubDate>
                        <description><![CDATA[Hi, 
 
the attached class is based on this idea:
You easily can create the same menu using this code:
 var LList = TQTXSideMenuList.Create(self, nil);  LList.Add(false,&#039;fa-home&#039;, &#039;Communi...]]></description>
                        <content:encoded><![CDATA[<p>Hi, </p>
<p> </p>
<p>the attached class is based on this idea: <a href="https://codepen.io/JFarrow/pen/nJgRga">https://codepen.io/JFarrow/pen/nJgRga</a></p>
<p>You easily can create the same menu using this code:</p>
<pre contenteditable="false"><code><span class="dws1-space"> </span><span class="dws1-reservedword">var</span><span class="dws1-space"> </span><span class="dws1-identifier">LList</span><span class="dws1-space"> </span><span class="dws1-symbol">=</span><span class="dws1-space"> </span><span class="dws1-identifier">TQTXSideMenuList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Create</span><span class="dws1-symbol">(</span><span class="dws1-identifier">self</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /><br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-home'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Community Dashboard'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-globe'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Global Surveyors'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-comments'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Group Hub Forums'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-camera-retro'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Survey Photos'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-film'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Surveying Tutorials'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-book'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Surveying Jobs'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-cogs'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Tools &amp; Resources'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-map-marker'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Member Map'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">false</span><span class="dws1-symbol">,</span><span class="dws1-string">'fa-info'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Documentation'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /><br /></span><span class="dws1-space">  </span><span class="dws1-identifier">LList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Add</span><span class="dws1-symbol">(</span><span class="dws1-identifier">true</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'fa-power-off'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-string">'Logout'</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">nil</span><span class="dws1-symbol">);<br /></span></code></pre>
<p>I tried to keep it simple and not using any asm instructions for it. In my case I will expand in order to arrange the menu located either on the left or right side of a page. </p>
<p>Christian</p>
<div id="wpfa-1503" class="wpforo-attached-file"><a class="wpforo-default-attachment" href="//login.quartexdeveloper.com/wp-content/uploads/wpforo/default_attachments/1713380325-sidemenu.zip" target="_blank" title="sidemenu.zip"><i class="fas fa-paperclip"></i>&nbsp;sidemenu.zip</a></div>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/sidemenu/</guid>
                    </item>
				                    <item>
                        <title>QR Code Scanner</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/qr-code-scanner/</link>
                        <pubDate>Mon, 29 Jan 2024 07:31:16 +0000</pubDate>
                        <description><![CDATA[Hi, this is a small snippet and shows how to use the QR code scanner from here:
unit qrscanner;

interface

uses
  qtx.sysutils, qtx.classes, qtx.dom.widgets, qtx.dom.types;

type
 ...]]></description>
                        <content:encoded><![CDATA[<p>Hi, this is a small snippet and shows how to use the QR code scanner from here:</p>
<p><a href="https://raw.githubusercontent.com/nimiq/qr-scanner/master/qr-scanner.legacy.min.js">https://raw.githubusercontent.com/nimiq/qr-scanner/master/qr-scanner.legacy.min.js</a></p>
<pre contenteditable="false">unit qrscanner;

interface

uses
  qtx.sysutils, qtx.classes, qtx.dom.widgets, qtx.dom.types;

type
 TQTXQRScanner = class;
 TQTXQRScannerConstructor = procedure (QTXScanner: TQTXQRScanner);

 TOnGetQRCode = procedure(Sender: TObject; Result: String);

 TQTXQRScanner = class(TQTXWidget)
 private
  FOnGetQRCode: TOnGetQRCode;
  FVideoElement: THandle;
  FScanner: THandle;
 public
  constructor Create(AOwner: TQTXComponent; CB: TQTXQRScannerConstructor); reintroduce; virtual;

  property OnGetQRCode: TOnGetQRCode read FOnGetQRCode write FOnGetQRCode;
 end;

implementation

constructor TQTXQRScanner.Create(AOwner: TQTXComponent; CB: TQTXQRScannerConstructor);

 procedure Callback(AResult: Variant);
 begin
  if assigned(FOnGetQRCode) then FOnGetQRCode(Self, AResult.data);
 end;

begin
  inherited Create(AOwner, procedure(Widget: TQTXWidget)
  begin
   Style.width := '100%';
   Style.height := '100%';

   asm
    const video = document.createElement('video');
    video.id = 'qr-video';

    @self.FVideoElement = video;
   end;
   Widget.Handle.appendChild(FVideoElement);
   if assigned(CB) then CB(self);

   TQTXDispatch.Execute(procedure()
   begin
    asm
      const scanner = new QrScanner(video, result =&gt; {
         @Callback(result);
        }, {
          highlightScanRegion: true,
          highlightCodeOutline: true,
        });

     @self.FScanner = scanner;
     scanner.start();
    end;
   end,1000);
  end);
end;

end.
</pre>
<p> </p>
<p> </p>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/qr-code-scanner/</guid>
                    </item>
				                    <item>
                        <title>Generate MD5</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/generate-md5/</link>
                        <pubDate>Tue, 21 Nov 2023 19:40:34 +0000</pubDate>
                        <description><![CDATA[Hi,
i am not sure if you ever needed to create an md5 hash function, but you might find this one helpful:
function MD5(const AInput: String): String;
begin
 asm
    var hc=&quot;0123456789ab...]]></description>
                        <content:encoded><![CDATA[<p>Hi,</p>
<p>i am not sure if you ever needed to create an md5 hash function, but you might find this one helpful:</p>
<pre contenteditable="false">function MD5(const AInput: String): String;
begin
 asm
    var hc="0123456789abcdef";
    function rh(n) {var j,s="";for(j=0;j&lt;=3;j++) s+=hc.charAt((n&gt;&gt;(j*8+4))&amp;0x0F)+hc.charAt((n&gt;&gt;(j*8))&amp;0x0F);return s;}
    function ad(x,y) {var l=(x &amp; 0xFFFF)+(y &amp; 0xFFFF);var m=(x&gt;&gt;16)+(y&gt;&gt;16)+(l&gt;&gt;16);return (m&lt;&lt;16)|(l &amp; 0xFFFF);}
    function rl(n,c)            {return (n&lt;&lt;c)|(n&gt;&gt;&gt;(32-c));}
    function cm(q,a,b,x,s,t)    {return ad(rl(ad(ad(a,q),ad(x,t)),s),b);}
    function ff(a,b,c,d,x,s,t)  {return cm((b &amp; c)|((~b) &amp; d),a,b,x,s,t);}
    function gg(a,b,c,d,x,s,t)  {return cm((b &amp; d)|(c &amp; (~d)),a,b,x,s,t);}
    function hh(a,b,c,d,x,s,t)  {return cm(b^c^d,a,b,x,s,t);}
    function ii(a,b,c,d,x,s,t)  {return cm(c^(b|(~d)),a,b,x,s,t);}
    function sb(x) {
        var i;var nblk=((x.length+8)&gt;&gt;6)+1;var blks=new Array(nblk*16);for(i=0;i&lt;nblk*16;i++) blks=0;
        for(i=0;i&lt;x.length;i++) blks|=x.charCodeAt(i)&lt;&lt;((i%4)*8);
        blks|=0x80&lt;&lt;((i%4)*8);blks=x.length*8;return blks;
    }
    var i,x=sb(""+@AInput),a=1732584193,b=-271733879,c=-1732584194,d=271733878,olda,oldb,oldc,oldd;
    for(i=0;i&lt;x.length;i+=16) {olda=a;oldb=b;oldc=c;oldd=d;
        a=ff(a,b,c,d,x, 7, -680876936);d=ff(d,a,b,c,x,12, -389564586);c=ff(c,d,a,b,x,17,  606105819);
        b=ff(b,c,d,a,x,22,-1044525330);a=ff(a,b,c,d,x, 7, -176418897);d=ff(d,a,b,c,x,12, 1200080426);
        c=ff(c,d,a,b,x,17,-1473231341);b=ff(b,c,d,a,x,22,  -45705983);a=ff(a,b,c,d,x, 7, 1770035416);
        d=ff(d,a,b,c,x,12,-1958414417);c=ff(c,d,a,b,x,17,     -42063);b=ff(b,c,d,a,x,22,-1990404162);
        a=ff(a,b,c,d,x, 7, 1804603682);d=ff(d,a,b,c,x,12,  -40341101);c=ff(c,d,a,b,x,17,-1502002290);
        b=ff(b,c,d,a,x,22, 1236535329);a=gg(a,b,c,d,x, 5, -165796510);d=gg(d,a,b,c,x, 9,-1069501632);
        c=gg(c,d,a,b,x,14,  643717713);b=gg(b,c,d,a,x,20, -373897302);a=gg(a,b,c,d,x, 5, -701558691);
        d=gg(d,a,b,c,x, 9,   38016083);c=gg(c,d,a,b,x,14, -660478335);b=gg(b,c,d,a,x,20, -405537848);
        a=gg(a,b,c,d,x, 5,  568446438);d=gg(d,a,b,c,x, 9,-1019803690);c=gg(c,d,a,b,x,14, -187363961);
        b=gg(b,c,d,a,x,20, 1163531501);a=gg(a,b,c,d,x, 5,-1444681467);d=gg(d,a,b,c,x, 9,  -51403784);
        c=gg(c,d,a,b,x,14, 1735328473);b=gg(b,c,d,a,x,20,-1926607734);a=hh(a,b,c,d,x, 4,    -378558);
        d=hh(d,a,b,c,x,11,-2022574463);c=hh(c,d,a,b,x,16, 1839030562);b=hh(b,c,d,a,x,23,  -35309556);
        a=hh(a,b,c,d,x, 4,-1530992060);d=hh(d,a,b,c,x,11, 1272893353);c=hh(c,d,a,b,x,16, -155497632);
        b=hh(b,c,d,a,x,23,-1094730640);a=hh(a,b,c,d,x, 4,  681279174);d=hh(d,a,b,c,x,11, -358537222);
        c=hh(c,d,a,b,x,16, -722521979);b=hh(b,c,d,a,x,23,   76029189);a=hh(a,b,c,d,x, 4, -640364487);
        d=hh(d,a,b,c,x,11, -421815835);c=hh(c,d,a,b,x,16,  530742520);b=hh(b,c,d,a,x,23, -995338651);
        a=ii(a,b,c,d,x, 6, -198630844);d=ii(d,a,b,c,x,10, 1126891415);c=ii(c,d,a,b,x,15,-1416354905);
        b=ii(b,c,d,a,x,21,  -57434055);a=ii(a,b,c,d,x, 6, 1700485571);d=ii(d,a,b,c,x,10,-1894986606);
        c=ii(c,d,a,b,x,15,   -1051523);b=ii(b,c,d,a,x,21,-2054922799);a=ii(a,b,c,d,x, 6, 1873313359);
        d=ii(d,a,b,c,x,10,  -30611744);c=ii(c,d,a,b,x,15,-1560198380);b=ii(b,c,d,a,x,21, 1309151649);
        a=ii(a,b,c,d,x, 6, -145523070);d=ii(d,a,b,c,x,10,-1120210379);c=ii(c,d,a,b,x,15,  718787259);
        b=ii(b,c,d,a,x,21, -343485551);a=ad(a,olda);b=ad(b,oldb);c=ad(c,oldc);d=ad(d,oldd);
    }
    @result = rh(a)+rh(b)+rh(c)+rh(d);
 end;
end;</pre>
<p>Frankly I dislike the fact to use third party libraries for basic things and this one is not grown directly on "my dung", but it works and fulfills my requirements.</p>
<p>Cheers</p>
<p>Christian</p>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/generate-md5/</guid>
                    </item>
				                    <item>
                        <title>Clock Component</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/clock-component/</link>
                        <pubDate>Fri, 13 Oct 2023 08:27:51 +0000</pubDate>
                        <description><![CDATA[Hi,
I&#039;ve developed a compact clock class for a side project. The main code is written in ASM-JavaScript Blocks, and I&#039;ve utilized CSS for rendering. While it may not be the optimal approach...]]></description>
                        <content:encoded><![CDATA[<p><span>Hi,</span></p>
<p><span>I've developed a compact clock class for a side project. The main code is written in ASM-JavaScript Blocks, and I've utilized CSS for rendering. While it may not be the optimal approach for a Qtx framework, I've chosen to use JavaScript for most of my internal processes in most of my projects. Maybe somebody has the nerve to wrap this into a package?</span></p>
<p>The usage itself is extremely simple. Just put the Watch on the Form and add a timer to update the hour and minute pointers.</p>
<pre contenteditable="false">var LWatch := TQTXWatch.create(self, procedure(Watch: TQTXWatch)
  begin
      var LTimer := TQTXEventRepeater.Create(
      function(Sender: TQTXCustomRepeater): TQTXRepeatResult
       begin
         Watch.SetTime(now);
         result := TQTXRepeatResult.rrContinue;
       end, 1000);
  end);</pre>
<p>Christian</p>
<div id="wpfa-1292" class="wpforo-attached-file"><a class="wpforo-default-attachment" href="//login.quartexdeveloper.com/wp-content/uploads/wpforo/default_attachments/1697185700-qtxdom_watch_pas_.zip" target="_blank" title="qtx.dom_.watch_.pas_.zip"><i class="fas fa-paperclip"></i>&nbsp;qtx.dom_.watch_.pas_.zip</a></div>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/clock-component/</guid>
                    </item>
				                    <item>
                        <title>TODO List Example</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/todo-list-example/</link>
                        <pubDate>Thu, 10 Aug 2023 09:05:01 +0000</pubDate>
                        <description><![CDATA[Hi, I wrote a simple TODO List Widget. Maybe somebody will find it as useful as I do :)
 
unit qtx.dom.todo;

interface

uses
  qtx.sysutils, qtx.classes, qtx.dom.widgets;

type
 T...]]></description>
                        <content:encoded><![CDATA[<p>Hi, I wrote a simple TODO List Widget. Maybe somebody will find it as useful as I do :)</p>
<p> </p>
<pre contenteditable="false">unit qtx.dom.todo;

interface

uses
  qtx.sysutils, qtx.classes, qtx.dom.widgets;

type
 TQTXTodoList = class;
 TQTXTodoListConstructor = procedure (Dashboard: TQTXTodoList);

  TQTXTodoList = class(TQTXWidget)
  private
   FItems: Array of TQTXWidget;
  public
   constructor Create(AOwner: TQTXComponent; CB: TQTXTodoListConstructor); reintroduce; virtual;
   procedure Add(ADescription: String);
   procedure Clear;

   property  Items: TQTXWidget read ( FItems );
   property  ItemCount: integer read (FItems.length);
  end;

implementation uses qtx.dom.stylesheet;

constructor TQTXTodoList.Create(AOwner: TQTXComponent; CB: TQTXTodoListConstructor);
begin
  inherited Create(AOwner, procedure(Widget: TQTXWidget)
  begin
    TQTXWidget.create(AOwner, procedure(Widget: TQTXWidget)
    begin
       Widget.InnerHtml := #'
        &lt;svg viewBox="0 0 0 0" style="position: absolute; z-index: -1; opacity: 0;"&gt;
        &lt;defs&gt;
          &lt;linearGradient id="boxGradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="25" y2="25"&gt;
            &lt;stop offset="0%"   stop-color="#27FDC7"/&gt;
            &lt;stop offset="100%" stop-color="#0FC0F5"/&gt;
          &lt;/linearGradient&gt;

          &lt;linearGradient id="lineGradient"&gt;
            &lt;stop offset="0%"    stop-color="#0FC0F5"/&gt;
            &lt;stop offset="100%"  stop-color="#27FDC7"/&gt;
          &lt;/linearGradient&gt;

          &lt;path id="TQTXTodoLine" stroke="url(#lineGradient)" d="M21 12.3h168v0.1z"&gt;&lt;/path&gt;
          &lt;path id="TQTXTodoBox" stroke="url(#boxGradient)" d="M21 12.7v5c0 1.3-1 2.3-2.3 2.3H8.3C7 20 6 19 6 17.7V7.3C6 6 7 5 8.3 5h10.4C20 5 21 6 21 7.3v5.4"&gt;&lt;/path&gt;
          &lt;path id="TQTXTodoCheck" stroke="url(#boxGradient)" d="M10 13l2 2 5-5"&gt;&lt;/path&gt;
          &lt;circle id="TQTXTodoCircle" cx="13.5" cy="12.5" r="10"&gt;&lt;/circle&gt;
        &lt;/defs&gt;
      &lt;/svg&gt;
      ';
    end);

    Widget.Width := 500;
    Widget.Height := 300;
    Widget.Style.overflowY := 'auto';
    if assigned(CB) then CB(self);
  end);
end;

procedure TQTXTodoList.Clear;
begin
 FItems.Clear;
end;


procedure TQTXTodoList.Add(ADescription: String);
begin
 var LItem = TQTXWidget.Create(self, procedure(Widget: TQTXWidget)
 begin
  Widget.CssClasses.ClassRemove('TQTXWidget');
  Widget.DisplayMode := TQTXWidgetDisplayMode.cdBlock;
  Widget.InnerHtml :=   '&lt;label class="TQTXTodo"&gt;'+
  '  &lt;input class="TQTXTodoState" type="checkbox" /&gt;'+
  '  &lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 25" class="TQTXTodoIcon"&gt;'+
  '    &lt;use xlink:href="#TQTXTodoLine" class="TQTXTodoLine"&gt;&lt;/use&gt;'+
  '    &lt;use xlink:href="#TQTXTodoBox" class="TQTXTodoBox"&gt;&lt;/use&gt;'+
  '    &lt;use xlink:href="#TQTXTodoCheck" class="TQTXTodoCheck"&gt;&lt;/use&gt;'+
  '    &lt;use xlink:href="#TQTXTodoCircle" class="TQTXTodoCircle"&gt;&lt;/use&gt;'+
  '  &lt;/svg&gt;'+
  '  &lt;div class="TQTXTodoText"&gt;'+ADescription+'&lt;/div&gt;'+
  '&lt;/label&gt;';
 end);
 FItems.Push(LItem);
end;

initialization
begin
 var lSheet := TQTXCSSRules.Global;
  lSheet.AddStyles(
   #'
      .TQTXTodoList {
        background: #FFF;
        font-size: 20px;
        max-width: 15em;
        margin: auto;
        padding: 0.5em 1em;
        box-shadow: 0 5px 30px rgba(0, 0, 0, 0.2);
      }
      .TQTXTodoList::-webkit-scrollbar {
        width: 8px;
      }

      .TQTXTodoList::-webkit-scrollbar-track {
        background-color: transparent; /* Hintergrundfarbe der Scrollleisten-Spur */
      }

      .TQTXTodoList::-webkit-scrollbar-thumb {
        background-color: rgba(0, 0, 0, 0.2); /* Farbe des Scrollleisten-Griffs */
      }

      .TQTXTodo {
        display: block;
        position: relative;
        padding: 1em 1em 1em 16%;
        margin: 0 auto;
        cursor: pointer;
        border-bottom: solid 1px #ddd;
      }
      .TQTXTodo:last-child {
        border-bottom: none;
      }
      .TQTXTodoState {
        position: absolute;
        top: 0;
        left: 0;
        opacity: 0;
      }
      .TQTXTodoText {
        color: #135156;
        transition: all 0.4s linear 0.4s;
      }
      .TQTXTodoIcon {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        width: 100%;
        height: auto;
        margin: auto;
        fill: none;
        stroke: #27FDC7;
        stroke-width: 2;
        stroke-linejoin: round;
        stroke-linecap: round;
      }
      .TQTXTodoLine,
      .TQTXTodoBox,
      .TQTXTodoCheck {
        transition: stroke-dashoffset 0.8s cubic-bezier(0.9, 0, 0.5, 1);
      }
      .TQTXTodoCircle {
        stroke: #27FDC7;
        stroke-dasharray: 1 6;
        stroke-width: 0;
        transform-origin: 13.5px 12.5px;
        transform: scale(0.4) rotate(0deg);
        -webkit-animation: none 0.8s linear;
                animation: none 0.8s linear;
      }
      .TQTXTodoBox {
        stroke-dasharray: 56.1053, 56.1053;
        stroke-dashoffset: 0;
        transition-delay: 0.16s;
      }
      .TQTXTodoCheck {
        stroke: #27FDC7;
        stroke-dasharray: 9.8995, 9.8995;
        stroke-dashoffset: 9.8995;
        transition-duration: 0.32s;
      }
      .TQTXTodoLine {
        stroke-dasharray: 168, 1684;
        stroke-dashoffset: 168;
      }
      .TQTXTodoCircle {
        -webkit-animation-delay: 0.56s;
                animation-delay: 0.56s;
        -webkit-animation-duration: 0.56s;
                animation-duration: 0.56s;
      }
      .TQTXTodoState:checked ~ .TQTXTodoText {
        transition-delay: 0s;
        color: #5EBEC1;
        opacity: 0.6;
      }
      .TQTXTodoState:checked ~ .TQTXTodoIcon .TQTXTodoBox {
        stroke-dashoffset: 56.1053;
        transition-delay: 0s;
      }
      .TQTXTodoState:checked ~ .TQTXTodoIcon .TQTXTodoLine {
        stroke-dashoffset: -8;
      }
      .TQTXTodoState:checked ~ .TQTXTodoIcon .TQTXTodoCheck {
        stroke-dashoffset: 0;
        transition-delay: 0.48s;
      }
      .TQTXTodoState:checked ~ .TQTXTodoIcon .TQTXTodoCircle {
        -webkit-animation-name: explode;
                animation-name: explode;
      }
   ');
end;
end.
</pre>
<p> </p>
<p>Regards,</p>
<p>Christian</p>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/todo-list-example/</guid>
                    </item>
				                    <item>
                        <title>Diary Class Example</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/diary-class-example/</link>
                        <pubDate>Sun, 21 May 2023 18:41:23 +0000</pubDate>
                        <description><![CDATA[Hi, 
I built a new small project to test grids aligning automatically depending on the available browser dimension. I wrapped this in a small Widget. Feel free to use or better to improve i...]]></description>
                        <content:encoded><![CDATA[<p>Hi, </p>
<p>I built a new small project to test grids aligning automatically depending on the available browser dimension. I wrapped this in a small Widget. Feel free to use or better to improve it.</p>
<div id="wpfa-1186" class="wpforo-attached-file"><a class="wpforo-default-attachment" href="//login.quartexdeveloper.com/wp-content/uploads/wpforo/default_attachments/1684694483-Diary.zip" target="_blank" title="Diary.zip"><i class="fas fa-paperclip"></i>&nbsp;Diary.zip</a></div>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/diary-class-example/</guid>
                    </item>
				                    <item>
                        <title>Unordered List Example</title>
                        <link>https://quartexdeveloper.com/community/html5-in-general/unordered-list-example/</link>
                        <pubDate>Mon, 15 May 2023 09:36:45 +0000</pubDate>
                        <description><![CDATA[The attached example uses
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
...
&lt;/ul&gt;
 
I am not sure if it is on purpose, or just forgotten. In the past I used these lists to build menus, so I w...]]></description>
                        <content:encoded><![CDATA[<p>The attached example uses</p>
<p>&lt;ul&gt;</p>
<p>&lt;li&gt;&lt;/li&gt;</p>
<p>...</p>
<p>&lt;/ul&gt;</p>
<p> </p>
<p>I am not sure if it is on purpose, or just forgotten. In the past I used these lists to build menus, so I wrote two tiny classes and a simple example for testing. It should be wrapped in a class I guess, but so far a simple:</p>
<pre contenteditable="false"><code><span class="dws1-identifier">TQTXDOMUList</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Create</span><span class="dws1-symbol">(</span><span class="dws1-identifier">self</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">procedure</span><span class="dws1-symbol">(</span><span class="dws1-identifier">List</span><span class="dws1-symbol">:</span><span class="dws1-space"> </span><span class="dws1-identifier">TQTXDOMUList</span><span class="dws1-symbol">)<br /></span><span class="dws1-space">  </span><span class="dws1-reservedword">begin<br /></span><span class="dws1-space">   </span><span class="dws1-reservedword">for</span><span class="dws1-space"> </span><span class="dws1-reservedword">var</span><span class="dws1-space"> </span><span class="dws1-identifier">i</span><span class="dws1-space"> </span><span class="dws1-symbol">:=</span><span class="dws1-space"> </span><span class="dws1-number">0</span><span class="dws1-space"> </span><span class="dws1-reservedword">to</span><span class="dws1-space"> </span><span class="dws1-identifier">high</span><span class="dws1-symbol">(</span><span class="dws1-identifier">C_Items</span><span class="dws1-symbol">)</span><span class="dws1-space"> </span><span class="dws1-reservedword">do<br /></span><span class="dws1-space">    </span><span class="dws1-identifier">TQTXDOMLItem</span><span class="dws1-symbol">.</span><span class="dws1-identifier">Create</span><span class="dws1-symbol">(</span><span class="dws1-identifier">List</span><span class="dws1-symbol">,</span><span class="dws1-space"> </span><span class="dws1-reservedword">procedure</span><span class="dws1-symbol">(</span><span class="dws1-identifier">Item</span><span class="dws1-symbol">:</span><span class="dws1-space"> </span><span class="dws1-identifier">TQTXDOMLItem</span><span class="dws1-symbol">)<br /></span><span class="dws1-space">    </span><span class="dws1-reservedword">begin<br /></span><span class="dws1-space">     </span><span class="dws1-identifier">Item</span><span class="dws1-symbol">.</span><span class="dws1-identifier">InnerHtml</span><span class="dws1-space"> </span><span class="dws1-symbol">:=</span><span class="dws1-space"> </span><span class="dws1-identifier">C_Items</span><span class="dws1-symbol">;<br /></span><span class="dws1-space">    </span><span class="dws1-reservedword">end</span><span class="dws1-symbol">);<br /></span><span class="dws1-space">  </span><span class="dws1-reservedword">end</span><span class="dws1-symbol">);<br /></span></code></pre>
<p>does the job too. </p>
<div id="wpfa-1177" class="wpforo-attached-file"><a class="wpforo-default-attachment" href="//login.quartexdeveloper.com/wp-content/uploads/wpforo/default_attachments/1684143405-UnorderedList.zip" target="_blank" title="UnorderedList.zip"><i class="fas fa-paperclip"></i>&nbsp;UnorderedList.zip</a></div>]]></content:encoded>
						                            <category domain="https://quartexdeveloper.com/community/html5-in-general/">HTML5 in general</category>                        <dc:creator>Hackbart</dc:creator>
                        <guid isPermaLink="true">https://quartexdeveloper.com/community/html5-in-general/unordered-list-example/</guid>
                    </item>
							        </channel>
        </rss>
		