Recent

Recent Posts

Pages: 1 ... 8 9 [10]
91
General / Re: Draw Behind Desktop Icons - porting
« Last post by atroesch on November 16, 2025, 07:46:33 pm »
Yes, really, because i know that i know nothing, thats why i ask here.
92
macOS / Mac OS X / Re: Problem with Qt5 on macOS
« Last post by mischi on November 16, 2025, 07:44:29 pm »
I build lazarus with qt6 on macOS 26.1 arm along this way:
1) create the Qt6pas framework in lcl/interfaces/qt6/cbindings
- /opt/local/libexec/qt6/bin/qmake
- make
- sudo make install
2) create lazarus:
- make bigide OPT="-gl -Ff/opt/local/libexec/qt6/lib" LCL_PLATFORM=qt6

Compilation and linking work, but otools -L lazarus yields:
   Qt6Pas.framework/Versions/6/Qt6Pas (compatibility version 6.2.0, current version 6.2.10)

So, /opt/local/libexec/qt6/lib is again missing. Unfortunately.

Edit: I finally got it: I need to change the id of the framework(See below). Then linking works.

This command:

sudo install_name_tool -id /opt/local/libexec/qt6/lib/Qt6Pas.framework/Versions/6/Qt6Pas Qt6Pas.framework/Qt6Pas

fixed it after installation. But this can also be done immediately after building the framework.

Maybe, it can also be done with some options to qmake or make when building the framework, but I leave this to others to investigate.

MiSchi
93
Options / Re: Lowercase Drive in LAZ 4.4 Project Inspector
« Last post by JuhaManninen on November 16, 2025, 07:34:56 pm »
This forum thread does not need closing. However if you find a way to reproduce the error, please create a bug report with exact steps to reproduce. Then we can figure out which revision caused it.

I don't believe it is a regression caused by Lazarus 4.4 bug fix release. It is more likely an older bug triggered by some unusual workflow.
94
macOS / Mac OS X / Re: New Mac mini M4 - FPC 3.2.2 on MacOS 26.1
« Last post by mischi on November 16, 2025, 07:30:38 pm »
That is for the very specific situation where you want an Intel Mac bootstrap compiler to build the AARCH64 one.
I did not even try that! I just built cross-compilers to build a AARCH64 bootstrap compiler that builds AARCH64 trunk/main.

But it is welcome but never necessity.

I am not sure, whether I completely get what you mean. Until now, the Intel compiler was used as bootstrap compiler to build the AARCH64 compiler from sources. So far, this was no problem since Rosetta was present by default. With macOS 26, the latter is no longer the case and a AARCH64 bootstrap compiler is a preferred option. This is what the pull request deals with by using the AARCH64 compiler from the disk image as bootstrap compiler.

Th installation with MacPorts has never been a necessity, but another possibility. For lazarus my claim is that it is more convenient. However, I understand the additional effort to install MacPorts and other barriers.

MiSchi
95
General / Cross-platform rich text
« Last post by lelanthran on November 16, 2025, 07:07:08 pm »
For a project I have in mind I need a text editor for the user to enter some prose, save it (possibly converting it to a text-based representation), and then load it later when they reopen the application.

I tried using various RTF components (Memos, usually) but they aren't really all that featureful and they aren't very cross-platform (One works only on Windows, for example).

I also tried a few  components that promised to accept a subset of HTML, and render it as a proper memo, but none of them were very successful; either the subset of HTML was too small to be useful or they just didn't work (one worked on Wayland but not on Xorg (or the other way around, not sure now), with the brokeness being a failure to update/repaint when the window changed).

Instead of looking at third-party components, are there any plans to include, at some point, a component that offers rich text (not RTF, which has very few capabilities).

In 2025, users editing a note want to select some text within their content, switch the font of it, change the color and size, set it to bold, underline and italic, give it  a background color, etc. They want to embed images and diagrams into this content. They want the ability to put red/blue/green squiggly lines in it to indicate spelling/grammar/etc errors. They want proper ordered lists, and proper unordered lists (with infinite nesting of both). They want to insert tables. They want to specify left/right/center/full justification, superscript/subscripts.

They may want to insert code blocks (i.e. blocks of code which are monospaced, with line counts, with syntax highlighting, etc), they may want actual blocks for quoted content (i.e. the quote has a 1px frame around it). They want to insert hyperlinks that work (and open the browser). They may want exact positioning, (via struts, for example), linebreaks represented during editing.

Even if the various RTF components worked flawlessly and across platforms, in 2025 RTF does not meet the expectations of users, regarding how the content should look. When you're making a TODO list, or calendar application, or shared-notes, etc ... user's want everything I specified above.

Are there any plans amongst the Lazarus community to move towards creating an editing component like this?
96
General / Re: Draw Behind Desktop Icons - porting
« Last post by jamie on November 16, 2025, 06:42:45 pm »
Really? 8)

Jamie
97
General / Re: Add new unit to a Lazarus project from an external tool
« Last post by Lulu on November 16, 2025, 06:34:27 pm »
Hi n7800, sorry my explanation was not good enough.
yes I'm writing a tool named Game Helper that allow to graphically design sprites and game levels for OGLCScene library.

Inside the tool, when user create a new project game, an associated Lazarus project is also created from a template. Let's call it the target Lazarus project.

Always inside the tool, when the user design and save a sprite or a level, the tool automatically generate a corresponding Pascal unit, saved inside the target Lazarus project.

Quote
you can open "Menu > Project > Project Inspector" and click the "Add" button in the toolbar

If possible I would like also the tool to do that automatically.

For now, Game Helper can add or remove an entry into  the clause unit of the LPR file (target Lazarus project)
98
General / Re: [SOLVED - Sort of!] Printing RichMemo
« Last post by AgriMensor on November 16, 2025, 06:27:08 pm »
Hi Badger!

Quote
I have two RichMemos and an image on a panel that represents a small card.  The image is movable and re-sizable and the RichMemos accommodate this by changing size.  I then need to print the 'card' (approx size for size). I tried the PaintTo method but the outcome was ridiculously small and the text on the  RichMemo was missing.

I know nothing about Mac environments, I'm afraid, but under Windows I experienced similar frustrations as you in trying to resolve text resizing (which I eventually managed to accomplish) and missing RichMemo text (which I didn't). Not to even mention lack of relevant documentation and sample routines.

After 2+ weeks of trying, I eventually stumbled over your contribution of nearly 7 years ago and I do sincerely hope that you are able to pick up this message after such a long time!

Your character-by-character printing approach, although laborious, solved the problem and I'm delighted that it has done so - I am probably too lazy to have ever tried this of my own volition, even if I had thought of it in the first place! Thank you!

I'd very much like to include you in my Credits list when the program is released if you feel OK with letting me know your name; I couldn't find it in your Profile.

Once again, many thanks.
99
Games / SameGame
« Last post by Guva on November 16, 2025, 06:19:18 pm »
A small example of an old classic game.

Code: Pascal  [Select][+][-]
  1. program samegame;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6. {$IFDEF LINUX}
  7.   cthreads,
  8. {$ENDIF}
  9.   Classes, SysUtils, CustApp, raylib, math;
  10.  
  11. type
  12.   { TRayApplication }
  13.   TRayApplication = class(TCustomApplication)
  14.   protected
  15.     procedure DoRun; override;
  16.   public
  17.     constructor Create(TheOwner: TComponent); override;
  18.     destructor Destroy; override;
  19.   end;
  20.  
  21. const
  22.   AppTitle = 'SameGame';
  23.   BOARD_WIDTH = 15;
  24.   BOARD_HEIGHT = 12;
  25.   CELL_SIZE = 40;
  26.   MARGIN_X = 50;
  27.   MARGIN_Y = 80;
  28.  
  29. type
  30.   TCellState = (csEmpty, csRed, csGreen, csBlue, csYellow, csPurple);
  31.   TGameState = (gsPlaying, gsGameOver, gsVictory);
  32.  
  33. var
  34.   Board: array[0..BOARD_WIDTH-1, 0..BOARD_HEIGHT-1] of TCellState;
  35.   Score: Integer;
  36.   GameState: TGameState;
  37.  
  38. { TRayApplication }
  39. procedure InitializeGame;
  40. var
  41.   x, y: Integer;
  42. begin
  43.   Randomize;
  44.   Score := 0;
  45.   GameState := gsPlaying;
  46.  
  47.   // Заполняем поле случайными цветами
  48.   for x := 0 to BOARD_WIDTH - 1 do
  49.     for y := 0 to BOARD_HEIGHT - 1 do
  50.       Board[x, y] := TCellState(Random(5) + 1); // 1-5 цвета, 0 - пусто
  51. end;
  52.  
  53. constructor TRayApplication.Create(TheOwner: TComponent);
  54. begin
  55.   inherited Create(TheOwner);
  56.     InitWindow( (BOARD_WIDTH * CELL_SIZE) + (MARGIN_X * 2), (BOARD_HEIGHT * CELL_SIZE)+ (MARGIN_Y * 2) , AppTitle);
  57.   SetTargetFPS(60);
  58.   InitializeGame;
  59. end;
  60.  
  61. function GetCellColor(State: TCellState): TColor;
  62. begin
  63.   case State of
  64.     csEmpty: Result := RAYWHITE;
  65.     csRed: Result := MAROON;
  66.     csGreen: Result := DARKGREEN;
  67.     csBlue: Result := DARKBLUE;
  68.     csYellow: Result := GOLD;
  69.     csPurple: Result := PURPLE;
  70.   else
  71.     Result := LIGHTGRAY;
  72.   end;
  73. end;
  74.  
  75. function HasValidMoves: Boolean;
  76. var
  77.   x, y: Integer;
  78.   currentColor: TCellState;
  79. begin
  80.   Result := False;
  81.  
  82.   for x := 0 to BOARD_WIDTH - 1 do
  83.   begin
  84.     for y := 0 to BOARD_HEIGHT - 1 do
  85.     begin
  86.       currentColor := Board[x, y];
  87.       if currentColor = csEmpty then
  88.         Continue;
  89.  
  90.       // Проверяем соседей справа и снизу
  91.       if (x < BOARD_WIDTH - 1) and (Board[x + 1, y] = currentColor) then
  92.       begin
  93.         Result := True;
  94.         Exit;
  95.       end;
  96.  
  97.       if (y < BOARD_HEIGHT - 1) and (Board[x, y + 1] = currentColor) then
  98.       begin
  99.         Result := True;
  100.         Exit;
  101.       end;
  102.     end;
  103.   end;
  104. end;
  105.  
  106. procedure FindConnected(x, y: Integer; Color: TCellState;
  107.   var Visited: array of Boolean; var Connected: array of Boolean);
  108. var
  109.   directions: array[0..3, 0..1] of Integer;
  110.   i, nx, ny: Integer;
  111. begin
  112.   if (x < 0) or (x >= BOARD_WIDTH) or (y < 0) or (y >= BOARD_HEIGHT) then
  113.     Exit;
  114.  
  115.   if Visited[y * BOARD_WIDTH + x] or (Board[x, y] <> Color) then
  116.     Exit;
  117.  
  118.   Visited[y * BOARD_WIDTH + x] := True;
  119.   Connected[y * BOARD_WIDTH + x] := True;
  120.  
  121.   directions[0, 0] := 1;  directions[0, 1] := 0;   // right
  122.   directions[1, 0] := -1; directions[1, 1] := 0;   // left
  123.   directions[2, 0] := 0;  directions[2, 1] := 1;   // down
  124.   directions[3, 0] := 0;  directions[3, 1] := -1;  // up
  125.  
  126.   for i := 0 to 3 do
  127.   begin
  128.     nx := x + directions[i, 0];
  129.     ny := y + directions[i, 1];
  130.     FindConnected(nx, ny, Color, Visited, Connected);
  131.   end;
  132. end;
  133.  
  134. function GetConnectedCount(x, y: Integer; Color: TCellState): Integer;
  135. var
  136.   Visited: array of Boolean;
  137.   Connected: array of Boolean;
  138.   i: Integer;
  139. begin
  140.   Result := 0;
  141.   if Color = csEmpty then Exit;
  142.  
  143.   SetLength(Visited, BOARD_WIDTH * BOARD_HEIGHT);
  144.   SetLength(Connected, BOARD_WIDTH * BOARD_HEIGHT);
  145.  
  146.   for i := 0 to Length(Visited) - 1 do
  147.   begin
  148.     Visited[i] := False;
  149.     Connected[i] := False;
  150.   end;
  151.  
  152.   FindConnected(x, y, Color, Visited, Connected);
  153.  
  154.   for i := 0 to Length(Connected) - 1 do
  155.     if Connected[i] then
  156.       Inc(Result);
  157. end;
  158.  
  159. procedure RemoveConnectedGroup(x, y: Integer; Color: TCellState);
  160. var
  161.   Visited: array of Boolean;
  162.   Connected: array of Boolean;
  163.   i, cx, cy: Integer;
  164. begin
  165.   if Color = csEmpty then Exit;
  166.  
  167.   SetLength(Visited, BOARD_WIDTH * BOARD_HEIGHT);
  168.   SetLength(Connected, BOARD_WIDTH * BOARD_HEIGHT);
  169.  
  170.   for i := 0 to Length(Visited) - 1 do
  171.   begin
  172.     Visited[i] := False;
  173.     Connected[i] := False;
  174.   end;
  175.  
  176.   FindConnected(x, y, Color, Visited, Connected);
  177.  
  178.   // Удаляем все подключенные блоки
  179.   for i := 0 to Length(Connected) - 1 do
  180.   begin
  181.     if Connected[i] then
  182.     begin
  183.       cx := i mod BOARD_WIDTH;
  184.       cy := i div BOARD_WIDTH;
  185.       Board[cx, cy] := csEmpty;
  186.     end;
  187.   end;
  188. end;
  189.  
  190. procedure ApplyGravity;
  191. var
  192.   x, y, emptyCount: Integer;
  193. begin
  194.   // Гравитация в столбцах - блоки падают вниз
  195.   for x := 0 to BOARD_WIDTH - 1 do
  196.   begin
  197.     emptyCount := 0;
  198.     // Проходим столбец снизу вверх
  199.     for y := BOARD_HEIGHT - 1 downto 0 do
  200.     begin
  201.       if Board[x, y] = csEmpty then
  202.         Inc(emptyCount)
  203.       else if emptyCount > 0 then
  204.       begin
  205.         // Перемещаем блок вниз
  206.         Board[x, y + emptyCount] := Board[x, y];
  207.         Board[x, y] := csEmpty;
  208.       end;
  209.     end;
  210.   end;
  211. end;
  212.  
  213. procedure RemoveEmptyColumns;
  214. var
  215.   x, shift, y: Integer;
  216.   columnEmpty: Boolean;
  217.   tempBoard: array[0..BOARD_WIDTH-1, 0..BOARD_HEIGHT-1] of TCellState;
  218. begin
  219.   // Создаем временную копию доски
  220.   for x := 0 to BOARD_WIDTH - 1 do
  221.     for y := 0 to BOARD_HEIGHT - 1 do
  222.       tempBoard[x, y] := Board[x, y];
  223.  
  224.   shift := 0;
  225.  
  226.   // Переносим непустые столбцы влево
  227.   for x := 0 to BOARD_WIDTH - 1 do
  228.   begin
  229.     columnEmpty := True;
  230.     for y := 0 to BOARD_HEIGHT - 1 do
  231.     begin
  232.       if tempBoard[x, y] <> csEmpty then
  233.       begin
  234.         columnEmpty := False;
  235.         Break;
  236.       end;
  237.     end;
  238.  
  239.     if not columnEmpty then
  240.     begin
  241.       // Копируем непустой столбец на новую позицию
  242.       for y := 0 to BOARD_HEIGHT - 1 do
  243.         Board[shift, y] := tempBoard[x, y];
  244.       Inc(shift);
  245.     end;
  246.   end;
  247.  
  248.   // Заполняем оставшиеся столбцы пустыми клетками
  249.   for x := shift to BOARD_WIDTH - 1 do
  250.     for y := 0 to BOARD_HEIGHT - 1 do
  251.       Board[x, y] := csEmpty;
  252. end;
  253.  
  254. function IsBoardEmpty: Boolean;
  255. var
  256.   x, y: Integer;
  257. begin
  258.   Result := True;
  259.   for x := 0 to BOARD_WIDTH - 1 do
  260.     for y := 0 to BOARD_HEIGHT - 1 do
  261.       if Board[x, y] <> csEmpty then
  262.       begin
  263.         Result := False;
  264.         Exit;
  265.       end;
  266. end;
  267.  
  268. procedure HandleMouseClick;
  269. var
  270.   MousePos: TVector2;
  271.   x, y: Integer;
  272.   groupSize: Integer;
  273. begin
  274.   if GameState <> gsPlaying then
  275.     Exit;
  276.  
  277.   MousePos := GetMousePosition();
  278.  
  279.   // Преобразуем координаты мыши в координаты доски
  280.   x := Trunc((MousePos.x - MARGIN_X) / CELL_SIZE);
  281.   y := Trunc((MousePos.y - MARGIN_Y) / CELL_SIZE);
  282.  
  283.   if (x < 0) or (x >= BOARD_WIDTH) or (y < 0) or (y >= BOARD_HEIGHT) then
  284.     Exit;
  285.  
  286.   if Board[x, y] = csEmpty then
  287.     Exit;
  288.  
  289.   // Проверяем размер группы
  290.   groupSize := GetConnectedCount(x, y, Board[x, y]);
  291.  
  292.   if groupSize < 2 then
  293.     Exit;
  294.  
  295.   // Удаляем группу и начисляем очки
  296.   RemoveConnectedGroup(x, y, Board[x, y]);
  297.   Score := Score + (groupSize - 1) * (groupSize - 1);
  298.  
  299.   // Применяем гравитацию и удаляем пустые столбцы
  300.   ApplyGravity;
  301.   RemoveEmptyColumns;
  302.  
  303.   // Проверяем условия окончания игры
  304.   if IsBoardEmpty then
  305.     GameState := gsVictory
  306.   else if not HasValidMoves then
  307.     GameState := gsGameOver;
  308. end;
  309.  
  310. procedure TRayApplication.DoRun;
  311. var
  312.   x, y: Integer;
  313.   cellColor: TColor;
  314.   rect: TRectangle;
  315.   groupSize, TextWidth: Integer;
  316.   MousePos: TVector2;
  317.   InstructionText, GameTitle, GameReset: string;
  318.   popupRect: TRectangle;
  319. begin
  320.   while (not WindowShouldClose) do
  321.   begin
  322.     // Обработка ввода
  323.     if IsMouseButtonPressed(MOUSE_BUTTON_LEFT) then
  324.       HandleMouseClick;
  325.  
  326.     if IsKeyPressed(KEY_R) then
  327.       InitializeGame;
  328.  
  329.     // Отрисовка
  330.     BeginDrawing();
  331.       ClearBackground(RAYWHITE);
  332.  
  333.       // Отрисовка заголовка по центру
  334.       GameTitle := 'SameGame';
  335.       TextWidth := MeasureText(PChar(GameTitle), 30);
  336.       DrawText(PChar(GameTitle), (GetScreenWidth() - TextWidth) div 2, 20, 30, GRAY);
  337.  
  338.       // Отрисовка счета и кнопки новой игры
  339.       DrawText(PChar('Score: ' + IntToStr(Score)), MARGIN_X, 20, 20, GRAY);
  340.  
  341.       GameReset := 'R - GameReset';
  342.       TextWidth := MeasureText(PChar(GameReset), 20);
  343.       DrawText(PChar(GameReset), GetScreenWidth() - TextWidth - MARGIN_X, 20, 20, GRAY);
  344.  
  345.       // Отрисовка игрового поля
  346.       for x := 0 to BOARD_WIDTH - 1 do
  347.       begin
  348.         for y := 0 to BOARD_HEIGHT - 1 do
  349.         begin
  350.           cellColor := GetCellColor(Board[x, y]);
  351.  
  352.           rect.x := MARGIN_X + x * CELL_SIZE;
  353.           rect.y := MARGIN_Y + y * CELL_SIZE;
  354.           rect.width := CELL_SIZE - 2;
  355.           rect.height := CELL_SIZE - 2;
  356.  
  357.           DrawRectangleRec(rect, cellColor);
  358.           DrawRectangleLinesEx(rect, 1, LIGHTGRAY);
  359.  
  360.           // Показываем размер группы при наведении
  361.           if Board[x, y] <> csEmpty then
  362.           begin
  363.             MousePos := GetMousePosition();
  364.             if (MousePos.x >= rect.x) and (MousePos.x <= rect.x + rect.width) and
  365.                (MousePos.y >= rect.y) and (MousePos.y <= rect.y + rect.height) then
  366.             begin
  367.               groupSize := GetConnectedCount(x, y, Board[x, y]);
  368.               if groupSize >= 2 then
  369.               begin
  370.                 DrawRectangleLinesEx(rect, 2 , BLACK);
  371.                 DrawText(PChar(IntToStr(groupSize)),
  372.                   Round(rect.x + rect.width / 2 - 4),
  373.                   Round(rect.y + rect.height / 2 - 5),
  374.                   10, BLACK);
  375.               end;
  376.             end;
  377.           end;
  378.         end;
  379.       end;
  380.  
  381.       // Отрисовка состояния игры по центру
  382.       case GameState of
  383.         gsGameOver:
  384.           begin
  385.             // Центрируем прямоугольник
  386.             popupRect.width := 400;
  387.             popupRect.height := 150;
  388.             popupRect.x := (GetScreenWidth() - popupRect.width) /2 ;
  389.             popupRect.y := 250;
  390.  
  391.             DrawRectangleRec(popupRect, Fade(DARKGRAY, 0.8));
  392.  
  393.             TextWidth := MeasureText('GAME OVER!', 30);
  394.             DrawText('GAME OVER!', (GetScreenWidth() - TextWidth) div 2, 270, 30, MAROON);
  395.  
  396.             TextWidth := MeasureText('No valid moves available', 20);
  397.             DrawText('No valid moves available', (GetScreenWidth() - TextWidth) div 2, 310, 20, RAYWHITE);
  398.  
  399.             TextWidth := MeasureText('Press R - for new game', 20);
  400.             DrawText('Press R - for new game', (GetScreenWidth() - TextWidth) div 2, 340, 20, RAYWHITE);
  401.           end;
  402.  
  403.         gsVictory:
  404.           begin
  405.             // Центрируем прямоугольник
  406.             popupRect.width := 400;
  407.             popupRect.height := 150;
  408.             popupRect.x := (GetScreenWidth() - popupRect.width) / 2;
  409.             popupRect.y := 250;
  410.  
  411.             DrawRectangleRec(popupRect, Fade(DARKGRAY, 0.8));
  412.  
  413.             TextWidth := MeasureText('Victory!', 30);
  414.             DrawText('Victory!', (GetScreenWidth() - TextWidth) div 2, 270, 30, DARKGREEN);
  415.  
  416.             TextWidth := MeasureText(PChar('Score: ' + IntToStr(Score)), 20);
  417.             DrawText(PChar('Score: ' + IntToStr(Score)), (GetScreenWidth() - TextWidth) div 2, 310, 20, RAYWHITE);
  418.  
  419.             TextWidth := MeasureText('Press R - for new game', 20);
  420.             DrawText('Press R - for new game', (GetScreenWidth() - TextWidth) div 2, 340, 20, RAYWHITE);
  421.           end;
  422.       end;
  423.  
  424.       // Инструкция по центру
  425.       InstructionText := 'Click groups of 2 or more same-colored blocks';
  426.       TextWidth := MeasureText(PChar(InstructionText), 20);
  427.       DrawText(PChar(InstructionText),
  428.         (GetScreenWidth() - TextWidth) div 2,
  429.         MARGIN_Y + BOARD_HEIGHT * CELL_SIZE + 20,
  430.         20, GRAY);
  431.  
  432.       EndDrawing();
  433.   end;
  434.   Terminate;
  435. end;
  436.  
  437. destructor TRayApplication.Destroy;
  438. begin
  439.   CloseWindow();
  440.   inherited Destroy;
  441. end;
  442.  
  443. var
  444.   Application: TRayApplication;
  445. begin
  446.   Application := TRayApplication.Create(nil);
  447.   Application.Title := AppTitle;
  448.   Application.Run;
  449.   Application.Free;
  450. end.    
  451.  
100
Graphics / Re: Converting bitmaps into a PSD file
« Last post by wp on November 16, 2025, 06:00:12 pm »
Vampyre Imaging (https://github.com/galfar/imaginglib) and FreeImage (https://freeimage.sourceforge.io/features.html) can handle PSD images. I don't know however whether they fulful the specific requirement in your post.
Pages: 1 ... 8 9 [10]

TinyPortal © 2005-2018