Related
I'm allowing users to select an icon from the full list of FontAwesome icons (using a List<ImageVector>). I'm going to open a dialog, and show the icons as IconButtons arranged in the list. There are ~1600 icons.
I implemented it using a LazyVerticalGrid, with a fixed number of columns. It works, but there's some lag loading the icons, and lag when scrolling the icons.
I'm converting this from a React Native project where I did the same thing (with a larger set of icons, actually) and scrolling that was pretty snappy, so I'm assuming it's possible to do performantly on native. Perhaps ImageVectors are heavier than the SVGs I was using in React Native?
I'm planning to provide a search box in the dialog where users can filter the list down by doing a fuzzy search on icon names, so the grid will change over time.
What sort of patterns should I be looking at here? Is LazyVerticalGrid the way to go, or should I be using a different approach entirely?
On Laziness
For an overview of use cases and appliable patterns you might be interested in the Android Dev Docs' page on Lists and Grids, încluding the topics Large data-sets (Paging) and the Tips on using Lazy layout.
This might wake your interest on the Android Jetpack Paging Library androidx.paging, which is designed for loading and displaying pages from large datasets, basically uniting the concepts of Laziness and Caching.
Currently you're only using Laziness. As Bartek Lipinski commented, that should usually be fine when the graphics to display are static. However, when they have to be loaded asynchronously, Paging will probably improve your performance.
Some Rules of Thumb
Scrolling
Pattern
No
Column or Row will be enough
Some
Column or Row with modifiers verticalScroll and horizontalScroll
More, static content
LazyColumn or LazyRow, resp. for gridding LazyVerticalGrid or LazyHorizontalGrid
More to mass, dynamic content
LazyColumn or one of its relatives with LazyPagingItems, so using the Paging Library androidx.paging
Also, as the docs say, consider adding contentType
. However, as Bartek Lipinski remarked, one usually benefits of contentType when there are scrollable elements of various types -- not only SVGs as maybe in your case. Still, giving hints to the system doesn't hurt, at least.
On Vector Graphics
As discussed in the comments, esp. by Subfly and Bartek Lipinski, though Laziness should be the main thing here, another bottleneck could be the loading of vector graphics during runtime.
If the graphics used are of static nature, then consider the usage of vector graphic assets. Those are supported for SVG and PSD since Android 5.0 (API level 21). Take also a look on the recommendations and some aspects of support and restrictions on SVG.
Summary
The basic formula is Laziness + Vector Assets with focus on the first. One might spice that with contentType and Paging.
This is a topic that may be considered something not necessarily "programming related"; however, I feel it is since I'm asking for specific techniques.
Essentially, as a web developer, I work with a variety of platforms that include a WYSIWYG editor in the backend (TinyMCE, WYGWAM, etc) and one of the selling points of such systems is that it becomes easier to manage your own content because of these tools.
In theory, sounds great, in practice, not so much.
It can be way too easy for a client to break a layout by using many of the advanced features of a WYSIWYG editor. They can start floating things, setting too much margin/padding, etc.
Generally, I have tried to build any of these types of pages with only some sensible default styles applied to a few of the most common tags, such as setting a font size, colors, some margins, and some text decorations.
I would like to know if anyone has used anything more advanced to essentially turn the output of:
$cms->getContent();
...or equivalent into something that is effectively sandboxed and operates entirely agnostic of any other style/layout elements being used.
As often as possible, I express to clients that they should purchase an HTML/CSS book for Dummies and read it so that they aren't deer in headlights when they click "code view" in a WYSIWYG. But I know they don't do this, nor do they hire anyone who has experience, and it ends up allowing a client more control than they should responsibly have.
Plus, it sucks when you are using their sites as work samples to show others knowing they have the ability to take your beautiful design and development and make it look like crap.
A few things:
I have a standard WYGWAM config that I reuse on new sites by importing the exp_wygwam_configs table.
I keep options very limited in the editors
Areas of the page delineated for images should use a File field, with an image resizer like CE Image used to insure proper size
Client training. Make videos with Camtasia or similar tool if you have to.
Use a custom stylesheet for WYGWAM that has a small subset of styles, so they can choose h2...h4, for example, but not h1 or h5.
After encountering a lot of issues with WYSIWYG editors (which, by the way, never reflect accurately what you "get" in the end), I now prefer to leave only the most basic formatting features in the editor's configuration. For example, take a look at stackoverflow's editor.
It's got the following features: bold, italic, link, quote, pictures, lists, and alignments. The only special feature here are code sample and html, which are targeted to this site's audience. Most of your client don't need them.
I think it's the best approach, because if you give your clients the feeling that they can do whatever they want in the page, but in the end, this content is filtered when the page is rendered, they are going to be really frustrated. Not to mention the fact that the site will be slowed by the filtering process and the need to put the filtered content in cache.
Sometimes the client indeed wants to have a special layout in a page, but I think that can be best done by customizing the CMS so that it fits the client need.
Say we have an overlay DHTML panel on a web page that contains two buttons in the top occupying whole width of the dialog, like this:
Text for Button 1 and Button 2 should be localized. Content of checkbox group is static and should not be localized.
There can be a big difference between button text width in different languages (~100% extra space in comparison with English version).
The question is which strategy to apply for sizing Button 1 and Button 2 depending on the length of the text content:
Make buttons fixed width and truncate text content with ellipsis.
Make buttons fixed width and wrap text content on the subsequent lines making buttons grow in height.
Make buttons fixed width but make them wide enough to host text in all languages without truncation or wrapping.
Make buttons dynamically adjust width and make panel grow horizontally with their size.
I am leaning towards using third or forth option according to the several UI localization best practices that were found:
Preparing the User Interface for Localization
Best Practices for Globalization and Localization
Globalization Step-by-Step - UI Considerations
Still we have some debate in the team discussing the best option and it would be interesting to hear concious outer voice of the community.
I am interested in the best approach for this specific case as well general guidelines for solving web UI sizing issues in regards of localization.
Thanks!
As you perhaps know, text shortened with ellipsis (or with a single dot) could be incomprehensible:
How compr. is th.?
You should seen a lot of this staff in mobile area (phones, tablets, etc.), such translations look ugly. OK, with lower screen resolutions you actually end up with no choice (unless you can create some auto-scrolling text). But in case of web interface you certainly have a choice.
Typically, there are two kind of solutions corresponding to your points #3 and #4. Personally, I am leaning to #4 - make buttons auto-sizable. This of course will result with inconsistently sized buttons, but there is little we can do about it.
If you cannot use solution #4 (i.e. UI Designer is strong opponent of this technique), you may modify solution #3 a bit. Basically, what I used in past projects was, I had buttons of fixed sizes and default size was capable to fit most of languages (except Polish and Russian of course), but I also had several CSS classes that defined wider buttons. When localizing into "too long" languages I simply used the most wide button class I could. If the text still didn't fit, then I asked the translators for shortening it (usually re-phrasing it and shorten the text with a single dot as a last resort).
However, please keep in mind that it increases localization costs. This is the reason I would not recommend this method.
As for solution #2, you will end up with ugly looking UI. You simply have no control over how browser will wrap a text, and you will have a lot of texts that go outside the button clipping rectangle (overlap it).
As for solution #1, using ellipsis is a bad idea for two reasons. First one is, ellipsis is not valid in many languages (this especially regards to Asian languages). The second one is, as I understand you want to do that automatically. In this case, you won't be able to measure strings - their actual, on screen size, written with a fall-back font. In case of web UI, you don't know whether user has particular font installed, so you will be guessing the size (OK, with Dojo you can theoretically measure it on the client side). This will of course result in overlapping text (if you decide on dynamic shortening over your chosen font) or totally incomprehensible text (if you decide on shortening after say 8 characters). I had a project which started to use static shortening, it was a total mess. Then we switch to dynamic and it is still not good enough.
To counter potential UI Designer argument that goes "we have no space for string expansion", I can only say that means that you designed the interface incorrectly for it is too crowded. This is the point where I18n goes hand in hand with UI design best practices: strive for simplicity (in UI design). The result would be easy to use and easy to localize application.
Ours is an open-source Mac application localized by volunteers. These volunteers will do their work on special localization builds of the software (with unstripped nibs), then send us the changes to integrate into the original xib and strings files.
The problem is that, while there is a way to integrate string changes without blowing away previous size changes, I can't see a way to integrate new string and size changes (as when we add or replace views).
The only way to do both that I can see is for localizers to work directly with the original xibs and send us diffs. That means they have to download the entire source code, not just a localizable version of the release, work in Xcode as well as IB, and either run the diff command themselves (per xib) or install and use Mercurial.
Is there any better way for a xib-based application?
UPDATE January 2014: Apple’s ‘autolayout’ code combined with their ‘Base’ localization stuff took most my ideas and improved on them. I recommend against using my old tools that I talk about in this answer. But, also, man was I right!
I strongly strongly STRONGLY recommend against frame changes in localizations. I know this runs counter to Apple's advice, but there are SO MANY problems with allowing frame changes - you end up with a billion edge cases.
Imagine you have 10 XIBs in your app, and you support 12 languages. You've got 120 different layouts to support, now. You just can't do this.
Change the strings, leave the views where they are. Make 'em bigger in ALL languages, if you need to. It sounds like this shouldn't work but it does. (I won three Apple Design Awards with an app that's localized in 10 or so languages this way.)
Specifics:
For radio and checkboxes, just let them extend far to the right, beyond the last English character. That also provides a nice big landing area for imprecise mousers.
For buttons, they should be wide anyhow, because it never looks good to have text cramped in the middle of the buttons.
For titles on tableview columns, you should autosize when you load 'em up, if needed.
For explanatory text, you should have some extra space to the right, and maybe an extra line. It just makes the English version of the XIB seem less cluttered. Sure, the Germans are going to see a slightly tighter XIB, but, hey, they're Germans -- they're probably used to that. There's probably even a German word for it. "Deutscheninterfakkenclutterlongen."
If a text field is centered, just add equal space on both sides. There's no reason not to.
I've combined this with scripts that suck all the strings out of my XIBs and put them in .strings files, and then dynamically put the strings back at run-time, so anyone can localize my app without any special tools. Just drop in a bunch of .strings files and run it!
Blog post including full source: [Lost in Translations]¹.
I confess that I'm not all that familiar with the process of localizing Mac apps. But I did run across a script that's part of the Three20 iPhone library that seems like it might be useful: diffstrings.py is a Python script that "compares your primary locale with all your other locales to help you determine which new strings need to be translated. It outputs XML files which can be translated, and then merged back into your strings files."
EDIT: As a companion to Wil Shipley's answer to this question, I'll add a link to a blog post he just wrote that goes into more detail about localization, and provides some of the tools that he's built to ease the process.
Where I used to work, we had this issue as well. Our app was getting translated into 10 different languages.
At first, we tried doing what Wil suggested, which is to make everything super wide and fit in every language. Unfortunately, "online backup" might be pretty short in English, but in other languages (especially Spanish), it's really long ("copia de seguridad" just means "backup"). Widening our UI made everything look pretty terrible.
One day, I was playing around with some Core Animation stuff and discovered the CAConstraint class. CAConstraint is basically a way to define a layout relationship between two CALayers. You give one layer a name (like "layerA") and then say "layerB is constrained [in such-and-such a way] to a sibling layer called layerA". Then, whenever the layer named layerA is repositioned or resized, layerB automatically moves as well. It's really neat, and it's just what we were looking for.
After a couple of days of work, I came up with what is now CHLayoutManager. It's basically a re-make of CAConstraint and friends, but for NSViews. Here's a simple example of how it works:
CHLayoutConstraint * centerHorizontal = [CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMidX relativeTo:#"superview" attribute:CHLayoutConstraintAttributeMidX];
CHLayoutConstraint * centerVertical = [CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMidY relativeTo:#"superview" attribute:CHLayoutConstraintAttributeMidY];
[aView addConstraint:centerHorizontal];
[aView addConstraint:centerVertical];
This will keep aView centered in its superview, regardless of how the superview is resized. Here's another:
[button1 setLayoutName:#"button1"];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMinX relativeTo:#"button1" attribute:CHLayoutConstraintAttributeMaxX]];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMaxY relativeTo:#"button1" attribute:CHLayoutConstraintAttributeMaxY]];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeWidth relativeTo:#"button1" attribute:CHLayoutConstraintAttributeWidth]];
This will keep button2 anchored to the right edge of button1, as well as keeping button2's Y position and width the same as button1's.
Internally, CHLayoutManager uses an NSValueTransformer to calculate the new positioning information. Some of the CHLayoutConstraint initializers accept an NSValueTransformer, so you can create arbitrarily complex layout manipulations.
We used this for constraining and laying out the entire UI, and then doing all of the localization in code (and subsequently calling -sizeToFit, with some modifications). Our UI would just flow into its final layout. It turned out to be extremely convenient. We'd just package up our .strings files, send them off to the translators, and then drop them in to place when we got them back, and our app would instantly be localized for that language.
CHLayoutManager isn't perfect. It doesn't resolve conflicts, but simply applies constraints in the order they're added. So you can constrain (for example) the MinX of a view 42 different ways, but only the last one will be used. Also, if you constrain the MinX and the MaxX, they'll also be applied in the order they're added and will not end up stretching or shrinking the width. In other words, constraining one attribute of a view will not affect the other attributes. It's compatible with 10.5+ (GC and non). However, due to some changes in Lion, it's unlikely that I'll address the shortcomings.
Despite these shortcomings, it's an extremely flexible framework, and (IMO) some pretty nifty code. (Plus, I swizzle -[NSView dealloc]! Yay!)
Update
Now that AppKit has this same functionality (via NSLayoutConstraint), I recommend using that system instead of CHLayoutManager. It is far more robust.
Bear in mind that XIB files are merely XML files in an obscure format, so you can translate those easily enough, provided that you can find what strings there are there to translate in the first place. For example, here's the snippet that creates a button called Jenson:
<object class="NSButtonCell" key="NSCell" id="41219959">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Jenson</string>
...
</object>
So you can get that string translated and then substitute occurrences of it in the XIB with your translated value. In order to verify it's working as expected, you could change the language to use random keys instead (like BUTTON_TITLE) which will make it easier to spot when one's missing.
However, the positions/sizes of the items are fixed, so you can have titles that overflow the space given in a different language. That's one of the reasons why Macs have separate XIB files for every language, to allow adjustments to be made on a language-by-language basis, however difficult it is to maintain.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm a blind college student who is taking an introduction to programming class that focuses on user interface design. The class is using Processing, which is completely inaccessible. I'm looking for a language that will allow me to create GUI's without drag and drop and hopefully be smart enough to do most of the layout without forcing me to specify control positions in pixels.
I know Perl, Java, C/C++, c#, and HTML. I was considering creating HTA applications. My only requirements are that the language must run under MS Windows, and must not use SWING or GTK as the underlying toolkit.
I would say that xaml would be a good choice:
Pixel manipulation is not needed
Item functionality in code behind
Can add pixels changing for control
later on
There is a lot of documentation on
how to use it
Maybe if you give us an idea of what you will need the language for we can give you better suggestions.
Speaking as a blind programmer:
C# + WinForms: You can either create the code by hand and use layout managers or calculate the sizes in your head, or if you're using the JAWS screen reader then there are scripts which will help you in the WinForms designer.
C# + WPF: Here you define your UI in XML, but it is more complex to get your head around. Certainly look at this as it is a very nice solution. the other problem with WPF at the moment is that not all screen readers support this newer technology.
Jamal Mazrui at www.EmpowermentZone.com has created something called "Layout By Code", but I have no experience with this.
HTML+Javascript would be nice, but I doubt it'd be allowed in your course.
WXWidgets: I don't have a lot of experience with this cross-platform, multi-language UI toolkit, but I believe it has layout managers and is thus used by several blind programmers I know.
Finally, I used to design Win32 resource scripts by hand, calculating sizes in my head (no layout managers). This is certainly achievable if you wanted to take this route.
In summary, WPF's nice, but make sure your screen reader works with this kind of app. The next best alternative is probably WinForms. If you like Layout By Code then use it, but if this is a skill you want for employment, then keep that in mind.
take a look on XAML. I think it could be a good start for both modern Windows and Web UI creators.
Tcl/Tk will do exactly what you want. The pack and grid layout managers are based on logical relative placement of the widgets.
Although the "native" language of Tk is Tcl, many other languages have a Tk binding.
label .l -text "this is a label"
button .b -text 'quit' -command "exit"
pack .l .b
Check out this project on codeplex. It may help you (as an alternative to processing&java)
http://bling.codeplex.com/
ling is a C#-based library for easily programming images, animations, interactions, and visualizations on Microsoft's WPF/.NET. Bling is oriented towards design technologists, i.e., designers who sometimes program, to aid in the rapid prototyping of rich UI design ideas. Students, artists, researchers, and hobbyists will also find Bling useful as a tool for quickly expressing ideas or visualizations. Bling's APIs and constructs are optimized for the fast programming of throw away code as opposed to the careful programming of production code.
Bling as the following features that aid in the rapid prototyping of rich UIs:
* Declarative constraints that maintain dynamic relationships in the UI without the need for complex event handling. For example, button.Width = 100 - slider.Value causes button to shrink as the slider thumb is moved to the right, or grow as it is moved to the left. Constraints have many benefits: they allow rich custom layouts to be expressed with very little code, they are easy animate, and they support UIs with lots of dynamic behavior.
* Simplified animation with one line of code. For example, button.Left.Animate.Duration(500).To = label.Right will cause button to move to the right of label in 500 milliseconds.
* Pixel shader effects without the need to write HLSL code or boilerplate code! For example, canvas.CustomEffect = (input, uv) => new ColorBl(new Point3DBl(1,1,1) - input[uv].ScRGB, input[uv].ScA); defines and installs a pixel shader on a canvas that inverts the canvas's colors. Pixel shading in Bling takes advantage of your graphics card to create rich, pixel-level effects.
* Support for multi-pass bitmap effects such as diffuse lighting.
* An experimental UI physics engine for integrating physics into user interfaces! The physics supported by Bling is flexible, controllable, and easy to program.
* Support for 2.5D lighting.
* A rich library of geometry routines; e.g., finding where two lines intersect, the base of a triangle, the area of triangle, or a point on Bezier curve. These routines are compatible with all of Bling's features; e.g., they can be used in express constraints, pixel shaders, or physical constraints. Bling also provides a rich API for manipulating angles in both degrees and radians.
* And many smaller things; e.g., a frame-based background animation manager and slide presentation system.
* As a lightweight wrapper around WPF, Bling code is completely compatible with conventional WPF code written in C#, XAML, or other .NET languages.
Bling is an open source project created by Sean McDirmid and friends to aid in design rapid prototyping. We used Bling to enhance our productivity and would like to share it with other WPF UI design prototypers.
I'd probably try using C#. It has reasonably friendly interfaces to windows common controls and the like even without making use of Drag and Drop. Just don't make use of the designer and code as normal.
I don't program in Java but I know that Java provides for the programmatic creation of the UI AND provides some wonderful Layout Management components (Native to Java without requiring SWING). I first got exposed to Layout Managers back in the good-old-days of X11 with X Toolkits (anybody remember Motif, OpenLook, HP Open View?) and Java seems to have adopted similar technology.
You can create Windows, Dialogs and Menus all from simple layout managers.
Being sighted myself and not having worked too closely on anything that has ever been audited for accessibility or heavily accessed by blind users, I don't think my answer will be terribly thorough. My first instinct however is to say that some kind of dynamic web server architecture that generates HTML like C#, PHP or ColdFusion is going to fit your description of handling most of the layout for you without requiring that you specify control positions in pixels. There certainly is the availability to specify control positions in pixels via CSS, but it's not required. And I know HTML also has well defined standards for accessibility, whereas I'm not sure what the status is on accessibility standards with other kinds of software.
You could use javascript and html. There's a port of processing to javascript, so you know that it is powerful enough for the things that your class will cover. You can author html without knowing a single thing about what it looks like. In fact that is the preferred way to author html.
The main downside of javascript is not javascript itself, but the browser dom. That is the interface into controlling the html elements. However, a library like jquery, or mootools, or dojo can take care of most of those problems.
As for accessiblity, have a look at WAI ARIA also opera's intro to WAI ARIA.a
WAI ARIA is a way to build rich javascript applications while playing nice with screen readers. It's very cool. I've not seen more work and passion put into making the web stack accessible in any other programming stack.