int main() { int T,m,i,j,d,min=INT_MAX; int dp[2][5]; scanf("%d",&T); while(T--) { scanf("%d",&m); for(i=0;i<=4;i++) dp[0][i] = INT_MAX; dp[1][4] = INT_MAX; dp[1][0] = INT_MAX; for(i=1;i<=m;i++) for(j=1;j<=3;j++) { scanf("%d",&d); dp[i%2][j] = d + ((i==1)?0:minV(dp[(i+1)%2][j-1],dp[(i+1)%2][j+1])); } for(j=1;j<=3;j++) if(dp[m%2][j]<min) min = dp[m%2][j]; printf("%d\n",min); min = INT_MAX; } return 0; }
int maximumGap(vector<int> &num) { int n = num.size(); if( n < 2 ) return 0; if( n == 2 ) return abs( num[0] - num[1] ); int Min = *min_element( num.begin() , num.end() ); int Max = *max_element( num.begin() , num.end() ); double d = double( Max - Min ) / ( n - 1 ); vector< int > maxV( n - 1 , -1 ); vector< int > minV( n - 1 , -1 ); for( int x : num ) { int hop = ( x == Max ? n-2 : double( x - Min ) / d ); maxV[hop] = max( maxV[hop] , x ); if( minV[hop] == -1 || minV[hop] > x ) minV[hop] = x; } n--; int i = 0, ret = 0; while( i < n && minV[i] == -1 ) i++; while( i < n ) { int j = i+1; while( j < n && minV[j] == -1 ) j++; if( j == n ) break; ret = max( ret , minV[j] - maxV[i] ); i = j; } return ret; }
/// Writes the contents of \p buffer of \p size into the stream. ostringstream& ostringstream::write (const void* buffer, size_type sz) { const char* buf = (const char*) buffer; for (size_type bw = 0; (bw = minV(sz, remaining() ? remaining() : overflow(sz))); buf += bw, sz -= bw) ostream::write (buf, bw); return (*this); }
Helper::AABB3f Geometry::CreateAABB() const { const Helper::AABB3f& worldAABB = mModel->GetAABB(); float width = worldAABB.GetWidth(); float height = worldAABB.GetHeight(); std::vector<D3DXVECTOR3> vertices(8); vertices[0] = D3DXVECTOR3(worldAABB.Corners[0].X, worldAABB.Corners[0].Y, worldAABB.Corners[0].Z); vertices[1] = D3DXVECTOR3(worldAABB.Corners[0].X, worldAABB.Corners[0].Y + height, worldAABB.Corners[0].Z); vertices[2] = D3DXVECTOR3(worldAABB.Corners[0].X + width, worldAABB.Corners[0].Y + height, worldAABB.Corners[0].Z); vertices[3] = D3DXVECTOR3(worldAABB.Corners[0].X + width, worldAABB.Corners[0].Y, worldAABB.Corners[0].Z); vertices[4] = D3DXVECTOR3(worldAABB.Corners[0].X, worldAABB.Corners[0].Y, worldAABB.Corners[1].Z); vertices[5] = D3DXVECTOR3(worldAABB.Corners[0].X, worldAABB.Corners[0].Y + height, worldAABB.Corners[1].Z); vertices[6] = D3DXVECTOR3(worldAABB.Corners[0].X + width, worldAABB.Corners[0].Y + height, worldAABB.Corners[1].Z); vertices[7] = D3DXVECTOR3(worldAABB.Corners[0].X + width, worldAABB.Corners[0].Y, worldAABB.Corners[1].Z); D3DXVECTOR3 minV(10e9, 10e9, 10e9); D3DXVECTOR3 maxV = -minV; for (int i = 0; i < vertices.size(); ++i) { D3DXVECTOR4 v(vertices[i], 1.0f); D3DXVec4Transform(&v, &v, &mWorld); minV.x = min(minV.x, v.x); minV.y = min(minV.y, v.y); minV.z = min(minV.z, v.z); maxV.x = max(maxV.x, v.x); maxV.y = max(maxV.y, v.y); maxV.z = max(maxV.z, v.z); } return Helper::AABB3f(Helper::Point3f(minV.x, minV.y, minV.z), Helper::Point3f(maxV.x, maxV.y, maxV.z)); }
GlReplicateAddOn::GlReplicateAddOn() : inherited(SZI[SZI_arp], GL_REPLICATE_KEY, SZ(SZ_Combine), SZ(SZ_Replicate), 1, 0) { GlRelAbs minV(0, 0), maxV(1, 256); // mDepth = AddParamType(new GlFloatParamType(_DEPTH_KEY, "Depth", 0, 1, 0.5, 0.01)); AddParamType(new GlRelAbsParamType(_DEPTH_KEY, SZ(SZ_Depth), minV, maxV, gInit, 0.01f)); }
/// Equivalent to a vsprintf on the string. int ostringstream::vformat (const char* fmt, va_list args) { size_t rv, space; do { space = remaining(); rv = vsnprintf (const_cast<char *>(ipos()), space, fmt, args); if (ssize_t(rv) < 0) rv = space; } while (rv >= space && rv < overflow(rv + 1)); SetPos (pos() + minV (rv, space)); return (int)(rv); }
void ITKImplicit::init(void) { //init from surface //Via dynamic cast we test whether the surface type allows for a transformation //into an ITKImplicit if (!surface) return; //init default image, this can still be overwritten myImage = ImageType::New(); SurfaceMesh * mesh=dynamic_cast<SurfaceMesh*>(surface); if (mesh) { mesh->computeBoundingBox(); gmVector3 maxV(mesh->bbox_max[0], mesh->bbox_max[1], mesh->bbox_max[2]); gmVector3 minV(mesh->bbox_min[0], mesh->bbox_min[1], mesh->bbox_min[2]); initScalingAndOriginFromBoundingBox(minV,maxV); //we have a special surface, a mesh surface initFromSurfaceMesh(mesh); } //surface could be an implicit Implicit * imp=dynamic_cast<Implicit*>(surface); if (imp) { //if we have an implicit we want to check whether the particle bounding box is set. //if so, we adjust the image if (bbox) { //we have a bounding box, so we use it to evaluate the //values. initScalingAndOriginFromBoundingBox(bbox->min, bbox->max); } else { initScalingAndOriginFromBoundingBox(gmVector3(-0.5,-0.5,-0.5), gmVector3(0.5,0.5,0.5)); } initFromImplicit(imp); } originalSpacing = myImage->GetSpacing(); originalOrigin = myImage->GetOrigin(); //we apply eventual transformations //and init the spline interpolator //we refit the particles bounding box applyParameterChanges(); }
void PhysicsManager::addLevelGeometry( Ogre::Entity* levelEntity, const std::vector<OgreNewt::CollisionPtr> &collisions) { RlAssert1(levelEntity); RlAssert1(levelEntity->getParentSceneNode()); SceneNode* node = levelEntity->getParentSceneNode(); //Level entity has to be attached to a scene node. // try one compound collision for the entity if there are several collisions OgreNewt::CollisionPtr collision; switch( collisions.size() ) { case 0: break; case 1: collision = collisions[0]; break; default: collision = OgreNewt::CollisionPtr(new OgreNewt::CollisionPrimitives::CompoundCollision(mWorld, collisions, 0)); break; } if( collision ) { OgreNewt::Body* body = new OgreNewt::Body(mWorld, collision ); body->attachNode(node); body->setPositionOrientation(node->_getDerivedPosition(), node->_getDerivedOrientation()); body->setMaterialGroupID(getMaterialID("level")); mLevelBodiesQuadTree.add(body); //mLevelBodies.push_back(body); } // adjust worldAABB Vector3 minV(mWorldAABB.getMinimum()); Vector3 maxV(mWorldAABB.getMaximum()); AxisAlignedBox entityAABB = levelEntity->getWorldBoundingBox(true); minV.makeFloor(entityAABB.getMinimum()); maxV.makeCeil(entityAABB.getMaximum()); mWorldAABB.setMinimum(minV - Vector3(50, 50, 50)); mWorldAABB.setMaximum(maxV + Vector3(50, 50, 50)); mWorld->setWorldSize(mWorldAABB); }
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { int max = maxV(p, q), min = minV(p, q); if(root == NULL) return NULL; TreeNode* temp = root; while(temp != NULL) { if(temp->val == max || temp->val == min) return temp; if(temp->val > max) { temp = temp->left; } else if(temp->val < min) { temp = temp->right; } else return temp; } }
bool brightRGB::getMin(const image& img,dvector& dest) const{ // image empty? if (img.empty()) { setStatusString("image empty"); dest.resize(0); return false; } const rgbPixel transColor = getParameters().transColor; ivector minV(3,32768-1); //2^15-1 image::const_iterator it = img.begin(); if(getParameters().transparent) { while(it != img.end()) { if(*it != transColor) { if((*it).getRed() < minV.at(0)) minV.at(0) = (*it).getRed(); if((*it).getGreen() < minV.at(1)) minV.at(1) = (*it).getGreen(); if((*it).getBlue() < minV.at(2)) minV.at(2) = (*it).getBlue(); } it++; } // only transparent pixels? if (minV.at(0)==32768-1) { setStatusString("only transparent pixels"); dest.resize(0); return false; } } else { // no transparent color while(it != img.end()) { if((*it).getRed() < minV.at(0)) minV.at(0) = (*it).getRed(); if((*it).getGreen() < minV.at(1)) minV.at(1) = (*it).getGreen(); if((*it).getBlue() < minV.at(2)) minV.at(2) = (*it).getBlue(); it++; } } dest.castFrom(minV); // normalize to 0..1 dest.divide(255); return true; };
// CREATEPLHKPHYSICALFROMMESHEASY // Convenience function for getting from a max node to a plHKPhysical and the requisite // Havok objects. // The node and the scene object don't have to correspond to the same Max object. // If the sAltNode is supplied, the node will be moved into the coordinate system of the bool plMaxMeshExtractor::Extract(plMaxMeshExtractor::NeutralMesh& mesh, plMaxNode* node, bool makeAABB, plMaxNode* sOwningNode) { mesh.fNumVerts = mesh.fNumFaces = 0; mesh.fVerts = nil; mesh.fFaces = nil; // if an alternate node was supplied, get its scene object. otherwise don't... plMaxNode* masterNode = sOwningNode ? sOwningNode : node; mesh.fL2W = masterNode->GetLocalToWorld44(); // // Create the arrays of verts and faces // bool isDummy = (node->EvalWorldState(0).obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0)); if (isDummy) { hsMatrix44 w2l = masterNode->GetWorldToLocal44(); MakeDummyMesh(node, mesh); // Localize the verts //for (int i = 0; i < mesh.fNumVerts; i++) // mesh.fVerts[i] = w2l * mesh.fVerts[i]; } else { // only get the max world-to-local transform if the node is moveable or instanced. otherwise verts stay global. Matrix3 w2l = masterNode->GetWorldToLocal(); // Matrix3 *localizer = nil; // if (masterNode->IsMovable() || masterNode->GetForceLocal() || masterNode->GetInstanced()) // localizer = &w2l; if (!MakeNormalMesh(node, mesh, &w2l)) return false; if (makeAABB) { hsPoint3 minV(FLT_MAX, FLT_MAX, FLT_MAX), maxV(-FLT_MAX, -FLT_MAX, -FLT_MAX); MeshMinMax(minV, maxV, mesh.fNumVerts, mesh.fVerts); MakeBoxMesh(node, mesh, minV, maxV); } } return true; }
/** * Print some informations concerning the object in a std::string and does a cleanup of the * memory. * * @return A std::string. **/ std::string stats() { std::string s; s += "*****************************************************\n"; s += "BitGraphZ2 object statistics\n\n"; s += "- memory used : " + toString(memory()) + "Mb\n"; s += "- lattice represented : [ " + toString(minV()) + " , " + toString(maxV()) + " ]^2\n"; s += "- Main grid size : [ " + toString(-LL) + " , " + toString(LL-1) + " ]^2 (" + toString((4*sizeof(int32)*LL*LL)/(1024*1024)) + "Mb)\n"; s += "- Size of a subsquare : " + toString(N*8) + " x " + toString(N*8) + " (" + toString(sizeof(_MSQ)) + "b each)\n"; s += "- Number of subsquare : " + toString(VV) + " (" + toString(((int64)VV)*sizeof(_MSQ) /(1024*1024)) + "Mb)\n\n"; s += "Number of point set : " + toString(nbSet()) + "\n"; s += "Surrounding square : "; if (minX() != LLONG_MAX) { s += "[ " + toString(minX()) + " , " + toString(maxX()) + " ] x [ " + toString(minY()) + " , " + toString(maxY()) + " ]\n"; } else {s += "No point set yet !\n";} s += "Memory used before cleanup\t" + toString(v) + "/" + toString(VV) + " (" + toString((int)(100*(((double)v)/((double)VV))))+ "%)\n"; cleanup(); s += "Memory used after cleanup\t" + toString(v) + "/" + toString(VV) + " (" + toString((int)(100*(((double)v)/((double)VV))))+ "%)\n"; s += "*****************************************************\n"; return s; }
BoundingBox3D Triangle3D::getBoundingBox() { float minX, minY, minZ; float maxX, maxY, maxZ; minX = minY = minZ = 10000000.0; maxX = maxY = maxZ = -10000000.0; for (int i = 0; i<3; i++) { if (minX > this->v[i].x()) minX = this->v[i].x(); if (minY > this->v[i].y()) minY = this->v[i].y(); if (minZ > this->v[i].z()) minZ = this->v[i].z(); if (maxX < this->v[i].x()) maxX = this->v[i].x(); if (maxY < this->v[i].y()) maxY = this->v[i].y(); if (maxZ < this->v[i].z()) maxZ = this->v[i].z(); } EigenVector3 minV(minX, minY, minZ); EigenVector3 maxV(maxX, maxY, maxZ); return BoundingBox3D(minV, maxV); }
bool BoundingCircle::isInside2D(const BoundingObject2D& bounding_obj) const { switch (bounding_obj.getObjectType()) { case BOX: return ( bounding_obj.minU() <= minU() && bounding_obj.maxU() >= maxU() && bounding_obj.minV() <= minV() && bounding_obj.maxV() >= maxV() ); case CIRCLE: return ( (position.distance(bounding_obj.centroid())+ ((const BoundingCircle&)bounding_obj).getRadius()) <= radius ); default: break; } return false; }
// ----------------------------------------------------------------------- // // // ROUTINE: CDebugLineFX::OnServerMessage // // PURPOSE: Read an update message from the server. // // ----------------------------------------------------------------------- // LTBOOL CDebugLineFX::OnServerMessage(ILTMessage_Read * pMsg) { // Read the number of lines. const int num_lines = pMsg->Readuint16(); // Set the new maximum number of lines m_nMaxLines = pMsg->Readuint32(); // See if the server is telling us to clear our old lines. m_bClearOldLines = (pMsg->Readuint8() != 0); #ifdef DEBUGLINEFX_DEBUG g_pLTClient->CPrint("Reading %d lines, clear lines is %s.", num_lines, m_bClearOldLines ? "true" : "false"); #endif // If we don't have any lines, we want to clear our old lines // so that the object will be re-positioned correctly. if( lines.empty() ) m_bClearOldLines = true; // Clear the lines from memory. The lines will be removed from // the line system in Update. if( m_bClearOldLines ) { #ifdef DEBUGLINEFX_DEBUG g_pLTClient->CPrint("Clearing %d lines.", lines.size()); #endif lines.clear(); } // Read each line. DebugLine new_line; LT_LINEF new_linef; LTVector maxV(0.0f,0.0f,0.0f); LTVector minV(0.0f,0.0f,0.0f); bool first = true; for(int i = 0; i < num_lines; ++i) { pMsg->ReadType(&new_line); new_linef.verts[0].x = new_line.vSource.x; new_linef.verts[0].y = new_line.vSource.y; new_linef.verts[0].z = new_line.vSource.z; new_linef.verts[1].x = new_line.vDest.x; new_linef.verts[1].y = new_line.vDest.y; new_linef.verts[1].z = new_line.vDest.z; new_linef.rgba.r = new_line.rgba.r; new_linef.rgba.g = new_line.rgba.g; new_linef.rgba.b = new_line.rgba.b; new_linef.rgba.a = new_line.rgba.a; lines.push_back( new_linef ); if (first) { first = false; maxV.x = Max(new_line.vSource.x,new_line.vDest.x); maxV.y = Max(new_line.vSource.y,new_line.vDest.y); maxV.z = Max(new_line.vSource.z,new_line.vDest.z); minV.x = Min(new_line.vSource.x,new_line.vDest.x); minV.y = Min(new_line.vSource.y,new_line.vDest.y); minV.z = Min(new_line.vSource.z,new_line.vDest.z); } else { maxV.x = Max(maxV.x,new_line.vSource.x); maxV.y = Max(maxV.y,new_line.vSource.y); maxV.z = Max(maxV.z,new_line.vSource.z); maxV.x = Max(maxV.x,new_line.vDest.x); maxV.y = Max(maxV.y,new_line.vDest.y); maxV.z = Max(maxV.z,new_line.vDest.z); minV.x = Min(minV.x,new_line.vSource.x); minV.y = Min(minV.y,new_line.vSource.y); minV.z = Min(minV.z,new_line.vSource.z); minV.x = Min(minV.x,new_line.vDest.x); minV.y = Min(minV.y,new_line.vDest.y); minV.z = Min(minV.z,new_line.vDest.z); } } char szDebugString[256]; pMsg->ReadString(szDebugString,sizeof(szDebugString)); m_pStr->SetText(szDebugString); if (num_lines) { vStrPos = (maxV + minV) / 2.0f; vStrPos.y += 16.0f; uint32 color = SET_ARGB(new_linef.rgba.a,new_linef.rgba.r,new_linef.rgba.g,new_linef.rgba.b); m_pStr->SetColor(color); } // Make sure the lines get updated. m_bUpdateLines = true; return LTTRUE; }
robot::robot(std::string filename,bool hideCollisionLinks,bool hideJoints,bool convexDecomposeNonConvexCollidables,bool createVisualIfNone,bool showConvexDecompositionDlg,bool centerAboveGround,bool makeModel,bool noSelfCollision,bool positionCtrl): filenameAndPath(filename) { printToConsole("URDF import operation started."); openFile(); readJoints(); readLinks(); readSensors(); createJoints(hideJoints,positionCtrl); createLinks(hideCollisionLinks,convexDecomposeNonConvexCollidables,createVisualIfNone,showConvexDecompositionDlg); createSensors(); std::vector<int> parentlessObjects; std::vector<int> allShapes; std::vector<int> allObjects; std::vector<int> allSensors; for (int i=0;i<int(vLinks.size());i++) { if (simGetObjectParent(vLinks[i]->nLinkVisual)==-1) parentlessObjects.push_back(vLinks[i]->nLinkVisual); allObjects.push_back(vLinks[i]->nLinkVisual); allShapes.push_back(vLinks[i]->nLinkVisual); if (vLinks[i]->nLinkCollision!=-1) { if (simGetObjectParent(vLinks[i]->nLinkCollision)==-1) parentlessObjects.push_back(vLinks[i]->nLinkCollision); allObjects.push_back(vLinks[i]->nLinkCollision); allShapes.push_back(vLinks[i]->nLinkCollision); } } for (int i=0;i<int(vJoints.size());i++) { if (vJoints[i]->nJoint!=-1) { if (simGetObjectParent(vJoints[i]->nJoint)==-1) parentlessObjects.push_back(vJoints[i]->nJoint); allObjects.push_back(vJoints[i]->nJoint); } } for (int i=0;i<int(vSensors.size());i++) { if (vSensors[i]->nSensor!=-1) { if (simGetObjectParent(vSensors[i]->nSensor)==-1) parentlessObjects.push_back(vSensors[i]->nSensor); allObjects.push_back(vSensors[i]->nSensor); allSensors.push_back(vSensors[i]->nSensor); } if (vSensors[i]->nSensorAux!=-1) { allObjects.push_back(vSensors[i]->nSensorAux); allSensors.push_back(vSensors[i]->nSensorAux); } } // If we want to alternate respondable mask: if (!noSelfCollision) { for (int i=0;i<int(parentlessObjects.size());i++) setLocalRespondableMaskCummulative_alternate(parentlessObjects[i],true); } // Now center the model: if (centerAboveGround) { bool firstValSet=false; C3Vector minV,maxV; for (int shNb=0;shNb<int(allShapes.size());shNb++) { float* vertices; int verticesSize; int* indices; int indicesSize; if (simGetShapeMesh(allShapes[shNb],&vertices,&verticesSize,&indices,&indicesSize,NULL)!=-1) { C7Vector tr; simGetObjectPosition(allShapes[shNb],-1,tr.X.data); C3Vector euler; simGetObjectOrientation(allShapes[shNb],-1,euler.data); tr.Q.setEulerAngles(euler); for (int i=0;i<verticesSize/3;i++) { C3Vector v(vertices+3*i); v*=tr; if (!firstValSet) { minV=v; maxV=v; firstValSet=true; } else { minV.keepMin(v); maxV.keepMax(v); } } simReleaseBuffer((char*)vertices); simReleaseBuffer((char*)indices); } } C3Vector shiftAmount((minV+maxV)*-0.5f); shiftAmount(2)+=(maxV(2)-minV(2))*0.5f; for (int i=0;i<int(parentlessObjects.size());i++) { C3Vector p; simGetObjectPosition(parentlessObjects[i],-1,p.data); p+=shiftAmount; simSetObjectPosition(parentlessObjects[i],-1,p.data); } } // Now create a model bounding box if that makes sense: if ((makeModel)&&(parentlessObjects.size()==1)) { int p=simGetModelProperty(parentlessObjects[0]); p|=sim_modelproperty_not_model; simSetModelProperty(parentlessObjects[0],p-sim_modelproperty_not_model); for (int i=0;i<int(allObjects.size());i++) { if (allObjects[i]!=parentlessObjects[0]) { int p=simGetObjectProperty(allObjects[i]); simSetObjectProperty(allObjects[i],p|sim_objectproperty_selectmodelbaseinstead); } } for (int i=0;i<int(allSensors.size());i++) { if (allSensors[i]!=parentlessObjects[0]) { int p=simGetObjectProperty(allSensors[i]); simSetObjectProperty(allSensors[i],p|sim_objectproperty_dontshowasinsidemodel); // sensors are usually large and it is ok if they do not appear as inside of the model bounding box! } } } // Now select all new objects: simRemoveObjectFromSelection(sim_handle_all,-1); for (int i=0;i<int(allObjects.size());i++) simAddObjectToSelection(sim_handle_single,allObjects[i]); printToConsole("URDF import operation finished.\n\n"); }
inline iterator iat (uoff_t pos) { return (begin() + minV (pos, size())); }
inline const_iterator iat (uoff_t pos) const { return (begin() + minV (pos, size())); }
void MVListBase::selectNext(uint direction,int count,ulong modifiers, ibool toTop) /**************************************************************************** * * Function: MVListBase::selectNext * Parameters: direction - Flags indicating the direction to move * count - Number of cells to move down * modifiers - Keyboard shift modifiers * toTop - True if the cell should be moved to the top * * Description: Adjusts the selection by the specified number of cells in * the specified direction. If the shift modifiers are set, * then the selection is extended. * ****************************************************************************/ { MVPoint oldCursor(cursor); int maxv = maxV(),minv = minV(); int maxh = maxH(),minh = minH(); if (direction & lsBelow) if ((cursor.y += count) > maxv) cursor.y = maxv; if (direction & lsAbove) if ((cursor.y -= count) < minv) cursor.y = minv; if (direction & lsRight) if ((cursor.x += count) > maxh) cursor.x = maxh; if (direction & lsLeft) if ((cursor.x -= count) < minh) cursor.x = minh; if (cursor != oldCursor || (flags & lsExtending)) { if ((flags & lsMultipleSelect) && (modifiers & mdShift)) { if (cursor == oldCursor) return; if (direction & lsLeft) { if (flags & lsExtendRight) { // We are currently extending in the opposite direction, // so clear all of the cells from the old cursor position // to one above the new cursor position. If the selection // is only one high, then turn off the extending flags. if (cursor.x <= selection.left()) { flags &= ~lsExtendHoriz; selection.right() = selection.left()+1; selection.left() = cursor.x; if (selection.left() != selection.right()-1) { flags |= lsExtendLeft; selectRange(selection); } } else selection.right() = cursor.x+1; clearRange(selection.right(),selection.top(), oldCursor.x+1,selection.bottom()); } else { // We are currently extending the selection in the same // direction, or have just started to extend the selection flags |= lsExtendLeft; selection.left() = cursor.x; selectRange(cursor.x,selection.top(), oldCursor.x,selection.bottom()); } } if (direction & lsRight) { if (flags & lsExtendLeft) { if (cursor.x >= selection.right()-1) { flags &= ~lsExtendHoriz; selection.left() = selection.right()-1; selection.right() = cursor.x+1; if (selection.left() != selection.right()-1) { flags |= lsExtendRight; selectRange(selection); } } else selection.left() = cursor.x; clearRange(oldCursor.x,selection.top(), selection.left(),selection.bottom()); } else { flags |= lsExtendRight; selection.right() = cursor.x+1; selectRange(oldCursor.x+1,selection.top(), cursor.x+1,selection.bottom()); } } if (direction & lsAbove) { if (flags & lsExtendDown) { if (cursor.y <= selection.top()) { flags &= ~lsExtendVert; selection.bottom() = selection.top()+1; selection.top() = cursor.y; if (selection.top() != selection.bottom()-1) { flags |= lsExtendUp; selectRange(selection); } } else selection.bottom() = cursor.y+1; clearRange(selection.left(),selection.bottom(), selection.right(),oldCursor.y+1); } else { flags |= lsExtendUp; selection.top() = cursor.y; selectRange(selection.left(),cursor.y, selection.right(),oldCursor.y); } } if (direction & lsBelow) { if (flags & lsExtendUp) { if (cursor.y >= selection.bottom()-1) { flags &= ~lsExtendVert; selection.top() = selection.bottom()-1; selection.bottom() = cursor.y+1; if (selection.top() != selection.bottom()-1) { flags |= lsExtendDown; selectRange(selection); } } else selection.top() = cursor.y; clearRange(selection.left(),oldCursor.y, selection.right(),selection.top()); } else { flags |= lsExtendDown; selection.bottom() = cursor.y+1; selectRange(selection.left(),oldCursor.y+1, selection.right(),cursor.y+1); } } dirtyCell(oldCursor); } else { // The selection is not being extended, so clear any previous // selection and turn extending off, and reselect the cell // under the cursor. flags &= ~lsExtending; if (!(flags & lsDisjointSelect)) { clearSelection(); selectCell(cursor); } else { dirtyCell(oldCursor); dirtyCell(cursor); } } MV_message(owner,evBroadcast,cmListCursorChanged,this); refresh(); } focusCurrent(toTop); }