This will replace a bunch of standalone OK/Cancel button instances in the project, while centralizing translation and theme handling. Much better. The "add new preset" dialog was the test bed for this feature, but it will be rolling out to other dialogs soon.
I'm not actually sure, but printing might have been broken across all OSes. :/ I can't remember the last time I printed an image, so this is a feature that receives very little testing! Thanks to Frans for raising this issue. Still to-do is a full-featured, custom print wizard, but that's a ways down the priority list ATM.
This automatically covers 95+% of command button instances in the project, so it's a perfect test-bed for the new tool. So far, so good.
There may be an automatic way to enable this behavior, but if so, I'm not aware of it!
… captions Captioned user controls now self-manage translations, which means we can cut some of the most time-consuming code from PD's real-time translation function.
I'm planning to develop specialized "OK" and "Cancel" variants (settable via property), and of course proper animation is still on the to-do list. But for now, the button should integrate pretty nicely with the default Windows 10 theme. But more importantly: this is one more custom control down! I'll shortly be replacing various standard and jcButton instances with the new control.
Apologies for the widespread list of files affected, but this is kind of a strange commit. Over the past year, it's gradually become clear that the Windows color management engine is a hot mess. A lot of crucial functionality is spread across two versions of the engine - the old ICMS engine, which dates back to the Windows 95-ME era, and the new WCS engine, introduced by Vista - so you can't simply use one engine or the other. Instead, you have to intermix the two depending on what you're trying to accomplish. The WCS engine is also frustrating because it's designed around Microsoft's custom color profile format, which absolutely nobody (including Microsoft) uses. ICC profiles are the standard, and you'll never encounter an image that uses the stupid Microsoft format. Worse still, things like color space constants are straight-up faulty, but they've been left as-is for backwards compatibility. For example, it recently came to my attention (http://www.vbforums.com/showthread.php?742257-Color-Management-(ICC-Profile)-support-in-VB6-guide-and-sample-project&p=4923873&viewfull=1#post4923873) that on certain versions of Windows, requesting a default sRGB profile will actually return the custom default WCS profile set by the user. To get an sRGB profile, you have to use the opposite constant - LCS_WINDOWS_COLOR_SPACE. AAAARRRGGGGHHHH. Anyway, an alternative solution is available. LittleCMS (https://github.com/mm2/Little-CMS) is a fantastic color management engine, and it's used by everyone under the sun (e.g. Google, Mozilla, GIMP, ImageMagick, MS Office on OSX), but integrating it into PD is complicated, as color management is a very low-level concept that shows up in a ton of different places. But I've gotten it compiled on my local PC, and am starting to run tests to figure out how best to make use of it in PD. Because of the complexity of the work, I'll be pursuing LittleCMS integration in a separate branch, but prior to that, I wanted to knock out some much-needed plugin management fixes. Thus this commit. Among other things, this commit makes it much easier to add new plugins in the future, by centralizing a bunch of redundant plugin management code. Since I was here, I've also implemented a request from several users to automatically fix faulty .zip file extractions. Some .zip programs (e.g. WinZip, which people still use for reasons I can't comprehend) do not honor .zip folder structure by default, so PD's plugins may get dumped into the core PD folder instead of staying in the /App folder where they belong. PD will now detect this, and rebuild the folder structure accordingly. Still to-do is integrating the new plugin management engine with the Plugin Manager dialog (which currently implements redundant copies of many plugin tasks). But at least this will make it easier to work on a separate LittleCMS branch in the meantime.
The slider/text-up-down control has been rewritten to make use of this new approach.
Sorry for the massive commit, but this type of UI overhaul is sometimes necessary! Besides the obvious improvements of using the new control, the .exe size also shrunk. Always nice. Also, some dialogs may look funny due to new spacing considerations. I'll deal with this later, after converting all bare label instances to pdLabel.
This was a blocker for the final push toward 1) dark theme support, 2) Unicode support, 3) proper TabStop support. The slider/text-up-down control is PD's primary user control. In 90+% of its appearances (e.g. adjustment and effect dialogs), it is accompanied by a label that displays the control's purpose. It's redundant and silly to require two controls for all these control instances, when we can simply integrate caption painting right into the text up/down UC! Besides freeing resources, this solves a number of simultaneous control-related issues that have been plaguing PD for some time. Of course, converting all label+slider instances to the newly updated slider will take time. The Effects > Light and Shadow > Blacklight form was used for initial testing. An additional caption is not always relevant (for example, on the main screen's tool windows, where captions are typically left-aligned instead of top-aligned). For these instances, the slider control's behavior hasn't changed. But for effect dialogs, the new "Caption" property should be used in place of an additional title label. As usual, the new "Caption" property is automatically sized to fit the slider's width, while also accounting for translations. This will make it much easier to eventually implement resizable dialogs, and perhaps someday, migrating all effects and adjustments into dockable panels on the main window.
Rather than use separate labels and input controls throughout the project, I will be reworking PD's various input controls to support a "title" property. This greatly reduces complexity (by cutting the program's control count roughly in half), and it makes it much easier to automate certain tasks. Because pdFont is a crucial part of this, I wanted to clean it up a bit. The use of a temporary DIB has been dropped in favor of a bare DC. I've also rewritten various measurement functions to work just fine, even if the class isn't attached to a DC yet.
Relates to #172. This commit exists solely for backup purposes; it is not a final solution.
Relates to #172 The ultimate goal for tab order in PD is to generate it automatically at run-time. This would save me a lot of trouble with tab order breaking when controls are rearranged/removed/inserted, and there's no reason we can't easily sort controls top-to-bottom, right-to-left, and automatically assign tab order accordingly. But before I can do that, I want to clean up the way PD's UCs report tab behavior. Instead of always handling it internally, it is sometimes beneficial to report an actual TabPress event. (For example, if a UC lives inside another UC, a TabPress should send focus to the next control *within* that UC, not a separate UC entirely!) To that end, I've updated the text box UC to have adjustable tab behavior. A property now controls whether tab presses raise a TabPress event, or whether it forwards focus immediately. Note that - by design - this breaks tab forwarding when a text box embedded in a UC receives a tab press. (After some testing, I'll be moving the "forward focus" code completely out of the UC and into a standalone module, so we don't have to repeat that code in all UCs.)
Forms are the first to get a much-needed rework. Since git fails to automatically detect renames (no idea why), this had to be done manually. It's not glamorous work, but I've already put it off much longer than I should, so it was time to get it done. Subfolder organization will be handled later. (I have some automated scripts I don't want to mess with at present; sorry.)
More GDI+ bugs, my favorite!
cCommonDialog served us well for many years, but now we must bid adieu.
Time to start purging the old, unwieldy cCommonDialog references, so we can have full Unicode compatibility for all user-facing save/load operations!
Most of these changes involve converting simple things like "Kill <filename>" to the Unicode-friendly "pdFSO.KillFile <filename>", but a few files received more comprehensive overhauls. The ultimate goal, as I've mentioned in previous commits, is to route all file handling through pdFSO. This commit brings us one huge step closer to that.
While here, I fixed a bunch of other random download issues. (Bad chunk size decisions, using strings instead of byte buffers, not supporting https downloads - ugh!) Pasting and click-dragging URLs should now work much better.
Two major changes here. 1) As much as possible, I've tried to rework pdPackager to not require intermediary arrays when reading/writing, and/or compressing/decompressing node data. This is made possible by new interaction functions with the underlying buffer class, which allow us to use naked pointers and pre-allocated buffers whenever possible, avoiding the need for interop via VB arrays. 2) Raster layers in PDI files were another opportunity for optimizations, as we must pre-allocate a DIB prior to extracting the actual pixel data from file. Historically, pixel data had to be extracted into a temporary array at its compression size, decompressed into a new array at its decompression size, then finally copied into the pre-allocated DIB. Besides wasting a huge amount of memory, it's time-consuming to repeatedly allocate large chunks of memory (50+ MB for a standard photo), allocations that are further compounded when loading images with multiple layers. But no more! Now, pdPackager exposes some (explicitly marked as dangerous) functions for circumstances when an external buffer can be safely pre-allocated, independent of pdPackager. When this happens, it can now perform a blind extraction+decompression directly from the master pdPackage buffer (typically compressed) to a caller-allocated buffer (like a DIB, in PD's case). Temporary buffers are no longer required or allocated, but obviously, these functions are only valid for circumstances where the caller can use other information (in our case, DIB stride, height, color depth) to pre-allocate a correctly sized buffer independent of pdPackage's internal measurements. Anyway, the take-home message is that PDI reading+writing is now much faster, which is particularly great for improving responsiveness of the Undo/Redo stack.
This was a large and complicated conversion, in part because pdSelection and pdDIB engage in some messy interop when saving selection files. Since I was here, I completely reworked the way these classes read and write files to focus much more on performance. A ton of intermediary DIB and array work was dropped, and as much as possible, these classes will now read and write relevant data directly into its final buffer(s). The performance improvements are particularly noticeable when working with raster selection data in the Undo/Redo chain.