### Problem description
The default result export functionality of the Find tool is limited to
only exporting data in a nonstandard text format. This PR adds support
for exporting the results in CSV, TSV or JSON format. The PR also
removes the old format.
### Implementation description
I added the classes `ExportFormatter`, `ExportFormatterCsv`,
`ExportFormatterTsv` and `ExportFormatterJson`, with similar
implementations to the pattern data exporters.
~~I also moved the `ViewFind::Occurrence` class into
`hex/helpers/types.hh`, so the exporters can access it.~~
### Screenshots
![image](https://github.com/WerWolv/ImHex/assets/45818400/c7a1016b-6494-416d-a963-86484952837c)
### Additional things
Another small change I made is moving the "{} entries found" line on the
same line as the Search and Reset buttons. I think it looks cleaner this
way, but if anyone disagrees, I can revert it.
---------
Co-authored-by: WerWolv <werwolv98@gmail.com>
### Problem description
At least on Windows (I have tested), it fails to save a layout on the
non-portable version of ImHex (unless we have an administrator
privilege).
The log (after an attempt to save a layout as "sample") will look like:
| Component | Message |
| --------- | ------- |
| `libimhex` | `Failed to save layout 'sample'. No writable path found`
|
But the underlying problem is platform-agnostic. It can be also a
problem on other platforms in other ways.
### Implementation description
The layout manager incorrectly queried whether the empty path
(effectively the current working directory) is writable before saving
the layout (not each "layouts" directories it queried earlier).
This is the snippet of the root cause.
```cxx
std::fs::path layoutPath;
for (const auto &path : hex::fs::getDefaultPaths(fs::ImHexPath::Layouts)) {
if (!hex::fs::isPathWritable(layoutPath))
continue;
layoutPath = path / fileName;
}
```
Look at the argument we are passing to `isPathWritable`. `layoutPath` is
a default (empty) `std::fs::path` object and will not be updated until
the directory describing itself is confirmed to be writable.
That caused a problem on non-portable version of Windows because:
1. The current working directory is usually the one of the executable
(`imhex-gui.exe`) and
2. That directory (`C:\Program Files\ImHex` by default) is usually not
writable unless ImHex is executed with an Administrator privilege.
The argument to `isPathWritable` should be `path` (containing one of the
`layouts` directories) and this PR fixes so that.
### Screenshots
### Additional things
This issue is hard to notice when developing because, to reproduce this
bug, the current working directory MUST NOT BE writable (usually
writable when we develop, even when we are working on the non-portable
Windows builds).
### Problem description
#### Problem 1
In borderless mode ImHex disables the standard macOS titlebar rendering
and input processing. As a result double clicking the titlebar does not
trigger the native macOS behavior set in `System Settings -> Desktop &
Dock -> Double-click a window's title bar to [Zoom/Minimize/Do
nothing]`.
#### Problem 2
The ImHex window shows up as blank/transparent when de-minimizing it
from the dock.
#### Problem 3
Widgets experience ghost hover inputs from the past position of the
cursor during live resizing.
### Implementation description
ImGui elements consume input events in the order they are drawn. As a
result by "drawing" an `InvisibleButton` over the content area of the
titlebar we can catch unprocessed clicks in the titlebar area.
Connecting this button's double clicks to the native window is then a
trivial endeavour.
The blank windows was caused by the rendering stack clearing the GL
buffer, but proceeding to draw nothing in it. I have short circuited
this path.
Ghost hover inputs were squelched by consistently moving the ImGui
cursor to `0, 0` during a live resize. The OS will dispatch a cursor
positioning event once the resizing ends, restoring normal behavior.
### Screenshots
N/A
### Additional things
N/A
---------
Co-authored-by: Nik <werwolv98@gmail.com>
### Problem description
https://gitlab.freedesktop.org/mesa/mesa/-/issues/11135
It turns out LLVMpipe only supports 4x multisampling. Checking
GL_MAX_SAMPLES seems like the right thing to do.
### Implementation description
~~Right now, I only check GL_MAX_SAMPLES. Depending on the format, we
might need to check GL_MAX_INTEGER_SAMPLES. I don't know how likely it
is that you might want to use a different format in the future,
glGetInternalformativ might be a safer option to retrieve the max number
of samples we can use.~~
Ended up implementing it with glGetInternalformativ.
### Additional things
I guess I could merge the ```if```s at lines 95, 99 and 103 in
imgui_imhex_extensions.cpp while we're at it.
---------
Co-authored-by: Nik <werwolv98@gmail.com>
### Problem description
By default, the cursor's blinking cycle is independent from user
actions, which feels unconventional while editing pattern code. This
change ensures that the blinking cycle is reset, and the cursor is made
visible every time the editor receives a keyboard event like character
entry, or arrow navigation.
### Implementation description
I moved the hard-coded blink timing numbers to their dedicated static
constant fields since now they are referenced from multiple different
places.
I added the function `void ResetCursorBlinkTime()` to `TextEditor.cpp`
that will reset the blink cycle to `currentMillis() -
sCursorBlinkOnTime`, ensuring that the cursor is visible. This function
is called for every keyboard and mouse click event.
### Screenshots
Before:
https://github.com/WerWolv/ImHex/assets/45818400/668c6802-79a3-450b-80d3-d6abf2ce27be
After:
https://github.com/WerWolv/ImHex/assets/45818400/ee7f60e0-a75f-416d-b86d-8d12b5cdadf2
---------
Co-authored-by: Nik <werwolv98@gmail.com>
### Problem description
In previous versions of ImHex, all tool windows were implemented as
static popups fixed in the upper left position of the hex view. This PR
refactors all tool popups to use floating windows that can be dragged
around by the user, or closed with a dedicated close button on the title
bar. These popup also support a stylable transparency when the user is
not hovering their mouse over the window.
### Implementation description
I rewrote the logic in `ViewHexEditor::drawPopup()` to use a custom
`ImGuiExt::BeginHoveringPopup` function for rendering the popup windows.
This new function is an almost exact replica of the built-in
`ImGui::BeginPopupModal`, except it does also displays the default
window title bar with a close button.
A second custom function, `ImGuiExt::PopupTitleBarButton` was also added
for rendering small icon-based buttons into the title bar of the parent
popup window. This new function was used to implement an optional
"Pinning" feature that individual popup implementations can specify. If
a window is pinned, it won't close automatically when its main action is
executed. For example, the "Select" button on the Select dialog will
close the popup by default, unless the window is pinned.
### Screenshots
Popup dialogs before:
![image](https://github.com/WerWolv/ImHex/assets/45818400/7c253181-8284-4076-a066-089403554f0f)
Popup dialogs after:
https://github.com/WerWolv/ImHex/assets/45818400/99d1a628-8ac1-40ac-9146-9062091bb0db
### Additional things
- When the user stops hovering their mouse over a popup window, it
becomes semi-transparent, making it easier to see the content behind it
- This PR also introduces the `styles.imhex.popup-alpha` style, making
the transparency effect configurable, including the ability to disable
the effect completely by setting `popup-alpha` to `1.0`.
- Fixed a bug that caused some popup windows to ignore the Enter and the
KeypadEnter keys. With this PR, all tool windows will execute their main
action when the user presses either one of the two Enter keys, and will
also close automatically unless the window is pinned.
### Possible changes and improvements
- Should the transparency effect be disabled if a window is pinned?
- Should the transparency factor be modifiable on the Settings/Interface
page?
- A keyboard shortcut could be added for quickly pinning / unpinning the
current window.
- Can the pin icon stay on the left, or should it be moved next to the
close button, with a similar circular background?
---------
Co-authored-by: WerWolv <werwolv98@gmail.com>