Fonts, Font-sizes and the MacOS

So, one of the questions I’ve occasionally been getting from Mac users is that they would really like the ability to shift the font and font sizes of the programs’ interface.  If you’ve used the Windows version of MarcEdit, this has been available for some time, but I’ve not put it into the Mac version in part, because, I didn’t know how.  The Mac UI is definitely different from what I’m use to, and the way that the AppKit exposes controls and the way controls are structures as a collection of Views and Subviews complicates some of the sizing and layout options.  But I’ve been wanting to provide something because on really high resolution screens, the application was definitely getting hard to read.

Anyway, I’m not sure if this is the best way to do it, but this is what I’ve come up with.  Essentially, it’s a function that can determine if an element has text, an image, and perform the font scaling, control resizing and ultimately, windows sizing to take advantage of Apples Autolayout features.  Code is below.

 

public void SizeLabels(NSWindow objW, NSControl custom_control = null)
		{
			string test_string = "THIS IS MY TEST STRING";

			string val = string.Empty;
			string font_name = "";
			string font_size = "";
			NSStringAttributes myattribute = new NSStringAttributes();


			cxmlini.GetSettings(XMLPath(), "settings", "mac_font_name", "", ref font_name);
			cxmlini.GetSettings(XMLPath(), "settings", "mac_font_size", "", ref font_size);



			if (string.IsNullOrEmpty(font_name) && string.IsNullOrEmpty(font_size))
			{
				return;
			}

			NSFont myfont = null;
			if (String.IsNullOrEmpty(font_name))
			{
				myfont = NSFont.UserFontOfSize((nfloat)System.Convert.ToInt32(font_size));

			}
			else if (String.IsNullOrEmpty(font_size))
			{
				font_size = "13";
				myfont = NSFont.FromFontName(font_name, (nfloat)System.Convert.ToInt32(font_size));
			}
			else {
				myfont = NSFont.FromFontName(font_name, (nfloat)System.Convert.ToInt32(font_size));
			}




			if (custom_control == null)
			{
				

				CoreGraphics.CGSize original_size = NSStringDrawing.StringSize(test_string, myattribute);

				myattribute.Font = myfont;
				CoreGraphics.CGSize new_size = NSStringDrawing.StringSize(test_string, myattribute);

				CoreGraphics.CGRect frame = objW.Frame;
				frame.Size = ResizeWindow(original_size, new_size, frame.Size);
				objW.MinSize = frame.Size;
				objW.SetFrame(frame, true);
				objW.ContentView.UpdateConstraints();
				//objW.ContentView.UpdateTrackingAreas();


				//MessageBox(objW, objW.Frame.Size.Width.ToString() + ":" + objW.Frame.Size.Height.ToString());

				foreach (NSView v in objW.ContentView.Subviews)
				{
					if (v.IsKindOfClass(new ObjCRuntime.Class("NSControl")))
					{
						NSControl mycontrol = ((NSControl)v);
						switch (mycontrol.GetType().ToString())
						{

							case "AppKit.NSTextField":
							case "AppKit.NSButtonCell":
							case "AppKit.NSBox":
							case "AppKit.NSButton":

								if (mycontrol.GetType().ToString() == "AppKit.NSButton")
								{
									if (((NSButton)mycontrol).Image != null)
									{
										break;
									}
								}

								mycontrol.Font = myfont;
								//if (!string.IsNullOrEmpty(mycontrol.StringValue))
								//{
								//	mycontrol.SizeToFit();
								//}
								mycontrol.UpdateConstraints();
								break;

						}

						if (mycontrol.Subviews.Length > 0)
						{
							SizeLabels(objW, mycontrol);
						}
					}
					else if (v.IsKindOfClass(new ObjCRuntime.Class("NSTabView")))
					{
						NSTabView mytabview = ((NSTabView)v);
						foreach (NSTabViewItem ti in mytabview.Items)
						{
							foreach (NSView tv in ti.View.Subviews)
							{
								if (tv.IsKindOfClass(new ObjCRuntime.Class("NSControl")))
								{
									SizeLabels(objW, (NSControl)tv);
								}
							}
						}
					}
				}
			}
			else {
				if (custom_control.Subviews.Length == 0)
				{
					if (custom_control.GetType().ToString() != "AppKit.NSButton" ||
						(custom_control.GetType().ToString() == "AppKit.NSButton" &&
						 ((NSButton)custom_control).Image == null))
					{
						custom_control.Font = myfont;
						custom_control.UpdateConstraints();
					}
				}
				else {
					foreach (NSView v in custom_control.Subviews)
					{

						NSControl mycontrol = ((NSControl)v);
						switch (mycontrol.GetType().ToString())
						{

							case "AppKit.NSTextField":
							case "AppKit.NSButtonCell":
							case "AppKit.NSBox":
							case "AppKit.NSButton":
								if (mycontrol.GetType().ToString() == "AppKit.NSButton")
								{
									if (((NSButton)mycontrol).Image != null)
									{
										break;
									}
								}
								mycontrol.Font = myfont;
								//if (!string.IsNullOrEmpty(mycontrol.StringValue))
								//{
								//	mycontrol.SizeToFit();
								//}
								mycontrol.UpdateConstraints();
								break;
							default:
								if (mycontrol.Subviews.Length > 0)
								{
									SizeLabels(objW, mycontrol);
								}
								break;
						}



					}
				}

			}

		}

And that was it. I’m sure there might be better ways, but this is (crossing my fingers) working for me right now.


Posted

in

, ,

by

Tags: