Is it possible to programatically create a xaml page? - c++-winrt

I might write no sense on the next lines:
I tried to derive a struct named mainpage from winrt::Windows::UI::Xaml::Controls::Page and pass it to winrt::xaml_typename<>(), in "<>" is mainpage.
It will be understandable when you look at the code:
Point number 1 "(1)" is the mainpage.h file, is very short.
Point number 2 "(2)" is the App.cpp file, it only has the necessary.
//(1) mainpage.h
#pragma once
#include "pch.h"
struct mainpage : winrt::Windows::UI::Xaml::Controls::Page
{
mainpage() {
winrt::Windows::UI::Xaml::Controls::Button thebutton = winrt::Windows::UI::Xaml::Controls::Button();
thebutton.Click([&](const IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& event_arg)
{
thebutton.Content(winrt::box_value(L"Clicked"));
});
}
};
//(2) App.cpp
#include "pch.h"
#include "mainpage.h"
struct App : winrt::Windows::UI::Xaml::ApplicationT<App>
{
void OnLaunched(const winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs& event_arg)
{
winrt::Windows::UI::Xaml::Controls::Frame root_frame{ nullptr };
winrt::Windows::UI::Xaml::UIElement content = winrt::Windows::UI::Xaml::Window::Current().Content();
if (content)
{
root_frame = content.try_as<winrt::Windows::UI::Xaml::Controls::Frame>();
}
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (root_frame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
root_frame = winrt::Windows::UI::Xaml::Controls::Frame();
root_frame.NavigationFailed({ this, &App::OnNavigationFailed });
if (event_arg.PreviousExecutionState() == winrt::Windows::ApplicationModel::Activation::ApplicationExecutionState::Terminated)
{
// Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}
if (event_arg.PrelaunchActivated() == false)
{
if (root_frame.Content() == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
root_frame.Navigate(winrt::xaml_typename<mainpage>(), box_value(event_arg.Arguments()));
}
// Place the frame in the current Window
winrt::Windows::UI::Xaml::Window::Current().Content(root_frame);
// Ensure the current window is active
winrt::Windows::UI::Xaml::Window::Current().Activate();
}
}
else
{
if (event_arg.PrelaunchActivated() == false)
{
if (root_frame.Content() == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
root_frame.Navigate(winrt::xaml_typename<mainpage>(), box_value(event_arg.Arguments()));
}
// Ensure the current window is active
winrt::Windows::UI::Xaml::Window::Current().Activate();
}
}
}
void App::OnNavigationFailed(const IInspectable&, const winrt::Windows::UI::Xaml::Navigation::NavigationFailedEventArgs& event_arg)
{
throw winrt::hresult_error(E_FAIL, winrt::hstring(L"Failed to load Page ") + event_arg.SourcePageType().Name);
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) {
winrt::Windows::UI::Xaml::Application::Start([](auto &&) { winrt::make<App>(); });
}
If it is not possible, how can I properly create a page?

It is simple if you have installed the CppWinRT VSIX. Then create a "View model" and edit the files. You shouldn't derive the struct from the winrt::Windows::UI::Xaml::Controls::Page class because winrt::xaml_typename<> needs a WinRT class in <>.

Related

Assigning QObject pointer works via assignment but not binding

I have something similar to the following code snippets. I am simplifying the code here for attempted brevity.
First, a subclass of QAbstractListModel with the following data() implementation, and Q_INVOKABLE get_thing() method, which returns a pointer to a QObject subclass, QML_thing:
QVariant data(QModelIndex& index, int role) {
const auto& thing = m_data.at(index.row()); // shared pointer to QML_thing
switch(role)
{
case Qt::DisplayRole:
return thing->name(); // this works
case WholeThingRole:
return QVariant::fromValue(QML_thing*>(thing.get());
}
}
QML_thing* getThing(int index) const
{
const thing = m_data.at(index); // shared pointer
return thing.get();
}
Next, I have a Repeater in a QML file that has this code:
Repeater {
id: repeater
model: thingModel
ThingDelegate {
thing: wholeThing // This calls the role, but ends up being null
}
onItemAdded {
item.thing = model.getThing(index) // this works, but 'breaks' the binding
}
}
My question is: why doesn't the thing: binding in QML work, but the thing = version does?

How to update the map properly using canvas and a button when the players relocate to a new location?

My game snapshot Attachment> Blockquote
My canvas constructs
public class DrawingView4 extends View{
DrawingView4(Context context4)
{
super(context4);
}
#Override protected void onDraw(Canvas canvas4)
{
int tile4=0;
if (DoneDrawFacilities && doneloading) {
}
else {
for (int i4=0; i4< 17 && notfixingorientation; i4++){
if (i4< 16) {
for (int ii4=0; ii4 < 16; ii4++){
try {
//Checking the data of all spots of the game map from package directory.
//Then Draw in canvas if the data of the spot occupied by type of human and core facilities,
FacilityList = new Gson().fromJson(FileUtil.readFile(FileUtil.getPackageDataDir(getApplicationContext()).concat("/GameResource/Tile".concat(String.valueOf((long)(tile4 + 1)).concat(".data")))), new TypeToken<ArrayList<HashMap<String, Object>>>(){}.getType());
if (FacilityList.get((int)0).get("Type").toString().equals("Human")) {
canvas4.drawBitmap(BitmapFactory.decodeFile(AllObjects.getString(String.valueOf((long)(tile4)), "")),null,new Rect(ii4*120, i4*120, 120*(ii4+1),120*(i4+1)), null);
}
if (FacilityList.get((int)0).get("Type").toString().equals("Core")) {
if (FacilityList.get((int)0).get("Name").toString().equals("Arena")) {
canvas4.drawBitmap(BitmapFactory.decodeFile(AllObjects.getString(String.valueOf((long)(tile4)), "")),null,new Rect(7*120, 7*120, 120*(8+1),120*(8+1)), null);
}
else {
}
}
} catch (Exception e) {
}
FacilityList.clear();
tile4++;
}
}
else {
DoneDrawFacilities = true;
}
}
}
}}
Blockquote
My Relocate button
//I use sharepreference called AllObjects rather than a list and I Only update the path of objects in specific tile in sharedpreference such as in variable 1, 2, etc. and then re-draw using this code below, next time I update the objects path and get this object path from the same json file in the package directory. Too decode to Bitmap and then Draw in canvas.
//Some other code are removed that just updating some data in specific file directory.
AA_structures_facilities.removeAllViews();
AA_structures_facilities.addView(new DrawingView4(GameActivity.this));
// But It freezes the screen or stop me from touching the touch event in a second everytime I update new canvas.
//WHILE MY touchevent is hundled in the parent LinearLayout where the canvas is placed.

C++/winRT xaml ContentDialog example

The documentation shows this C# snippet:
async void DisplayDeleteFileDialog(){
ContentDialog deleteFileDialog = new ContentDialog{
Title = "Delete file permanently?",
Content = "If you delete this file, you won't be able to recover it. Do you want to delete it?",
PrimaryButtonText = "Delete",
CloseButtonText = "Cancel"
};
ContentDialogResult result = await deleteFileDialog.ShowAsync();
// Delete the file if the user clicked the primary button.
/// Otherwise, do nothing.
if (result == ContentDialogResult.Primary) {
// Delete the file.
}
else {
// The user clicked the CLoseButton, pressed ESC, Gamepad B, or the system back button.
// Do nothing.
}
}
What I'm requesting is a C++/winRT version of this snippet.
IAsyncAction Async()
{
ContentDialog dialog;
dialog.Title(box_value(L"title"));
dialog.Content(box_value(L"content"));
dialog.PrimaryButtonText(L"primary");
dialog.CloseButtonText(L"close");
auto result = co_await dialog.ShowAsync();
if (result == ContentDialogResult::Primary)
{
}
}
I wanted to open content dialog on button click so I tried the code snippet provided by Kenny Kerr. Everything seemed to work fine without error but when i clicked the button no dialog was seen. i fixed it by placing below code
dialog.XamlRoot(myButton().XamlRoot());
Before auto result = co_await dialog.ShowAsync() line.
ContentDialog.xaml, xaml.h, xaml.cpp should not have the name or classes
named Windows::UI::Xaml::Controls::ContentDialog!!! My name is
ContentDialog1
DirectXPage.xaml.cpp
void YourNamespace::DirectXPage::UpdateStatus(String^ strMessage,
NotifyType type)
{
switch (type)
{
case NotifyType::StatusMessage:
StatusBorder->Background = ref new
SolidColorBrush(Windows::UI::Colors::Green);
break;
case NotifyType::ErrorMessage:
StatusBorder->Background = ref new
SolidColorBrush(Windows::UI::Colors::Red);
break;
default:
break;
}
StatusBlock->Text = strMessage;
// Collapse the StatusBlock if it has no text to conserve real estate.
if (StatusBlock->Text != "")
{
StatusBorder->Visibility = Windows::UI::Xaml::Visibility::Visible;
StatusPanel->Visibility = Windows::UI::Xaml::Visibility::Visible;
}
else
{
StatusBorder->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
StatusPanel->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
// Raise an event if necessary to enable a screen reader to announce
the status update.
auto peer = dynamic_cast<FrameworkElementAutomationPeer^>
(FrameworkElementAutomationPeer::FromElement(StatusBlock));
if (peer != nullptr)
{
peer->RaiseAutomationEvent(AutomationEvents::LiveRegionChanged);
}
}
void YourNameSpace::DirectXPage::NotifyUser(Platform::String^ strMessage,
NotifyType type)
{
if (Dispatcher->HasThreadAccess)
{
UpdateStatus(strMessage, type);
}
else
{
Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new
DispatchedHandler([strMessage, type, this]()
{
UpdateStatus(strMessage, type);
ContentDialog1^ dlg = ref new ContentDialog1();
dlg->ContentDialog_SetTitle(L"Error Message");
dlg->ContentDialog_SetTextBlock(L"All textures must be chosen from
the x64\\Release or Debug\\YourNamespace\\AppX\\Assets\\
(Folder or sub-Folders)");
Windows::Foundation::IAsyncOperation<ContentDialogResult>^ result =
dlg->ShowAsync();
if (result->GetResults() == ContentDialogResult::Primary) {}
if (result->GetResults() == ContentDialogResult::Secondary) {}
}));
}
}

Xamarin forms: Multiple navigation patterns in the same app

Can we have multiple navigation patterns in a single app?
In my app.xaml page I added a function
void SetUpNavigation()
{
var page = FreshPageModelResolver.ResolvePageModel<LaunchPageModel>();
var navPage = new FreshNavigationContainer(page);
MainPage = navPage;
}
But after a user signs in I want to use master detail page. Is there a way to do that ??
Yes. You just have to set the MainPage of your app again. In our projects, we use a helper class which have a method Restart with following logic:
public static void Restart(View view, NavigationType navtype)
{
// Reset the mainpage depending on the navigation type
if (navtype == NavigationType.RestartWithMasterPage)
{
Application.Current.MainPage = new MasterPage(view);
}
else if (navtype == NavigationType.Restart)
{
Application.Current.MainPage = new NavigationPage(view);
}
else
{
// Just show the page
Application.Current.MainPage = view;
}
}
The NavigationType is an enum:
public enum NavigationType
{
Normal,
Restart,
RestartWithMasterPage
}

Pause application in QML when app is in background Symbian

I want to know of any pure QML way to find out whether the application is in the background or not and then accordingly stop or play music. In meego the alternate way to do is through the PlatformWindow Element but it does not exist in Symbian QML. Help needed please
Finally I got it working :) and i did it though Qt way... here are the steps
1) Create a class MyEventFilter
class myEventFilter : public QObject
{
bool eventFilter(QObject *obj, QEvent *event) {
switch(event->type()) {
case QEvent::WindowActivate:
emit qmlvisiblechange(true);
qDebug() << "Window activated";
bis_foreground=true;
return true;
case QEvent::WindowDeactivate:
emit qmlvisiblechange(false);
qDebug() << "Window deactivated";
bis_foreground=false;
return true;
default:
return false;
}
}
void dosomething();
private:
int something;
public:
bool bis_foreground;
Q_OBJECT
public slots:
Q_INVOKABLE QString checkvisibility() {
if (bis_foreground==true) return "true";
else return "false";
}
signals:
void qmlvisiblechange(bool is_foreground);
};
2) Then in main.cpp include this file include the class and add setContext propery like this
context->setContextProperty("myqmlobject", &ef);
3) in qml file call it like this:
Item {
id: name
Connections
{
target:myqmlobject
onQmlvisiblechange:
{
if(is_foreground)
{
//dont do anything...
}
else
{
playSound.stop()
}
}
}
}
Enjoy :)
Why do you need a pure QML way?
You can detect if an application has been sent to the background by installing an event filter.
Check: http://www.developer.nokia.com/Community/Wiki/Detecting_when_a_Qt_application_has_been_switched_to_the_background_and_when_resumed
For a "pure" QML way, there is the Symbian QML element:
http://doc.qt.nokia.com/qt-components-symbian/qml-symbian.html
It has a foreground property that indicates whether the app is in the foreground or in the background. You can try connecting to onForegroundChanged.
From the documentation, the Symbian element is not "creatable". It exists as a context property named symbian. So a sample usage would be:
import QtQuick 1.1
import com.nokia.symbian 1.1
PageStackWindow {
id: window
initialPage: MainPage {tools: toolBarLayout}
showStatusBar: true
showToolBar: true
function appForegroundChanged() {
console.log("Foreground: " + symbian.foreground)
}
function appCurrentTimeChanged() {
console.log("Current time: " + symbian.currentTime)
}
Component.onCompleted: {
symbian.currentTimeChanged.connect(appCurrentTimeChanged)
symbian.foregroundChanged.connect(appForegroundChanged)
}
ToolBarLayout {
id: toolBarLayout
ToolButton {
flat: true
iconSource: "toolbar-back"
onClicked: window.pageStack.depth <= 1 ? Qt.quit() : window.pageStack.pop()
}
}
}