Using the value of a Holotoolkit slider - toolkit

I have just started using the Mixed Reality Toolkit (former Holotoolkit) and I am trying to use a slider.
So I made a scene with a 3DTextPrefab, a Button and a Slider.
I wrote a script and attach it to the 3DTextPrefab. This script is
public class Clicker : MonoBehaviour {
public GameObject ObjectToShow;
public float waitTime;
private void Awake()
{
ObjectToShow.SetActive(false);
}
public void Click()
{
TextMesh tm = ObjectToShow.GetComponent("TextMesh") as TextMesh;
tm.text = "Hello with parameter" + waitTime;
ObjectToShow.SetActive(true);
StartCoroutine(HideAfterTimeout());
}
public void setWaitTime(float t)
{
waitTime = t;
}
IEnumerator HideAfterTimeout()
{
// yield return new WaitForSeconds(0.1f);
yield return new WaitForSeconds(waitTime);
ObjectToShow.SetActive(false);
}
}
In the button, there is the "Interactive" script (by default), so I added the 3dTextPrefab as an object to the OnSelectedEvents list and selected its Click function.
Doing this every time I click on the button, it calls the click function of the Prefab script. So far so goo.
I tried to do something similar with the slider so I added the prefab as an object to the Slider Gesture Control script's OnUpdateEvent and selected its setWaitTime function.
My problem is, the setWaitTime function has a parameter and I can see that in the inspector. This parameter has to be the actual value of the slider.
How do you get the actual value of the slider to put it there?

The slider should have a value property that you can read from. Add the slider to your script, assign your slider to the slot in the inspector and then you can access the value property from inside of your script.

Related

best approach to open a pop up window for large data

i am new to wpf and i need to open up a pop up a new window on grid row click which contains lots of data and controls on it.i am confused with the correct approach. i am using mvvm pattern.should i make a window control or user control or something else. and how to open that pop up inside a function. please help with example
If I need to display a new Window in my MVVM-Application I use the following approach:
At first I have an interface with a method to show the new dialog:
internal interface IDialogManager
{
void DisplayData(object data);
}
And an implementation like:
internal class DialogManager : IDialogManager
{
public void DisplayData(object data)
{
LotOfDataViewModel lotOfDataViewModel = new LotOfDataViewModel(data);
LotOfDataView lotOfDataView = new LotOfDataView
{
DataContext = lotOfDataViewModel
};
lotOfDataView.ShowDialog();
}
}
LotOfDataViewModel and LotOfDataView are the new Dialog where you want to show your data.
In your actual ViewModel you introduce a new property like:
private IDialogManager dialogManager;
private IDialogManager DialogManager
{
get { return dialogManager ?? (dialogManager = new DialogManager()); }
}
And the you can show your large data with:
DialogManager.DisplayData(myData);

Cannot access native WpfButton in UI Test, get Exception: System.NotSupportedExceptions

I'm trying to access a native Wpf control property within the UI test framework (MS UI Tests). My specific issue is that, when I try accessing a WpfButton control property (e.g., IsVisible) using the function call WpfButtonObject.GetProperty("IsVisible"), the exception "System.NotSupportedExceptions" occurs. I'm able to see this WpfButton property using Snoop; so, I'm wondering if the GetProperty call is correct? Please see my related code below. Thanks for any insight.
UIMap.cs: Test function for a pressing a WpfButton. Please note the call uIButton.GetPropery("IsVisible"). This is where the exception occurs:
public void PressButtonTest()
{
WpfButton uIButton = this.UIMainWindowWindow.UIButtonButton;
object state = uIButton.GetProperty("IsVisible"); // Throws SystemNotSupportedException exception
bool stateBool = (bool)state;
Assert.IsTrue(stateBool, "Button is visible");
PressButton();
}
UIMap.Designer.cs: WpfButton property:
public WpfButton UIButtonButton
{
get
{
if ((this.mUIButtonButton == null))
{
this.mUIButtonButton = new WpfButton(this);
#region Search Criteria
this.mUIButtonButton.SearchProperties[WpfButton.PropertyNames.AutomationId] = "button";
this.mUIButtonButton.WindowTitles.Add("MainWindow");
#endregion
}
return this.mUIButtonButton;
}
}
Here's what I've done:
Point point;
bool isClickable = uIButton.TryGetClickablePoint(out point);
Assert.IsTrue(isClickable, "No clickable point was found, button not visible.");
By the way, your message in your Assert (2nd parameter) is inaccurate because it's only used on fail... in your case, when the button would not be visible. So in your output it would say "Button is visible" on failure when in fact it was not.

Unity UI Slider to change UI Text

Ok Im using unity 4.6 and have a UI slider visible to the player. Beside the slider I have a UI Text which is showing a String of 500. The Slider head is at the right hand side (500) and can be slid left towards what I want to be 0.
I have the following code in place but when i slide the slider the Text value starts at 500 and automatically changes to 0.99 and moves the whole way down to 0 on the left hand side. If i was to slide it back up to the right hand side it has a value of 1.
public class SliderUITextUpdate : MonoBehaviour {
string sliderTextString = "500";
public Text sliderText;
public void textUpdate(float textUpdateNumber)
{
sliderTextString = textUpdateNumber.ToString ();
sliderText.text = sliderTextString;
}
}
This script is attached to a Manager object (just an empty gameobject) and then the text game object is applied in the inspector.
On the slider object I am using the OnValueChanged() ability in the inspector. To which I have attached the Manager gameobject and set it to use SliderUITexture.textUpdate
Any help would be great thanks !
public class SliderUITextUpdate : MonoBehaviour {
string sliderTextString = "500";
public Text sliderText;
public Slider mainSlider;
void Awake(){
mainSlider.maxValue = 500;
}
public void textUpdate(float textUpdateNumber)
{
sliderTextString = textUpdateNumber.ToString ();
sliderText.text = sliderTextString;
}
}
get the referece for that slider in inspector

Pattern for binding commands on a child ViewModel from a parent menu

I'm creating a WPF MVVM app using Caliburn Micro. I have a set of buttons in a menu (Ribbon) that live in the view for my shell view model, which is a ScreenConductor. Based on the currently active Screen view model, I would like to have the ribbon buttons be disabled/enabled if they are available for use with the active Screen, and call actions or commands on the active Screen.
This seems like a common scenario. Is there a pattern for creating this behavior?
Why don't you do the reverse thing, instead of checking which commands are supported by the current active screen, let the active screen populate the menu or ribbon tab with all the controls that it supports, (i would let it inject its own user control which might just be a complete menu or a ribbon tab all by itself), this will also enhance the user experience as it will only show the user the controls that he can work with for the current active screen.
EDIT: Just looking at your question again and I'm thinking that this is much simpler than it looks
The only issue I can see you having is that a lack of a handler (and guard) method on a child VM will mean that buttons that don't have an implementation on the currently active VM will still be enabled.
The default strategy for CM is to try and find a matching method name (after parsing the action text) and if one is not found, to leave the button alone. If you were to customise that behaviour so that the default is for buttons to be disabled, you could easily get it working by just implementing the command buttons in your shell, making sure to set the command target to the active item:
In the shell define your buttons, making sure they have a target that points to the active child VM
<Button cal:Message.Attach="Command1" cal:Action.TargetWithoutContext="{Binding ActiveItem}" />
Then just implement the method in your child VM as per usual
public void Command1() { }
and optionally a CanXX guard
public bool CanCommand1
{
get
{
if(someCondition) return false;
return true;
}
}
Assuming you don't get much more complex than this, it should work for you
I'm going to have a quick look at the CM source and see if I can come up with something that works for this
EDIT:
Ok you can customise the ActionMessage.ApplyAvailabilityEffect func to get the effect you want - in your bootstrapper.Configure() method (or somewhere at startup) use:
ActionMessage.ApplyAvailabilityEffect = context =>
{
var source = context.Source;
if (ConventionManager.HasBinding(source, UIElement.IsEnabledProperty))
{
return source.IsEnabled;
}
if (context.CanExecute != null)
{
source.IsEnabled = context.CanExecute();
}
// Added these 3 lines to get the effect you want
else if (context.Target == null)
{
source.IsEnabled = false;
}
// EDIT: Bugfix - need this to ensure the button is activated if it has a target but no guard
else
{
source.IsEnabled = true;
}
return source.IsEnabled;
};
This seems to work for me - there is no target for methods which couldn't be bound to a command, so in that case I just set IsEnabled to false. This activates buttons only when a method with a matching signature is found on the active child VM - obviously give it a good test before you use it :)
Create methods and accompanying boolean properties for each of your commands on your shell view model. (See code below for an example.) Caliburn.Micro's conventions will wire them up to the buttons for you automatically. Then simply raise property changed events for the boolean properties when you change views to have them be re-evaluated.
For example, let's say you have a Save button. The name of that button in your xaml would be Save, and in your view model, you would have a Save method along with a CanSave boolean property. See below:
public void Save()
{
var viewModelWithSave = ActiveItem as ISave;
if (viewModelWithSave != null) viewModelWithSave.Save();
}
public bool CanSave { get { return ActivateItem is ISave; } }
Then, in your conductor, whenever you change your active screen, you would call NotifyOfPropertyChange(() => CanSave);. Doing this will cause your button to be disabled or enabled depending upon if the active screen is capable of dealing with that command. In this example, if the active screen doesn't implement ISave, then the Save button would be disabled.
I would use the Caliburn.Micro event aggregation in this scenario, as follows:
Create a class named ScreenCapabilities with a bunch of Boolean attributes (e.g. CanSave, CanLoad, etc.)
Create a message named ScreenActivatedMessage with a property of type ScreenCapabilities
Create a view model for your ribbon that subscribes to (handles) the ScreenActivatedMessage
In the ribbon view model's Handle method, set the local CanXXX properties based on the supplied ScreenCapabilities.
It would look something like this (code typed by hand, not tested):
public class ScreenCapabilities
{
public bool CanSave { get; set; }
// ...
}
public class ScreenActivatedMessage
{
public ScreenCapabilities ScreenCapabilities { get; set; }
// ...
}
public class RibbonViewModel : PropertyChangedBase, IHandle<ScreenActivatedMessage>
{
private bool _canSave;
public bool CanSave
{
get { return _canSave; }
set { _canSave = value; NotifyPropertyChanged(() => CanSave); }
}
// ...
public void Handle(ScreenActivatedMessage message)
{
CanSave = message.ScreenCapabilities.CanSave;
// ...
}
}
Then, somewhere appropriate, when the screen changes, publish the message. See see Caliburn.Micro wiki for more info.
Define a property (let's say ActiveScreen) for the active screen in the shell view model.
And let's assume you have properties for the each button such as DeleteButton, AddButton.
Screen is a viewmodel for the screens.
private Screen activeScreen;
public Screen ActiveScreen
{
get
{
return activeScreen;
}
set
{
activeScreen= value;
if (activeScreen.Name.equals("Screen1"))
{
this.AddButton.IsEnabled = true;
this.DeleteButton.IsEnabled = false;
}
if else (activeScreen.Name.equals("Screen2"))
{
this.AddButton.IsEnabled = true;
this.DeleteButton.IsEnabled = true;
}
NotifyPropertyChanged("ActiveScreen");
}
}

Passing variables from main form to input form

I have a simple question. I have a main form, and then a startup form from where I can select a new 3D model to generate. When selecting a new 3D model from the startup form, I want to check first whether the previous model I worked on has been saved or not. I simply want to pass a boolean value from the main form to the startup form using a delegate, but I can't seem to access the main form or any of its variables. I thought it would be as simple as saying: <code>frmMain myForm = new frmMain();</code>, but typing frmMain doesn't show up anything in intellisense.
Any hints?
Add a public property on your main form
public bool IsDirty
{
get;set;
}
you can then access this.ParentForm.IsDirty in your startup form,
remember to pass a reference to the main form when you show the startup form ... startupForm.showDialog(this);
Your main form is not accessible to Startup form.You have to store it to something that is accessible at a point where you want to use it.
You can do it by following way also ( along with other ways :)
// This class is mainly used to transfer values in between different components of the system
public class CCurrent
{
public static Boolean Saved = false;
}
make sure you put this class in namespace which is accessible to both the forms.
Now In your frmMain form set the value of CCurrent.Saved and access it in your startup form.
Here's my suggestion:
place a 3DModel object property in your main form:
private Model _model;
Declare your startup form as a Dialog ( like OpenFileDialog) and do something like this:
public void OpenModel()
{
using(var frm=new StartUpForm())
{
if(frm.ShowDialog()==DialogResult.OK))
{
if(_model.IsDirty)
{
if(MessageBox.Show("Model is changed do you want to save it?","",MessageBoxButtons.YesNo)==DialogResult.Yes)
_model.Save();
_model=frm.SelectedModel;
}
}
}
}
your startup form should have a interface like this:
public interface IStartupForm:IDisposable
{
DialogResult ShowDialog(IWin32Window parent);
Model SelectedModel{get;}
}

Resources