Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to determine the working area of the desktop even when the taskbar is hidden.

I have two Rectangles, the screen's bounds and the taskbar's bounds. I need to subtract the taskbar's bounds Rectangle from the screen Rectangle to determine the available working area of the desktop. Basically, I want to come up with Screen.WorkingArea except when the taskbar is hidden.

Say the screen rectangle X,Y,W,H = 0,0,1680,1050 and the taskbar X,Y,W,H is 0,1010,1680,40. I need to subtract the second from the first to determine that the working area is 0,0,1680,1010.

The taskbar can be on either of the four sides of the screen and I know there's got to be a better method than determining where the taskbar is and then having a separate line of code to generate a new Rectangle for each of the four possible positions.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
218 views
Welcome To Ask or Share your Answers For Others

1 Answer

Assuming rectangle 2 is contained in rectangle 1 (if not, use the intersection of both rectangles as the rectangle 2):

-------------------------
|      rectangle 1      |
|                       |
|     -------------     |
|     |rectangle 2|     |
|     -------------     |
|                       |
|                       |
-------------------------

If you subtract rectangle 2 from rectangle 1, you will get an area with a hole:

-------------------------
|                       |
|                       |
|     -------------     |
|     |    hole   |     |
|     -------------     |
|                       |
|                       |
-------------------------

This area can be decomposed into 4 rectangles:

-------------------------
|          A            |
|                       |
|-----------------------|
|  B  |   hole    |  C  |
|-----------------------|
|                       |
|          D            |
-------------------------

If rectangle 1 and rectangle 2 are three sides coincident, you will get 1 rectangle from the subtracted area (which is your case). In general, you will get at most 4 rectangles.

The implementation in objective-c (sorry, don't have visual studio at this moment):

// returns the rectangles which are part of rect1 but not part of rect2
NSArray* rectSubtract(CGRect rect1, CGRect rect2)
{
    if (CGRectIsEmpty(rect1)) {
        return @[];
    }
    CGRect intersectedRect = CGRectIntersection(rect1, rect2);

    // No intersection
    if (CGRectIsEmpty(intersectedRect)) {
        return @[[NSValue valueWithCGRect:rect1]];
    }

    NSMutableArray* results = [NSMutableArray new];

    CGRect remainder;
    CGRect subtractedArea;
    subtractedArea = rectBetween(rect1, intersectedRect, &remainder, CGRectMaxYEdge);

    if (!CGRectIsEmpty(subtractedArea)) {
        [results addObject:[NSValue valueWithCGRect:subtractedArea]];
    }

    subtractedArea = rectBetween(remainder, intersectedRect, &remainder, CGRectMinYEdge);
    if (!CGRectIsEmpty(subtractedArea)) {
        [results addObject:[NSValue valueWithCGRect:subtractedArea]];
    }

    subtractedArea = rectBetween(remainder, intersectedRect, &remainder, CGRectMaxXEdge);
    if (!CGRectIsEmpty(subtractedArea)) {
        [results addObject:[NSValue valueWithCGRect:subtractedArea]];
    }

    subtractedArea = rectBetween(remainder, intersectedRect, &remainder, CGRectMinXEdge);
    if (!CGRectIsEmpty(subtractedArea)) {
        [results addObject:[NSValue valueWithCGRect:subtractedArea]];
    }

    return results;
}

// returns the area between rect1 and rect2 along the edge
CGRect rectBetween(CGRect rect1, CGRect rect2, CGRect* remainder, CGRectEdge edge)
{
    CGRect intersectedRect = CGRectIntersection(rect1, rect2);
    if (CGRectIsEmpty(intersectedRect)) {
        return CGRectNull;
    }

    CGRect rect3;
    float chopAmount = 0;
    switch (edge) {
        case CGRectMaxYEdge:
            chopAmount = rect1.size.height - (intersectedRect.origin.y - rect1.origin.y);
            if (chopAmount > rect1.size.height) { chopAmount = rect1.size.height; }
            break;
        case CGRectMinYEdge:
            chopAmount = rect1.size.height - (CGRectGetMaxY(rect1) - CGRectGetMaxY(intersectedRect));
            if (chopAmount > rect1.size.height) { chopAmount = rect1.size.height; }
            break;
        case CGRectMaxXEdge:
            chopAmount = rect1.size.width - (intersectedRect.origin.x - rect1.origin.x);
            if (chopAmount > rect1.size.width) { chopAmount = rect1.size.width; }
            break;
        case CGRectMinXEdge:
            chopAmount = rect1.size.width - (CGRectGetMaxX(rect1) - CGRectGetMaxX(intersectedRect));
            if (chopAmount > rect1.size.width) { chopAmount = rect1.size.width; }
            break;
        default:
            break;
    }

    CGRectDivide(rect1, remainder, &rect3, chopAmount, edge);

    return rect3;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...