Ticket #515: trippleclick.patch

File trippleclick.patch, 6.5 KB (added by Christoph Seipel, 14 years ago)

implements double and triple-click selection. Updated, after a used function has changed.

  • trunk/binaries/data/mods/public/gui/session_new/input.js

     
    2424var placementPosition;
    2525var placementEntity;
    2626
     27//Time in milliseconds in which a double click is recognized
     28var doubleclickTime = 500;
     29var doubleclickTimer = 0;
     30var doubleclicked = false;
     31
    2732var mouseX = 0;
    2833var mouseY = 0;
    2934var specialKeyStates = {};
     
    478483        case "mousebuttonup":
    479484            if (ev.button == SDL_BUTTON_LEFT)
    480485            {
    481                 var ents = Engine.PickEntitiesAtPoint(ev.x, ev.y);
    482                 if (!ents.length)
     486                //is this a double-click?
     487                var now = new Date();
     488                if (now.getTime()-doubleclickTimer < doubleclickTime)
    483489                {
    484                     g_Selection.reset();
     490                    var onScreenOnly;
     491
     492                    if (!doubleclicked)
     493                    {
     494                        //this is a double click
     495                        onScreenOnly = true;
     496                                                               
     497                        //set doubleclicked, maybe this is going to be a trippleclick
     498                        doubleclicked = true;
     499                    }
     500                    else
     501                    {
     502                        //this is a trippleclick
     503                        onScreenOnly = false;
     504                       
     505                    }
    485506                   
    486                     inputState = INPUT_NORMAL;
    487                     return true;
     507                    var ents = Engine.PickSimilarEntities(ev.x, ev.y, Engine.GetPlayerID(), onScreenOnly);
     508                                       
     509                    // Remove units if selection is too large
     510                    if (ents.length > MAX_SELECTION_SIZE)
     511                            ents = ents.slice(0, MAX_SELECTION_SIZE);
     512   
     513                        // Set selection list
     514                        g_Selection.setHighlightList([]);
     515                        g_Selection.reset();
     516                        g_Selection.addList(ents);
     517   
     518                        // Create the selection groups
     519                        g_Selection.groups.createGroups(ents);
     520                       
     521                   
     522
    488523                }
     524                else
     525                {
     526                    //this is a single click, but it could become double
     527                    doubleclickTimer = now.getTime();
     528                    doubleclicked = false;
     529                   
     530                    var ents = Engine.PickEntitiesAtPoint(ev.x, ev.y);
     531                    if (!ents.length)
     532                    {
     533                        g_Selection.reset();
     534                   
     535                        inputState = INPUT_NORMAL;
     536                        return true;
     537                    }
    489538
    490                 g_Selection.reset();
    491                 g_Selection.addList([ents[0]]);
     539                    g_Selection.reset();
     540                    g_Selection.addList([ents[0]]);
     541                   
     542                }
     543           
    492544
    493545                inputState = INPUT_NORMAL;
    494546                return true;
  • trunk/source/simulation2/helpers/Selection.h

     
    4646 */
    4747std::vector<entity_id_t> PickEntitiesInRect(CSimulation2& simulation, CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner);
    4848
     49/**
     50 * Finds a selectable entity under the given screen coordinate
     51 * and returns all units with the same visualActors short name,
     52 * when onScreenOnly is set, only Units on screen are returned.
     53 */
     54std::vector<entity_id_t> PickSimilarEntities(CSimulation2& simulation, CCamera& camera, int screenX, int screenY, int owner, bool onScreenOnly);
    4955} // namespace
    5056
    5157#endif // INCLUDED_SELECTION
  • trunk/source/simulation2/helpers/Selection.cpp

     
    117117
    118118    return hitEnts;
    119119}
     120
     121std::vector<entity_id_t> EntitySelection::PickSimilarEntities(CSimulation2& simulation, CCamera& camera, int screenX, int screenY, int owner, bool onScreenOnly)
     122{
     123    std::wstring entVisualActor(L"");
     124    std::vector<entity_id_t> hitEnts;
     125
     126    // Determine a reference unit beneath the cursor
     127    std::vector<entity_id_t> entities = EntitySelection::PickEntitiesAtPoint(simulation,camera,screenX,screenY);
     128    if (entities.size() > 0) {
     129        entity_id_t referenceEntity;
     130        referenceEntity = entities[0];
     131        CmpPtr<ICmpVisual> cmpVisual(simulation.GetSimContext(), referenceEntity);
     132        entVisualActor = cmpVisual->GetActorShortName();
     133    }
     134
     135    const CSimulation2::InterfaceList& ents = simulation.GetEntitiesWithInterface(IID_Selectable);
     136    for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
     137    {
     138        entity_id_t ent = it->first;
     139
     140        // Ignore entities not owned by 'owner'
     141        CmpPtr<ICmpOwnership> cmpOwnership(simulation.GetSimContext(), ent);
     142        if (cmpOwnership.null() || cmpOwnership->GetOwner() != owner)
     143            continue;
     144
     145        // Find the current interpolated model position.
     146        // (We just use the centre position and not the whole bounding box, because maybe
     147        // that's better for users trying to select objects in busy areas)
     148
     149        CmpPtr<ICmpVisual> cmpVisual(simulation.GetSimContext(), ent);
     150        if (cmpVisual.null())
     151            continue;
     152
     153        CVector3D position = cmpVisual->GetPosition();
     154
     155        // Reject if it's not on-screen (e.g. it's behind the camera)
     156        if (onScreenOnly && !camera.GetFrustum().IsPointVisible(position))
     157            continue;
     158
     159        // Take all remaining units, whose actor's short name is the same as the reference unit's
     160        if(cmpVisual->GetActorShortName() == entVisualActor) {
     161            hitEnts.push_back(ent);
     162        }
     163    }
     164
     165    return hitEnts;
     166}
  • trunk/source/gui/scripting/ScriptFunctions.cpp

     
    126126    return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player);
    127127}
    128128
     129std::vector<entity_id_t> PickSimilarEntities(void* UNUSED(cbdata), int x, int y, int player, bool onScreenOnly)
     130{
     131    return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, player, onScreenOnly);
     132}
     133
     134
    129135CFixedVector3D GetTerrainAtPoint(void* UNUSED(cbdata), int x, int y)
    130136{
    131137    CVector3D pos = g_Game->GetView()->GetCamera()->GetWorldCoordinates(x, y, true);
     
    309315    // Entity picking
    310316    scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, &PickEntitiesAtPoint>("PickEntitiesAtPoint");
    311317    scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, int, int, &PickFriendlyEntitiesInRect>("PickFriendlyEntitiesInRect");
     318    scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, bool, &PickSimilarEntities>("PickSimilarEntities");
    312319    scriptInterface.RegisterFunction<CFixedVector3D, int, int, &GetTerrainAtPoint>("GetTerrainAtPoint");
    313320
    314321    // Network / game setup functions