Does anyone know how CvVictoryScreen::drawTabs works

Uty

I hate you, Milkman Dan
Joined
Apr 13, 2005
Messages
124
Location
Newark, Delaware
In my military advisor mod I want to add a menu similar to the one you see at the bottom of the CvVictoryScreen. Those items are (I'm pretty sure) added during a call to drawTabs. That function ends up calling screen.setText( ... ) quite a bit. The second argument (attach to) is empty ... which makes no sense to me. Does anyone know how this works?

Fun side note: my changes just cause the advisor screen to be totally blank, aside from the background. Heh.
 
The way it reads to me is that since "screen" is an instance of getScreen, which is in itself a call to CyGInterfaceScreen, you don't need the "attach to" reference, as it is self-referential... In other words, by doing

screen.setText(text, no screen specified)

you are saying put this text on "screen", which is the current screen instance.

That is, if I am understanding you correctly. Unfortunately, according to this link

http://civilization4.net/files/modding/PythonAPI/

CyGInterfaceScreen will not be in the SDK, so a "type/test/type/test" cycle may be the only way to really figure out what is happening.

Sorry if I'm wrong, or not helpful... Which is always possible/probable/likely... :)

And as to your side note on the screen being blank... I had the same thing happen again and again working on my HoF screen mod... It was usually a good sign I'd done something goofy... :)
 
I'm not sure why the argument is empty but would guess the same as Fallblau.

As for your screen being blank, I had this problem at first when adding a new screen to the foreign advisor (including a new tab). It seems like this problem is caused when the panels aren't set up correctly. In the InterfaceScreen function two panels are added to the screen...a top and a bottom panel. But then after those are created, another function is called. Normally this function either itself calls other functions or it first of all creates yet another panel. (this is in most screen classes, after a quick look at the MilitaryAdvisor class it looks like it could be a bit different.)

So using foreign advisor as a example (as I know the code for that screen the best). The interfaceScreen function sets up a few general things about the screen and the top and bottom panels. It then calls a DrawContents function, which then works out what screen should be showing and calls a function to draw that screen.

Now one of the first things each of those (draw screen) functions does, is creates another panel

In the foreign advisor class they use the following code:

mainPanelName = self.getNextWidgetName()
screen.addPanel(mainPanelName, "", "", True, True, 50, 100, self.W_SCREEN - 100, self.H_SCREEN - 200, PanelStyles.PANEL_STYLE_EMPTY)


Then after that, they draw the contents of the screen. Finally after they have finished drawing their own screen contents, they return to the general DrawContents function. Which in the case of the foreign advisor screen, then draws those tabs at the bottom of the screen.

Now what I found out is if you don't add that mainpanel before the tabs (or I think anything else) are drawn then the screen will be blank.

Of course I could be wrong and there could be another reason why my screen was blank when I added a new screen (and its draw function) and forgot to add that main panel at the start of that function.
 
I did look around last night when I was modding, and I found what you're talking about where they add the "top" and "bottom" panels. I tried to add my tabs right there after the bottom panel is initialized, but perhaps there is more processing that needs to be done first.

I'll see what happens if I model the foreign advisor's workflow more closely. I'm a bit concerned about using the GetNextWidget type functions because I havn't been able to figure out what it does. I *speculate* it determines what the current widget is and gets the next one on the "list" that is defined at the beginning of the class. Might as well dive in, the worst that can happen is a blank screen ;)

Thanks both of you for the insight ..
 
I think that will be your problem then...you putting your code straight after the top and bottom panel are added, rather than letting it add the "main panel" as well first. So there should be a top panel, a bottom panel and a main panel.

As for the getnextwidgetname, going by the foreignadvisor class, it basically just makes every widget have a different name by adding a number after a standard widgetname (which is different for each advisor, with the foreign advisor the widgets have the name "ForeignAdvisorWidget" and then the number is added by the nextwidgetname function).

Then in the handle input function, you can check for a inputclass related to a widget with the name "ForeignAdvisorWidget" (note as far as I can tell, any numbers in the name are ignored at this point...) by using:

if (inputClass.getFunctionName() == "ForeignAdvisorWidget")

Then you can check what number it was. I think the way to get this is to call:

inputClass.getID()


Again I could be wrong about all this, but that is how it seems to work.

BTW I don't use the getnextwidget function when adding new widgets. I find it easier just to give them all a name (but making sure they are all different). As I'm still not 100% sure about all of this. So I just have a seperate if line for each widget, like...

if (inputClass.getFunctionName() == "Whatever_name_I_used")

But the one good thing about the getnextwidgetname is that it does keep a record of the widgets named by it, so when the screen is redrawn they are all deleted first (and then redrawn) as they should be. If you use your own names then you need to add the code to the deleteAllWidgets(self) function to delete them.
 
getNextWidgetName is just a way to essentially get around having to keep track of your naming in this sort of case where you are going to create and destroy a "widget" before creating another one... Just a shortcut, I'd imagine...
 
I wrote a function and called it at the end of interfaceScreen(). The menu looks like it always does. Maybe my text isn't getting attached or set in a valid location? Hmm

(With other widget/tab defines)
self.PROMOTE_TAB_ID = "PromoteTabWidget"

(With other non-gui defines)
self.X_LINK = 100
self.Y_LINK = 726

(In a new xml file)
<TEXT>
<Tag>TXT_KEY_MILITARY_PROMOTE_TITLE</Tag>
<English>Promotion</English>
</TEXT>

(last line of interfaceScreen)
self.populateBottomMenu()

(new function .. i've tried it with and without the deleteAllWidgets())
def populateBottomMenu(self):
self.deleteAllWidgets()
screen = self.getScreen()
screen.setText(self.PROMOTE_TAB_ID, "", u"<font=4>" + localText.getText("TXT_KEY_MILITARY_PROMOTE_TITLE", ()).upper() + "</font>", CvUtil.FRONT_CENTER_JUSTIFY, self.X_LINK, self.Y_LINK, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
 
Its hard to tell exactly what you are doing wrong from that code.

If you download a test mod I posted here: http://forums.civfanatics.com/showthread.php?t=140408

It has a new screen (with tab) added to the foreign advisor.

In it the InterfaceScreen function sets up the basic things about the screen, and then calls the DrawContents function.

One of the first things that function does is to see what screen should be showing with the following code:

if (self.iScreen == FOREIGN_TEST):
self.drawtest()
elif (self.iScreen == FOREIGN_RELATIONS_SCREEN):
self.drawRelations(bInitial)
elif (self.iScreen == FOREIGN_ACTIVE_TRADE_SCREEN):
self.drawActive()
else:
self.drawPossibleDeals()

My new screen is the FOREIGN_TEST one. So if that should be showing it will call the drawtest function. In this it first adds the main panel then I add some more widgets (not tabs), then it returns back to the DrawContents function.

Once back in the drawContents function, the tabs are added. My new tab is the last one to be added and the code for it is:

szActivId = self.getNextWidgetName()
if (self.iScreen != FOREIGN_TEST):
screen.setText(szActivId, "", u"<font=4>" + localText.getText("TXT_KEY_FOREIGN_TEST", ()).upper() + u"</font>", CvUtil.FONT_LEFT_JUSTIFY, xLink-50, self.Y_LINK, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_FOREIGN_ADVISOR, FOREIGN_TEST, -1)
else:
screen.setText(szActivId, "", u"<font=4>" + localText.getColorText("TXT_KEY_FOREIGN_TEST", (), gc.getInfoTypeForString("COLOR_YELLOW")).upper() + u"</font>", CvUtil.FONT_LEFT_JUSTIFY, xLink-50, self.Y_LINK, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_FOREIGN_ADVISOR, -1, -1)
xLink += self.DX_LINK
 
Top Bottom