Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / interface_v3 / action_handler_misc.cpp
blob4c4b9e81461bae04bddc0e2d1489d14459477384
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2015 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
22 #include "action_handler_misc.h"
23 #include "interface_manager.h"
24 #include "nel/gui/ctrl_button.h"
25 #include "nel/gui/group_container.h"
26 #include "nel/gui/group_editbox.h"
27 #include "people_interraction.h"
28 #include "nel/misc/algo.h"
29 #include "nel/gui/interface_expr.h"
30 #include "nel/gui/interface_link.h"
31 #include "../client_chat_manager.h"
32 #include "../motion/user_controls.h"
33 #include "../entity_cl.h"
34 #include "../client_cfg.h"
35 #include "../fog_map.h"
36 #include "../sky_render.h"
37 #include "../continent_manager.h"
38 #include "../main_loop.h"
39 #include "../misc.h"
41 using namespace std;
42 using namespace NLMISC;
43 using namespace NL3D;
45 ////////////
46 // EXTERN //
47 ////////////
49 extern CClientChatManager ChatMngr;
50 extern UScene *SceneRoot;
51 extern UScene *SkyScene;
52 extern UScene *Scene;
53 extern CFogState MainFogState;
54 extern CFogState RootFogState;
55 extern CLightCycleManager LightCycleManager;
56 extern UCamera MainCam;
57 extern CContinentManager ContinentMngr;
58 extern NLMISC::CLog g_log;
60 ////////////
61 // static //
62 ////////////
63 //static CCDBNodeLeaf *MenuColorWidgetValue = NULL; // db entry for the color menu widget (Red)
65 void preRenderNewSky ();
67 // ***************************************************************************
68 class CAHCommand : public IActionHandler
70 public:
72 virtual void execute (CCtrlBase * /* pCaller */, const string &Params)
74 ICommand::execute(Params, g_log);
77 REGISTER_ACTION_HANDLER (CAHCommand, "command");
79 // ***************************************************************************
80 // ***************************************************************************
81 // class CActionHandlerShowOne
82 // ***************************************************************************
83 // ***************************************************************************
86 // ***************************************************************************
87 REGISTER_ACTION_HANDLER (CActionHandlerShowOne, "show_one");
89 // ***************************************************************************
90 void CActionHandlerShowOne::execute (CCtrlBase * /* pCaller */, const std::string &params)
92 CInterfaceManager *mngr= CInterfaceManager::getInstance();
93 string wndListValue= getParam(params, "list");
94 string wndShow= getParam(params, "show");
96 // get the list
97 vector<string> wndList;
98 splitString(wndListValue, ",", wndList);
100 // hide all window from the list.
101 for(uint i=0;i<wndList.size();i++)
103 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(wndList[i]);
104 if(wnd)
105 wnd->setActive(false);
108 // show the one needed
109 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(wndShow);
110 if(wnd)
111 wnd->setActive(true);
115 // ***************************************************************************
116 REGISTER_ACTION_HANDLER (CActionHandlerActive, "set_active");
117 // ***************************************************************************
118 void CActionHandlerActive::execute (CCtrlBase * /* pCaller */, const std::string &params)
120 std::string active = getParam(params, "active");
121 std::string target = getParam(params, "target");
122 CInterfaceExprValue activeValue;
123 if (CInterfaceExpr::eval(active, activeValue, NULL))
125 if (!activeValue.toBool())
127 nlwarning("<CActionHandlerActive::execute> The 'active' param must be convertible to a boolean");
128 return;
130 CInterfaceManager *mngr = CInterfaceManager::getInstance();
131 CInterfaceElement *wnd = CWidgetManager::getInstance()->getElementFromId(target);
132 if(!wnd)
134 nlwarning("<CActionHandlerActive::execute> Can't get window %s", target.c_str());
135 return;
137 wnd->setActive(activeValue.getBool());
139 else
141 nlwarning("<CActionHandlerActive::execute> can't parse the 'active' param");
142 return;
146 // ***************************************************************************
147 REGISTER_ACTION_HANDLER (CActionHandlerSetOpen, "set_open");
148 // ***************************************************************************
149 void CActionHandlerSetOpen::execute (CCtrlBase * /* pCaller */, const std::string &params)
151 std::string open = getParam(params, "open");
152 std::string target = getParam(params, "target");
153 CInterfaceExprValue activeValue;
154 if (CInterfaceExpr::eval(open, activeValue, NULL))
156 if (!activeValue.toBool())
158 nlwarning("<CActionHandlerActive::execute> The 'active' param must be co,vertible to a boolean");
159 return;
161 CInterfaceManager *mngr = CInterfaceManager::getInstance();
162 CGroupContainer *wnd = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId(target));
163 if(!wnd)
165 nlwarning("<CActionHandlerActive::execute> Can't get window %s", target.c_str());
166 return;
168 wnd->setOpen(activeValue.getBool());
170 else
172 nlwarning("<CActionHandlerActive::execute> can't parse the 'active' param");
173 return;
177 // ***************************************************************************
178 // ***************************************************************************
179 // CActionHandlerHideClose
180 // ***************************************************************************
181 // ***************************************************************************
183 // ***************************************************************************
184 REGISTER_ACTION_HANDLER (CActionHandlerHideClose, "hide_close");
186 // ***************************************************************************
187 void CActionHandlerHideClose::execute (CCtrlBase * /* pCaller */, const std::string &params)
189 CInterfaceManager *mngr= CInterfaceManager::getInstance();
190 string hideValue= getParam(params, "hide");
191 string closeValue= getParam(params, "close");
193 // get the list
194 vector<string> hideList;
195 splitString(hideValue, ",", hideList);
196 vector<string> closeList;
197 splitString(closeValue, ",", closeList);
199 // hide all window from the hide list.
200 uint i;
201 for(i=0;i<hideList.size();i++)
203 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(hideList[i]);
204 if(wnd)
205 wnd->setActive(false);
208 // close all containers from the hide list.
209 for(i=0;i<closeList.size();i++)
211 // get a container if possible
212 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(closeList[i]);
213 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(wnd);
214 if(pIC)
215 pIC->close();
221 // ***************************************************************************
222 // ***************************************************************************
223 // Misc
224 // ***************************************************************************
225 // ***************************************************************************
228 // ***************************************************************************
229 REGISTER_ACTION_HANDLER (CActionHandlerEnterModal, "enter_modal");
230 REGISTER_ACTION_HANDLER (CActionHandlerPushModal, "push_modal");
231 REGISTER_ACTION_HANDLER (CActionHandlerLeaveModal, "leave_modal");
233 // ***************************************************************************
234 void CActionHandlerEnterModal::execute(CCtrlBase *pCaller, const std::string &params)
236 CInterfaceManager *pIM= CInterfaceManager::getInstance();
238 // get the group from param
239 string groupName= getParam(params, "group");
240 CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(groupName) );
241 if(group)
243 UserControls.stopFreeLook();
245 // enable the modal
246 CWidgetManager::getInstance()->enableModalWindow(pCaller, group);
248 else
250 nlwarning("<CActionHandlerEnterModal::execute> Couldn't find group %s", groupName.c_str());
254 // ***************************************************************************
255 void CActionHandlerPushModal::execute(CCtrlBase *pCaller, const std::string &params)
257 CInterfaceManager *mngr= CInterfaceManager::getInstance();
259 // get the group from param
260 string groupName= getParam(params, "group");
261 CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(groupName) );
262 if(group)
264 // enable the modal
265 CWidgetManager::getInstance()->pushModalWindow(pCaller, group);
267 else
269 nlwarning("<CActionHandlerPushModal::execute> Couldn't find group %s", groupName.c_str());
274 // ***************************************************************************
275 void CActionHandlerLeaveModal::execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
277 CInterfaceManager *mngr= CInterfaceManager::getInstance();
279 // quit the modal
280 CWidgetManager::getInstance()->popModalWindow();
284 // ***************************************************************************
285 // proc
286 // ***************************************************************************
287 class CActionHandlerProc : public IActionHandler
289 public:
290 virtual void execute (CCtrlBase *pCaller, const std::string &params)
292 // split the parameters
293 vector<string> paramList;
294 splitString(params, "|", paramList);
295 if(paramList.empty())
296 return;
298 // execute the procedure
299 CWidgetManager::getInstance()->runProcedure(paramList[0], pCaller, paramList);
302 REGISTER_ACTION_HANDLER (CActionHandlerProc, "proc");
305 /** Confirm that a group container can be deactivated
307 class CActionHandlerConfirmCanDeactivate : public IActionHandler
309 public:
310 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* params */)
312 CGroupContainer::validateCanDeactivate(true);
315 REGISTER_ACTION_HANDLER (CActionHandlerConfirmCanDeactivate, "confirm_can_deactivate");
317 /** Cancel a group container deactivation
319 class CActionHandlerCancelCanDeactivate : public IActionHandler
321 public:
322 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* params */)
324 CGroupContainer::validateCanDeactivate(false);
327 REGISTER_ACTION_HANDLER (CActionHandlerCancelCanDeactivate, "cancel_can_deactivate");
333 // ***************************************************************************
334 // ***************************************************************************
335 // EditBox
336 // ***************************************************************************
337 // ***************************************************************************
340 // ***************************************************************************
341 class CActionHandlerEditBoxNumber : public IActionHandler
343 public:
344 virtual void execute (CCtrlBase *pCaller, const std::string &params)
346 CGroupEditBox *pEditBox= dynamic_cast<CGroupEditBox*>(pCaller);
347 if(!pEditBox)
348 return;
352 // get the dblink dest
353 string dblink= getParam(params, "value");
354 if(dblink.empty())
355 return;
357 // get the value
358 sint64 val= pEditBox->getInputStringAsInt64();
360 string valueStr;
361 // see if a max value has been set
362 valueStr = getParam(params, "max_value");
363 if (!valueStr.empty())
365 CInterfaceExprValue maxValue;
366 if (!CInterfaceExpr::eval(valueStr, maxValue) || !maxValue.toInteger())
368 nlwarning("<CActionHandlerEditBoxNumber::execute> Can't eval maxValue, or can't convert to integer : %s", valueStr.c_str());
369 return;
371 val = std::min(maxValue.getInteger(), val);
373 // see if a min value has been set
374 valueStr = getParam(params, "min_value");
375 if (!valueStr.empty())
377 CInterfaceExprValue minValue;
378 if (!CInterfaceExpr::eval(valueStr, minValue) || !minValue.toInteger())
380 nlwarning("<CActionHandlerEditBoxNumber::execute> Can't eval minValue, or can't convert to integer : %s", valueStr.c_str());
381 return;
383 val = std::max(minValue.getInteger(), val);
385 // set in the database
386 CInterfaceProperty prop;
387 prop.link(dblink.c_str());
388 prop.setSInt64(val);
389 string updateText = getParam(params, "update_text");
390 bool mustUpdate = updateText.empty() ? true : CInterfaceElement::convertBool(updateText.c_str());
392 if (mustUpdate)
394 // replace the editbox string
395 pEditBox->setInputStringAsInt64(val);
396 pEditBox->setSelectionAll();
400 REGISTER_ACTION_HANDLER (CActionHandlerEditBoxNumber, "editbox_number");
402 // ***************************************************************************
403 // Dynamic creation of interface links
404 // ***************************************************************************
405 /** Add a link to an interface element
407 class CActionHandlerAddLink : public IActionHandler
409 virtual void execute (CCtrlBase *pCaller, const std::string &params)
411 std::string expr = getParam(params, "expr");
412 std::string targets = getParam(params, "target");
413 std::string id = getParam(params, "id");
414 std::string ah = getParam(params, "action");
415 std::string ahparam = getParam(params, "params");
416 std::string ahcond = getParam(params, "cond");
417 if (id.empty())
419 nlwarning("<CActionHandlerAddLink> Must specify a link's id");
420 return;
422 CInterfaceGroup *parentGroup = dynamic_cast<CInterfaceGroup *>(pCaller);
423 if (!parentGroup)
425 if (pCaller) parentGroup = pCaller->getParent();
428 std::vector<CInterfaceLink::CTargetInfo> targetsVect;
429 std::vector<CInterfaceLink::CCDBTargetInfo> cdbTargetsVect;
430 bool result = CInterfaceLink::splitLinkTargetsExt(targets, parentGroup, targetsVect, cdbTargetsVect);
431 if (!result)
433 nlwarning("<CActionHandlerAddLink> Couldn't parse all links");
435 // add the link
436 CInterfaceLink *il = new CInterfaceLink;
437 il->init(targetsVect, cdbTargetsVect, expr, ah, ahparam, ahcond, parentGroup);
438 CInterfaceManager *im = CInterfaceManager::getInstance();
439 CWidgetManager::getInstance()->getParser()->addLink(il, id);
440 il->update();
443 REGISTER_ACTION_HANDLER (CActionHandlerAddLink, "add_link");
445 /** Remove a link from an interface element
447 class CActionHandlerRemoveLink : public IActionHandler
449 virtual void execute (CCtrlBase * /* pCaller */, const std::string &params)
451 std::string id = getParam(params, "id");
452 if (id.empty())
454 nlwarning("<CActionHandlerRemoveLink> Must specify a link's id");
455 return;
457 CInterfaceManager *im = CInterfaceManager::getInstance();
458 CWidgetManager::getInstance()->getParser()->removeLink(id);
461 REGISTER_ACTION_HANDLER (CActionHandlerRemoveLink, "remove_link");
463 // ***************************************************************************
464 REGISTER_ACTION_HANDLER (CActionHandlerEvalExpr, "eval_expr");
465 // ***************************************************************************
466 void CActionHandlerEvalExpr::execute(CCtrlBase * /* pCaller */, const std::string &params)
468 std::string expr = getParam(params, "expr");
469 if (expr.empty())
471 nlwarning("<CActionHandlerEvalExpr::execute> 'expr' parameter not found or empty.");
472 return;
474 CInterfaceExprValue dummyResult; // result not used
475 if (!CInterfaceExpr::eval(expr, dummyResult))
477 nlwarning("<CActionHandlerEvalExpr::execute> Couldn't eval expression");
479 return;
482 // ***************************************************************************
483 CInterfaceGroup *createMenuColorWidget(const string &colDbEntry,
484 const string &toolTipTextID,
485 const string &ccdTitle)
487 CInterfaceManager *im = CInterfaceManager::getInstance();
488 pair<string, string> params[3] =
490 make_pair(string("col_db_entry"), colDbEntry),
491 make_pair(string("tooltip"), toolTipTextID),
492 make_pair(string("ccd_title"), ccdTitle),
494 return CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_color_widget", "", params, 3);
497 // ***************************************************************************
498 struct CCameraBackup
500 CViewport Viewport;
501 CFrustum Frustum;
505 // *********************************************************
506 CCameraBackup setupCameraForScreenshot(UScene &scene, uint left, uint right, uint top, uint bottom, uint screenShotWidth, uint screenShotHeight)
508 CCameraBackup cb;
509 cb.Frustum = scene.getCam().getFrustum();
510 cb.Viewport = scene.getViewport();
511 // Build a frustum
512 CFrustum frustumPart;
513 frustumPart.Left = cb.Frustum.Left+(cb.Frustum.Right-cb.Frustum.Left)*((float)left/(float)screenShotWidth);
514 frustumPart.Right = cb.Frustum.Left+(cb.Frustum.Right-cb.Frustum.Left)*((float)right/(float)screenShotWidth);
515 frustumPart.Top = cb.Frustum.Top+(cb.Frustum.Bottom-cb.Frustum.Top)*((float)top/(float)screenShotHeight);
516 frustumPart.Bottom = cb.Frustum.Top+(cb.Frustum.Bottom-cb.Frustum.Top)*((float)bottom/(float)screenShotHeight);
517 frustumPart.Near = cb.Frustum.Near;
518 frustumPart.Far = cb.Frustum.Far;
519 frustumPart.Perspective = cb.Frustum.Perspective;
521 // Build a viewport
522 CViewport viewport;
523 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
524 viewport.init (0, 0, (float)(right-left)/Driver->getWindowWidth(), (float)(bottom-top)/Driver->getWindowHeight());
526 // Activate all this
527 scene.getCam().setFrustum (frustumPart);
528 scene.setViewport (viewport);
530 return cb;
534 // *********************************************************
535 static void restoreCamera(UScene &scene, const CCameraBackup &backup)
537 scene.getCam().setFrustum (backup.Frustum);
538 scene.setViewport(backup.Viewport);
541 // ***************************************************************************
542 void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint screenShotWidth, uint screenShotHeight)
544 CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight);
545 CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight);
546 commitCamera();
547 // sky setup are copied from main scene before rendering so no setup done here
548 renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom);
549 restoreCamera(*Scene, cbScene);
550 restoreCamera(*SceneRoot, cbCanopy);
551 commitCamera();
554 // ***************************************************************************
556 void getBuffer (CBitmap &btm)
558 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
560 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
562 // Destination image
563 CBitmap temp;
564 btm.resize (ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight, CBitmap::RGBA);
566 uint top;
567 uint bottom = std::min (Driver->getWindowHeight (), ClientCfg.ScreenShotHeight);
568 for (top=0; top<ClientCfg.ScreenShotHeight; top+=Driver->getWindowHeight ())
570 uint left;
571 uint right = std::min (Driver->getWindowWidth (), ClientCfg.ScreenShotWidth);
572 for (left=0; left<ClientCfg.ScreenShotWidth; left+=Driver->getWindowWidth ())
574 Driver->clearBuffers (CRGBA::Black);
575 renderSceneScreenShot (left, right, top, bottom, ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
576 // Get the bitmap
577 Driver->getBuffer (temp);
578 Driver->swapBuffers ();
579 btm.blit (temp, 0, Driver->getWindowHeight ()-(bottom-top), right-left, bottom-top, left, top);
581 // Next
582 right = std::min (right+Driver->getWindowWidth (), ClientCfg.ScreenShotWidth);
585 // Next
586 bottom = std::min (bottom+Driver->getWindowHeight (), ClientCfg.ScreenShotHeight);
589 else
591 Driver->getBuffer(btm);
595 void displayScreenShotSavedInfo(const string &filename)
597 CInterfaceManager *pIM = CInterfaceManager::getInstance();
598 string msg = "'" + filename + "' " + CI18N::get("uiScreenshotSaved");
599 pIM->displaySystemInfo(msg);
602 bool screenshotZBuffer(const std::string &filename)
604 std::string::size_type pos = filename.find(".");
606 if (pos == std::string::npos)
607 return false;
609 std::string filename_z = filename.substr(0, pos) + "_z" + filename.substr(pos);
610 std::string ext = filename.substr(pos+1);
612 std::vector<float> z;
613 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
615 Driver->getZBuffer(z);
617 float min = std::numeric_limits<float>::max();
618 float max = std::numeric_limits<float>::min();
620 // get min and max values
621 for(uint i = 0; i < z.size(); ++i)
623 float value = z[i];
624 if (value > max)
626 max = value;
628 else if (value < min)
630 min = value;
634 max = max - min;
636 CBitmap zi;
637 zi.resize(Driver->getWindowWidth(), Driver->getWindowHeight());
638 CRGBA *dest = (CRGBA *) &zi.getPixels()[0];
640 for(uint k = 0; k < z.size(); ++k)
642 // normalize values
643 uint8 i = (uint8) ((z[k] - min) * 255.f / max);
644 dest->set(i, i, i, i);
645 ++ dest;
650 COFile f;
651 f.open(filename_z);
652 if (ext == "png")
653 zi.writePNG(f, 32);
654 else
655 zi.writeTGA(f, 32);
657 catch(...)
659 return false;
662 return true;
665 static std::string findNewScreenShotFileName(std::string filename)
667 // make screenshot directory if it does not exist
668 if (!CFile::isExists(ClientCfg.ScreenShotDirectory))
669 CFile::createDirectory(ClientCfg.ScreenShotDirectory);
671 filename = CPath::standardizePath(ClientCfg.ScreenShotDirectory) + filename;
672 static char cstime[25];
673 time_t dtime;
674 time(&dtime);
675 struct tm *tms = localtime(&dtime);
676 if (tms)
678 strftime(cstime, 25, "%Y-%m-%d", tms);
680 std::string::size_type pos = filename.find_last_of('.');
682 // fallback if no extension is given
683 if (pos == std::string::npos)
684 filename = filename + "_" + cstime + "_";
685 else
686 filename = filename.substr(0, pos) + "_" + cstime + "_" + filename.substr(pos);
689 // screenshot_YYYY-MM-DD_000.jpg
690 return CFile::findNewFile(filename);
693 void screenShotTGA()
695 CBitmap btm;
696 getBuffer (btm);
698 string filename = findNewScreenShotFileName("screenshot.tga");
699 COFile fs(filename);
701 if (!btm.writeTGA(fs, 24, false))
703 fs.close();
704 CFile::deleteFile(filename);
705 return;
708 if (ClientCfg.ScreenShotZBuffer)
709 screenshotZBuffer(filename);
711 nlinfo("Screenshot '%s' saved in tga format (%ux%u)", filename.c_str(), ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
712 displayScreenShotSavedInfo(filename);
715 void screenShotPNG()
717 CBitmap btm;
718 getBuffer (btm);
720 string filename = findNewScreenShotFileName("screenshot.png");
721 COFile fs(filename);
723 if (!btm.writePNG(fs, 24))
725 fs.close();
726 CFile::deleteFile(filename);
727 return;
730 if (ClientCfg.ScreenShotZBuffer)
731 screenshotZBuffer(filename);
733 nlinfo("Screenshot '%s' saved in png format (%ux%u)", filename.c_str(), ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
734 displayScreenShotSavedInfo(filename);
737 void screenShotJPG()
739 CBitmap btm;
740 getBuffer (btm);
742 string filename = findNewScreenShotFileName("screenshot.jpg");
743 COFile fs(filename);
745 if (!btm.writeJPG(fs))
747 fs.close();
748 CFile::deleteFile(filename);
749 return;
752 if (ClientCfg.ScreenShotZBuffer)
753 screenshotZBuffer(filename);
755 nlinfo("Screenshot '%s' saved in jpg format (%ux%u)", filename.c_str(), ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
756 displayScreenShotSavedInfo(filename);
759 // ***************************************************************************
761 class CAHScreenShot : public IActionHandler
763 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
765 // if custom screenshot size is asked, then do it right now
766 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
768 // Custom screen shot ?
769 screenShotTGA();
771 else
773 // post screenshot request
774 ScreenshotRequest = ScreenshotRequestTGA;
779 // ***************************************************************************
780 REGISTER_ACTION_HANDLER (CAHScreenShot, "screen_shot");
782 // ***************************************************************************
783 class CAHScreenShotJPG : public IActionHandler
785 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
787 // if custom screenshot size is asked, then do it right now
788 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
790 screenShotJPG();
792 else
794 // post screenshot request
795 ScreenshotRequest = ScreenshotRequestJPG;
799 // ***************************************************************************
800 REGISTER_ACTION_HANDLER (CAHScreenShotJPG, "screen_shot_jpg");
802 // ***************************************************************************
803 class CAHScreenShotPNG : public IActionHandler
805 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
807 // if custom screenshot size is asked, then do it right now
808 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
810 screenShotPNG();
812 else
814 // post screenshot request
815 ScreenshotRequest = ScreenshotRequestPNG;
819 // ***************************************************************************
820 REGISTER_ACTION_HANDLER (CAHScreenShotPNG, "screen_shot_png");
823 // ***************************************************************************
824 // Reply to the last people who talked in the chat -> this change the target of the main chat to the name of the last teller
825 class CAHReplyTeller : public IActionHandler
827 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
829 if (!PeopleInterraction.LastSenderName.empty())
831 CChatWindow *w = PeopleInterraction.ChatGroup.Window;
832 if (w)
834 w->setKeyboardFocus();
835 w->enableBlink(1);
836 PeopleInterraction.ChatGroup.Filter.setTargetPlayer(CEntityCL::removeTitleAndShardFromName(PeopleInterraction.LastSenderName));
837 CGroupEditBox *eb = w->getEditBox();
838 if (eb != NULL)
840 eb->bypassNextKey();
847 REGISTER_ACTION_HANDLER (CAHReplyTeller, "reply_teller")
849 // ***************************************************************************
850 // Reply to the last people who talked in the chat only once (display '/tell name' in the last activated chat window)
851 class CAHReplyTellerOnce : public IActionHandler
853 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
855 // display a /tell command in the main chat
856 if (!PeopleInterraction.LastSenderName.empty())
858 CChatWindow *w = PeopleInterraction.ChatGroup.Window;
859 if (w)
861 w->setKeyboardFocus();
862 w->enableBlink(1);
863 w->setCommand("tell " + CEntityCL::removeTitleAndShardFromName(PeopleInterraction.LastSenderName) + " ", false);
864 CGroupEditBox *eb = w->getEditBox();
865 if (eb != NULL)
867 eb->bypassNextKey();
873 REGISTER_ACTION_HANDLER (CAHReplyTellerOnce, "reply_teller_once")
875 // ***************************************************************************
876 /** Cycle through the last people on which a 'tell' has been done.
877 * Focus must be in a window with a target (main chat or user chat), otherwise the main chat is used
879 class CAHCycleTell : public IActionHandler
881 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
883 CInterfaceManager *im = CInterfaceManager::getInstance();
884 if (!im->isInGame()) return;
885 const string *lastTellPeople = ChatMngr.cycleLastTell();
886 if (!lastTellPeople) return;
887 // just popup the main chat
888 //CChatWindow *w = PeopleInterraction.MainChat.Window;
889 CChatWindow *w = PeopleInterraction.ChatGroup.Window;
890 if (w)
892 w->setKeyboardFocus();
893 w->enableBlink(1);
894 //PeopleInterraction.MainChat.Filter.setTargetPlayer(*lastTellPeople);
895 PeopleInterraction.ChatGroup.Filter.setTargetPlayer(*lastTellPeople);
899 REGISTER_ACTION_HANDLER (CAHCycleTell, "cycle_tell")
904 // temp for test : set last sender name
905 NLMISC_COMMAND(slsn, "Temp : set the name of the last sender.", "<name>")
907 if (args.size() != 1) return false;
908 PeopleInterraction.LastSenderName = args[0];
909 return true;
912 // ***************************************************************************
913 bool CStringPostProcessRemoveName::cbIDStringReceived(string &inOut)
915 // extract the replacement id
916 string strNewTitle = CEntityCL::getTitleFromName(inOut);
918 // retrieve the translated string
919 if (!strNewTitle.empty())
921 inOut = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(strNewTitle, Woman);
923 // Sometimes translation contains another title
924 string::size_type pos = inOut.find('$');
925 if (pos != string::npos)
927 inOut = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(inOut), Woman);
931 else
932 inOut.clear();
934 return true;
937 // ***************************************************************************
938 bool CStringPostProcessRemoveTitle::cbIDStringReceived(string &inOut)
940 inOut = CEntityCL::removeTitleAndShardFromName(inOut);
941 return true;
944 // ***************************************************************************
945 bool CStringPostProcessNPCRemoveTitle::cbIDStringReceived(string &inOut)
947 string sOut = CEntityCL::removeTitleAndShardFromName(inOut);
948 if (sOut.empty())
950 CStringPostProcessRemoveName SPPRM;
951 SPPRM.cbIDStringReceived(inOut);
953 else
955 inOut = sOut;
957 return true;
962 // ***************************************************************************
963 class CAHAnimStart : public IActionHandler
965 public:
966 virtual void execute (CCtrlBase * /* pCaller */, const std::string &Params)
968 string sAnim = getParam(Params, "anim");
969 CWidgetManager::getInstance()->startAnim(sAnim);
972 REGISTER_ACTION_HANDLER (CAHAnimStart, "anim_start");
974 // ***************************************************************************
975 class CAHAnimStop : public IActionHandler
977 public:
978 virtual void execute (CCtrlBase * /* pCaller */, const std::string &Params)
980 string sAnim = getParam(Params, "anim");
981 CWidgetManager::getInstance()->stopAnim(sAnim);
984 REGISTER_ACTION_HANDLER (CAHAnimStop, "anim_stop");