Ticket #3212: viewer.patch

File viewer.patch, 19.5 KB (added by s0600204, 9 years ago)

The requested patch, against r17047

  • gui/common/tooltips.js

     
    357357}
    358358
    359359/**
     360 * Returns the resources this entity supplies in the specified entity's tooltip
     361 */
     362function getResourceSupplyTooltip(template)
     363{
     364    if (!template.supply)
     365        return "";
     366
     367    var supply = template.supply;
     368    var type = (supply.type[0] === "treasure") ? supply.type[1] : supply.type[0];
     369
     370    var txt = txtFormats.header[0] + translate("Resource Supply:") + txtFormats.header[1] + " ";
     371    txt += sprintf(translate("%(component)s %(amount)s"), { component: getCostComponentDisplayName(type), amount: supply.amount });
     372
     373    return txt;
     374}
     375
     376/**
    360377 * Returns the population bonus information to display in the specified entity's construction button tooltip.
    361378 */
    362379function getPopulationBonusTooltip(template)
  • gui/page_viewer.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2<page>
     3    <include>common/modern/setup.xml</include>
     4    <include>common/modern/styles.xml</include>
     5    <include>common/modern/sprites.xml</include>
     6
     7    <include>common/setup_resources.xml</include>
     8    <include>common/sprite1.xml</include>
     9    <include>common/styles.xml</include>
     10    <include>common/common_sprites.xml</include>
     11    <include>common/common_styles.xml</include>
     12
     13    <include>viewer/styles.xml</include>
     14    <include>viewer/sprites.xml</include>
     15    <include>viewer/viewer.xml</include>
     16    <include>viewer/setup.xml</include>
     17</page>
  • gui/session/selection_details.js

     
    246246
    247247    // Icon image
    248248    if (template.icon)
     249    {
    249250        Engine.GetGUIObjectByName("icon").sprite = "stretched:session/portraits/" + template.icon;
     251        Engine.GetGUIObjectByName("iconBorder").onpressright = function () { showEntityDetails(entState.template); };
     252    }
    250253    else
    251254        // TODO: we should require all entities to have icons, so this case never occurs
    252255        Engine.GetGUIObjectByName("icon").sprite = "bkFillBlack";
     
    419422        updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection);
    420423    }
    421424}
     425
     426/**
     427 * Pauses game and opens the entity details viewer on a given entity
     428 */
     429function showEntityDetails(entityName = null)
     430{
     431    pauseGame();
     432    var data = { // TODO civ should be that of entity, not that of current player
     433        "entityName" : entityName,
     434        "callback": "resumeGame",
     435        "civ": g_Players[Engine.GetPlayerID()].civ,
     436    };
     437    Engine.PushGuiPage("page_viewer.xml", data);
     438}
  • gui/session/selection_panels.js

     
    303303    "setAction": function(data)
    304304    {
    305305        data.button.onPress = function () { startBuildingPlacement(data.item, data.playerState); };
     306        data.button.onPressRight = function () { showEntityDetails(data.item); };
    306307    },
    307308    "setTooltip": function(data)
    308309    {
     
    833834            // as we're in a loop, we need to limit the scope with a closure
    834835            // else the last value of the loop will be taken, rather than the current one
    835836            button.onpress = (function(template) { return function () { addResearchToQueue(data.unitEntState.id, template); }; })(data.entType[i]);
     837            button.onPressRight = function () { showEntityDetails("tech/"+data.item); };
    836838            // on mouse enter, show a cross over the other icons
    837839            button.onmouseenter = (function(others, icons) {
    838840                return function() {
     
    10551057    "setAction": function(data)
    10561058    {
    10571059        data.button.onPress = function() { addTrainingToQueue(data.selection, data.item, data.playerState); };
     1060        data.button.onPressRight = function () { showEntityDetails(data.item); };
    10581061    },
    10591062    "setCountDisplay": function(data)
    10601063    {
     
    11201123    },
    11211124};
    11221125
    1123 
    1124 
    11251126/**
    11261127 * If two panels need the same space, so they collide,
    11271128 * the one appearing first in the order is rendered.
  • gui/session/selection_panels_middle/single_details_area.xml

     
    6161    </object>
    6262   
    6363    <!-- Big unit icon -->
    64     <object size="-8 -8 88 88" type="image" name="iconBorder" sprite="iconBorder" tooltip_style="sessionToolTip">
     64    <object size="-8 -8 88 88" type="button" name="iconBorder" sprite="iconBorder" tooltip_style="sessionToolTip">
    6565        <object size="1 1 100%-1 100%-1" type="image" name="icon" ghost="true"/>
    6666   
    6767        <!-- Experience bar -->
  • gui/structree/draw.js

     
    3939            stru = g_ParsedData.structures[stru];
    4040            Engine.GetGUIObjectByName("phase["+i+"]_struct["+s+"]_icon").sprite = "stretched:session/portraits/"+stru.icon;
    4141            Engine.GetGUIObjectByName("phase["+i+"]_struct["+s+"]_icon").tooltip = assembleTooltip(stru);
     42            setViewerOnPress("phase["+i+"]_struct["+s+"]_icon", stru);
    4243            Engine.GetGUIObjectByName("phase["+i+"]_struct["+s+"]_name").caption = translate(stru.name.specific);
    4344            thisEle.hidden = false;
    4445
     
    119120    prodEle.sprite = "stretched:session/portraits/"+prod.icon;
    120121    prodEle.tooltip = assembleTooltip(prod);
    121122    prodEle.hidden = false;
     123    setViewerOnPress(prodEle, prod);
    122124    return true;
    123125}
    124126
     127function setViewerOnPress(ele, entity)
     128{
     129    if (typeof ele === "string")
     130        ele = Engine.GetGUIObjectByName(ele);
     131    ele.onpressright = function () { Engine.PushGuiPage("page_viewer.xml", entity); };
     132}
     133
    125134/**
    126135 * Calculate row position offset (accounting for different number of prod rows per phase).
    127136 */
     
    146155    }
    147156}
    148157
    149 
    150158/**
    151159 * Positions certain elements that only need to be positioned once
    152160 * (as <repeat> does not reposition automatically).
     
    256264    if (template.auras)
    257265        txt += getAurasTooltip(template);
    258266
    259     if (template.health)
    260         txt += '\n' + sprintf(translate("%(label)s %(details)s"), {
    261             label: txtFormats.header[0] + translate("Health:") + txtFormats.header[1],
    262             details: template.health
    263         });
     267    txt += getEntityStats(template);
    264268
    265     if (template.healer)
    266         txt += '\n' + getHealerTooltip(template);
    267 
    268     if (template.attack)
    269         txt += '\n' + getAttackTooltip(template);
    270 
    271     if (template.armour)
    272         txt += '\n' + getArmorTooltip(template.armour);
    273 
    274     txt += '\n' + getSpeedTooltip(template);
    275 
    276     if (template.gather)
    277     {
    278         var rates = [];
    279         for (let type in template.gather)
    280             rates.push(sprintf(translate("%(resourceIcon)s %(rate)s"), {
    281                 resourceIcon: getCostComponentDisplayName(type),
    282                 rate: template.gather[type]
    283             }));
    284 
    285         txt += '\n' + sprintf(translate("%(label)s %(details)s"), {
    286             label: txtFormats.header[0] + translate("Gather Rates:") + txtFormats.header[1],
    287             details: rates.join("  ")
    288         });
    289     }
    290 
    291269    return txt;
    292270}
  • gui/structree/helper.js

     
    8787    var template = loadTemplate(templateName);
    8888    return GetTemplateDataHelper(template);
    8989}
     90
     91function getEntityStats(template)
     92{
     93    var txt = "";
     94
     95    if (template.health)
     96        txt += "\n" + sprintf(translate("%(label)s %(details)s"), {
     97            label: txtFormats.header[0] + translate("Health:") + txtFormats.header[1],
     98            details: template.health
     99        });
     100
     101    if (template.healer)
     102        txt += "\n" + getHealerTooltip(template);
     103
     104    if (template.attack)
     105        txt += "\n" + getAttackTooltip(template);
     106
     107    if (template.armour)
     108        txt += "\n" + getArmorTooltip(template.armour);
     109
     110    if (template.speed)
     111        txt += "\n" + getSpeedTooltip(template);
     112
     113    if (template.gather)
     114    {
     115        var rates = [];
     116        for (let type in template.gather)
     117            rates.push(sprintf(translate("%(resourceIcon)s %(rate)s"), {
     118                resourceIcon: getCostComponentDisplayName(type),
     119                rate: template.gather[type]
     120            }));
     121
     122        txt += "\n" + sprintf(translate("%(label)s %(details)s"), {
     123            label: txtFormats.header[0] + translate("Gather Rates:") + txtFormats.header[1],
     124            details: rates.join("  ")
     125        });
     126    }
     127
     128    if (template.supply)
     129        txt += "\n" + getResourceSupplyTooltip(template);
     130
     131    return txt;
     132}
  • gui/structree/load.js

     
    5353    }
    5454
    5555    unit.gather = getGatherRates(templateName);
     56   
     57    unit.history = template.Identity.History;
    5658
    5759    if (template.Heal)
    5860        unit.healer = {
     
    6567        for (let build of template.Builder.Entities._string.split(" "))
    6668        {
    6769            build = build.replace("{civ}", g_SelectedCiv);
    68             if (g_Lists.structures.indexOf(build) < 0)
     70            if (typeof g_Lists !== "undefined" && g_Lists.structures.indexOf(build) < 0)
    6971                g_Lists.structures.push(build);
    7072        }
    7173
     
    8688            structure.required = structure.requiredTechnology;
    8789    }
    8890
     91    structure.history = template.Identity.History;
     92
    8993    structure.production = {
    9094        "technology": [],
    9195        "units": []
     
    97101            {
    98102                build = build.replace("{civ}", g_SelectedCiv);
    99103                structure.production.units.push(build);
    100                 if (g_Lists.units.indexOf(build) < 0)
     104                if (typeof g_Lists !== "undefined" && g_Lists.units.indexOf(build) < 0)
    101105                    g_Lists.units.push(build);
    102106            }
    103107
     
    105109            for (let research of template.ProductionQueue.Technologies._string.split(" "))
    106110            {
    107111                structure.production.technology.push(research);
    108                 if (g_Lists.techs.indexOf(research) < 0)
     112                if (typeof g_Lists !== "undefined" && g_Lists.techs.indexOf(research) < 0)
    109113                    g_Lists.techs.push(research);
    110114            }
    111115    }
  • gui/structree/rows.xml

     
    66            <repeat count="12" var="s">
    77                <object type="image" style="StructBox" name="phase[k]_struct[s]">
    88                    <object type="text" style="StructNameSpecific" name="phase[k]_struct[s]_name"/>
    9                     <object type="image" style="StructIcon" name="phase[k]_struct[s]_icon"
     9                    <object type="button" style="StructIcon" name="phase[k]_struct[s]_icon"
    1010                        sprite="stretched:pregame/shell/logo/wfg_logo_white.png"
    1111                    />
    1212                    <repeat count="4" var="r">
    1313                        <object name="phase[k]_struct[s]_row[r]">
    1414                            <repeat count="16" var="p">
    15                                 <object type="image" style="ProdBox" name="phase[k]_struct[s]_row[r]_prod[p]"/>
     15                                <object type="button" style="ProdBox" name="phase[k]_struct[s]_row[r]_prod[p]"/>
    1616                            </repeat>
    1717                        </object>
    1818                    </repeat>
  • gui/viewer/setup.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<setup>
     4
     5</setup>
  • gui/viewer/sprites.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<sprites>
     4    <sprite name="IconFrame_Gold">
     5        <image
     6            border="true"
     7            bordercolor="163 163 103"
     8            backcolor="0 0 0 0"
     9            size="0 0 100% 100%"
     10        />
     11        <image
     12            border="true"
     13            bordercolor="0 0 0"
     14            backcolor="0 0 0 0"
     15            size="1 1 100%-1 100%-1"
     16        />
     17    </sprite>
     18
     19    <sprite name="ModernDialogNoTitle">
     20
     21        <!-- background -->
     22        <image texture = "global/modern/background.png"
     23            texture_size = "0 0 512 512"
     24            size = "4 0 100%-4 100%-4"
     25        />
     26
     27        <!-- shading -->
     28        <!-- we just mirror the same texture on the top and bottom -->
     29        <image texture = "global/modern/shadow-low.png"
     30            texture_size = "0 0 1024 128"
     31            size = "4 100%-132 100%-4 100%-4"
     32        />
     33
     34        <image texture = "global/modern/shadow-low.png"
     35            texture_size = "1024 128 0 0"
     36            size = "4 0 100%-4 128"
     37        />
     38
     39        <!-- top and bottom edge -->
     40        <image texture = "global/modern/border.png"
     41            real_texture_placement = "0 0 2048 8"
     42            size = "4 0%-4 100%-4 4"
     43        />
     44        <image texture = "global/modern/border.png"
     45            real_texture_placement = "0 0 2048 8"
     46            size = "4 100%-8 100%-4 100%"
     47        />
     48
     49        <!-- corners -->
     50        <image texture = "global/modern/dialog-deco-top.png"
     51            real_texture_placement = "0 0 64 32"
     52            texture_size = "64 0 0 32"
     53            size = "-14 -21 50 11"
     54        />
     55        <image texture = "global/modern/dialog-deco-top.png"
     56            real_texture_placement = "0 0 64 32"
     57            texture_size = "0 0 64 32"
     58            size = "100%-50 -21 100%+14 11"
     59        />
     60        <image texture = "global/modern/dialog-deco-bottom.png"
     61            real_texture_placement = "0 0 64 32"
     62            texture_size = "64 0 0 32"
     63            size = "-31 100%-23 33 100%+9"
     64        />
     65        <image texture = "global/modern/dialog-deco-bottom.png"
     66            real_texture_placement = "0 0 64 32"
     67            texture_size = "0 0 64 32"
     68            size = "100%-31 100%-23 100%+33 100%+9"
     69        />
     70    </sprite>
     71   
     72    <sprite name="ModernTitle">
     73        <image texture = "global/modern/titlebar-middle.png"
     74            real_texture_placement = "0 0 128 32"
     75            size = "50%-108 0 50%+108 33"
     76        />
     77        <image texture = "global/modern/titlebar-left.png"
     78            real_texture_placement = "0 0 32 32"
     79            size = "-36 0 0 33"
     80        />
     81        <image texture = "global/modern/titlebar-left.png"
     82            real_texture_placement = "32 32 0 0"
     83            size = "100% 0 100%+36 33"
     84        />
     85    </sprite>
     86
     87</sprites>
  • gui/viewer/styles.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<styles>
     4    <style name="IconFrame"
     5        sprite="IconFrame_Gold"
     6        size="0 0 100% 100%"
     7        ghost="true"
     8    />
     9
     10    <style name="Title"
     11        textcolor="white"
     12        text_align="center"
     13        text_valign="top"
     14    />
     15
     16    <style name="BodyText"
     17        textcolor="white"
     18        text_align="left"
     19        text_valign="top"
     20    />
     21</styles>
  • gui/viewer/viewer.js

     
     1
     2/* Globals */
     3var g_SelectedCiv = "gaia"; // fallback default
     4var g_CallbackSet = false;
     5
     6/**
     7 * Init. Also populates the gui objects.
     8 *
     9 * @arg template The object or the template name of the entity to be displayed
     10 */
     11function init (template = null) {
     12    if (!template)
     13    {
     14        error("Viewer: No template provided");
     15        closeViewer();
     16        return;
     17    }
     18    else if (typeof template === "string" || template.entityName)
     19    {
     20        var templateName = template.entityName || template;
     21        if (template.callback)
     22            g_CallbackSet = true;
     23        if (template.civ)
     24            g_SelectedCiv = template.civ;
     25
     26        template = loadTemplateFromName(templateName);
     27        if (!template)
     28        {
     29            error("Viewer: unable to recognise or load template: "+templateName);
     30            closeViewer();
     31            return;
     32        }
     33    }
     34
     35    Engine.GetGUIObjectByName("entityName").caption = getEntityNamesFormatted(template);
     36    Engine.GetGUIObjectByName("entityIcon").sprite = "stretched:session/portraits/" + template.icon;
     37
     38    var caption = "";
     39    if (template.cost)
     40        caption += getEntityCostTooltip(template, 1) + "\n";
     41    Engine.GetGUIObjectByName("entityStats").caption = caption + getEntityStats(template);
     42
     43    var txt = "";
     44
     45    if (template.tooltip)
     46        txt += "\n" + txtFormats.body[0] +  translate(template.tooltip) + txtFormats.body[1] + "\n";
     47
     48    if (template.history)
     49        txt += "\n" + txtFormats.body[0] +  translate(template.history) + txtFormats.body[1] + "\n";
     50
     51    if (template.description)
     52        txt += "\n" + txtFormats.body[0] +  translate(template.description) + txtFormats.body[1] + "\n";
     53
     54    if (template.auras)
     55        txt += getAurasTooltip(template) + "\n";
     56   
     57    txt += getVisibleEntityClassesFormatted(template);
     58
     59    Engine.GetGUIObjectByName("entityInfo").caption = txt;
     60}
     61
     62/**
     63 * Determines the requested template and loads it
     64 *
     65 * @arg templateName The template name. If loading a technology, then `tech/` must be prefixed.
     66 * @return The entity object if successful, false if not
     67 */
     68function loadTemplateFromName(templateName)
     69{
     70    if (templateName.indexOf("|") > -1)
     71        templateName = templateName.slice(templateName.indexOf("|")+1);
     72    var prefix = templateName.slice(0, templateName.indexOf("/"));
     73
     74    switch (prefix)
     75    {
     76    case "structures":
     77    case "other":
     78        return loadStructure(templateName);
     79        break;
     80
     81    case "units":
     82        return loadUnit(templateName);
     83        break;
     84
     85    case "gaia":
     86        return loadResource(templateName);
     87        break;
     88
     89    case "tech":
     90        return loadTechnology(templateName.substr(templateName.indexOf("/")+1));
     91        break;
     92
     93    default:
     94        // do nothing (error message is given elsewhere)
     95    }
     96
     97    return false;
     98}
     99
     100/**
     101 * Overrides near-identical function in gui/common/tooltips.js
     102 * (Just so we can get slightly bigger text)
     103 */
     104function getEntityNamesFormatted(template)
     105{
     106    var names = "";
     107    var generic = template.name.generic;
     108    var specific = template.name.specific;
     109    if (specific)
     110    {
     111        // drop caps for specific name
     112        names += '[font="sans-bold-20"]' + specific[0] + '[/font]' +
     113            '[font="sans-bold-16"]' + specific.slice(1).toUpperCase() + '[/font]';
     114
     115        if (generic)
     116            names += '[font="sans-bold-16"] (' + generic + ')[/font]';
     117    }
     118    else if (generic)
     119        names = '[font="sans-bold-20"]' + generic + "[/font]";
     120    else
     121        names = "???";
     122
     123    return names;
     124}
     125
     126function loadResource(templateName)
     127{
     128    var template = loadTemplate(templateName);
     129    var resource = GetTemplateDataHelper(template);
     130
     131    resource.history = template.Identity.History;
     132
     133    resource.supply = {
     134        "type": template.ResourceSupply.Type.split("."),
     135        "amount": template.ResourceSupply.Amount,
     136    };
     137
     138    return resource;
     139}
     140
     141/**
     142 * Closes the page
     143 */
     144function closeViewer()
     145{
     146    if (g_CallbackSet)
     147        Engine.PopGuiPageCB(0);
     148    else
     149        Engine.PopGuiPage();
     150}
  • gui/viewer/viewer.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2
     3<objects>
     4    <script file="gui/common/functions_civinfo.js"/>
     5    <script file="gui/common/functions_utility.js"/>
     6    <script file="gui/common/tooltips.js"/>
     7    <script file="gui/viewer/viewer.js"/>
     8    <script file="gui/structree/helper.js"/>
     9    <script file="gui/structree/load.js"/>
     10
     11    <!-- Add a translucent black background to fade out whatever's behind this -->
     12    <object type="image" z="0" sprite="bkTranslucent"/>
     13
     14    <object type="image" sprite="ModernDialogNoTitle" size="50%-250 50%-300 50%+250 50%+300">
     15
     16        <object name="entityName" type="text" style="Title" size="8 12 100%-8 48"/>
     17
     18        <object name="entityIcon" type="image"
     19            size="16 48 128+16 128+48"
     20            sprite="stretched:pregame/shell/logo/wfg_logo_white.png"
     21        >
     22            <object type="image" style="IconFrame"/>
     23        </object>
     24
     25        <object name="entityStats" type="text" style="BodyText" size="128+20 44 100%-8 50%"/>
     26
     27        <object name="entityInfo" type="text" style="BodyText" size="16 128+48 100%-16 100%"/>
     28
     29        <!-- Close page -->
     30        <object
     31            type="button"
     32            style="StoneButton"
     33            size="100%-164 100%-44 100%-16 100%-16"
     34            hotkey="cancel"
     35        >
     36            <translatableAttribute id="caption">Close</translatableAttribute>
     37            <action on="Press"><![CDATA[
     38                closeViewer();
     39            ]]></action>
     40        </object>
     41    </object>
     42
     43</objects>