I'm trying to create tags/labels/badges to tag certain words(actually sometimes multiple words can constitute a tag). Currently, I've added a custom NSAttributedString key that I have used to tag words with their part of speech. I want to tag these words with a rounded background coloring. I've gone through the code in this sample code, that creates tags like this:
But the example code just takes existing NSTextElements(paragraph level) and applies styling to them. When I plug into the same delegate functions from the text code all the text elements are paragraph level. For example
This is one.
This is two.
Would create two text elements: This is one. and This is two.. I'm curious how I can split these into multiple text elements. For example if I wanted to just tag EGG in EGG SANDWICH NO. 2, I'm guessing I need to split that text element into two(EGG and SANDWICH NO. 2), but I can't figure out how to do that currently, or find any examples of adding word tags to text on MacOS(The app does not need to support iOS, only MacOS).
Am I along the right track for accomplishing this? If so, what's the best way to split up the NSTextElements?
I had a similar problem and failed in a way that I really discourage to do that.
TextKit 2 is evolving. I report on trying to create a NSTextElement subclass below the NSTextParagraph level in macOS Ventana (autumn 2022).
My problem was to communicate the layout position of a text attachment, which is part of the attributed string, to the text view to position the associated subview and its exclusion path accordingly - a standard problem for text with figures.
The path to introduce a subclass of an NSTextElement into the text layout process is via delegates.
Starting at the text store:
NSTextContentStoreDelegate offers methods to introduce custom NSTextElements depending on the content of the NSAttributedString:
1. Paragraph Level:
func textContentStorage(NSTextContentStorage, textParagraphWith: NSRange) -> NSTextParagraph?
2. Arbitrary NSTextElement Level:
func textContentManager(NSTextContentManager, textElementAt: NSTextLocation) -> NSTextElement?
NSTextLayoutManagerDelegate can deliver custom NSTextLayoutFragment objects for these custom NSTextElements:
func textLayoutManager( _ textLayoutManager: NSTextLayoutManager, textLayoutFragmentFor location: NSTextLocation, in textElement: NSTextElement) -> NSTextLayoutFragment
The custom NSTextLayoutFragment objects can do what you desire.
I tried to subclass on the NSTextElement level (using method 2 of NSTextContentStoreDelegate) and used a custom NSTextLayoutFragment to execute my code. The result was that the entire layout process stopped when this custom NSTextLayoutFragment object was encountered. I overrode all methods that are in the documentation of the NSTextLayoutFragment to catch the problem and failed. Even worse, I introduced memory problems into my code that Swift as a language should guard against. At places where I and the compiler expected a model object the executing code saw the view which displays this model object.
I finally accepted that I can not go below the paragraph level and subclassed NSTextParagraph and introduced this class using the first and not the second NSTextContentStorageDelegate method. I solved the desired atomisation down to the attachment within the subclasses. That worked immediately and brought the desired functionality in a very precise and efficient way.
I have built a bokeh app that allows users to select windows in data and run python code to find and label (with markers) extreme values within these limits. For ease of interaction, I use the box select tool for the range selection. My problem arises when repeating this process for subsequent cases. After markers are placed for the results, they are rendered invisible by setting alpha to zero and another case needs to be chosen. When the new select box includes previous markers, they become visible based on the selection. How do I override this default behavior? Can markers be made unselectable? or can I add code to the customJS to hide them after they are selected?
Thanks in advance for any help!
There are a few possible approaches. If you just want non-selected glyphs to "disappear" visually, you can set a policy to do that as described here:
http://docs.bokeh.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs
Basically, for bokeh.plotting, pass
nonselection_fill_alpha=0.0,
nonselection_line_alpha=0.0,
as arguments to your plot.circle call or whatever. Or if you are using the low level bokeh.models interface, something like:
renderer.nonselection_glyph = Circle(fill_alpha=0.0, line_alpha=0.0)
But be aware (I think you already are) that the invisible markers are still there, and still selectable if the user happens to draw a box over them with the selection tool.
If you truly want only a subset of the data to be visible and selectable after a selection, I'd say you want to replace the data in the column data source wholesale with the subset in your selection callback.
I have a subform bugging me. The mainform contains buttons etc. Everytime the user close/open the form, the columns width is reset to whatever the table likes. If i open the table directly, the size is as i want. If i change it in the subform, it is not saved. (See screendump)
I would like "Phase" to stay about 2 cm width. I can enter the subform and edit the "Width" but that is only applied to the other views.
I hope you can help, Emil.
I realize this post is almost 2 years old, but I ran into the same problem and came across this post.
I am running MS Access 2013 on Windows 7 Ultimate. I did not find the solutions offered here to work for me, so, I set out to find something that would work for me before I went to VBA code. (Incidentally, I appreciate the link offered by #Patrick_Honorez in his comment on the original post because that was going to be my fall-back solution.)
Anyway, here is what worked for me and I hope perhaps it will work for others as well:
Open the parent form.
In the subform, right-click the column header
for the column for which you wish to adjust the width.
Select the “Field Width” item from the context menu.
In the “Column Width” dialog that appears in step 3, enter the desired column width in points, or, use the [Best Fit] button. Then click the [OK] button to close the dialog and return to the form.
Right-click the parent form’s border to bring up the parent form’s context menu. Click the “Save” item in the context menu.
Now close the parent form.
The next time the form is loaded, the column widths should be as set it step 4 above--at least they are for my setup.
I see this post is quite old and OP must have figured someway to tackle the issue. I came across same issue today and found solution on this link.
For anybody else having same issue, use following code (I modified the code a little because original code from the above mentioned post saves column width of only text boxes but my form has combo boxes too, column width of which was not getting saved) in close and open events of your subform and then open main form in Form View and then manually select desired widths either by mouse, by entering column width value or using best fit. Save the form and reopen to check results. That's it.
Private Sub Form_Close()
Dim ctrl As Control
For Each ctrl In Me.Controls
If (ctrl.ControlType = acTextBox Or ctrl.ControlType = acComboBox) Then
SaveSetting "propertiesDBS", Me.Name, ctrl.Name, ctrl.ColumnWidth
End If
Next
End Sub
Private Sub Form_Open(Cancel As Integer)
Dim ctrl As Control
Dim frm As Form
Dim w As Long
For Each ctrl In Me.Controls
If (ctrl.ControlType = acTextBox Or ctrl.ControlType = acComboBox) Then
w = GetSetting("propertiesDBS", Me.Name, ctrl.Name, 0)
If w <> 0 Then ctrl.ColumnWidth = w
End If
Next
End Sub
I know this is late to the party and most likely going to be the last comment anyone reads, but this can be done quite simply in MS Access 2016 - by someone like myself who has no more than 4 days experience in databasing overall and no experience with writing custom Macro's or VB Script (using only what is native to MS Access).
Here's how I did it.
Scenario - Split Form (Form + Datasheet).
Extra Recommendations:
It pays to be across all properties of every object type in your database, as a change in a field property can cause unpredictable erratic effects, which take ages to figure out why it happened and how to stop it from happening again, whilst delivering your desired outcome.
Me.Requery in your VBA script after every necessary event and also in your main form (generally the 'After Update' event is used most), and be wary that too many Me.Requery's (in unnecessary events) can also be detrimental - so too much of a good thing can be a bad thing.
Bottom Line Up Front - Modify the format of your query that is to be exported/printed.
In 'Design View' of the query you are concerned with, ensure that the fields are in the order you need them outputted in first as this is exactly how the macro will present them for export/print (example could be "Australia" then "Northern Territory" then "Town's In The Northern Half Of The State" then "Darwin" then "Suburbs In The Northern Half Of City").
Switch to 'DataSheet View' in the same query and use the top left folded over triangle looking thingy to highlight the entire data set then right click that same triangle to present an options menu. Select 'Row Height' and type in "15" (default row height in Excel).
Deselect the entire spreadsheet and this time select every column (left click the left most column, hold shift button, scroll over to the right to the far end of the data set and click the last column) and then right click one of the highlighted columns to present another menu. Select 'Field Width' and within that new pop-up menu select 'Best Fit' and then 'OK'.
(Optional - not sure if this helps or hinders but I did it for my purpose) With the columns still selected right click one of the highlighted columns again and select 'Freeze Fields'.
My scenario had buttons with macros configured to run filtered reports so I was able to check this by simply clicking any of those buttons and seeing the report formatting, which it held true to the work I had just done. I exported using another button with a macro that exports to Excel with 'Print Formatting' selected (my main form also had the datasheet view as the only thing that could be printed and was also set in 'Print' formatting.
The Excel spreadsheet opened with all row heights and column widths in a way that I could read every field/record with perfect ease and without extra modification.
This also worked for cascaded combo boxes, with the export only outputting the 'drilled down/filtered' datasheet records, in a format that required no further modifications.
Hope this helps someone, as its saved my hide! :)
Open the Main form in Design. Go to the SubForm. Click on the square at the top left of the SubForm and select 'Properties'. Right-Click the control 'Phase' and click 'Properties'.Click the 'Format' tab and select 'Width'. What do you see there? That should control the widht of control 'Phase' unless you have some overriding coding elsewhere. Input the size you want and see what happens.
Use continuous forms instead. It gives you complete control over how your subform displays.
If you open your subform directly, your property sheet menu should display automatically if the default view is "Datasheet." Click on "All" and change the "Auto Resize" property to "No." This should solve the issue and avoid the need for VBA.
This only works when you open the subform separately. So if you want the changes to be reflected within your main form, you'll have to close it and switch back and forth.
Super annoying by default.
It seems to work as one would expect of you set the view mode to layout view. Drag column widths as needed and save. Go back to form view and it works. It's really dumb it doesn't work the same way in form view our design view.
In Access 365, open main form, right-click sub-form datasheet columns that need width adjustment, use the Field Width to adjust, click on border of main form to select Layout view, and save changes.
Open subform in datasheet view (by double click on subform in the left pannel)
Resize columns as you want by dragging or by right-click the column header for the column for which you wish to adjust the width and select the “Field Width” item from the context menu.
Right-click the subform border to bring up the context menu. Click the “Save” item in the context menu.
Either open the Main Form in Layout View or directly open your Subform in Datasheet View. Right Click on the Field Header, select Field Width, and enter the desired width. Save. Bewm.
My solution (Access 2016) was to create the main & subform, recreate the subform on its own using form wizard and set it up the way I want it, rename the original subform to something else, and finally rename the recreated subform to the original form name. Open the main form and the subform should be laid out the way you want it. You can then delete the original subform you renamed.
I'm using a datarepeater control, version 10.0 in visual studio 2010. The CurrentItemIndex seems to update before the textbox leave event when I use the mouse to move to the next row. So, when I retrieve the value from the textbox, I don't now what ItemIndex it is associated with. This doesn't happen when the keyboard is used to move to the next row. Anyone see this happen. Version 9.0 on the datarepeater did work this way.
To answer you directly, here are some C# snippets. I'm assuming that you already have the TextBox object (or other control) as implied in your question. I will also assume that you're inside an event handler (e.g. TextChanged). If you haven't already done it, you need to use the object sender parameter and not the design-time declared TextBox control (i.e. do not use TextBox1, or similar object) because it will just refer to the DataRepeaterItem template control and not the individual control for the data row you're interested in.
TextBox itemTextBox = sender as TextBox;
//* DataRepeaterItem is a control which contains other controls for each data "row"
DataRepeaterItem drItem = itemTextBox.Parent as DataRepeaterItem;
//* Retrieve the particular data item
int idx = drItem.ItemIndex;
//* If DataRepeater is bound to a BindingSource, for example,
//* one can retrieve the underlying data item
object dataItem = myBindingSource.List[idx];
I've experienced various bugs and challenges with control focus and data updates with the DataRepeater. There is no guarantee of exactly which order the events fire: Leave, LostFocus, CurrentItemChanged, etc. And as you've observed, it differs depending on whether you use the mouse within the DataRepeater or to/from another control on the form or using the keyboard. There may indeed be an established algorithm, but I have observed differences from documentation. The situation is complicated when the data-handling framework (e.g. BindingSource, CurrencyManager) also subscribes to these events and updates things out of order from what you might expect or want. I don't have a suggestion on how to handle these issues, but I hope the code above can at least get you access to the particular index and data for the control you're in.
I'm using two UIPageControls in a view to reflect chapters and pages. So I have defined one UIPageControl named chapterCount and one named pageCount just to show where the user is. I handle the flipping of the pages with swipes rather than using the UIPageControls (so no methods defined for them).
I change their values as the user change pages with the following code:
chapterCount.numberOfPages = chapters;
chapterCount.currentPage = chapterNumber;
pageCount.numberOfPages = pages;
pageCount.currentPage = pageNumber;
[chapterCount updateCurrentPageDisplay];
[pageCount updateCurrentPageDisplay];
Where chapters, chapterNumber, pages and pageNumber all are integers.
The first time I flip through the pages it normally works fine, but when I go to a previous chapter or start a new chapter, the first (or last depending on direction) dot is not showed. Please see picture (upper half is missing a dot, lower one OK).
alt text http://img80.imageshack.us/img80/3339/pagecontrol.png
Its the same code updating the controls and sometime I get a dot, sometimes not. When I check the variables with NSLOG they are correct (eg the same for both pictures above).
I have checked Apple's documentation and tried their example but no luck.
Where should I start troubleshooting? I'm getting crazy!!
I finally found the problem :-)
An UIPageControl that is given a value 0 for number of pages will not show correctly the next time it is updated. I was reading chapter and page numbers from an array and in the beginning (let's say cover of the book) there are no pages and no chapters to show, so I happily set these to 0. Since I did not want to change the source data in my array I used MAX(pages , 1) for numberOfPages, so now it's working like clockwork.
Are you sure your chapterCount and pageCount views are not nil? You can have valid values all day, a message to nil does nothing and returns nil. Double check your view and controller wiring/unwiring when you change chapters.
EDIT:
confirm the size of the control is big enough to hold all your pages, and the view bounds is not clipped. For example, if you had 10 pages, and the "current" page was 10, but there were only 9 dots visible, it would appear as though nothing is highlighted because the white dot would be clipped from the visible area by being outside the viewable bounds. You can adjust the size dynamically using this:
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount