vrtc / flowerpicker (public) (License: GPLv3) (since 2019-11-07) (hash sha1)
Flowerpicker is a GUI extension, that is an add-on, for World of Warcraft game client. It is under development and not yet ready for usage by players.
List of commits:
Subject Hash Author Date (UTC)
Add date filter and update report menu graphics ce4a1f43ddcbcc0335bc48846e822c3ce2e8dbcb Vladyslav Bondarenko 2019-11-16 02:42:57
Add page edit box 29145203c22b9da8098138abfa32c76b16fcde3f Vladyslav Bondarenko 2019-11-15 17:38:28
Add draggable desktop icon af19ebc80cbfba6c60e955d508d5de8724f510cc Vladyslav Bondarenko 2019-11-15 16:17:34
Fix build script to package documentation add58a0668c2d726f2cb7a06ab44890308961f9b Vladyslav Bondarenko 2019-11-12 17:05:08
Add Luacheck static analysis with Gradle b9274ae52d8de1c6f3be31cd967d09d6f3ae1cf8 Vladyslav Bondarenko 2019-11-12 16:50:47
Apply LDoc with Gradle 3643910c9413638c6c5ef0224fe106758dcf18eb Vladyslav Bondarenko 2019-11-12 14:08:46
Add report at runtime mock 1401862377ee083669c51fb850c8b0a97154b68b Vladyslav Bondarenko 2019-11-11 20:30:53
Add basic fishing registration ec6c45c1c89890cad3ae591d2483c47b94cacf86 Vladyslav Bondarenko 2019-11-08 18:57:30
Add world resource node harvest registration 2c7e1542abf677efc70a616291921f92ed9c04dd Vladyslav Bondarenko 2019-11-07 12:16:39
Update registration of money operations f0b4ec71099900dd51b5a4c35ce688586d6ddbfe Vladyslav Bondarenko 2019-11-06 19:49:01
Add basic money income via looting registration 9cfb08138268bb6985db1729c160b444a5e4e56a Vladyslav Bondarenko 2019-11-06 14:07:53
Update event format 554e63f3490dc48befe37fbfacf5c8c9ad188451 Vladyslav Bondarenko 2019-11-06 09:59:18
Initial commit f014031ddd4b2422ef5d000f33ad6602e64c9b36 Vladyslav Bondarenko 2019-11-05 20:29:14
Commit ce4a1f43ddcbcc0335bc48846e822c3ce2e8dbcb - Add date filter and update report menu graphics
Author: Vladyslav Bondarenko
Author date (UTC): 2019-11-16 02:42
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2019-11-16 02:42
Parent(s): 5b487e158a11268fd9003f2a13e5b824d51e7194
Signer:
Signing key:
Signing status: N
Tree: e99c04271e2ebc589ef9f010012c4c091abd638c
File Lines added Lines deleted
.luacheckrc 6 0
Flowerpicker.lua 416 76
File .luacheckrc changed (mode: 100644) (index e7f217c..38bade5)
... ... stds.wow = {
37 37 stds.flowerpicker = { stds.flowerpicker = {
38 38 globals = { globals = {
39 39 "FlowerpickerAddOnFrame", "FlowerpickerAddOnFrame",
40 "FlowerpickerFilterSinceDayEditBox",
41 "FlowerpickerFilterSinceMonthEditBox",
42 "FlowerpickerFilterSinceYearEditBox",
43 "FlowerpickerFilterUntilDayEditBox",
44 "FlowerpickerFilterUntilMonthEditBox",
45 "FlowerpickerFilterUntilYearEditBox",
40 46 "FlowerpickerLootCache", "FlowerpickerLootCache",
41 47 "FlowerpickerPageEditBox", "FlowerpickerPageEditBox",
42 48 "FlowerpickerReportFrame", "FlowerpickerReportFrame",
File Flowerpicker.lua changed (mode: 100644) (index f8ae1ef..4ca4262)
... ... local function sanitiseShort(supposedNumber)
93 93 return sane return sane
94 94 end end
95 95
96 --[[ begin http://lua-users.org/wiki/DayOfWeekAndDaysInMonthExample ]]--
97
98 local function is_leap_year(year)
99 return year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0)
100 end
101
102 local function get_days_in_month(month, year)
103 return month == 2 and is_leap_year(year) and 29
104 or ("\31\28\31\30\31\30\31\31\30\31\30\31"):byte(month)
105 end
106
107 --[[ end http://lua-users.org/wiki/DayOfWeekAndDaysInMonthExample ]]--
108
96 109 --[[-- --[[--
97 110 Maps given value to an integer if possible. Maps given value to an integer if possible.
98 111 Given a number, then returns an integer in [-2147483648, 2147483647]. Given a number, then returns an integer in [-2147483648, 2147483647].
 
... ... local function mapSpellNameToHarvestTypeDesignation(spellName)
437 450 return t return t
438 451 end end
439 452
453 --[[--
454 Access realm name in which event took place property of a given event object.
455 @function getEventRealmName
456 @param event a table that is given event object
457 @return string that is realm name
458 @see createEventHarvest
459 ]]
460 local function getEventRealmName(event)
461 assert (event ~= nil)
462 assert ('table' == type(event))
463 local realmName = sanitiseAnyName(event[1])
464
465 assert (validateAnyName(realmName))
466 return realmName
467 end
468
469 --[[--
470 Access player character name property of a given event object.
471 @function getEventCharacterName
472 @see createEventHarvest
473 @param event a table that is given event object
474 @return string that is player character name
475 ]]
476 local function getEventCharacterName(event)
477 assert (event ~= nil)
478 assert ('table' == type(event))
479 local characterName = sanitiseAnyName(event[2])
480
481 assert (validateAnyName(characterName))
482 return characterName
483 end
484
440 485 --[[-- --[[--
441 486 Access item name property of a given event object. Access item name property of a given event object.
442 487 @function getEventItemName @function getEventItemName
 
... ... local function getEventItemQuantity(event)
485 530 return itemQuantity return itemQuantity
486 531 end end
487 532
533 --[[--
534 ]]
535 local function getEventTimestamptz(event)
536 assert (event ~= nil)
537 assert ('table' == type(event))
538 local timestamptz = sanitiseTimestamp(event[5])
539
540 assert (validateTimestamp(timestamptz))
541 return timestamptz
542 end
543
544 --[[--
545 Checks if a given elements matches a given predicate.
546 @function queryFilter
547 @param element registry entry to filter
548 @param predicateTable a table that is a predicate object to match the element against
549 @return `true` if the element matches, `false` otherwise
550 @see query
551 ]]
552 local function queryFilter(event, predicateTable)
553 assert (event ~= nil)
554 assert ('table' == type(event))
555 assert (predicateTable ~= nil)
556 assert ('table' == type(predicateTable))
557
558 local eventRealmName = getEventRealmName(event)
559 local eventCharacterName = getEventCharacterName(event)
560 local eventTimestamptz = getEventTimestamptz(event)
561
562 local matches = eventRealmName == predicateTable.realmName and
563 eventCharacterName == predicateTable.characterName and
564 (eventTimestamptz >= predicateTable.sinceTimestamptz and
565 eventTimestamptz <= predicateTable.untilTimestamptz)
566
567 assert (matches ~= nil)
568 assert ('boolean' == type(matches))
569 return matches
570 end
571
488 572 --[[-- --[[--
489 573 Event registry accessor. Event registry accessor.
490 574 @function query @function query
491 575 @param dao a table that is the entire event registry to query @param dao a table that is the entire event registry to query
492 576 @return table that is the result set of the query @return table that is the result set of the query
493 577 ]] ]]
494 local function query(dao, pageNumber)
578 local function query(dao, predicateTable, pageNumber)
495 579 assert (dao ~= nil) assert (dao ~= nil)
496 580 assert ('table' == type(dao)) assert ('table' == type(dao))
497 581
582 assert (predicateTable ~= nil)
583 assert ('table' == type(predicateTable))
584
498 585 local p = sanitiseShort(pageNumber) local p = sanitiseShort(pageNumber)
499 586 assert (validatePositiveAndNonZero(p)) assert (validatePositiveAndNonZero(p))
500 587 local maxEntryQuantityPerPage = 16 local maxEntryQuantityPerPage = 16
 
... ... local function query(dao, pageNumber)
514 601 while (i < j) do while (i < j) do
515 602 i = i + 1 i = i + 1
516 603 e = dao[i] e = dao[i]
517 eventType = getEventTypeDesignation(e)
518 itemName = getEventItemName(e)
519 itemQuantity = getEventItemQuantity(e)
520 local k = 0
521 r = nil
522 while (k < #resultTable) do
523 k = k + 1
524 r = resultTable[k]
525 if eventType == r[1] and itemName == r[2] then
526 r[3] = r[3] + itemQuantity
527 break
528 else
529 r = nil
604 if queryFilter(e, predicateTable) then
605 eventType = getEventTypeDesignation(e)
606 itemName = getEventItemName(e)
607 itemQuantity = getEventItemQuantity(e)
608 local k = 0
609 r = nil
610 while (k < #resultTable) do
611 k = k + 1
612 r = resultTable[k]
613 if eventType == r[1] and itemName == r[2] then
614 r[3] = r[3] + itemQuantity
615 break
616 else
617 r = nil
618 end
619 end
620 if nil == r and #resultTable then
621 r = {eventType, itemName, itemQuantity}
622 table.insert(resultTable, r)
530 623 end end
531 end
532 if nil == r and #resultTable then
533 r = {eventType, itemName, itemQuantity}
534 table.insert(resultTable, r)
535 624 end end
536 625 end end
537 626
 
... ... local function main(self, event, arg1, arg2, arg3, arg4)
1011 1100 end end
1012 1101 end end
1013 1102
1103 local function getFilterDateSinceTimestamptz()
1104 local sinceYearEditBox = FlowerpickerFilterSinceYearEditBox
1105 local sy = sinceYearEditBox:GetNumber()
1106 local sinceMonthEditBox = FlowerpickerFilterSinceMonthEditBox
1107 local sm = sinceMonthEditBox:GetNumber()
1108 local sinceDayEditBox = FlowerpickerFilterSinceDayEditBox
1109 local sd = sinceDayEditBox:GetNumber()
1110 return string.format('%04d-%02d-%02d 00:00:00', sy, sm, sd) .. get_tzoffset(get_timezone())
1111 end
1112
1113 local function getFilterDateUntilTimestamptz()
1114 local untilYearEditBox = FlowerpickerFilterUntilYearEditBox
1115 local uy = untilYearEditBox:GetNumber()
1116 local untilMonthEditBox = FlowerpickerFilterUntilMonthEditBox
1117 local um = untilMonthEditBox:GetNumber()
1118 local untilDayEditBox = FlowerpickerFilterUntilDayEditBox
1119 local ud = untilDayEditBox:GetNumber()
1120 return string.format('%04d-%02d-%02d 23:59:59', uy, um, ud) .. get_tzoffset(get_timezone())
1121 end
1122
1014 1123 --[[-- --[[--
1015 1124 Query event registry and display the results in a report for the player. Query event registry and display the results in a report for the player.
1016 1125 The result of the function is a side effect that updates the state of the The result of the function is a side effect that updates the state of the
 
... ... local function reportRefresh()
1027 1136 local e local e
1028 1137 local et local et
1029 1138 local dao = FlowerpickerSavedVariables local dao = FlowerpickerSavedVariables
1139
1140 local predicateTable = {
1141 realmName = GetRealmName(),
1142 characterName = UnitName('player'),
1143 sinceTimestamptz = getFilterDateSinceTimestamptz(),
1144 untilTimestamptz = getFilterDateUntilTimestamptz(),
1145 }
1146
1030 1147 local pageEditBox = FlowerpickerPageEditBox local pageEditBox = FlowerpickerPageEditBox
1031 1148 assert (pageEditBox ~= nil) assert (pageEditBox ~= nil)
1032 1149 assert ('table' == type(pageEditBox)) assert ('table' == type(pageEditBox))
 
... ... local function reportRefresh()
1034 1151 if not validatePositiveAndNonZero(pageNumber) then if not validatePositiveAndNonZero(pageNumber) then
1035 1152 pageNumber = 1 pageNumber = 1
1036 1153 end end
1037 local resultTable = query(dao, pageNumber)
1154 local resultTable = query(dao, predicateTable, pageNumber)
1038 1155 local reportEntryTableSize = sanitiseShort(#resultTable) local reportEntryTableSize = sanitiseShort(#resultTable)
1039 1156 assert (reportEntryTableSize ~= nil) assert (reportEntryTableSize ~= nil)
1040 1157 assert (reportEntryTableSize >= 0) assert (reportEntryTableSize >= 0)
 
... ... local function reportHide()
1074 1191 f:Hide() f:Hide()
1075 1192 end end
1076 1193
1077 local function createInputBox(newInputBoxName, newInputBoxParent, newInputBoxLengthChars)
1194 local function createEditBox(newInputBoxName, newInputBoxParent, newInputBoxLengthChars)
1078 1195 local newInputBox = CreateFrame("EditBox", newInputBoxName, newInputBoxParent, "InputBoxTemplate"); local newInputBox = CreateFrame("EditBox", newInputBoxName, newInputBoxParent, "InputBoxTemplate");
1079 1196 newInputBox:SetPoint("CENTER", 0, 0); newInputBox:SetPoint("CENTER", 0, 0);
1080 1197 newInputBox:SetSize(16*newInputBoxLengthChars, 16); newInputBox:SetSize(16*newInputBoxLengthChars, 16);
 
... ... local function createInputBox(newInputBoxName, newInputBoxParent, newInputBoxLen
1098 1215 return newInputBox; return newInputBox;
1099 1216 end end
1100 1217
1101 local function initGUIPagination(reportFrame)
1102 local pageEditBoxLenght = 2
1103 local pageEditBox = createInputBox('FlowerpickerPageEditBox', reportFrame, pageEditBoxLenght)
1218 local function reportFilterDateSet(
1219 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1220 untilYearEditBox, untilMonthEditBox, untilDayEditBox,
1221 sinceDateTable, untilDateTable
1222 )
1223 assert (sinceYearEditBox ~= nil)
1224 assert ('table' == type(sinceYearEditBox))
1225 assert (sinceMonthEditBox ~= nil)
1226 assert ('table' == type(sinceMonthEditBox))
1227 assert (sinceDayEditBox ~= nil)
1228 assert ('table' == type(sinceDayEditBox))
1229
1230 assert (untilYearEditBox ~= nil)
1231 assert ('table' == type(untilYearEditBox))
1232 assert (untilMonthEditBox ~= nil)
1233 assert ('table' == type(untilMonthEditBox))
1234 assert (untilDayEditBox ~= nil)
1235 assert ('table' == type(untilDayEditBox))
1236
1237 assert (sinceDateTable ~= nil)
1238 assert ('table' == type(sinceDateTable))
1239 assert (untilDateTable ~= nil)
1240 assert ('table' == type(untilDateTable))
1241
1242 local sinceInstance = time(sinceDateTable)
1243 local untilInstance = time(untilDateTable)
1244 --[[ Note that the argument order to `difftime` function is important. ]]--
1245 local diff = difftime(untilInstance, sinceInstance)
1246 if diff < 0 then
1247 local swapper = untilDateTable
1248 untilDateTable = sinceDateTable
1249 sinceDateTable = swapper
1250 end
1251
1252 sinceYearEditBox:SetNumber(sinceDateTable.year)
1253 sinceMonthEditBox:SetNumber(sinceDateTable.month)
1254 sinceDayEditBox:SetNumber(sinceDateTable.day)
1255
1256 untilYearEditBox:SetNumber(untilDateTable.year)
1257 untilMonthEditBox:SetNumber(untilDateTable.month)
1258 untilDayEditBox:SetNumber(untilDateTable.day)
1259 end
1260
1261 local function reportFilterDateReset(
1262 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1263 untilYearEditBox, untilMonthEditBox, untilDayEditBox,
1264 radioButtonYear, radioButtonMonth, radioButtonDay
1265 )
1266 assert (sinceYearEditBox ~= nil)
1267 assert ('table' == type(sinceYearEditBox))
1268 assert (sinceMonthEditBox ~= nil)
1269 assert ('table' == type(sinceMonthEditBox))
1270 assert (sinceDayEditBox ~= nil)
1271 assert ('table' == type(sinceDayEditBox))
1272
1273 assert (untilYearEditBox ~= nil)
1274 assert ('table' == type(untilYearEditBox))
1275 assert (untilMonthEditBox ~= nil)
1276 assert ('table' == type(untilMonthEditBox))
1277 assert (untilDayEditBox ~= nil)
1278 assert ('table' == type(untilDayEditBox))
1279
1280 assert (radioButtonYear ~= nil)
1281 assert ('table' == type(radioButtonYear))
1282 assert (radioButtonMonth ~= nil)
1283 assert ('table' == type(radioButtonMonth))
1284 assert (radioButtonDay ~= nil)
1285 assert ('table' == type(radioButtonDay))
1286
1287 local sinceDateTable
1288 local untilDateTable
1289 local dateTable = date('*t', time())
1290
1291 assert (dateTable ~= nil)
1292 assert ('table' == type(dateTable))
1293 local d = get_days_in_month(dateTable.month, dateTable.year)
1294
1295 if radioButtonYear:GetChecked() then
1296 sinceDateTable = date('*t',
1297 time{year=dateTable.year, month=1, day=1}
1298 )
1299 untilDateTable = date('*t',
1300 time{year=dateTable.year, month=12, day=d, hour=23, min=59, sec=59}
1301 )
1302 elseif radioButtonMonth:GetChecked() then
1303 sinceDateTable = date('*t',
1304 time{year=dateTable.year, month=dateTable.month, day=1}
1305 )
1306 untilDateTable = date('*t',
1307 time{year=dateTable.year, month=dateTable.month, day=d, hour=23, min=59, sec=59}
1308 )
1309 else
1310 radioButtonDay:SetChecked(true)
1311 sinceDateTable = date('*t',
1312 time{year=dateTable.year, month=dateTable.month, day=dateTable.day, hour=0}
1313 )
1314 untilDateTable = date('*t',
1315 time{year=dateTable.year, month=dateTable.month, day=dateTable.day, hour=23, min=59, sec=59}
1316 )
1317 end
1318
1319 reportFilterDateSet(
1320 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1321 untilYearEditBox, untilMonthEditBox, untilDayEditBox,
1322 sinceDateTable, untilDateTable
1323 )
1324 end
1325
1326 local function initGUIFilterDateCheckButton(
1327 navFrame,
1328 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1329 untilYearEditBox, untilMonthEditBox, untilDayEditBox
1330 )
1331 local radioButtonDay = CreateFrame('CHECKBUTTON',
1332 'FlowerpickerFilterThisDayCheckButton', navFrame, 'UIRadioButtonTemplate')
1333 local radioButtonMonth = CreateFrame('CHECKBUTTON',
1334 'FlowerpickerFilterThisMonthCheckButton', navFrame, 'UIRadioButtonTemplate')
1335 local radioButtonYear = CreateFrame('CHECKBUTTON',
1336 'FlowerpickerFilterThisYearCheckButton', navFrame, 'UIRadioButtonTemplate')
1337
1338 radioButtonDay:SetPoint('TOPLEFT', navFrame, 0, -32*3)
1339 radioButtonMonth:SetPoint('TOPLEFT', navFrame, 0, -32*4)
1340 radioButtonYear:SetPoint('TOPLEFT', navFrame, 0, -32*5)
1341
1342 local radioButtonDayText = getglobal(radioButtonDay:GetName() .. 'Text')
1343 radioButtonDayText:SetText('This day')
1344
1345 local radioButtonMonthText = getglobal(radioButtonMonth:GetName() .. 'Text')
1346 radioButtonMonthText:SetText('This month')
1347
1348 local radioButtonYearText = getglobal(radioButtonYear:GetName() .. 'Text')
1349 radioButtonYearText:SetText('This year')
1350
1351 local function radioButtonOnClickCallback(self)
1352 radioButtonDay:SetChecked(radioButtonDay == self)
1353 radioButtonMonth:SetChecked(radioButtonMonth == self)
1354 radioButtonYear:SetChecked(radioButtonYear == self)
1355 reportFilterDateReset(
1356 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1357 untilYearEditBox, untilMonthEditBox, untilDayEditBox,
1358 radioButtonYear, radioButtonMonth, radioButtonDay
1359 )
1360 end
1361
1362 radioButtonDay:SetScript('OnClick', radioButtonOnClickCallback)
1363 radioButtonMonth:SetScript('OnClick', radioButtonOnClickCallback)
1364 radioButtonYear:SetScript('OnClick', radioButtonOnClickCallback)
1365
1366 return radioButtonYear, radioButtonMonth, radioButtonDay
1367 end
1368
1369 local function initGUIFilterDateEditBox(navFrame)
1370 local sinceYearEditBox = createEditBox('FlowerpickerFilterSinceYearEditBox', navFrame, 4)
1371 sinceYearEditBox:SetPoint('TOPLEFT', navFrame, 0, -32*1)
1372 local sinceMonthEditBox = createEditBox('FlowerpickerFilterSinceMonthEditBox', navFrame, 2)
1373 sinceMonthEditBox:SetPoint('TOPLEFT', navFrame, 16*5, -32*1)
1374 local sinceDayEditBox = createEditBox('FlowerpickerFilterSinceDayEditBox', navFrame, 2)
1375 sinceDayEditBox:SetPoint('TOPLEFT', navFrame, 16*8, -32*1)
1376
1377 local untilYearEditBox = createEditBox('FlowerpickerFilterUntilYearEditBox', navFrame, 4)
1378 untilYearEditBox:SetPoint('TOPLEFT', navFrame, 0, -32*2)
1379 local untilMonthEditBox = createEditBox('FlowerpickerFilterUntilMonthEditBox', navFrame, 2)
1380 untilMonthEditBox:SetPoint('TOPLEFT', navFrame, 16*5, -32*2)
1381 local untilDayEditBox = createEditBox('FlowerpickerFilterUntilDayEditBox', navFrame, 2)
1382 untilDayEditBox:SetPoint('TOPLEFT', navFrame, 16*8, -32*2)
1383
1384 return sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1385 untilYearEditBox, untilMonthEditBox, untilDayEditBox
1386 end
1387
1388 local function initGUIFilterDate(reportFrame)
1389 local sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1390 untilYearEditBox, untilMonthEditBox, untilDayEditBox = initGUIFilterDateEditBox(reportFrame)
1391
1392 local radioButtonYear, radioButtonMonth, radioButtonDay = initGUIFilterDateCheckButton(reportFrame,
1393 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1394 untilYearEditBox, untilMonthEditBox, untilDayEditBox
1395 )
1396
1397 reportFilterDateReset(
1398 sinceYearEditBox, sinceMonthEditBox, sinceDayEditBox,
1399 untilYearEditBox, untilMonthEditBox, untilDayEditBox,
1400 radioButtonYear, radioButtonMonth, radioButtonDay
1401 )
1402 end
1403
1404 local function initGUIFilter(reportFrame)
1405 initGUIFilterDate(reportFrame)
1406 end
1407
1408 local function initGUIPagination(navFrame)
1409 local pageEditBoxLength = 2
1410 local pageEditBox = createEditBox('FlowerpickerPageEditBox', navFrame, pageEditBoxLength)
1104 1411 pageEditBox:SetPoint('BOTTOMRIGHT', -8, 8) pageEditBox:SetPoint('BOTTOMRIGHT', -8, 8)
1105 1412 pageEditBox:SetNumber(1) pageEditBox:SetNumber(1)
1106 1413 pageEditBox:SetScript('OnEnterPressed', reportRefresh) pageEditBox:SetScript('OnEnterPressed', reportRefresh)
 
... ... local function initGUIMinimise()
1133 1440 showBtn:Show() showBtn:Show()
1134 1441 end end
1135 1442
1136 --[[--
1137 Describe the add-on's graphical user interface.
1138 This function instantiates frames that comprise the graphical user interface
1139 of the add-on, specifically report that displays user queries against the
1140 event registry.
1141 @function initGUI
1142 @see init
1143 @param addonFrame table that is game frame to attach the GUI frame to
1144 @return void
1145 ]]
1146 local function initGUI(addonFrame)
1147 assert (nil ~= addonFrame)
1148 assert ('table' == type(addonFrame))
1149 addonFrame:Show()
1150
1151 local reportFrame = CreateFrame('FRAME', 'FlowerpickerReportFrame', addonFrame)
1152 reportFrame:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', 128, -128)
1153 reportFrame:SetSize(768, 512)
1154 reportFrame:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background",
1155 edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
1156 tile = true, tileSize = 16, edgeSize = 16,
1157 insets = { left = 4, right = 4, top = 4, bottom = 4 }});
1158 reportFrame:SetBackdropColor(0, 0, 0, 1);
1159
1160 local minimiseBtn = CreateFrame('BUTTON', 'FlowerpickerButtonMinimise', reportFrame, 'UIPanelButtonTemplate')
1161 minimiseBtn:SetPoint('TOPRIGHT', reportFrame, 'TOPRIGHT', 0, 0)
1162 minimiseBtn:SetSize(256, 32)
1163 minimiseBtn:SetText('Hide report')
1443 local function initGUIHead(reportFrame)
1444 local headFrame = CreateFrame('FRAME', 'FlowerpickerHeadFrame', reportFrame)
1445 headFrame:SetSize(reportFrame:GetWidth(), 32)
1446 headFrame:SetPoint('TOPLEFT', reportFrame, 'TOPLEFT', 0, 32)
1447
1448 local headBackground = headFrame:CreateTexture(headFrame:GetName() .. 'Background', 'BACKGROUND')
1449 headBackground:SetAllPoints()
1450 headBackground:SetTexture(53 / 255, 185 / 255, 79 / 171, 1)
1451
1452 local header = headFrame:CreateFontString('FlowerpickerHeaderText', 'OVERLAY')
1453 header:SetAllPoints()
1454 header:SetFont("Interface\\AddOns\\flowerpicker\\DejaVuSansMono.ttf", 16)
1455 header:SetText('Flowerpicker report')
1456 header:SetTextColor(1, 1, 1)
1457 headFrame.text = header
1458
1459 local minimiseBtn = CreateFrame('BUTTON', 'FlowerpickerMinimiseButton', headFrame, 'UIPanelButtonTemplate')
1460 minimiseBtn:SetPoint('TOPRIGHT', headFrame, 'TOPRIGHT', 0, 0)
1461 minimiseBtn:SetSize(32, 32)
1462 minimiseBtn:SetText('X')
1164 1463 minimiseBtn:SetScript('OnClick', reportHide) minimiseBtn:SetScript('OnClick', reportHide)
1165 1464 minimiseBtn:Show() minimiseBtn:Show()
1465 return headFrame
1466 end
1467
1468 local function initGUINav(reportFrame)
1469 local navFrame = CreateFrame('FRAME', 'FlowerpickerNavFrame', reportFrame)
1470 navFrame:SetSize(256, reportFrame:GetHeight())
1471 navFrame:SetPoint('TOPRIGHT', reportFrame, 'TOPRIGHT', 0, 0)
1472
1473 local navBackground = navFrame:CreateTexture(navFrame:GetName() .. 'Background', 'BACKGROUND')
1474 navBackground:SetAllPoints()
1475 navBackground:SetTexture(23 / 255, 63 / 255, 79 / 255, 1)
1476
1477 initGUIPagination(navFrame)
1478 initGUIFilter(navFrame)
1166 1479
1167 local nextBtn = CreateFrame('BUTTON', 'FlowerpickerButtonNext', reportFrame, 'UIPanelButtonTemplate')
1168 nextBtn:SetPoint('TOPRIGHT', reportFrame, 'TOPRIGHT', 0, -32*1)
1169 nextBtn:SetSize(256, 32)
1170 nextBtn:SetText('Next')
1171 nextBtn:Show()
1480 local refreshBtn = CreateFrame('BUTTON', 'FlowerpickerRefreshButton', navFrame, 'UIPanelButtonTemplate')
1481 refreshBtn:SetPoint('BOTTOMLEFT', navFrame, 'BOTTOMLEFT', 0, 32)
1482 refreshBtn:SetSize(navFrame:GetWidth(), 32)
1483 refreshBtn:SetText('Refresh')
1484 refreshBtn:SetScript('OnClick', reportRefresh)
1172 1485
1173 local prevBtn = CreateFrame('BUTTON', 'FlowerpickerButtonPrevious', reportFrame, 'UIPanelButtonTemplate')
1174 prevBtn:SetPoint('TOPRIGHT', reportFrame, 'TOPRIGHT', 0, -32*2)
1175 prevBtn:SetSize(256, 32)
1176 prevBtn:SetText('Previous')
1177 prevBtn:Show()
1486 return navFrame
1487 end
1488
1489 local function initGUIMain(reportFrame)
1490 local mainFrame = CreateFrame('FRAME', 'FlowerpickerMainFrame', reportFrame)
1491 mainFrame:SetSize(512, 512)
1492 mainFrame:SetPoint('TOPLEFT', reportFrame, 'TOPLEFT', 0, 0)
1178 1493
1179 reportFrame.entryTable = {}
1494 local mainBackground = mainFrame:CreateTexture(mainFrame:GetName() .. 'Background', 'BACKGROUND')
1495 mainBackground:SetAllPoints()
1496 mainBackground:SetTexture(3 / 255, 9 / 255, 13 / 255, 1)
1497
1498 mainFrame.entryTable = {}
1180 1499 local maxEntryQuantityPerPage = 16 local maxEntryQuantityPerPage = 16
1181 1500 local offseth local offseth
1182 1501 local en local en
1183 local ew = 512
1184 local eh = 32
1502 local ew = mainFrame:GetWidth()
1503 local eh = mainFrame:GetHeight() / maxEntryQuantityPerPage
1185 1504 local i = 0 local i = 0
1186 1505 local e local e
1187 1506 local et local et
 
... ... local function initGUI(addonFrame)
1192 1511 e = CreateFrame('FRAME', en, reportFrame) e = CreateFrame('FRAME', en, reportFrame)
1193 1512 e:SetSize(ew, eh) e:SetSize(ew, eh)
1194 1513 e:SetPoint('TOPLEFT', reportFrame, 'TOPLEFT', 0, offseth) e:SetPoint('TOPLEFT', reportFrame, 'TOPLEFT', 0, offseth)
1195 e:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background",
1196 edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
1197 tile = true, tileSize = 16, edgeSize = 16,
1198 insets = { left = 4, right = 4, top = 4, bottom = 4 }});
1199 e:SetBackdropColor(0, 0, 0, 1);
1200 1514
1201 1515 et = e:CreateFontString(e:GetName() .. 'Text', 'OVERLAY') et = e:CreateFontString(e:GetName() .. 'Text', 'OVERLAY')
1202 1516 et:SetFont("Interface\\AddOns\\flowerpicker\\DejaVuSansMono.ttf", 14) et:SetFont("Interface\\AddOns\\flowerpicker\\DejaVuSansMono.ttf", 14)
 
... ... local function initGUI(addonFrame)
1206 1520
1207 1521 assert (e ~= nil) assert (e ~= nil)
1208 1522 et:SetText(e:GetName()) et:SetText(e:GetName())
1209 reportFrame.entryTable[i] = e
1523 mainFrame.entryTable[i] = e
1210 1524 end end
1211 1525
1212 reportFrame:Show()
1526 return mainFrame
1527 end
1528
1529 --[[--
1530 Describe the add-on's graphical user interface.
1531 This function instantiates frames that comprise the graphical user interface
1532 of the add-on, specifically report that displays user queries against the
1533 event registry.
1534 @function initGUI
1535 @see init
1536 @param addonFrame table that is game frame to attach the GUI frame to
1537 @return void
1538 ]]
1539 local function initGUI(addonFrame)
1540 assert (nil ~= addonFrame)
1541 assert ('table' == type(addonFrame))
1542 addonFrame:Show()
1543
1544 local reportFrame = CreateFrame('FRAME', 'FlowerpickerReportFrame', addonFrame)
1545 reportFrame:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', 128, -128)
1546 reportFrame:SetSize(768, 512)
1547
1548 initGUIHead(reportFrame)
1549 initGUIMain(reportFrame)
1550 initGUINav(reportFrame)
1213 1551 initGUIMinimise() initGUIMinimise()
1214 initGUIPagination(reportFrame)
1215 1552 reportHide() reportHide()
1216 1553 end end
1217 1554
 
... ... local function init()
1254 1591 local api = { local api = {
1255 1592 ['registerLootGainFromCorpse'] = registerLootGainFromCorpse, ['registerLootGainFromCorpse'] = registerLootGainFromCorpse,
1256 1593 ['registerLootGainFromResourceNode'] = registerLootGainFromResourceNode, ['registerLootGainFromResourceNode'] = registerLootGainFromResourceNode,
1257 ['registerMoneyGainFromCorpse'] = registerMoneyGainFromCorpse
1594 ['registerMoneyGainFromCorpse'] = registerMoneyGainFromCorpse,
1595 ['reportRefresh'] = reportRefresh
1258 1596 } }
1259 1597 addonFrame.api = api addonFrame.api = api
1260 1598
 
... ... local function init()
1289 1627 reportRefresh() reportRefresh()
1290 1628 end end
1291 1629
1292 local frame = CreateFrame('FRAME', 'FlowerpickerAddOnFrame', UIParent)
1293 frame:RegisterEvent('ADDON_LOADED')
1294 frame:SetScript('OnEvent', init)
1630 do
1631 local frame = CreateFrame('FRAME', 'FlowerpickerAddOnFrame', UIParent)
1632 frame:RegisterEvent('ADDON_LOADED')
1633 frame:SetScript('OnEvent', init)
1634 end
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/flowerpicker

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/flowerpicker

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/flowerpicker

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main