Angular 12 prevent browser tab/window close leave event if any form validation is required - browser

#HostListener('window:beforeunload', ['$event']) beforeunload($event:
any) {
$event.preventDefault();
$event.returnValue = false; } #HostListener('window :unload', ['$event']) unload($event: any) {
const isvalid = this.isFormValid(); if(!isvalid) { return false ; // don't close the tab ; skip unload event; } else {
this.SaveandClose(); } }
Note: if any validation is required then show a message popup window should not close
and skip the window :unload event.

Related

Accelerator keys not working when modeless popup has the focus

My main CDialog sometimes displays a child modeless dialog like this:
It is only displayed if the user has configured it to automatically display.
It gets displayed via the main dialogs OnInitDialog where this function is called:
void CChristianLifeMinistryEditorDlg::DisplayAssignHistoryDialog()
{
BOOL bShowAssignHistoryDialog;
bShowAssignHistoryDialog = theApp.GetNumberSetting(_T("Options"), _T("SM_ShowAssignHist"), TRUE);
if (bShowAssignHistoryDialog)
{
m_pAssignHistoryDlg = std::make_unique<CAssignHistoryDlg>(); // .release();
if (m_pAssignHistoryDlg != nullptr)
{
m_pAssignHistoryDlg->SetAssignHistMap(&m_mapSPtrHist, &m_HistoryOriginal);
m_pAssignHistoryDlg->Create(IDD_DIALOG_ASSIGN_HISTORY, this);
m_pAssignHistoryDlg->ShowWindow(SW_SHOWNORMAL);
m_pAssignHistoryDlg->UpdateWindow();
m_pAssignHistoryDlg->EnableTree(false);
}
}
}
WhatI have noticed is that some of my main windows ACCELERATOR hotkey keys don't always work. I then realised that this is because the popup window has the focus. If i single click anywhere on the main dialog to give it focus, then my accelerator hotkeys function.
Is there any way that we can easily still allow the main editor to process it's hotkeys even though the modeless window might have focus? A standard way to cater for this?
The main window handles the accelerators like this:
BOOL CChristianLifeMinistryEditorDlg::PreTranslateMessage(MSG * pMsg)
{
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}
}
And the popup modeless window also makes use of PreTranslateMessage (incase it is relevant):
BOOL CAssignHistoryDlg::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch{}, bDealtWith = bDealtWith = FALSE ;
if ( (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP ||
pMsg->message == WM_CHAR)
&& pMsg->wParam == VK_RETURN)
{
// Eat it.
bNoDispatch = TRUE ;
bDealtWith = TRUE ;
}
if (!bDealtWith)
bNoDispatch = CResizingDialog::PreTranslateMessage(pMsg);
return bNoDispatch ;
}
I would pass your m_hAccelTable from CChristianLifeMinistryEditorDlg to CAssignHistoryDlg and add this to the beginning of CAssignHistoryDlg::PreTranslateMessage:
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetParent()->GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}

SDL How to check if window is maximized or minimized

I'm trying to make a borderless window that can be maximized and minimized, but I can't get any information on how to get the current state of the window (if it's minimized or maximized) and how to use it.
(edit) rough snippets of the code:
SDL_Rect minimize_area = {0,0,20,20};
Button minimize_window_button = Button(minimize_area);
SDL_Rect maximize_area = {0,0,20,20};
Button maximize_window_button = Button(maximize_area);
SDL_Rect close_area = {0,0,20,20};
Button close_window_button = Button(close_area);
// Program loop
while ( SDL_PollEvent( &event ) ) {
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) {
mouse.updateMousePosition();
if (close_window_button.mouseInDstRect(mouse.pos.x, mouse.pos.y)) running = false;
if (maximize_window_button.mouseInDstRect(mouse.pos.x, mouse.pos.y)) {
if (/* WAY TO KNOW IF THE WINDOW IS MAXIMIZED */) {
SDL_MaximizeWindow(window);
} else {
SDL_RestoreWindow(window);
}
}
if (minimize_window_button.mouseInDstRect(mouse.pos.x, mouse.pos.y)) {
if (/* WAY TO KNOW IF WINDOW IS MINIMIZED or UNMINIMIZED */) {
SDL_MinimizeWindow(window);
} else {
SDL_RestoreWindow(window);
}
}
}
SDL_Log("click!");
break;
}
SDL_GetWindowFlags(), check the SDL_WINDOW_MINIMIZED & SDL_WINDOW_MAXIMIZED bits.

Support for interruptions in bot

Do you know if there is way to implement global message handlers that can support commands like stop, bye, cancel, exit Virtual assistant bot ? I am trying to implement something like this.
I have a virtual assistant built already and it has couple of Skills or Skill Bots.
When user is in the multi turn conversation with a Skill, user should be able to exit out of skill by commands like stop, bye, cancel, exit.
I found old v3 doc but nothing for v4.
Check the documentations provided here Handling User Interruption They explain how to handle user interruption for SDK v4
Find below an example of how you can configure this in the Virtual Assistant.
In your MainDialog.cs
Add the following for your OnContinueDialogAsync: Keeping in mind that you can change and edit this as you see fit just be sure to check the OnInterruptDialogAsync result (status in this example) before you continue
protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken))
{
var status = await OnInterruptDialogAsync(innerDc, cancellationToken).ConfigureAwait(false);
if (status == InterruptionAction.Resume)
{
// Resume the waiting dialog after interruption
await innerDc.RepromptDialogAsync().ConfigureAwait(false);
return EndOfTurn;
}
else if (status == InterruptionAction.Waiting)
{
// Stack is already waiting for a response, shelve inner stack
return EndOfTurn;
}
else
{
var activity = innerDc.Context.Activity;
if (activity.IsStartActivity())
{
await OnStartAsync(innerDc).ConfigureAwait(false);
}
switch (activity.Type)
{
case ActivityTypes.Message:
{
// Note: This check is a workaround for adaptive card buttons that should map to an event (i.e. startOnboarding button in intro card)
if (activity.Value != null)
{
await OnEventAsync(innerDc).ConfigureAwait(false);
}
else
{
var result = await innerDc.ContinueDialogAsync().ConfigureAwait(false);
switch (result.Status)
{
case DialogTurnStatus.Empty:
{
await RouteAsync(innerDc).ConfigureAwait(false);
break;
}
case DialogTurnStatus.Complete:
{
// End active dialog
await innerDc.EndDialogAsync().ConfigureAwait(false);
break;
}
default:
{
break;
}
}
}
// If the active dialog was ended on this turn (either on single-turn dialog, or on continueDialogAsync) run CompleteAsync method.
if (innerDc.ActiveDialog == null)
{
await CompleteAsync(innerDc).ConfigureAwait(false);
}
break;
}
case ActivityTypes.Event:
{
//do something for event activity
break;
}
case ActivityTypes.Invoke:
{
// Used by Teams for Authentication scenarios.
break;
}
default:
{
await OnSystemMessageAsync(innerDc).ConfigureAwait(false);
break;
}
}
return EndOfTurn;
}
}
And override OnInterruptDialogAsync like below example:
This example includes LUIS but you can do whatever you want in OnInterruptDialogAsync
protected override async Task<InterruptionAction> OnInterruptDialogAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
var result = InterruptionAction.NoAction;
if (dc.Context.Activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(dc.Context.Activity.Text))
{
// get current activity locale
var localeConfig = _services.GetCognitiveModels();
// check general luis intent
localeConfig.LuisServices.TryGetValue("General", out var luisService);
if (luisService == null)
{
throw new Exception("The specified LUIS Model could not be found in your Skill configuration.");
}
else
{
var luisResult = await luisService.RecognizeAsync<GeneralLuis>(dc.Context, cancellationToken);
var topIntent = luisResult.TopIntent();
if (topIntent.score > 0.5)
{
switch (topIntent.intent)
{
case GeneralLuis.Intent.Cancel:
{
result = await OnCancel(dc);
break;
}
case GeneralLuis.Intent.Help:
{
result = await OnHelp(dc);
break;
}
case GeneralLuis.Intent.Logout:
{
result = await OnLogout(dc);
break;
}
}
}
}
}
return result;
}

How to define different context menus for different objects in autodesk forge

I want to define different context menus for different objects in forge viewer,this is my code
viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT,function(e){
if(viewer.getSelection().length==0){return;}
var selectId=viewer.getSelection()[0];
viewer.search("Cabinet",function(ids){
if(ids.indexOf(selectId)!=-1){
viewer.registerContextMenuCallback('CabinetMsg', function (menu, status) {
if (status.hasSelected) {
menu.push({
title: "CabinetMsg",
target: function () {
openLayer('CabinetMsg','954','775','CabinetMsg.html')
}
});
}
});
}else{
viewer.registerContextMenuCallback('CabinetMsg', function (menu, status) {
if (status.hasSelected) {
menu.forEach(function(el,index){
if(el.title=="CabinetMsg"){
menu.splice(menu.indexOf(index),1)
}
})
}
});
}
})
});
But push elements to the array is always later than the context menus show. My custom context menu is always show when I select another object. What I can do?
The codes you provided will create 2 new sub items to the context menu. Here is a way for this case, i.e. you have to write your own ViewerObjectContextMenu. In addition, you need do hitTest in ViewerObjectContextMenu.buildMenu to get dbId selected by the mouse right clicking. Here is the example for you:
class MyContextMenu extends Autodesk.Viewing.Extensions.ViewerObjectContextMenu {
constructor( viewer ) {
super( viewer );
}
isCabinet( dbId ) {
// Your logic for determining if selected element is cabinet or not.
return false;
}
buildMenu( event, status ) {
const menu = super.buildMenu( event, status );
const viewport = this.viewer.container.getBoundingClientRect();
const canvasX = event.clientX - viewport.left;
const canvasY = event.clientY - viewport.top;
const result = that.viewer.impl.hitTest(canvasX, canvasY, false);
if( !result || !result.dbId ) return menu;
if( status.hasSelected && this.isCabinet( result.dbId ) ) {
menu.push({
title: 'CabinetMsg',
target: function () {
openLayer( 'CabinetMsg', '954', '775', 'CabinetMsg.html' );
}
});
}
return menu;
}
}
After this, you could write an extension to replace default viewer context menu with your own menu. Here also is the example:
class MyContextMenuExtension extends Autodesk.Viewing.Extension {
constructor( viewer, options ) {
super( viewer, options );
}
load() {
this.viewer.setContextMenu( new MyContextMenu( this.viewer ) );
return true;
}
unload() {
this.viewer.setContextMenu( new Autodesk.Viewing.Extensions.ViewerObjectContextMenu( this.viewer ) );
return true;
}
}
Hope this help.

Using Close Command in Method

I am trying to fire a command to close my page after finalizing the execution of a method. However, the Close() command is not working.
According to the code below, how do I close my view after finishing the method execution?
My Model:
public IMvxCommand BtnSaveCommand
{
get
{
return new MvxAsyncCommand(updateOrder);
}
}
private async Task<bool> updateOrder()
{
var errors = validator.Validate(this);
if (!errors.IsValid)
{
messageService.showMessage(errors);
return false;
}
var responseEdit = await orderService.update(configureOrder());
if (responseEdit == null)
{
messageService.showMessage("Pedido " + Item.id + " foi editado com sucesso.");
configureUpdateItem();
//Close View
Close(this);
}
else
{
messageService.showMessage((IErrorCollection)responseEdit);
}
return true;
}
--Update
Adding more information, when triggered the Close(this) command I get the following error:
Mvx: Warning: 325,38 Do not know how to close this viewmodel - topmost view does not present this viewmodel
You need to call DismissViewController() on the NavigationController

Resources