Recent

Author Topic: "MS-Paint" clone  (Read 7065 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
"MS-Paint" clone
« on: June 19, 2021, 01:01:27 pm »
Preferably using standard components, is there an easy way to have an "intentionally crude" bitmap editor with visible grid like the original MS-Paint?

I want to write something quick-and-dirty to test some other software, which has a bitmap editor of say 150 cols x 64 rows and some per-row configuration stuff. I'm not sure whether a TDrawGrid can be drawn on using the mouse etc., and a TPaintBox looks far too "finessed".

Any suggestions would be appreciated, I rarely do anything which is graphical.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Fred vS

  • Hero Member
  • *****
  • Posts: 2285
    • StrumPract is the musicians best friend
Re: "MS-Paint" clone
« Reply #1 on: June 19, 2021, 01:30:01 pm »
This.

Fre;D
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
Re: "MS-Paint" clone
« Reply #2 on: June 19, 2021, 02:23:06 pm »
Thanks, I'll take a look but its excessive resolution and lack of explicit gridding suggests that I might be better off with a TDrawGrid... even if I'm not able to draw lines etc. directly onto it.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jamie

  • Hero Member
  • *****
  • Posts: 4742
Re: "MS-Paint" clone
« Reply #3 on: June 19, 2021, 04:36:37 pm »
Yes, The TDrawGrid works very well for such things..

I have something that uses that for the titled icon view and when ever I mouse over a cell I have a form that pops up with the actual image in view and editable.

 Of course that is an option I supply for quick access but can also be done by clicking the image which places into a editable form.

 If you create one TpainForm and use a Tab control you can create multiples of TPaintform and have the   images active at all times.

 for space concerns you can also use file cache for the images that are not being viewed in the tabs and grid..
The only true wisdom is knowing you know nothing

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
Re: "MS-Paint" clone
« Reply #4 on: June 19, 2021, 05:29:31 pm »
Thanks for that Jamie. I must admit that I've yet to get to grips with some of the inbuilt grid editing stuff, but this is a test program and being able to get at each row's parameters is more important than interactive drawing.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jamie

  • Hero Member
  • *****
  • Posts: 4742
Re: "MS-Paint" clone
« Reply #5 on: June 19, 2021, 05:46:26 pm »
The draw grid does not store anything of your data, it simply takes you through the steps needed to represent your data.

For example the OnDrawCell is the even you need.it supplies the col,row index and it supplies the drawing Rectangle with the needed bounds rectangle.
 
 The canvas to use is that of the drawGrid itself

 What I do is Cast around the Sender .. With TDrawGrid(Sender)  do Begin... End; because that way a single method can be used for multiple draw grid instances.

 In your case, if all your images are the same size you can use a TImageList and the COL,ROW can compose the image index.
Example:
   Index := Row*ColCount+Col;

of course if the images are not all the same size then you need to do something a little different like create a file cache with a numerical index on them..

 Unless there is some component laying around that can handle staggered image sizes.

The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 8570
Re: "MS-Paint" clone
« Reply #6 on: June 19, 2021, 06:05:00 pm »
Here is a little (incomplete) demo to show the principle. The basic idea is that there must be a bitmap in which your draw by using the bitmap's canvas methods. After each drawing step you repaint the drawgrid which reads the bitmap pixel by pixel and paints the cells corresponding to the pixel colors.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
Re: "MS-Paint" clone
« Reply #7 on: June 19, 2021, 07:52:12 pm »
Jamie, Wp: thanks. In practice each cell represents a single pixel, and I'm exercising various encoding/decoding stuff where a different algorithm and optional palette may be selected for each row.

I've got something roughed out which is adequate, and am moving on to the various dialog(u)es/forms before getting back into the low-level code.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
Re: "MS-Paint" clone
« Reply #8 on: June 20, 2021, 09:21:42 am »
I wonder whether somebody who knows what he's doing could spare a moment to look at the attached and tell me what I'm doing wrong.

I've hung an event onto the TDrawGrid to invoke a custom editor form or dialogue, it works as expected the first time one of the left-hand cells is clicked but after that it's triggered by a mouseover. Lazarus trunk (as of a few days ago), both gtk2 and qt5.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

wp

  • Hero Member
  • *****
  • Posts: 8570
Re: "MS-Paint" clone
« Reply #9 on: June 20, 2021, 10:57:37 am »
Your example cannot be compiled because it is missing the SelectRowFormatCode unit. Luckily it is not needed, after removing it from uses, I could see the issue.

I think that OnSelectCell is a very complex event. I would not use it to show something interruptive like a message box. The problem is that the internal state variable FGridState was set in the OnMouseDown event to gsSelecting and is still like that after the message box was clicked away. So, the grid is still in selecting state which fires the OnSelectCell again when your mouse enters one of these cells a second time. The FGridState would be reset in the MouseUp event but this never occurs because of the ShowMessage.

A better solution would be to use the OnClick event to display the ShowMessage , and to use OnSelectCell only to control whether a cell can be selected or not (CanSelect parameter). Of course you need some status variables to control the appearance of the message box in the general purpose OnClick event.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
Re: "MS-Paint" clone
« Reply #10 on: June 20, 2021, 11:28:35 am »
Your example cannot be compiled because it is missing the SelectRowFormatCode unit. Luckily it is not needed, after removing it from uses, I could see the issue.

Sorry, I removed the modal window in case that was related and /thought/ I'd commented out the unit.

Quote
I think that OnSelectCell is a very complex event. I would not use it to show something interruptive like a message box. The problem is that the internal state variable FGridState was set in the OnMouseDown event to gsSelecting and is still like that after the message box was clicked away. So, the grid is still in selecting state which fires the OnSelectCell again when your mouse enters one of these cells a second time. The FGridState would be reset in the MouseUp event but this never occurs because of the ShowMessage.

A recent comment by Remy also alluded to the component complexity. So basically, there are strict limits on what can be put in OnSelectCell etc. and it's down to me to familiarise myself with the "proper practice".

I suppose this would also explain why some event handlers can be tricky to debug... I fairly regularly find myself locking up KDE and needing to kill the debuggee from a text session <Ctrl><Alt><F1>.

Quote
A better solution would be to use the OnClick event to display the ShowMessage , and to use OnSelectCell only to control whether a cell can be selected or not (CanSelect parameter). Of course you need some status variables to control the appearance of the message box in the general purpose OnClick event.

The messagebox was basically a placeholder after I ripped out the modal window. The convenience of OnSelectCell is that it passes the column and row as parameters... could somebody remind me of the best alternative where a handler e.g. OnClick doesn't provide these?

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

wp

  • Hero Member
  • *****
  • Posts: 8570
Re: "MS-Paint" clone
« Reply #11 on: June 20, 2021, 11:31:49 am »
The convenience of OnSelectCell is that it passes the column and row as parameters... could somebody remind me of the best alternative where a handler e.g. OnClick doesn't provide these?
The position of the active cell can be retrieved from the .Col and .Row properties of the grid.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

MarkMLl

  • Hero Member
  • *****
  • Posts: 2853
Re: "MS-Paint" clone
« Reply #12 on: June 20, 2021, 11:39:19 am »
The convenience of OnSelectCell is that it passes the column and row as parameters... could somebody remind me of the best alternative where a handler e.g. OnClick doesn't provide these?
The position of the active cell can be retrieved from the .Col and .Row properties of the grid.

Many thanks for that, looking good. I was being extremely wary lest a click was processed distinct from the action of a cell being selected or set active.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018