bgrabitmap / lazpaint

🎨 Cross-platform image editor with raster and vector layers similar to Paint.Net written in Lazarus (Free Pascal)
https://lazpaint.github.io/
GNU General Public License v3.0
406 stars 57 forks source link

Be able to assign the keyboard numbers to palette colors #539

Closed shmalex closed 6 months ago

shmalex commented 1 year ago

Proposal: to be able to bind the numbers from keyboard to specific colors.

User case: When I am explaining the math to someone, i user the Pen to draw and it would be more conviniant to switch between colors by pressing the numbers 0-9 on keyboard.

Thanks!

circular17 commented 1 year ago

Good idea

Lulu04 commented 1 year ago

Hi Shmalex and Circular, Are the colors selected by pressing keys 0-9 on the keyboard the first 10 on the palette?

circular17 commented 1 year ago

That's a good question. Assigning the first 10 colors may limit flexibility and might not cater to users' specific habits or preferences.

I imagined various possibilities and among these the simplest I've found is the following.

  1. The user selects a color with the color palette or with the color chooser.
  2. The user presses Ctrl and a digit (0-9). This will associate a digit to the "active color". This binding process would be managed within the UMainFormLayout unit, specifically in the TMainFormLayout.CatchToolKey* methods. If the current tool doesn't consume the input (false result), it will be deferred to the FPaletteToolbar instance.

So I suggest to add a function in the TPaletteToolbar class and also to store the association of colors in the UPaletteToolbar unit. You need to keep track whether or not the Ctrl key is pressed.

MacOS Considerations: We'd use VK_SNAP and VK_SNAP2 from the UTool unit to check for the Ctrl key. This will handle MacOS Command key's behavior (the Ctrl key is used to switch mouse button on MacOS so we use the Cmd key instead on this platform).

Active color: To know which is the "active color", use the property ChooseColorTarget of LazPaintInstance (this will be for example ctForeColorSolid) and pass it to the function GetColor(ATarget: TColorTarget): TBGRAPixel of LazPaintInstance. This will give you the actual color.

  1. The association is displayed in the palette, if it is one of the colors of the palette, as a digit displayed on the color rectangle. The code to display the digit would be near the end of TPaletteToolbar.RepaintPalette function. You need to consider how it interacts with the check mark for the last added color. You will see as well a test to determine whether to display in black or white depending on the lightness of the color.

  2. The association I think would be as well display in the choose color (round rectangle at the bottom left). The code that displays that is in procedure TChooseColorInterface.vsColorViewRedraw of the unit UChooseColorInterface.

  3. When using a tool, one can press a digit (0-9) to set the color. This will be handled in the new functions defined in the palette unit. If Alt is pressed, then the color is assigned to the BackColor, otherwise to the ForeColor. I suggest to refactor the PickColor method to extract how to set the current color. You need to keep track whether or not the Alt key is pressed.

I hope this provides a clear path forward. If you have further insights or questions, please share them here. We aim to make this feature as intuitive and user-friendly as possible.

circular17 commented 1 year ago

Note: In https://github.com/bgrabitmap/lazpaint/commit/ef76535b73cadd75b6d04bd1232ee3020220c0f9, I have modified the palette drawing so that the rectangles can grow if there is more room in the palette, so that the digit would be more readable. Please retrieve the latest version before modifiying.

Lulu04 commented 1 year ago

At first glance, it seemed easy enough to implement, but I think I was wrong! I've never delved that deeply into your code. Ok, let's give it a try! I hope it won't take you more time to explain and correct my code than it would to add this extension yourself...

Note: latest version retrieved.

Lulu04 commented 1 year ago

In case the user recalls up a color he hasn't yet defined, what should be done? Nothing or set a default color. If so, which one?

circular17 commented 1 year ago

I would say nothing would be done

circular17 commented 6 months ago

done on dev