Beispiel #1
0
void
drawScoreBoard( BoardCtxt* board )
{
    if ( board->scoreBoardInvalid ) {
        short ii;

        XP_U16 nPlayers = board->gi->nPlayers;
        XP_ASSERT( nPlayers <= MAX_NUM_PLAYERS );
        if ( nPlayers > 0 ) {
            ModelCtxt* model = board->model;
            XP_S16 curTurn = server_getCurrentTurn( board->server );
            XP_U16 selPlayer = board->selPlayer;
            XP_S16 nTilesInPool = server_countTilesInPool( board->server );
            XP_Rect scoreRect = board->scoreBdBounds;
            XP_S16* adjustDim;
            XP_S16* adjustPt;
            XP_U16 remWidth, remHeight, remDim;
            DrawScoreData* dp;
            DrawScoreData datum[MAX_NUM_PLAYERS];
            ScoresArray scores;
            XP_Bool isVertical = !board->scoreSplitHor;
            XP_Bool remFocussed = XP_FALSE;
            XP_Bool focusAll = XP_FALSE;
#ifdef KEYBOARD_NAV
            XP_S16 cursorIndex = -1;
            if ( (board->focussed == OBJ_SCORE) && !board->hideFocus ) {
                focusAll = !board->focusHasDived;
                if ( !focusAll ) {
                    cursorIndex = board->scoreCursorLoc;
                    remFocussed = CURSOR_LOC_REM == cursorIndex;                
                    --cursorIndex;                                              
                }
            }
#endif
            /* Get the scores from the model or by calculating them based on
               the end-of-game state. */
            if ( board->gameOver ) {
                model_figureFinalScores( model, &scores, NULL );
            } else {
                for ( ii = 0; ii < nPlayers; ++ii ) {
                    scores.arr[ii] = model_getPlayerScore( model, ii );
                }
            }

            if ( draw_scoreBegin( board->draw, &board->scoreBdBounds, nPlayers, 
                                  scores.arr, nTilesInPool, 
                                  dfsFor( board, OBJ_SCORE ) ) ) {
                XP_U16 totalDim = 0; /* not counting rem */
                XP_U16 gotPct;

                /* Let platform decide whether the rem: string should be given
                   any space once there are no tiles left.  On Palm that space
                   is clickable to drop a menu, so will probably leave it. */
                if ( !draw_measureRemText( board->draw, &board->scoreBdBounds, 
                                           nTilesInPool, &remWidth, 
                                           &remHeight ) ) {
                    remWidth = remHeight = 0;
                }
                XP_ASSERT( remWidth <= board->scoreBdBounds.width );
                XP_ASSERT( remHeight <= board->scoreBdBounds.height );
                remDim = isVertical? remHeight : remWidth;

                if ( isVertical ) {
                    adjustPt = &scoreRect.top;
                    adjustDim = &scoreRect.height;
                } else {
                    adjustPt = &scoreRect.left;
                    adjustDim = &scoreRect.width;
                }
                *adjustDim -= remDim;

                /* Give as much room as possible to the entry for the player
                   whose turn it is so name can be drawn.  Do that by
                   formatting that player's score last, and passing each time
                   the amount of space left.  Platform code can then fill that
                   space.
                */

                /* figure spacing for each scoreboard entry */
                XP_MEMSET( &datum, 0, sizeof(datum) );
                totalDim = 0;
                for ( dp = datum, ii = 0; ii < nPlayers; ++ii, ++dp ) {
                    LocalPlayer* lp = &board->gi->players[ii];

                    /* This is a hack! */
                    dp->dsi.lsc = board_ScoreCallback;
                    dp->dsi.lscClosure = model;
#ifdef KEYBOARD_NAV
                    if ( (ii == cursorIndex) || focusAll ) {
                        dp->dsi.flags |= CELL_ISCURSOR;
                    }
#endif
                    dp->dsi.playerNum = ii;
                    dp->dsi.totalScore = scores.arr[ii];
                    dp->dsi.isTurn = (ii == curTurn);
                    dp->dsi.name = emptyStringIfNull(lp->name);
                    dp->dsi.selected = board->trayVisState != TRAY_HIDDEN
                        && ii==selPlayer;
                    dp->dsi.isRobot = LP_IS_ROBOT(lp);
                    dp->dsi.isRemote = !lp->isLocal;
                    dp->dsi.nTilesLeft = (nTilesInPool > 0)? -1:
                        model_getNumTilesTotal( model, ii );

                    draw_measureScoreText( board->draw, &scoreRect,
                                           &dp->dsi, &dp->width, 
                                           &dp->height );

                    XP_ASSERT( dp->width <= scoreRect.width );
                    XP_ASSERT( dp->height <= scoreRect.height );
                    totalDim += isVertical ? dp->height : dp->width;
                }

                gotPct = (*adjustDim * 100) / totalDim;
                for ( dp = datum, ii = 0; ii < nPlayers; ++ii, ++dp ) {
                    if ( isVertical ) {
                        dp->height = (dp->height * gotPct) / 100;
                    } else {
                        dp->width = (dp->width * gotPct) / 100;
                    }
                }

                scoreRect = board->scoreBdBounds; /* reset */

                /* at this point, the scoreRect should be anchored at the
                   scoreboard rect's upper left.  */

                if ( remDim > 0 ) {
                    XP_Rect innerRect;
                    *adjustDim = remDim;
                    centerIn( &innerRect, &scoreRect, remWidth, remHeight );
                    draw_drawRemText( board->draw, &innerRect, &scoreRect, 
                                      nTilesInPool, focusAll || remFocussed );
                    *adjustPt += remDim;
#ifdef KEYBOARD_NAV
                    board->remRect = scoreRect;
                    /* Hack: don't let the cursor disappear if Rem: goes
                       away */
                } else if ( board->scoreCursorLoc == CURSOR_LOC_REM ) {
                    board->scoreCursorLoc = selPlayer + 1;
#endif
                }

                board->remDim = remDim;

                for ( dp = datum, ii = 0; ii < nPlayers; ++dp, ++ii ) {
                    XP_Rect innerRect;
                    XP_U16 dim = isVertical? dp->height:dp->width;
                    *adjustDim = board->pti[ii].scoreDims = dim;

                    centerIn( &innerRect, &scoreRect, dp->width, dp->height );
                    draw_score_drawPlayer( board->draw, &innerRect, &scoreRect,
                                           gotPct, &dp->dsi );
#ifdef KEYBOARD_NAV
                    XP_MEMCPY( &board->pti[ii].scoreRects, &scoreRect, 
                               sizeof(scoreRect) );
#endif
                    *adjustPt += *adjustDim;
                }

                draw_objFinished( board->draw, OBJ_SCORE, 
                                  &board->scoreBdBounds, 
                                  dfsFor( board, OBJ_SCORE ) );

                board->scoreBoardInvalid = XP_FALSE;
            }
        }
    }

    drawTimer( board );
} /* drawScoreBoard */
Beispiel #2
0
void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
{
    // load styles used by all widgets
    for(const OTMLNodePtr& node : styleNode->children()) {
        if(node->tag() == "color")
            setColor(node->value<Color>());
        else if(node->tag() == "x")
            setX(node->value<int>());
        else if(node->tag() == "y")
            setY(node->value<int>());
        else if(node->tag() == "pos")
            setPosition(node->value<Point>());
        else if(node->tag() == "width")
            setWidth(node->value<int>());
        else if(node->tag() == "height")
            setHeight(node->value<int>());
        else if(node->tag() == "rect")
            setRect(node->value<Rect>());
        else if(node->tag() == "background")
            setBackgroundColor(node->value<Color>());
        else if(node->tag() == "background-color")
            setBackgroundColor(node->value<Color>());
        else if(node->tag() == "background-offset-x")
            setBackgroundOffsetX(node->value<int>());
        else if(node->tag() == "background-offset-y")
            setBackgroundOffsetY(node->value<int>());
        else if(node->tag() == "background-offset")
            setBackgroundOffset(node->value<Point>());
        else if(node->tag() == "background-width")
            setBackgroundWidth(node->value<int>());
        else if(node->tag() == "background-height")
            setBackgroundHeight(node->value<int>());
        else if(node->tag() == "background-size")
            setBackgroundSize(node->value<Size>());
        else if(node->tag() == "background-rect")
            setBackgroundRect(node->value<Rect>());
        else if(node->tag() == "icon")
            setIcon(stdext::resolve_path(node->value(), node->source()));
        else if(node->tag() == "icon-source")
            setIcon(stdext::resolve_path(node->value(), node->source()));
        else if(node->tag() == "icon-color")
            setIconColor(node->value<Color>());
        else if(node->tag() == "icon-offset-x")
            setIconOffsetX(node->value<int>());
        else if(node->tag() == "icon-offset-y")
            setIconOffsetY(node->value<int>());
        else if(node->tag() == "icon-offset")
            setIconOffset(node->value<Point>());
        else if(node->tag() == "icon-width")
            setIconWidth(node->value<int>());
        else if(node->tag() == "icon-height")
            setIconHeight(node->value<int>());
        else if(node->tag() == "icon-size")
            setIconSize(node->value<Size>());
        else if(node->tag() == "icon-rect")
            setIconRect(node->value<Rect>());
        else if(node->tag() == "opacity")
            setOpacity(node->value<float>());
        else if(node->tag() == "enabled")
            setEnabled(node->value<bool>());
        else if(node->tag() == "visible")
            setVisible(node->value<bool>());
        else if(node->tag() == "checked")
            setChecked(node->value<bool>());
        else if(node->tag() == "dragable")
            setChecked(node->value<bool>());
        else if(node->tag() == "on")
            setOn(node->value<bool>());
        else if(node->tag() == "focusable")
            setFocusable(node->value<bool>());
        else if(node->tag() == "phantom")
            setPhantom(node->value<bool>());
        else if(node->tag() == "size")
            setSize(node->value<Size>());
        else if(node->tag() == "fixed-size")
            setFixedSize(node->value<bool>());
        else if(node->tag() == "clipping")
            setClipping(node->value<bool>());
        else if(node->tag() == "border") {
            auto split = stdext::split(node->value(), " ");
            if(split.size() == 2) {
                setBorderWidth(stdext::safe_cast<int>(split[0]));
                setBorderColor(stdext::safe_cast<Color>(split[1]));
            } else
                throw OTMLException(node, "border param must have its width followed by its color");
        }
        else if(node->tag() == "border-width")
            setBorderWidth(node->value<int>());
        else if(node->tag() == "border-width-top")
            setBorderWidthTop(node->value<int>());
        else if(node->tag() == "border-width-right")
            setBorderWidthRight(node->value<int>());
        else if(node->tag() == "border-width-bottom")
            setBorderWidthBottom(node->value<int>());
        else if(node->tag() == "border-width-left")
            setBorderWidthLeft(node->value<int>());
        else if(node->tag() == "border-color")
            setBorderColor(node->value<Color>());
        else if(node->tag() == "border-color-top")
            setBorderColorTop(node->value<Color>());
        else if(node->tag() == "border-color-right")
            setBorderColorRight(node->value<Color>());
        else if(node->tag() == "border-color-bottom")
            setBorderColorBottom(node->value<Color>());
        else if(node->tag() == "border-color-left")
            setBorderColorLeft(node->value<Color>());
        else if(node->tag() == "margin-top")
            setMarginTop(node->value<int>());
        else if(node->tag() == "margin-right")
            setMarginRight(node->value<int>());
        else if(node->tag() == "margin-bottom")
            setMarginBottom(node->value<int>());
        else if(node->tag() == "margin-left")
            setMarginLeft(node->value<int>());
        else if(node->tag() == "margin") {
            std::string marginDesc = node->value();
            std::vector<std::string> split;
            boost::split(split, marginDesc, boost::is_any_of(std::string(" ")));
            if(split.size() == 4) {
                setMarginTop(stdext::safe_cast<int>(split[0]));
                setMarginRight(stdext::safe_cast<int>(split[1]));
                setMarginBottom(stdext::safe_cast<int>(split[2]));
                setMarginLeft(stdext::safe_cast<int>(split[3]));
            } else if(split.size() == 3) {
                int marginTop = stdext::safe_cast<int>(split[0]);
                int marginHorizontal = stdext::safe_cast<int>(split[1]);
                int marginBottom = stdext::safe_cast<int>(split[2]);
                setMarginTop(marginTop);
                setMarginRight(marginHorizontal);
                setMarginBottom(marginBottom);
                setMarginLeft(marginHorizontal);
            } else if(split.size() == 2) {
                int marginVertical = stdext::safe_cast<int>(split[0]);
                int marginHorizontal = stdext::safe_cast<int>(split[1]);
                setMarginTop(marginVertical);
                setMarginRight(marginHorizontal);
                setMarginBottom(marginVertical);
                setMarginLeft(marginHorizontal);
            } else if(split.size() == 1) {
                int margin = stdext::safe_cast<int>(split[0]);
                setMarginTop(margin);
                setMarginRight(margin);
                setMarginBottom(margin);
                setMarginLeft(margin);
            }
        }
        else if(node->tag() == "padding-top")
            setPaddingTop(node->value<int>());
        else if(node->tag() == "padding-right")
            setPaddingRight(node->value<int>());
        else if(node->tag() == "padding-bottom")
            setPaddingBottom(node->value<int>());
        else if(node->tag() == "padding-left")
            setPaddingLeft(node->value<int>());
        else if(node->tag() == "padding") {
            std::string paddingDesc = node->value();
            std::vector<std::string> split;
            boost::split(split, paddingDesc, boost::is_any_of(std::string(" ")));
            if(split.size() == 4) {
                setPaddingTop(stdext::safe_cast<int>(split[0]));
                setPaddingRight(stdext::safe_cast<int>(split[1]));
                setPaddingBottom(stdext::safe_cast<int>(split[2]));
                setPaddingLeft(stdext::safe_cast<int>(split[3]));
            } else if(split.size() == 3) {
                int paddingTop = stdext::safe_cast<int>(split[0]);
                int paddingHorizontal = stdext::safe_cast<int>(split[1]);
                int paddingBottom = stdext::safe_cast<int>(split[2]);
                setPaddingTop(paddingTop);
                setPaddingRight(paddingHorizontal);
                setPaddingBottom(paddingBottom);
                setPaddingLeft(paddingHorizontal);
            } else if(split.size() == 2) {
                int paddingVertical = stdext::safe_cast<int>(split[0]);
                int paddingHorizontal = stdext::safe_cast<int>(split[1]);
                setPaddingTop(paddingVertical);
                setPaddingRight(paddingHorizontal);
                setPaddingBottom(paddingVertical);
                setPaddingLeft(paddingHorizontal);
            } else if(split.size() == 1) {
                int padding = stdext::safe_cast<int>(split[0]);
                setPaddingTop(padding);
                setPaddingRight(padding);
                setPaddingBottom(padding);
                setPaddingLeft(padding);
            }
        }
        // layouts
        else if(node->tag() == "layout") {
            std::string layoutType;
            if(node->hasValue())
                layoutType = node->value();
            else
                layoutType = node->valueAt<std::string>("type", "");

            if(!layoutType.empty()) {
                UILayoutPtr layout;
                if(layoutType == "horizontalBox")
                    layout = UIHorizontalLayoutPtr(new UIHorizontalLayout(asUIWidget()));
                else if(layoutType == "verticalBox")
                    layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget()));
                else if(layoutType == "grid")
                    layout = UIGridLayoutPtr(new UIGridLayout(asUIWidget()));
                else if(layoutType == "anchor")
                    layout = UIAnchorLayoutPtr(new UIAnchorLayout(asUIWidget()));
                else
                    throw OTMLException(node, "cannot determine layout type");
                setLayout(layout);
            }

            if(node->hasChildren())
                m_layout->applyStyle(node);
        }
        // anchors
        else if(boost::starts_with(node->tag(), "anchors.")) {
            UIWidgetPtr parent = getParent();
            if(!parent) {
                if(m_firstOnStyle)
                    throw OTMLException(node, "cannot create anchor, there is no parent widget!");
                else
                    continue;
            }

            UIAnchorLayoutPtr anchorLayout = parent->getLayout()->asUIAnchorLayout();
            if(!anchorLayout)
                throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!");

            std::string what = node->tag().substr(8);
            if(what == "fill") {
                fill(node->value());
            } else if(what == "centerIn") {
                centerIn(node->value());
            } else {
                Fw::AnchorEdge anchoredEdge = Fw::translateAnchorEdge(what);

                if(node->value() == "none") {
                    removeAnchor(anchoredEdge);
                } else {
                    std::vector<std::string> split = stdext::split(node->value(), ".");
                    if(split.size() != 2)
                        throw OTMLException(node, "invalid anchor description");

                    std::string hookedWidgetId = split[0];
                    Fw::AnchorEdge hookedEdge = Fw::translateAnchorEdge(split[1]);

                    if(anchoredEdge == Fw::AnchorNone)
                        throw OTMLException(node, "invalid anchor edge");

                    if(hookedEdge == Fw::AnchorNone)
                        throw OTMLException(node, "invalid anchor target edge");

                    addAnchor(anchoredEdge, hookedWidgetId, hookedEdge);
                }
            }
            // lua functions
        } else if(boost::starts_with(node->tag(), "@")) {
            // load once
            if(m_firstOnStyle) {
                std::string funcName = node->tag().substr(1);
                std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]";
                g_lua.loadFunction(node->value(), funcOrigin);
                luaSetField(funcName);
            }
            // lua fields value
        } else if(boost::starts_with(node->tag(), "&")) {
            std::string fieldName = node->tag().substr(1);
            std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]";
            g_lua.evaluateExpression(node->value(), fieldOrigin);
            luaSetField(fieldName);
        }
    }
}